Changes of Revision 16

pipewire-aptx.changes Changed
x
 
1
@@ -1,4 +1,9 @@
2
 -------------------------------------------------------------------
3
+Sat Oct 15 16:39:17 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.59
6
+
7
+-------------------------------------------------------------------
8
 Sun Sep 18 13:29:55 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
9
 
10
 - Update to version 0.3.58
11
pipewire-aptx.spec Changed
10
 
1
@@ -7,7 +7,7 @@
2
 %define soversion 0_2
3
 
4
 Name:           pipewire-aptx
5
-Version:        0.3.58
6
+Version:        0.3.59
7
 Release:        0
8
 Summary:        PipeWire Bluetooth aptX codec plugin
9
 License:        MIT
10
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-peaks-c.c Deleted
39
 
1
@@ -1,37 +0,0 @@
2
-/* Spa
3
- *
4
- * Copyright © 2018 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include <math.h>
27
-
28
-#include "resample-peaks-impl.h"
29
-
30
-static inline float find_abs_max_c(const float *s, uint32_t n_samples, float m)
31
-{
32
-   uint32_t n;
33
-   for (n = 0; n < n_samples; n++)
34
-       m = fmaxf(fabsf(sn), m);
35
-   return m;
36
-}
37
-
38
-MAKE_PEAKS(c);
39
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-peaks-impl.h Deleted
94
 
1
@@ -1,92 +0,0 @@
2
-/* Spa
3
- *
4
- * Copyright © 2020 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include <math.h>
27
-
28
-#include <spa/utils/defs.h>
29
-
30
-#include "resample.h"
31
-
32
-struct peaks_data {
33
-   uint32_t o_count;
34
-   uint32_t i_count;
35
-   float max_f;
36
-};
37
-
38
-#define DEFINE_PEAKS(arch)                     \
39
-void resample_peaks_process_##arch(struct resample *r,         \
40
-   const void * SPA_RESTRICT src, uint32_t *in_len,        \
41
-   void * SPA_RESTRICT dst, uint32_t *out_len)
42
-
43
-#define MAKE_PEAKS(arch)                       \
44
-DEFINE_PEAKS(arch)                         \
45
-{                                  \
46
-   struct peaks_data *pd = r->data;                \
47
-   uint32_t c, i, o, end, chunk, i_count, o_count;         \
48
-                                   \
49
-   if (SPA_UNLIKELY(r->channels == 0))             \
50
-       return;                         \
51
-                                   \
52
-   for (c = 0; c < r->channels; c++) {             \
53
-       const float *s = srcc;              \
54
-       float *d = dstc, m = pd->max_fc;            \
55
-                                   \
56
-       o_count = pd->o_count;                  \
57
-       i_count = pd->i_count;                  \
58
-       o = i = 0;                      \
59
-                                   \
60
-       while (i < *in_len && o < *out_len) {           \
61
-           end = ((uint64_t) (o_count + 1)         \
62
-               * r->i_rate) / r->o_rate;       \
63
-           end = end > i_count ? end - i_count : 0;    \
64
-           chunk = SPA_MIN(end, *in_len);          \
65
-                                   \
66
-           m = find_abs_max_##arch(&si, chunk - i, m); \
67
-                                   \
68
-           i += chunk;                 \
69
-                                   \
70
-           if (i == end) {                 \
71
-               do++ = m;               \
72
-               m = 0.0f;               \
73
-               o_count++;              \
74
-           }                       \
75
-       }                           \
76
-       pd->max_fc = m;                 \
77
-   }                               \
78
-   *out_len = o;                           \
79
-   *in_len = i;                            \
80
-   pd->o_count = o_count;                      \
81
-   pd->i_count = i_count + i;                  \
82
-                                   \
83
-   while (pd->i_count >= r->i_rate) {              \
84
-       pd->i_count -= r->i_rate;               \
85
-       pd->o_count -= r->o_rate;               \
86
-   }                               \
87
-}
88
-
89
-
90
-DEFINE_PEAKS(c);
91
-#if defined (HAVE_SSE)
92
-DEFINE_PEAKS(sse);
93
-#endif
94
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample-peaks-sse.c Deleted
66
 
1
@@ -1,64 +0,0 @@
2
-/* Spa
3
- *
4
- * Copyright © 2018 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include <math.h>
27
-
28
-#include <xmmintrin.h>
29
-
30
-#include "resample-peaks-impl.h"
31
-
32
-static inline float hmax_ps(__m128 val)
33
-{
34
-   __m128 t = _mm_movehl_ps(val, val);
35
-   t = _mm_max_ps(t, val);
36
-   val = _mm_shuffle_ps(t, t, 0x55);
37
-   val = _mm_max_ss(t, val);
38
-   return _mm_cvtss_f32(val);
39
-}
40
-
41
-static inline float find_abs_max_sse(const float *s, uint32_t n_samples, float m)
42
-{
43
-   __m128 in2, max;
44
-   uint32_t n, unrolled;
45
-   const __m128 mask = _mm_set1_ps(-0.0f);
46
-
47
-   max = _mm_set1_ps(m);
48
-
49
-   unrolled = n_samples & ~7;
50
-
51
-   for (n = 0; n < unrolled; n += 8) {
52
-       in0 = _mm_loadu_ps(&sn + 0);
53
-       in1 = _mm_loadu_ps(&sn + 4);
54
-       in0 = _mm_andnot_ps(mask, in0);
55
-       in1 = _mm_andnot_ps(mask, in1);
56
-       max = _mm_max_ps(max, in0);
57
-       max = _mm_max_ps(max, in1);
58
-   }
59
-   for (; n < n_samples; n++)
60
-       m = fmaxf(fabsf(sn), m);
61
-
62
-   return fmaxf(hmax_ps(max), m);
63
-}
64
-
65
-MAKE_PEAKS(sse);
66
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codecs.c Deleted
201
 
1
@@ -1,209 +0,0 @@
2
-/*
3
- * BlueALSA - bluez-a2dp.c
4
- * Copyright (c) 2016-2017 Arkadiusz Bokowy
5
- *
6
- * This file is a part of bluez-alsa.
7
- *
8
- * This project is licensed under the terms of the MIT license.
9
- *
10
- */
11
-
12
-#include <spa/utils/string.h>
13
-
14
-#include "a2dp-codecs.h"
15
-
16
-int a2dp_codec_select_config(const struct a2dp_codec_config configs, size_t n,
17
-                uint32_t cap, int preferred_value)
18
-{
19
-   size_t i;
20
-   int *scores, res;
21
-   unsigned int max_priority;
22
-
23
-   if (n == 0)
24
-       return -EINVAL;
25
-
26
-   scores = calloc(n, sizeof(int));
27
-   if (scores == NULL)
28
-       return -errno;
29
-
30
-   max_priority = configs0.priority;
31
-   for (i = 1; i < n; ++i) {
32
-       if (configsi.priority > max_priority)
33
-           max_priority = configsi.priority;
34
-   }
35
-
36
-   for (i = 0; i < n; ++i) {
37
-       if (!(configsi.config & cap)) {
38
-           scoresi = -1;
39
-           continue;
40
-       }
41
-       if (configsi.value == preferred_value)
42
-           scoresi = 100 * (max_priority + 1);
43
-       else if (configsi.value > preferred_value)
44
-           scoresi = 10 * (max_priority + 1);
45
-       else
46
-           scoresi = 1;
47
-
48
-       scoresi *= configsi.priority + 1;
49
-   }
50
-
51
-   res = 0;
52
-   for (i = 1; i < n; ++i) {
53
-       if (scoresi > scoresres)
54
-           res = i;
55
-   }
56
-
57
-   if (scoresres < 0)
58
-       res = -EINVAL;
59
-
60
-   free(scores);
61
-   return res;
62
-}
63
-
64
-bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id,
65
-              const void *caps, size_t caps_size,
66
-              const struct a2dp_codec_audio_info *info,
67
-              const struct spa_dict *global_settings)
68
-{
69
-   uint8_t configA2DP_MAX_CAPS_SIZE;
70
-   int res;
71
-
72
-   if (codec_id != codec->codec_id)
73
-       return false;
74
-
75
-   if (caps == NULL)
76
-       return false;
77
-
78
-   res = codec->select_config(codec, 0, caps, caps_size, info, global_settings, config);
79
-   if (res < 0)
80
-       return false;
81
-
82
-   return ((size_t)res == caps_size);
83
-}
84
-
85
-#ifdef CODEC_PLUGIN
86
-
87
-struct impl {
88
-   struct spa_handle handle;
89
-   struct spa_bluez5_codec_a2dp bluez5_codec_a2dp;
90
-};
91
-
92
-static int
93
-impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
94
-{
95
-   struct impl *this;
96
-
97
-   spa_return_val_if_fail(handle != NULL, -EINVAL);
98
-   spa_return_val_if_fail(interface != NULL, -EINVAL);
99
-
100
-   this = (struct impl *) handle;
101
-
102
-   if (spa_streq(type, SPA_TYPE_INTERFACE_Bluez5CodecA2DP))
103
-       *interface = &this->bluez5_codec_a2dp;
104
-   else
105
-       return -ENOENT;
106
-
107
-   return 0;
108
-}
109
-
110
-static int
111
-impl_clear(struct spa_handle *handle)
112
-{
113
-   spa_return_val_if_fail(handle != NULL, -EINVAL);
114
-   return 0;
115
-}
116
-
117
-static size_t
118
-impl_get_size(const struct spa_handle_factory *factory, const struct spa_dict *params)
119
-{
120
-   return sizeof(struct impl);
121
-}
122
-
123
-static int
124
-impl_init(const struct spa_handle_factory *factory,
125
-       struct spa_handle *handle,
126
-       const struct spa_dict *info,
127
-       const struct spa_support *support,
128
-       uint32_t n_support)
129
-{
130
-   struct impl *this;
131
-
132
-   spa_return_val_if_fail(factory != NULL, -EINVAL);
133
-   spa_return_val_if_fail(handle != NULL, -EINVAL);
134
-
135
-   handle->get_interface = impl_get_interface;
136
-   handle->clear = impl_clear;
137
-
138
-   this = (struct impl *) handle;
139
-
140
-   this->bluez5_codec_a2dp.codecs = codec_plugin_a2dp_codecs;
141
-   this->bluez5_codec_a2dp.iface = SPA_INTERFACE_INIT(
142
-       SPA_TYPE_INTERFACE_Bluez5CodecA2DP,
143
-       SPA_VERSION_BLUEZ5_CODEC_A2DP,
144
-       NULL,
145
-       this);
146
-
147
-   return 0;
148
-}
149
-
150
-static const struct spa_interface_info impl_interfaces = {
151
-        {SPA_TYPE_INTERFACE_Bluez5CodecA2DP,},
152
-};
153
-
154
-static int
155
-impl_enum_interface_info(const struct spa_handle_factory *factory,
156
-            const struct spa_interface_info **info,
157
-            uint32_t *index)
158
-{
159
-   spa_return_val_if_fail(factory != NULL, -EINVAL);
160
-   spa_return_val_if_fail(info != NULL, -EINVAL);
161
-   spa_return_val_if_fail(index != NULL, -EINVAL);
162
-
163
-   switch (*index) {
164
-   case 0:
165
-       *info = &impl_interfaces*index;
166
-       break;
167
-   default:
168
-       return 0;
169
-   }
170
-   (*index)++;
171
-
172
-   return 1;
173
-}
174
-
175
-static const struct spa_dict_item handle_info_items = {
176
-        { SPA_KEY_FACTORY_DESCRIPTION, "Bluetooth codec plugin" },
177
-};
178
-
179
-static const struct spa_dict handle_info = SPA_DICT_INIT_ARRAY(handle_info_items);
180
-
181
-static struct spa_handle_factory handle_factory = {
182
-   SPA_VERSION_HANDLE_FACTORY,
183
-   NULL,
184
-   &handle_info,
185
-   impl_get_size,
186
-   impl_init,
187
-   impl_enum_interface_info,
188
-};
189
-
190
-SPA_EXPORT
191
-int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
192
-{
193
-   spa_return_val_if_fail(factory != NULL, -EINVAL);
194
-   spa_return_val_if_fail(index != NULL, -EINVAL);
195
-
196
-   if (handle_factory.name == NULL)
197
-       handle_factory.name = codec_plugin_factory_name;
198
-
199
-   switch (*index) {
200
-   case 0:
201
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-codecs.h Deleted
169
 
1
@@ -1,167 +0,0 @@
2
-/* Spa A2DP codec API
3
- *
4
- * Copyright © 2020 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-#ifndef SPA_BLUEZ5_A2DP_CODECS_H_
26
-#define SPA_BLUEZ5_A2DP_CODECS_H_
27
-
28
-#include <stdint.h>
29
-#include <stddef.h>
30
-
31
-#include <spa/param/audio/format.h>
32
-#include <spa/param/bluetooth/audio.h>
33
-#include <spa/utils/names.h>
34
-#include <spa/support/plugin.h>
35
-#include <spa/pod/pod.h>
36
-#include <spa/pod/builder.h>
37
-#include <spa/support/log.h>
38
-
39
-#include "a2dp-codec-caps.h"
40
-
41
-/*
42
- * The codec plugin SPA interface is private.  The version should be incremented
43
- * when any of the structs or semantics change.
44
- */
45
-
46
-#define SPA_TYPE_INTERFACE_Bluez5CodecA2DP SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:A2DP:Private"
47
-
48
-#define SPA_VERSION_BLUEZ5_CODEC_A2DP      5
49
-
50
-struct spa_bluez5_codec_a2dp {
51
-   struct spa_interface iface;
52
-   const struct a2dp_codec * const *codecs;    /**< NULL terminated array */
53
-};
54
-
55
-#define A2DP_CODEC_FACTORY_NAME(basename)      (SPA_NAME_API_CODEC_BLUEZ5_A2DP "." basename)
56
-
57
-#ifdef CODEC_PLUGIN
58
-#define A2DP_CODEC_EXPORT_DEF(basename,...)    \
59
-   const char *codec_plugin_factory_name = A2DP_CODEC_FACTORY_NAME(basename); \
60
-   static const struct a2dp_codec * const codec_plugin_a2dp_codec_list = { __VA_ARGS__, NULL };    \
61
-   const struct a2dp_codec * const * const codec_plugin_a2dp_codecs = codec_plugin_a2dp_codec_list;
62
-
63
-extern const struct a2dp_codec * const * const codec_plugin_a2dp_codecs;
64
-extern const char *codec_plugin_factory_name;
65
-#endif
66
-
67
-#define A2DP_CODEC_FLAG_SINK       (1 << 0)
68
-
69
-#define A2DP_CODEC_DEFAULT_RATE        48000
70
-#define A2DP_CODEC_DEFAULT_CHANNELS    2
71
-
72
-enum {
73
-   NEED_FLUSH_NO = 0,
74
-   NEED_FLUSH_ALL = 1,
75
-   NEED_FLUSH_FRAGMENT = 2,
76
-};
77
-
78
-struct a2dp_codec_audio_info {
79
-   uint32_t rate;
80
-   uint32_t channels;
81
-};
82
-
83
-struct a2dp_codec {
84
-   enum spa_bluetooth_audio_codec id;
85
-   uint8_t codec_id;
86
-   a2dp_vendor_codec_t vendor;
87
-
88
-   const char *name;
89
-   const char *description;
90
-   const char *endpoint_name;  /**< Endpoint name. If NULL, same as name */
91
-   const struct spa_dict *info;
92
-
93
-   const size_t send_buf_size;
94
-
95
-   const struct a2dp_codec *duplex_codec;  /**< Codec for non-standard A2DP duplex channel */
96
-
97
-   int (*fill_caps) (const struct a2dp_codec *codec, uint32_t flags,
98
-           uint8_t capsA2DP_MAX_CAPS_SIZE);
99
-   int (*select_config) (const struct a2dp_codec *codec, uint32_t flags,
100
-           const void *caps, size_t caps_size,
101
-           const struct a2dp_codec_audio_info *info,
102
-           const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE);
103
-   int (*enum_config) (const struct a2dp_codec *codec, uint32_t flags,
104
-           const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
105
-           struct spa_pod_builder *builder, struct spa_pod **param);
106
-   int (*validate_config) (const struct a2dp_codec *codec, uint32_t flags,
107
-           const void *caps, size_t caps_size,
108
-           struct spa_audio_info *info);
109
-
110
-   /** qsort comparison sorting caps in order of preference for the codec.
111
-    * Used in codec switching to select best remote endpoints.
112
-    * The caps handed in correspond to this codec_id, but are
113
-    * otherwise not checked beforehand.
114
-    */
115
-   int (*caps_preference_cmp) (const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
116
-           const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info,
117
-           const struct spa_dict *global_settings);
118
-
119
-   void *(*init_props) (const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings);
120
-   void (*clear_props) (void *);
121
-   int (*enum_props) (void *props, const struct spa_dict *settings, uint32_t id, uint32_t idx,
122
-           struct spa_pod_builder *builder, struct spa_pod **param);
123
-   int (*set_props) (void *props, const struct spa_pod *param);
124
-
125
-   void *(*init) (const struct a2dp_codec *codec, uint32_t flags, void *config, size_t config_size,
126
-           const struct spa_audio_info *info, void *props, size_t mtu);
127
-   void (*deinit) (void *data);
128
-
129
-   int (*update_props) (void *data, void *props);
130
-
131
-   int (*get_block_size) (void *data);
132
-
133
-   int (*abr_process) (void *data, size_t unsent);
134
-
135
-   int (*start_encode) (void *data,
136
-       void *dst, size_t dst_size, uint16_t seqnum, uint32_t timestamp);
137
-   int (*encode) (void *data,
138
-       const void *src, size_t src_size,
139
-       void *dst, size_t dst_size,
140
-       size_t *dst_out, int *need_flush);
141
-
142
-   int (*start_decode) (void *data,
143
-       const void *src, size_t src_size, uint16_t *seqnum, uint32_t *timestamp);
144
-   int (*decode) (void *data,
145
-       const void *src, size_t src_size,
146
-       void *dst, size_t dst_size,
147
-       size_t *dst_out);
148
-
149
-   int (*reduce_bitpool) (void *data);
150
-   int (*increase_bitpool) (void *data);
151
-
152
-   void (*set_log) (struct spa_log *global_log);
153
-};
154
-
155
-struct a2dp_codec_config {
156
-   uint32_t config;
157
-   int value;
158
-   unsigned int priority;
159
-};
160
-
161
-int a2dp_codec_select_config(const struct a2dp_codec_config configs, size_t n,
162
-   uint32_t cap, int preferred_value);
163
-
164
-bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id,
165
-   const void *caps, size_t caps_size, const struct a2dp_codec_audio_info *info,
166
-   const struct spa_dict *global_settings);
167
-
168
-#endif
169
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-sink.c Deleted
201
 
1
@@ -1,1786 +0,0 @@
2
-/* Spa A2DP Sink
3
- *
4
- * Copyright © 2018 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include <unistd.h>
27
-#include <stddef.h>
28
-#include <stdio.h>
29
-#include <arpa/inet.h>
30
-#include <sys/ioctl.h>
31
-
32
-#include <spa/support/plugin.h>
33
-#include <spa/support/loop.h>
34
-#include <spa/support/log.h>
35
-#include <spa/support/system.h>
36
-#include <spa/utils/list.h>
37
-#include <spa/utils/keys.h>
38
-#include <spa/utils/names.h>
39
-#include <spa/utils/result.h>
40
-#include <spa/utils/string.h>
41
-#include <spa/monitor/device.h>
42
-
43
-#include <spa/node/node.h>
44
-#include <spa/node/utils.h>
45
-#include <spa/node/io.h>
46
-#include <spa/node/keys.h>
47
-#include <spa/param/param.h>
48
-#include <spa/param/latency-utils.h>
49
-#include <spa/param/audio/format.h>
50
-#include <spa/param/audio/format-utils.h>
51
-#include <spa/pod/filter.h>
52
-
53
-#include <sbc/sbc.h>
54
-
55
-#include "defs.h"
56
-#include "rtp.h"
57
-#include "a2dp-codecs.h"
58
-
59
-static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.sink.a2dp");
60
-#undef SPA_LOG_TOPIC_DEFAULT
61
-#define SPA_LOG_TOPIC_DEFAULT &log_topic
62
-
63
-#define DEFAULT_CLOCK_NAME "clock.system.monotonic"
64
-
65
-struct props {
66
-   uint32_t min_latency;
67
-   uint32_t max_latency;
68
-   int64_t latency_offset;
69
-   char clock_name64;
70
-};
71
-
72
-#define FILL_FRAMES 2
73
-#define MAX_BUFFERS 32
74
-#define MIN_LATENCY    128
75
-#define MAX_LATENCY    8192
76
-#define BUFFER_SIZE    (MAX_LATENCY*8)
77
-
78
-struct buffer {
79
-   uint32_t id;
80
-#define BUFFER_FLAG_OUT    (1<<0)
81
-   uint32_t flags;
82
-   struct spa_buffer *buf;
83
-   struct spa_meta_header *h;
84
-   struct spa_list link;
85
-};
86
-
87
-struct port {
88
-   struct spa_audio_info current_format;
89
-   uint32_t frame_size;
90
-   unsigned int have_format:1;
91
-
92
-   uint64_t info_all;
93
-   struct spa_port_info info;
94
-   struct spa_io_buffers *io;
95
-   struct spa_latency_info latency;
96
-#define IDX_EnumFormat 0
97
-#define IDX_Meta   1
98
-#define IDX_IO     2
99
-#define IDX_Format 3
100
-#define IDX_Buffers    4
101
-#define IDX_Latency    5
102
-#define N_PORT_PARAMS  6
103
-   struct spa_param_info paramsN_PORT_PARAMS;
104
-
105
-   struct buffer buffersMAX_BUFFERS;
106
-   uint32_t n_buffers;
107
-
108
-   struct spa_list free;
109
-   struct spa_list ready;
110
-
111
-   size_t ready_offset;
112
-};
113
-
114
-struct impl {
115
-   struct spa_handle handle;
116
-   struct spa_node node;
117
-
118
-   struct spa_log *log;
119
-   struct spa_loop *data_loop;
120
-   struct spa_system *data_system;
121
-
122
-   struct spa_hook_list hooks;
123
-   struct spa_callbacks callbacks;
124
-
125
-   uint64_t info_all;
126
-   struct spa_node_info info;
127
-#define IDX_PropInfo   0
128
-#define IDX_Props  1
129
-#define N_NODE_PARAMS  2
130
-   struct spa_param_info paramsN_NODE_PARAMS;
131
-   struct props props;
132
-
133
-   struct spa_bt_transport *transport;
134
-   struct spa_hook transport_listener;
135
-
136
-   struct port port;
137
-
138
-   unsigned int started:1;
139
-   unsigned int following:1;
140
-
141
-   unsigned int is_duplex:1;
142
-
143
-   struct spa_source source;
144
-   int timerfd;
145
-   struct spa_source flush_source;
146
-   struct spa_source flush_timer_source;
147
-   int flush_timerfd;
148
-
149
-   struct spa_io_clock *clock;
150
-   struct spa_io_position *position;
151
-
152
-   uint64_t current_time;
153
-   uint64_t next_time;
154
-   uint64_t last_error;
155
-
156
-   const struct a2dp_codec *codec;
157
-   bool codec_props_changed;
158
-   void *codec_props;
159
-   void *codec_data;
160
-   struct spa_audio_info codec_format;
161
-
162
-   int need_flush;
163
-   bool fragment;
164
-   uint64_t fragment_timeout;
165
-   uint32_t block_size;
166
-   uint8_t bufferBUFFER_SIZE;
167
-   uint32_t buffer_used;
168
-   uint32_t header_size;
169
-   uint32_t frame_count;
170
-   uint16_t seqnum;
171
-   uint32_t timestamp;
172
-   uint64_t sample_count;
173
-   uint8_t tmp_bufferBUFFER_SIZE;
174
-   uint32_t tmp_buffer_used;
175
-   uint32_t fd_buffer_size;
176
-};
177
-
178
-#define CHECK_PORT(this,d,p)    ((d) == SPA_DIRECTION_INPUT && (p) == 0)
179
-
180
-static void reset_props(struct impl *this, struct props *props)
181
-{
182
-   props->min_latency = MIN_LATENCY;
183
-   props->max_latency = MAX_LATENCY;
184
-   props->latency_offset = 0;
185
-   strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name));
186
-}
187
-
188
-static int impl_node_enum_params(void *object, int seq,
189
-           uint32_t id, uint32_t start, uint32_t num,
190
-           const struct spa_pod *filter)
191
-{
192
-   struct impl *this = object;
193
-   struct spa_pod *param;
194
-   struct spa_pod_builder b = { 0 };
195
-   uint8_t buffer1024;
196
-   struct spa_result_node_params result;
197
-   uint32_t count = 0, index_offset = 0;
198
-   bool enum_codec = false;
199
-
200
-   spa_return_val_if_fail(this != NULL, -EINVAL);
201
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/a2dp-source.c Deleted
201
 
1
@@ -1,1643 +0,0 @@
2
-/* Spa A2DP Source
3
- *
4
- * Copyright © 2018 Wim Taymans
5
- * Copyright © 2019 Collabora Ltd.
6
- *
7
- * Permission is hereby granted, free of charge, to any person obtaining a
8
- * copy of this software and associated documentation files (the "Software"),
9
- * to deal in the Software without restriction, including without limitation
10
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
- * and/or sell copies of the Software, and to permit persons to whom the
12
- * Software is furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice (including the next
15
- * paragraph) shall be included in all copies or substantial portions of the
16
- * Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
- * DEALINGS IN THE SOFTWARE.
25
- */
26
-
27
-#include <unistd.h>
28
-#include <stddef.h>
29
-#include <stdio.h>
30
-#include <time.h>
31
-#include <fcntl.h>
32
-#include <sys/types.h>
33
-#include <sys/socket.h>
34
-
35
-#include <spa/support/plugin.h>
36
-#include <spa/support/loop.h>
37
-#include <spa/support/log.h>
38
-#include <spa/support/system.h>
39
-#include <spa/utils/list.h>
40
-#include <spa/utils/keys.h>
41
-#include <spa/utils/names.h>
42
-#include <spa/utils/result.h>
43
-#include <spa/utils/string.h>
44
-#include <spa/monitor/device.h>
45
-
46
-#include <spa/node/node.h>
47
-#include <spa/node/utils.h>
48
-#include <spa/node/io.h>
49
-#include <spa/node/keys.h>
50
-#include <spa/param/param.h>
51
-#include <spa/param/latency-utils.h>
52
-#include <spa/param/audio/format.h>
53
-#include <spa/param/audio/format-utils.h>
54
-#include <spa/pod/filter.h>
55
-
56
-#include "defs.h"
57
-#include "rtp.h"
58
-#include "a2dp-codecs.h"
59
-
60
-static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.source.a2dp");
61
-#undef SPA_LOG_TOPIC_DEFAULT
62
-#define SPA_LOG_TOPIC_DEFAULT &log_topic
63
-
64
-#include "decode-buffer.h"
65
-
66
-#define DEFAULT_CLOCK_NAME "clock.system.monotonic"
67
-
68
-struct props {
69
-   char clock_name64;
70
-};
71
-
72
-#define FILL_FRAMES 2
73
-#define MAX_BUFFERS 32
74
-
75
-struct buffer {
76
-   uint32_t id;
77
-   unsigned int outstanding:1;
78
-   struct spa_buffer *buf;
79
-   struct spa_meta_header *h;
80
-   struct spa_list link;
81
-};
82
-
83
-struct port {
84
-   struct spa_audio_info current_format;
85
-   uint32_t frame_size;
86
-   unsigned int have_format:1;
87
-
88
-   uint64_t info_all;
89
-   struct spa_port_info info;
90
-   struct spa_io_buffers *io;
91
-   struct spa_io_rate_match *rate_match;
92
-   struct spa_latency_info latency;
93
-#define IDX_EnumFormat 0
94
-#define IDX_Meta   1
95
-#define IDX_IO     2
96
-#define IDX_Format 3
97
-#define IDX_Buffers    4
98
-#define IDX_Latency    5
99
-#define N_PORT_PARAMS  6
100
-   struct spa_param_info paramsN_PORT_PARAMS;
101
-
102
-   struct buffer buffersMAX_BUFFERS;
103
-   uint32_t n_buffers;
104
-
105
-   struct spa_list free;
106
-   struct spa_list ready;
107
-
108
-   struct spa_bt_decode_buffer buffer;
109
-};
110
-
111
-struct impl {
112
-   struct spa_handle handle;
113
-   struct spa_node node;
114
-
115
-   struct spa_log *log;
116
-   struct spa_loop *data_loop;
117
-   struct spa_system *data_system;
118
-
119
-   struct spa_hook_list hooks;
120
-   struct spa_callbacks callbacks;
121
-
122
-   uint32_t quantum_limit;
123
-
124
-   uint64_t info_all;
125
-   struct spa_node_info info;
126
-#define IDX_PropInfo   0
127
-#define IDX_Props  1
128
-#define IDX_NODE_IO    2
129
-#define N_NODE_PARAMS  3
130
-   struct spa_param_info paramsN_NODE_PARAMS;
131
-   struct props props;
132
-
133
-   struct spa_bt_transport *transport;
134
-   struct spa_hook transport_listener;
135
-
136
-   struct port port;
137
-
138
-   unsigned int started:1;
139
-   unsigned int transport_acquired:1;
140
-   unsigned int following:1;
141
-   unsigned int matching:1;
142
-   unsigned int resampling:1;
143
-
144
-   unsigned int is_input:1;
145
-   unsigned int is_duplex:1;
146
-   unsigned int use_duplex_source:1;
147
-
148
-   int fd;
149
-   struct spa_source source;
150
-
151
-   struct spa_source timer_source;
152
-   int timerfd;
153
-
154
-   struct spa_io_clock *clock;
155
-        struct spa_io_position *position;
156
-
157
-   uint64_t current_time;
158
-   uint64_t next_time;
159
-
160
-   const struct a2dp_codec *codec;
161
-   bool codec_props_changed;
162
-   void *codec_props;
163
-   void *codec_data;
164
-   struct spa_audio_info codec_format;
165
-
166
-   uint8_t buffer_read4096;
167
-   struct timespec now;
168
-   uint64_t sample_count;
169
-
170
-   int duplex_timerfd;
171
-   uint64_t duplex_timeout;
172
-};
173
-
174
-#define CHECK_PORT(this,d,p)    ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
175
-
176
-static void reset_props(struct props *props)
177
-{
178
-   strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name));
179
-}
180
-
181
-static int impl_node_enum_params(void *object, int seq,
182
-           uint32_t id, uint32_t start, uint32_t num,
183
-           const struct spa_pod *filter)
184
-{
185
-   struct impl *this = object;
186
-   struct spa_pod *param;
187
-   struct spa_pod_builder b = { 0 };
188
-   uint8_t buffer1024;
189
-   struct spa_result_node_params result;
190
-   uint32_t count = 0, index_offset = 0;
191
-   bool enum_codec = false;
192
-
193
-   spa_return_val_if_fail(this != NULL, -EINVAL);
194
-   spa_return_val_if_fail(num != 0, -EINVAL);
195
-
196
-        result.id = id;
197
-   result.next = start;
198
-      next:
199
-        result.index = result.next++;
200
-
201
pipewire-0.3.58.tar.gz/.gitlab-ci.yml -> pipewire-0.3.59.tar.gz/.gitlab-ci.yml Changed
13
 
1
@@ -268,9 +268,9 @@
2
   extends:
3
     - .build_on_fedora
4
   variables:
5
-    # Fedora doesn't have libfreeaptx, lc3plus, or roc
6
+    # Fedora doesn't have libfreeaptx, lc3plus, lc3, or roc
7
     # libcamera has no stable API, so let's not chase that target
8
-    MESON_OPTIONS: "-Dauto_features=enabled -Dbluez5-codec-aptx=disabled -Dbluez5-codec-lc3plus=disabled -Droc=disabled -Dlibcamera=disabled"
9
+    MESON_OPTIONS: "-Dauto_features=enabled -Dbluez5-codec-aptx=disabled -Dbluez5-codec-lc3plus=disabled -Dbluez5-codec-lc3=disabled -Droc=disabled -Dlibcamera=disabled"
10
   parallel:
11
     matrix:
12
       - CC: gcc, clang
13
pipewire-0.3.58.tar.gz/NEWS -> pipewire-0.3.59.tar.gz/NEWS Changed
92
 
1
@@ -1,3 +1,80 @@
2
+# PipeWire 0.3.59 (2022-09-30)
3
+
4
+This is a bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+  - Fix possible wrong samplerate in loopback streams after suspend and
9
+    rate switch.
10
+  - module-filter-chain can now adapt to the graph samplerate.
11
+  - Fix some potential stuttering and crackling in pulse-server.
12
+  - Add Bluetooth LE support. This requires experimental kernel and bluez
13
+    support.
14
+  - The ALSA plugin has more options to control the buffer size. This can
15
+    be used to work around high latency in davinci resolve.
16
+  - Many bugfixes and improvements.
17
+
18
+
19
+## PipeWire
20
+  - Add audio capture example with volume meter.
21
+  - Fix a case where a rate switch would not suspend all the nodes of the
22
+    driver first. This could cause wrong samplerates in streams.
23
+  - Fix a case where a node would be Paused while still added to the
24
+    graph, causing potential crashes. (#2701)
25
+
26
+## Modules
27
+  - module-filter-chain and module-loopback now use the resample.prefill
28
+    option to avoid buffering extra samples and causing unwanted latency
29
+    when resampling is activated.
30
+  - module-filter-chain can now adapt to the graph samplerate.
31
+  - Improve module-raop to support the ALAC codec as raw PCM.
32
+  - Improve RTSP parsing to improve compatibility.
33
+
34
+## Tools
35
+  - Fix 100% CPU in pw-cli monitor mode. (#2709)
36
+  - spa-acp-tool can now be exited with ctrl-D.
37
+
38
+## SPA
39
+  - Various libcamera fixes and improvements.
40
+  - Set stride on audioconvert output buffers.
41
+  - Make sure we always place the last requested size from the resampler
42
+    on the buffers in pw-stream.
43
+  - Add resample.prefill option in the resampler to fill the history with
44
+    0 so that we don't have smaller buffers at the start.
45
+  - Make sure that when an overflow corrupts a POD, that it will always
46
+    stay corrupted.
47
+  - Rate limit some ALSA warnings and reduce some unwanted warnings.
48
+  - Don't recalculate the audioconverter state for each pause/play. (#2701)
49
+  - Fix some POD parsing inconsistencies and potential overflows.
50
+  - Add support for Asus Xonar SE.
51
+  - Fix Flush command handling. It should not stop playback. (#2726)
52
+  - Refactor the peaks function and add some unit tests and optimizations.
53
+  - The channelmix has an optimized nXm converter and new unit tests.
54
+  - Normalization in the channelmixer was fixed.
55
+
56
+## pulse-server
57
+  - The requested latency of record streams was reduced to fix some
58
+    stuttering in Teamspeak. (#2702)
59
+  - Tweak the max amount of bytes sent to a client. (#2711) (#2715)
60
+  - Improve maxlength calculations, this fixes some crackling noise with
61
+    high samplerate and channel counts in some players (audacious).
62
+
63
+## Bluetooth
64
+  - Merge Bluetooth LE support.
65
+  - Make sure we are backward compatible with WirePlumber.
66
+  - Fix some HFP and HSP AT command parsing. (#2463)
67
+  - Use HFP by default over HSP.
68
+
69
+## ALSA
70
+  - Increase max number of periods.
71
+  - The parameters handling was improved. There is now an option to set the
72
+    buffer-bytes of the ALSA plugin.
73
+  - PIPEWIRE_ALSA can now be used as an environment variable to restrict the
74
+    plugin formats and buffer size.
75
+
76
+Older versions:
77
+
78
+
79
 # PipeWire 0.3.58 (2022-09-15)
80
 
81
 This is a bugfix release that is API and ABI compatible with previous
82
@@ -64,9 +141,6 @@
83
     wakeups. (#1697)
84
 
85
 
86
-Older versions:
87
-
88
-
89
 # PipeWire 0.3.57 (2022-09-02)
90
 
91
 This is a bugfix release that is API and ABI compatible with previous
92
pipewire-0.3.58.tar.gz/man/pipewire.1.rst.in -> pipewire-0.3.59.tar.gz/man/pipewire.1.rst.in Changed
10
 
1
@@ -47,6 +47,8 @@
2
 SEE ALSO
3
 ========
4
 
5
+``pw-top(1)``,
6
+``pw-dump(1)``,
7
 ``pw-mon(1)``,
8
 ``pw-cat(1)``,
9
 ``pw-cli(1)``,
10
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
15
 
1
@@ -27,6 +27,8 @@
2
 SVG files from the .plot files is generated, along with a .html file to
3
 visualize the profiling results in a browser.
4
 
5
+This function uses the same data used by *pw-top*.
6
+
7
 OPTIONS
8
 =======
9
 
10
@@ -52,3 +54,4 @@
11
 ========
12
 
13
 ``pipewire(1)``,
14
+``pw-top(1)``,
15
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
9
 
1
@@ -168,4 +168,7 @@
2
 ========
3
 
4
 ``pipewire(1)``,
5
+``pw-dump(1)``,
6
+``pw-cli(1)``,
7
+``pw-profiler(1)``,
8
 
9
pipewire-0.3.58.tar.gz/meson.build -> pipewire-0.3.59.tar.gz/meson.build Changed
13
 
1
@@ -1,9 +1,9 @@
2
 project('pipewire', 'c' ,
3
-  version : '0.3.58',
4
+  version : '0.3.59',
5
   license :  'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ,
6
   meson_version : '>= 0.59.0',
7
   default_options :  'warning_level=3',
8
-                      'c_std=gnu99',
9
+                      'c_std=gnu11',
10
                       'cpp_std=c++17',
11
                       'b_pie=true',
12
                       #'b_sanitize=address,undefined',
13
pipewire-0.3.58.tar.gz/meson_options.txt -> pipewire-0.3.59.tar.gz/meson_options.txt Changed
12
 
1
@@ -120,6 +120,10 @@
2
         description: 'Enable Opus open source codec implementation',
3
         type: 'feature',
4
         value: 'auto')
5
+option('bluez5-codec-lc3',
6
+        description: 'Enable LC3 open source codec implementation',
7
+        type: 'feature',
8
+        value: 'disabled')
9
 option('control',
10
        description: 'Enable control spa plugin integration',
11
        type: 'feature',
12
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
201
 
1
@@ -64,6 +64,26 @@
2
 
3
 #define MIN_PERIOD 64
4
 
5
+#define MIN_PERIOD_BYTES   (128)
6
+#define MAX_PERIOD_BYTES   (2*1024*1024)
7
+
8
+#define MIN_BUFFER_BYTES   (2*MIN_PERIOD_BYTES)
9
+#define MAX_BUFFER_BYTES   (2*MAX_PERIOD_BYTES)
10
+
11
+struct params {
12
+   const char *node_name;
13
+   const char *server_name;
14
+   const char *playback_node;
15
+   const char *capture_node;
16
+   const char *role;
17
+   snd_pcm_format_t format;
18
+   int rate;
19
+   int channels;
20
+   int period_bytes;
21
+   int buffer_bytes;
22
+   uint32_t flags;
23
+};
24
+
25
 typedef struct {
26
    snd_pcm_ioplug_t io;
27
 
28
@@ -178,6 +198,7 @@
29
        pw_thread_loop_destroy(pw->main_loop);
30
    free(pw->node_name);
31
    free(pw->target);
32
+   free(pw->role);
33
    snd_output_close(pw->output);
34
    fclose(pw->log_file);
35
    free(pw);
36
@@ -942,8 +963,7 @@
37
    .query_chmaps = snd_pcm_pipewire_query_chmaps,
38
 };
39
 
40
-static int pipewire_set_hw_constraint(snd_pcm_pipewire_t *pw, int rate,
41
-       snd_pcm_format_t format, int channels, int period_bytes)
42
+static int pipewire_set_hw_constraint(snd_pcm_pipewire_t *pw, struct params *p)
43
 {
44
    unsigned int access_list = {
45
        SND_PCM_ACCESS_MMAP_INTERLEAVED,
46
@@ -975,26 +995,38 @@
47
    int max_channels;
48
    int min_period_bytes;
49
    int max_period_bytes;
50
+   int min_buffer_bytes;
51
+   int max_buffer_bytes;
52
    int err;
53
 
54
-   if (rate > 0) {
55
-       min_rate = max_rate = rate;
56
+   if (p->rate > 0) {
57
+       min_rate = max_rate = SPA_CLAMP(p->rate, 1, MAX_RATE);
58
    } else {
59
        min_rate = 1;
60
        max_rate = MAX_RATE;
61
    }
62
-   if (channels > 0) {
63
-       min_channels = max_channels = channels;
64
+   if (p->channels > 0) {
65
+       min_channels = max_channels = SPA_CLAMP(p->channels, 1, MAX_CHANNELS);
66
    } else {
67
        min_channels = 1;
68
        max_channels = MAX_CHANNELS;
69
    }
70
-   if (period_bytes > 0) {
71
-       min_period_bytes = max_period_bytes = period_bytes;
72
+   if (p->period_bytes > 0) {
73
+       min_period_bytes = max_period_bytes = SPA_CLAMP(p->period_bytes,
74
+               MIN_PERIOD_BYTES, MAX_PERIOD_BYTES);
75
    } else {
76
-       min_period_bytes = 128;
77
-       max_period_bytes = 2*1024*1024;
78
+       min_period_bytes = MIN_PERIOD_BYTES;
79
+       max_period_bytes = MAX_PERIOD_BYTES;
80
    }
81
+   if (p->buffer_bytes > 0) {
82
+       min_buffer_bytes = max_buffer_bytes = SPA_CLAMP(p->buffer_bytes,
83
+               MIN_BUFFER_BYTES, MAX_BUFFER_BYTES);
84
+   } else {
85
+       min_buffer_bytes = MIN_BUFFER_BYTES;
86
+       max_buffer_bytes = MAX_BUFFER_BYTES;
87
+   }
88
+   if (min_period_bytes * 2 > max_buffer_bytes)
89
+       min_period_bytes = max_period_bytes = max_buffer_bytes / 2;
90
 
91
    if ((err = snd_pcm_ioplug_set_param_list(&pw->io, SND_PCM_IOPLUG_HW_ACCESS,
92
                           SPA_N_ELEMENTS(access_list), access_list)) < 0 ||
93
@@ -1003,22 +1035,22 @@
94
        (err = snd_pcm_ioplug_set_param_minmax(&pw->io, SND_PCM_IOPLUG_HW_RATE,
95
                           min_rate, max_rate)) < 0 ||
96
        (err = snd_pcm_ioplug_set_param_minmax(&pw->io, SND_PCM_IOPLUG_HW_BUFFER_BYTES,
97
-                          MIN_BUFFERS*min_period_bytes,
98
-                          MIN_BUFFERS*max_period_bytes)) < 0 ||
99
+                          min_buffer_bytes,
100
+                          max_buffer_bytes)) < 0 ||
101
        (err = snd_pcm_ioplug_set_param_minmax(&pw->io,
102
                           SND_PCM_IOPLUG_HW_PERIOD_BYTES,
103
                           min_period_bytes,
104
                           max_period_bytes)) < 0 ||
105
        (err = snd_pcm_ioplug_set_param_minmax(&pw->io, SND_PCM_IOPLUG_HW_PERIODS,
106
-                          MIN_BUFFERS, MAX_BUFFERS)) < 0) {
107
+                          MIN_BUFFERS, 1024)) < 0) {
108
        pw_log_warn("Can't set param list: %s", snd_strerror(err));
109
        return err;
110
    }
111
 
112
-   if (format != SND_PCM_FORMAT_UNKNOWN) {
113
+   if (p->format != SND_PCM_FORMAT_UNKNOWN) {
114
        err = snd_pcm_ioplug_set_param_list(&pw->io,
115
                SND_PCM_IOPLUG_HW_FORMAT,
116
-               1, (unsigned int *)&format);
117
+               1, (unsigned int *)&p->format);
118
        if (err < 0) {
119
            pw_log_warn("Can't set param list: %s", snd_strerror(err));
120
            return err;
121
@@ -1075,60 +1107,77 @@
122
    .write = log_write,
123
 };
124
 
125
-static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name,
126
-               const char *node_name,
127
-               const char *server_name,
128
-               const char *playback_node,
129
-               const char *capture_node,
130
-               const char *role,
131
-               snd_pcm_stream_t stream,
132
-               int mode,
133
-               uint32_t flags,
134
-               int rate,
135
-               snd_pcm_format_t format,
136
-               int channels,
137
-               int period_bytes)
138
+static int snd_pcm_pipewire_open(snd_pcm_t **pcmp,
139
+       struct params *p, snd_pcm_stream_t stream, int mode)
140
 {
141
    snd_pcm_pipewire_t *pw;
142
    int err;
143
    const char *str;
144
    struct pw_properties *props = NULL;
145
    struct pw_loop *loop;
146
+   uint32_t val;
147
 
148
    assert(pcmp);
149
    pw = calloc(1, sizeof(*pw));
150
    if (!pw)
151
        return -ENOMEM;
152
 
153
+   props = pw_properties_new(NULL, NULL);
154
+   if (props == NULL) {
155
+       err = -errno;
156
+       goto error;
157
+   }
158
+
159
+   str = getenv("PIPEWIRE_ALSA");
160
+   if (str != NULL) {
161
+       pw_properties_update_string(props, str, strlen(str));
162
+       if ((str = pw_properties_get(props, "alsa.format")))
163
+           p->format = snd_pcm_format_value(str);
164
+       if ((str = pw_properties_get(props, "alsa.rate")) &&
165
+           spa_atou32(str, &val, 0))
166
+           p->rate = val;
167
+       if ((str = pw_properties_get(props, "alsa.channels")) &&
168
+           spa_atou32(str, &val, 0))
169
+           p->channels = val;
170
+       if ((str = pw_properties_get(props, "alsa.period-bytes")) &&
171
+           spa_atou32(str, &val, 0))
172
+           p->period_bytes = val;
173
+       if ((str = pw_properties_get(props, "alsa.buffer-bytes")) &&
174
+           spa_atou32(str, &val, 0))
175
+           p->buffer_bytes = val;
176
+   }
177
+
178
    str = getenv("PIPEWIRE_REMOTE");
179
    if (str != NULL && str0 != '\0')
180
-       server_name = str;
181
+       p->server_name = str;
182
 
183
    str = getenv("PIPEWIRE_NODE");
184
 
185
    pw_log_debug("%p: open name:%s stream:%s mode:%d flags:%08x rate:%d format:%s "
186
-           "channels:%d period-bytes:%d target:'%s'", pw, name,
187
-           snd_pcm_stream_name(stream), mode, flags, rate,
188
-           snd_pcm_format_name(format), channels, period_bytes, str);
189
+           "channels:%d period-bytes:%d buffer-bytes:%d target:'%s'", pw, p->node_name,
190
+           snd_pcm_stream_name(stream), mode, p->flags, p->rate,
191
+           snd_pcm_format_name(p->format), p->channels, p->period_bytes,
192
+           p->buffer_bytes, str);
193
 
194
    pw->fd = -1;
195
    pw->io.poll_fd = -1;
196
-   pw->flags = flags;
197
+   pw->flags = p->flags;
198
    pw->log_file = fopencookie(pw, "w", io_funcs);
199
    if (pw->log_file == NULL) {
200
        pw_log_error("can't create log file: %m");
201
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
72
 
1
@@ -4,9 +4,14 @@
2
 defaults.pipewire.node "-1"
3
 defaults.pipewire.exclusive false
4
 defaults.pipewire.role ""
5
+defaults.pipewire.rate 0
6
+defaults.pipewire.format ""
7
+defaults.pipewire.channels 0
8
+defaults.pipewire.period_bytes 0
9
+defaults.pipewire.buffer_bytes 0
10
 
11
 pcm.pipewire {
12
-   @args  SERVER NODE EXCLUSIVE ROLE 
13
+   @args  SERVER NODE EXCLUSIVE ROLE RATE FORMAT CHANNELS PERIOD_BYTES BUFFER_BYTES 
14
    @args.SERVER {
15
        type string
16
        default {
17
@@ -35,7 +40,41 @@
18
            name defaults.pipewire.role
19
        }
20
    }
21
-
22
+   @args.RATE {
23
+       type integer
24
+       default {
25
+           @func refer
26
+           name defaults.pipewire.rate
27
+       }
28
+   }
29
+   @args.FORMAT {
30
+       type string
31
+       default {
32
+           @func refer
33
+           name defaults.pipewire.format
34
+       }
35
+   }
36
+   @args.CHANNELS {
37
+       type integer
38
+       default {
39
+           @func refer
40
+           name defaults.pipewire.channels
41
+       }
42
+   }
43
+   @args.PERIOD_BYTES {
44
+       type integer
45
+       default {
46
+           @func refer
47
+           name defaults.pipewire.period_bytes
48
+       }
49
+   }
50
+   @args.BUFFER_BYTES {
51
+       type integer
52
+       default {
53
+           @func refer
54
+           name defaults.pipewire.buffer_bytes
55
+       }
56
+   }
57
 
58
    type pipewire
59
    server $SERVER
60
@@ -43,6 +82,11 @@
61
    capture_node $NODE
62
    exclusive $EXCLUSIVE
63
    role $ROLE
64
+   rate $RATE
65
+   format $FORMAT
66
+   channels $CHANNELS
67
+   period_bytes $PERIOD_BYTES
68
+   buffer_bytes $BUFFER_BYTES
69
    hint {
70
        show on
71
        description "PipeWire Sound Server"
72
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
9
 
1
@@ -24,6 +24,7 @@
2
 
3
 #ifndef PIPEWIRE_JACK_EXTENSIONS_H
4
 #define PIPEWIRE_JACK_EXTENSIONS_H
5
+#include <stdint.h>
6
 
7
 #ifdef __cplusplus
8
 extern "C" {
9
pipewire-0.3.58.tar.gz/po/hu.po -> pipewire-0.3.59.tar.gz/po/hu.po Changed
201
 
1
@@ -1,18 +1,18 @@
2
-# Hungarian translation of PipeWire
3
-# Copyright (C) 2012, 2016. Free Software Foundation, Inc.
4
+# Hungarian translation for PipeWire.
5
+# Copyright (C) 2012, 2016, 2022. Free Software Foundation, Inc.
6
 # This file is distributed under the same license as the PipeWire package.
7
 #
8
-# KAMI <kami911@gmail.com>, 2012.
9
+# KAMI <kami911 at gmail dot com>, 2012.
10
 # Gabor Kelemen <kelemeng at ubuntu dot com>, 2016.
11
-# Balázs Úr <urbalazs at gmail dot com>, 2016.
12
+# Balázs Úr <ur.balazs at fsf dot hu>, 2016, 2022.
13
 msgid ""
14
 msgstr ""
15
 "Project-Id-Version: PipeWire master\n"
16
-"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
17
-"issues/new\n"
18
-"POT-Creation-Date: 2021-04-18 16:54+0800\n"
19
-"PO-Revision-Date: 2020-07-21 15:29+0000\n"
20
-"Last-Translator: Balázs Meskó <meskobalazs@mailbox.org>\n"
21
+"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
22
+"issues\n"
23
+"POT-Creation-Date: 2022-09-15 15:26+0000\n"
24
+"PO-Revision-Date: 2022-09-21 22:35+0200\n"
25
+"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n"
26
 "Language-Team: Hungarian <https://translate.fedoraproject.org/projects/"
27
 "pipewire/pipewire/hu/>\n"
28
 "Language: hu\n"
29
@@ -20,12 +20,9 @@
30
 "Content-Type: text/plain; charset=UTF-8\n"
31
 "Content-Transfer-Encoding: 8bit\n"
32
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
33
-"X-Generator: Weblate 4.1.1\n"
34
-"X-Poedit-Language: Hungarian\n"
35
-"X-Poedit-Country: HUNGARY\n"
36
-"X-Poedit-SourceCharset: utf-8\n"
37
+"X-Generator: Lokalize 19.12.3\n"
38
 
39
-#: src/daemon/pipewire.c:43
40
+#: src/daemon/pipewire.c:46
41
 #, c-format
42
 msgid ""
43
 "%s options\n"
44
@@ -33,40 +30,64 @@
45
 "      --version                         Show version\n"
46
 "  -c, --config                          Load config (Default %s)\n"
47
 msgstr ""
48
+"%s kapcsolók\n"
49
+"  -h, --help                            Ezen súgó megjelenítése\n"
50
+"      --version                         Verzió megjelenítése\n"
51
+"  -c, --config                          Beállítás betöltése (alapérték: %s)\n"
52
 
53
 #: src/daemon/pipewire.desktop.in:4
54
 msgid "PipeWire Media System"
55
-msgstr ""
56
+msgstr "PipeWire médiarendszer"
57
 
58
 #: src/daemon/pipewire.desktop.in:5
59
 msgid "Start the PipeWire Media System"
60
-msgstr ""
61
+msgstr "A PipeWire médiarendszer indítása"
62
 
63
-#: src/examples/media-session/alsa-monitor.c:526
64
-#: spa/plugins/alsa/acp/compat.c:187
65
-msgid "Built-in Audio"
66
-msgstr "Belső hangforrás"
67
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180
68
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
69
+#, c-format
70
+msgid "Tunnel to %s/%s"
71
+msgstr "Alagút ide: %s/%s"
72
 
73
-#: src/examples/media-session/alsa-monitor.c:530
74
-#: spa/plugins/alsa/acp/compat.c:192
75
-msgid "Modem"
76
-msgstr "Modem"
77
+#: src/modules/module-fallback-sink.c:51
78
+msgid "Dummy Output"
79
+msgstr "Üres kimenet"
80
+
81
+#: src/modules/module-pulse-tunnel.c:662
82
+#, c-format
83
+msgid "Tunnel for %s@%s"
84
+msgstr "Alagút ehhez: %s@%s"
85
 
86
-#: src/examples/media-session/alsa-monitor.c:539
87
+#: src/modules/module-zeroconf-discover.c:332
88
 msgid "Unknown device"
89
-msgstr ""
90
+msgstr "Ismeretlen eszköz"
91
+
92
+#: src/modules/module-zeroconf-discover.c:344
93
+#, c-format
94
+msgid "%s on %s@%s"
95
+msgstr "%s ezen: %s@%s"
96
 
97
-#: src/tools/pw-cat.c:991
98
+#: src/modules/module-zeroconf-discover.c:348
99
+#, c-format
100
+msgid "%s on %s"
101
+msgstr "%s ezen: %s"
102
+
103
+#: src/tools/pw-cat.c:784
104
 #, c-format
105
 msgid ""
106
-"%s options <file>\n"
107
+"%s options <file>|-\n"
108
 "  -h, --help                            Show this help\n"
109
 "      --version                         Show version\n"
110
 "  -v, --verbose                         Enable verbose operations\n"
111
 "\n"
112
 msgstr ""
113
+"%s kapcsolók <fájl>|-\n"
114
+"  -h, --help                            Ezen súgó megjelenítése\n"
115
+"      --version                         Verzió megjelenítése\n"
116
+"  -v, --verbose                         Részletes műveletek engedélyezése\n"
117
+"\n"
118
 
119
-#: src/tools/pw-cat.c:998
120
+#: src/tools/pw-cat.c:791
121
 #, c-format
122
 msgid ""
123
 "  -R, --remote                          Remote daemon name\n"
124
@@ -80,11 +101,30 @@
125
 "                                          or direct samples (256)\n"
126
 "                                          the rate is the one of the source "
127
 "file\n"
128
-"      --list-targets                    List available targets for --target\n"
129
+"  -P  --properties                      Set node properties\n"
130
 "\n"
131
 msgstr ""
132
+"  -R, --remote                          Távoli démon neve\n"
133
+"      --media-type                      Médiatípus beállítása (alapérték: "
134
+"%s)\n"
135
+"      --media-category                  Médiakategória beállítása\n"
136
+"                                          (alapérték: %s)\n"
137
+"      --media-role                      Médiaszerep beállítása (alapérték: "
138
+"%s)\n"
139
+"      --target                          Csomópont céljának beállítása\n"
140
+"                                          (alapérték: %s), a 0 azt jelenti,\n"
141
+"                                          hogy ne linkeljen\n"
142
+"      --latency                         Csomópont késleltetésének "
143
+"beállítása\n"
144
+"                                          (alapérték: %s)\n"
145
+"                                          Xegység (egység = s, ms, us, ns)\n"
146
+"                                          vagy közvetlen minták (256)\n"
147
+"                                          a gyakoriság a forrásfájl egyike\n"
148
+"  -P  --properties                      Csomópont tulajdonságainak "
149
+"beállítása\n"
150
+"\n"
151
 
152
-#: src/tools/pw-cat.c:1016
153
+#: src/tools/pw-cat.c:809
154
 #, c-format
155
 msgid ""
156
 "      --rate                            Sample rate (req. for rec) (default "
157
@@ -103,16 +143,39 @@
158
 "%d)\n"
159
 "\n"
160
 msgstr ""
161
+"      --rate                            Mintavételi gyakoriság (kötelező a\n"
162
+"                                          rögzítéshez) (alapérték: %u)\n"
163
+"      --channels                        Csatornák száma (kötelező a\n"
164
+"                                          rögzítéshez) (alapérték: %u)\n"
165
+"      --channel-map                     Csatornaleképezés\n"
166
+"                                          ezek egyike: „stereo”, "
167
+"„surround-51”\n"
168
+"                                          stb. vagy csatornanevek vesszővel\n"
169
+"                                          tagolt listája, például: „FL,FR”\n"
170
+"      --format                          Mintavételi formátum: %s (kötelező "
171
+"a\n"
172
+"                                          rögzítéshez) (alapérték: %s)\n"
173
+"      --volume                          Adatfolyam hangereje 0-1.0\n"
174
+"                                          (alapérték: %.3f)\n"
175
+"  -q  --quality                         Újramintavételezési minőség (0-15)\n"
176
+"                                          (alapérték: %d)\n"
177
+"\n"
178
 
179
-#: src/tools/pw-cat.c:1033
180
+#: src/tools/pw-cat.c:826
181
 msgid ""
182
 "  -p, --playback                        Playback mode\n"
183
 "  -r, --record                          Recording mode\n"
184
 "  -m, --midi                            Midi mode\n"
185
+"  -d, --dsd                             DSD mode\n"
186
 "\n"
187
 msgstr ""
188
+"  -p, --playback                        Lejátszási mód\n"
189
+"  -r, --record                          Rögzítési mód\n"
190
+"  -m, --midi                            Midi mód\n"
191
+"  -d, --dsd                             DSD mód\n"
192
+"\n"
193
 
194
-#: src/tools/pw-cli.c:2932
195
+#: src/tools/pw-cli.c:2255
196
 #, c-format
197
 msgid ""
198
 "%s options command\n"
199
@@ -122,360 +185,353 @@
200
 "  -r, --remote                          Remote daemon name\n"
201
pipewire-0.3.58.tar.gz/po/it.po -> pipewire-0.3.59.tar.gz/po/it.po Changed
148
 
1
@@ -34,11 +34,11 @@
2
 
3
 #: src/daemon/pipewire.desktop.in:4
4
 msgid "PipeWire Media System"
5
-msgstr "Sistema Multimediale PipeWire"
6
+msgstr "Sistema multimediale PipeWire"
7
 
8
 #: src/daemon/pipewire.desktop.in:5
9
 msgid "Start the PipeWire Media System"
10
-msgstr "Avvia il Sistema Multimediale PipeWire"
11
+msgstr "Avvia il sistema multimediale PipeWire"
12
 
13
 #: src/examples/media-session/alsa-monitor.c:526
14
 #: spa/plugins/alsa/acp/compat.c:187
15
@@ -144,16 +144,16 @@
16
 
17
 #: spa/plugins/alsa/acp/alsa-mixer.c:2711
18
 msgid "Docking Station Microphone"
19
-msgstr "Microfono docking station"
20
+msgstr "Microfono della docking station"
21
 
22
 #: spa/plugins/alsa/acp/alsa-mixer.c:2712
23
 msgid "Docking Station Line In"
24
-msgstr "Linea in docking station"
25
+msgstr "Linea di ingresso nella docking station"
26
 
27
 #: spa/plugins/alsa/acp/alsa-mixer.c:2713
28
 #: spa/plugins/alsa/acp/alsa-mixer.c:2804
29
 msgid "Line In"
30
-msgstr "Line-In"
31
+msgstr "Linea di ingresso"
32
 
33
 #: spa/plugins/alsa/acp/alsa-mixer.c:2714
34
 #: spa/plugins/alsa/acp/alsa-mixer.c:2798
35
@@ -258,7 +258,7 @@
36
 
37
 #: spa/plugins/alsa/acp/alsa-mixer.c:2811
38
 msgid "Line Out"
39
-msgstr "Line-Out"
40
+msgstr "Linea di uscita"
41
 
42
 #: spa/plugins/alsa/acp/alsa-mixer.c:2812
43
 msgid "Analog Mono Output"
44
@@ -350,7 +350,7 @@
45
 #: spa/plugins/alsa/acp/alsa-mixer.c:4542
46
 #: spa/plugins/alsa/acp/alsa-mixer.c:4543
47
 msgid "Multichannel"
48
-msgstr "Multi canale"
49
+msgstr "Multicanale"
50
 
51
 #: spa/plugins/alsa/acp/alsa-mixer.c:4544
52
 msgid "Analog Surround 2.1"
53
@@ -442,7 +442,7 @@
54
 
55
 #: spa/plugins/alsa/acp/alsa-mixer.c:4701
56
 msgid "Multichannel Duplex"
57
-msgstr "Duplex multi canale"
58
+msgstr "Duplex multicanale"
59
 
60
 #: spa/plugins/alsa/acp/alsa-mixer.c:4702
61
 msgid "Stereo Duplex"
62
@@ -477,11 +477,11 @@
63
 msgstr0 ""
64
 "snd_pcm_avail() ha restituito un valore molto grande: %lu byte (%lu ms).\n"
65
 "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
66
-"questo problema agli sviluppatori ALSA."
67
+"questo problema ai suoi sviluppatori."
68
 msgstr1 ""
69
 "snd_pcm_avail() ha restituito un valore molto grande: %lu byte (%lu ms).\n"
70
 "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
71
-"questo problema agli sviluppatori ALSA."
72
+"questo problema ai suoi sviluppatori."
73
 
74
 #: spa/plugins/alsa/acp/alsa-util.c:1241
75
 #, c-format
76
@@ -498,11 +498,11 @@
77
 msgstr0 ""
78
 "snd_pcm_delay() ha restituito un valore molto grande: %li byte (%s%lu ms).\n"
79
 "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
80
-"questo problema agli sviluppatori ALSA."
81
+"questo problema ai suoi sviluppatori."
82
 msgstr1 ""
83
 "snd_pcm_delay() ha restituito un valore molto grande: %li byte (%s%lu ms).\n"
84
 "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
85
-"questo problema agli sviluppatori ALSA."
86
+"questo problema ai suoi sviluppatori."
87
 
88
 #: spa/plugins/alsa/acp/alsa-util.c:1288
89
 #, c-format
90
@@ -515,7 +515,7 @@
91
 "snd_pcm_avail() ha restituito dei valori strani: delay %lu è minore di avail "
92
 "%lu.\n"
93
 "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
94
-"questo problema agli sviluppatori ALSA."
95
+"questo problema ai suoi sviluppatori."
96
 
97
 #: spa/plugins/alsa/acp/alsa-util.c:1331
98
 #, c-format
99
@@ -533,12 +533,12 @@
100
 "snd_pcm_mmap_begin() ha restituito un valore molto grande: %lu byte (%lu "
101
 "ms).\n"
102
 "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
103
-"questo problema agli sviluppatori ALSA."
104
+"questo problema ai suoi sviluppatori."
105
 msgstr1 ""
106
 "snd_pcm_mmap_begin() ha restituito un valore molto grande: %lu byte (%lu "
107
 "ms).\n"
108
 "Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
109
-"questo problema agli sviluppatori ALSA."
110
+"questo problema ai suoi sviluppatori."
111
 
112
 #: spa/plugins/bluez5/bluez5-device.c:1010
113
 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
114
@@ -547,20 +547,20 @@
115
 #: spa/plugins/bluez5/bluez5-device.c:1033
116
 #, c-format
117
 msgid "High Fidelity Playback (A2DP Sink, codec %s)"
118
-msgstr "Riproduzione ad Alta Fedeltà (A2DP Sink, codec %s)"
119
+msgstr "Riproduzione ad alta fedeltà (A2DP Sink, codec %s)"
120
 
121
 #: spa/plugins/bluez5/bluez5-device.c:1035
122
 #, c-format
123
 msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
124
-msgstr "Duplex ad Alta Fedeltà (Sorgente/Sink, A2DP codec %s)"
125
+msgstr "Duplex ad alta fedeltà (Sorgente/Sink, A2DP codec %s)"
126
 
127
 #: spa/plugins/bluez5/bluez5-device.c:1041
128
 msgid "High Fidelity Playback (A2DP Sink)"
129
-msgstr "Riproduzione ad Alta Fedeltà (A2DP Sink)"
130
+msgstr "Riproduzione ad alta fedeltà (A2DP Sink)"
131
 
132
 #: spa/plugins/bluez5/bluez5-device.c:1043
133
 msgid "High Fidelity Duplex (A2DP Source/Sink)"
134
-msgstr "Duplex ad Alta Fedeltà (A2DP Source/Sink)"
135
+msgstr "Duplex ad alta fedeltà (A2DP Source/Sink)"
136
 
137
 #: spa/plugins/bluez5/bluez5-device.c:1070
138
 #, c-format
139
@@ -573,7 +573,7 @@
140
 
141
 #: spa/plugins/bluez5/bluez5-device.c:1140
142
 msgid "Handsfree"
143
-msgstr "Sistema mani-libere"
144
+msgstr "Vivavoce"
145
 
146
 #: spa/plugins/bluez5/bluez5-device.c:1155
147
 msgid "Headphone"
148
pipewire-0.3.58.tar.gz/po/pl.po -> pipewire-0.3.59.tar.gz/po/pl.po Changed
174
 
1
@@ -8,8 +8,8 @@
2
 "Project-Id-Version: pipewire\n"
3
 "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
4
 "issues\n"
5
-"POT-Creation-Date: 2022-08-27 13:57+0000\n"
6
-"PO-Revision-Date: 2022-08-27 16:00+0200\n"
7
+"POT-Creation-Date: 2022-09-15 15:26+0000\n"
8
+"PO-Revision-Date: 2022-09-25 15:20+0200\n"
9
 "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
10
 "Language-Team: Polish <community-poland@mozilla.org>\n"
11
 "Language: pl\n"
12
@@ -51,7 +51,7 @@
13
 msgid "Dummy Output"
14
 msgstr "Głuche wyjście"
15
 
16
-#: src/modules/module-pulse-tunnel.c:648
17
+#: src/modules/module-pulse-tunnel.c:662
18
 #, c-format
19
 msgid "Tunnel for %s@%s"
20
 msgstr "Tunel dla %s@%s"
21
@@ -195,7 +195,7 @@
22
 msgstr "Dźwięk w zastosowaniach profesjonalnych"
23
 
24
 #: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
25
-#: spa/plugins/bluez5/bluez5-device.c:1188
26
+#: spa/plugins/bluez5/bluez5-device.c:1236
27
 msgid "Off"
28
 msgstr "Wyłączone"
29
 
30
@@ -222,7 +222,7 @@
31
 
32
 #: spa/plugins/alsa/acp/alsa-mixer.c:2657
33
 #: spa/plugins/alsa/acp/alsa-mixer.c:2741
34
-#: spa/plugins/bluez5/bluez5-device.c:1360
35
+#: spa/plugins/bluez5/bluez5-device.c:1454
36
 msgid "Microphone"
37
 msgstr "Mikrofon"
38
 
39
@@ -288,7 +288,7 @@
40
 msgstr "Brak podbicia basów"
41
 
42
 #: spa/plugins/alsa/acp/alsa-mixer.c:2672
43
-#: spa/plugins/bluez5/bluez5-device.c:1366
44
+#: spa/plugins/bluez5/bluez5-device.c:1460
45
 msgid "Speaker"
46
 msgstr "Głośnik"
47
 
48
@@ -403,7 +403,7 @@
49
 
50
 #: spa/plugins/alsa/acp/alsa-mixer.c:4484
51
 #: spa/plugins/alsa/acp/alsa-mixer.c:4642
52
-#: spa/plugins/bluez5/bluez5-device.c:1348
53
+#: spa/plugins/bluez5/bluez5-device.c:1442
54
 msgid "Headset"
55
 msgstr "Słuchawki z mikrofonem"
56
 
57
@@ -627,77 +627,92 @@
58
 msgid "Modem"
59
 msgstr "Modem"
60
 
61
-#: spa/plugins/bluez5/bluez5-device.c:1199
62
+#: spa/plugins/bluez5/bluez5-device.c:1247
63
 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
64
 msgstr "Bramka dźwięku (źródło A2DP i AG HSP/HFP)"
65
 
66
-#: spa/plugins/bluez5/bluez5-device.c:1224
67
+#: spa/plugins/bluez5/bluez5-device.c:1272
68
 #, c-format
69
 msgid "High Fidelity Playback (A2DP Sink, codec %s)"
70
 msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP, kodek %s)"
71
 
72
-#: spa/plugins/bluez5/bluez5-device.c:1227
73
+#: spa/plugins/bluez5/bluez5-device.c:1275
74
 #, c-format
75
 msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
76
 msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP, kodek %s)"
77
 
78
-#: spa/plugins/bluez5/bluez5-device.c:1235
79
+#: spa/plugins/bluez5/bluez5-device.c:1283
80
 msgid "High Fidelity Playback (A2DP Sink)"
81
 msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP)"
82
 
83
-#: spa/plugins/bluez5/bluez5-device.c:1237
84
+#: spa/plugins/bluez5/bluez5-device.c:1285
85
 msgid "High Fidelity Duplex (A2DP Source/Sink)"
86
 msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP)"
87
 
88
-#: spa/plugins/bluez5/bluez5-device.c:1265
89
+#: spa/plugins/bluez5/bluez5-device.c:1322
90
+#, c-format
91
+msgid "High Fidelity Playback (BAP Sink, codec %s)"
92
+msgstr "Odtwarzanie o wysokiej dokładności (odpływ BAP, kodek %s)"
93
+
94
+#: spa/plugins/bluez5/bluez5-device.c:1326
95
+#, c-format
96
+msgid "High Fidelity Input (BAP Source, codec %s)"
97
+msgstr "Wejście o wysokiej dokładności (źródło BAP, kodek %s)"
98
+
99
+#: spa/plugins/bluez5/bluez5-device.c:1330
100
+#, c-format
101
+msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
102
+msgstr "Dupleks o wysokiej dokładności (źródło/odpływ BAP, kodek %s)"
103
+
104
+#: spa/plugins/bluez5/bluez5-device.c:1359
105
 #, c-format
106
 msgid "Headset Head Unit (HSP/HFP, codec %s)"
107
 msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP, kodek %s)"
108
 
109
-#: spa/plugins/bluez5/bluez5-device.c:1270
110
+#: spa/plugins/bluez5/bluez5-device.c:1364
111
 msgid "Headset Head Unit (HSP/HFP)"
112
 msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP)"
113
 
114
-#: spa/plugins/bluez5/bluez5-device.c:1349
115
-#: spa/plugins/bluez5/bluez5-device.c:1354
116
-#: spa/plugins/bluez5/bluez5-device.c:1361
117
-#: spa/plugins/bluez5/bluez5-device.c:1367
118
-#: spa/plugins/bluez5/bluez5-device.c:1373
119
-#: spa/plugins/bluez5/bluez5-device.c:1379
120
-#: spa/plugins/bluez5/bluez5-device.c:1385
121
-#: spa/plugins/bluez5/bluez5-device.c:1391
122
-#: spa/plugins/bluez5/bluez5-device.c:1397
123
+#: spa/plugins/bluez5/bluez5-device.c:1443
124
+#: spa/plugins/bluez5/bluez5-device.c:1448
125
+#: spa/plugins/bluez5/bluez5-device.c:1455
126
+#: spa/plugins/bluez5/bluez5-device.c:1461
127
+#: spa/plugins/bluez5/bluez5-device.c:1467
128
+#: spa/plugins/bluez5/bluez5-device.c:1473
129
+#: spa/plugins/bluez5/bluez5-device.c:1479
130
+#: spa/plugins/bluez5/bluez5-device.c:1485
131
+#: spa/plugins/bluez5/bluez5-device.c:1491
132
 msgid "Handsfree"
133
 msgstr "Zestaw głośnomówiący"
134
 
135
-#: spa/plugins/bluez5/bluez5-device.c:1355
136
+#: spa/plugins/bluez5/bluez5-device.c:1449
137
 msgid "Handsfree (HFP)"
138
 msgstr "Zestaw głośnomówiący (HFP)"
139
 
140
-#: spa/plugins/bluez5/bluez5-device.c:1372
141
+#: spa/plugins/bluez5/bluez5-device.c:1466
142
 msgid "Headphone"
143
 msgstr "Słuchawki"
144
 
145
-#: spa/plugins/bluez5/bluez5-device.c:1378
146
+#: spa/plugins/bluez5/bluez5-device.c:1472
147
 msgid "Portable"
148
 msgstr "Przenośne"
149
 
150
-#: spa/plugins/bluez5/bluez5-device.c:1384
151
+#: spa/plugins/bluez5/bluez5-device.c:1478
152
 msgid "Car"
153
 msgstr "Samochód"
154
 
155
-#: spa/plugins/bluez5/bluez5-device.c:1390
156
+#: spa/plugins/bluez5/bluez5-device.c:1484
157
 msgid "HiFi"
158
 msgstr "HiFi"
159
 
160
-#: spa/plugins/bluez5/bluez5-device.c:1396
161
+#: spa/plugins/bluez5/bluez5-device.c:1490
162
 msgid "Phone"
163
 msgstr "Telefon"
164
 
165
-#: spa/plugins/bluez5/bluez5-device.c:1403
166
+#: spa/plugins/bluez5/bluez5-device.c:1497
167
 msgid "Bluetooth"
168
 msgstr "Bluetooth"
169
 
170
-#: spa/plugins/bluez5/bluez5-device.c:1404
171
+#: spa/plugins/bluez5/bluez5-device.c:1498
172
 msgid "Bluetooth (HFP)"
173
 msgstr "Bluetooth (HFP)"
174
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
12
 
1
@@ -161,8 +161,9 @@
2
    *target += info->chunk_size;
3
 
4
    for (i = 0, size = 0; i < n_datas; i++) {
5
+       int64_t align = data_alignsi;
6
        info->max_align = SPA_MAX(info->max_align, data_alignsi);
7
-       size = SPA_ROUND_UP_N(size, data_alignsi);
8
+       size = SPA_ROUND_UP_N(size, align);
9
        size += datasi.maxsize;
10
    }
11
    info->data_size = size;
12
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
37
 
1
@@ -64,9 +64,15 @@
2
    void *data;     /**< pointer to metadata */
3
 };
4
 
5
-#define spa_meta_first(m)  ((m)->data)
6
-#define spa_meta_end(m)        SPA_PTROFF((m)->data,(m)->size,void)
7
-#define spa_meta_check(p,m)    (SPA_PTROFF(p,sizeof(*p),void) <= spa_meta_end(m))
8
+static inline void *spa_meta_first(const struct spa_meta *m) {
9
+   return m->data;
10
+}
11
+#define spa_meta_first spa_meta_first
12
+static inline void *spa_meta_end(const struct spa_meta *m) {
13
+   return SPA_PTROFF(m->data,m->size,void);
14
+}
15
+#define spa_meta_end spa_meta_end
16
+#define spa_meta_check(p,m)    (SPA_PTROFF(p,sizeof(*(p)),void) <= spa_meta_end(m))
17
 
18
 /**
19
  * Describes essential buffer header metadata such as flags and
20
@@ -92,11 +98,14 @@
21
    struct spa_region region;
22
 };
23
 
24
-#define spa_meta_region_is_valid(m)    ((m)->region.size.width != 0 && (m)->region.size.height != 0)
25
+static inline bool spa_meta_region_is_valid(const struct spa_meta_region *m) {
26
+   return m->region.size.width != 0 && m->region.size.height != 0;
27
+}
28
+#define spa_meta_region_is_valid spa_meta_region_is_valid
29
 
30
 /** iterate all the items in a metadata */
31
 #define spa_meta_for_each(pos,meta)                    \
32
-   for (pos = (__typeof(pos))spa_meta_first(meta);         \
33
+   for ((pos) = (__typeof(pos))spa_meta_first(meta);           \
34
        spa_meta_check(pos, meta);                  \
35
             (pos)++)
36
 
37
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
14
 
1
@@ -36,10 +36,10 @@
2
  */
3
 
4
 #ifndef spa_debug
5
-#define spa_debug(fmt,...) ({ printf(fmt"\n", ## __VA_ARGS__); })
6
+#define spa_debug(fmt,...) ({ printf((fmt"\n"), ## __VA_ARGS__); })
7
 #endif
8
 #ifndef spa_debugn
9
-#define spa_debugn(fmt,...)    ({ printf(fmt, ## __VA_ARGS__); })
10
+#define spa_debugn(fmt,...)    ({ printf((fmt), ## __VA_ARGS__); })
11
 #endif
12
 
13
 /**
14
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
17
 
1
@@ -121,12 +121,12 @@
2
    int __res = 0;                          \
3
    spa_callbacks_call_res(&(n)->callbacks,             \
4
            struct spa_graph_node_callbacks, __res,     \
5
-           method, version, ##__VA_ARGS__);        \
6
+           method, (version), ##__VA_ARGS__);      \
7
    __res;                              \
8
 })
9
 
10
-#define spa_graph_node_process(n)      spa_graph_node_call(n, process, 0, n)
11
-#define spa_graph_node_reuse_buffer(n,p,i) spa_graph_node_call(n, reuse_buffer, 0, n, p, i)
12
+#define spa_graph_node_process(n)      spa_graph_node_call((n), process, 0, (n))
13
+#define spa_graph_node_reuse_buffer(n,p,i) spa_graph_node_call((n), reuse_buffer, 0, (n), (p), (i))
14
 
15
 struct spa_graph_port {
16
    struct spa_list link;       /**< link in node port list */
17
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
14
 
1
@@ -80,10 +80,10 @@
2
 #define spa_audio_aec_method(o,method,version,...)         \
3
 ({                                 \
4
    int _res = -ENOTSUP;                        \
5
-   struct spa_audio_aec *_o = o;                   \
6
+   struct spa_audio_aec *_o = (o);                 \
7
    spa_interface_call_res(&_o->iface,              \
8
            struct spa_audio_aec_methods, _res,     \
9
-           method, version, ##__VA_ARGS__);        \
10
+           method, (version), ##__VA_ARGS__);      \
11
    _res;                               \
12
 })
13
 
14
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
32
 
1
@@ -71,7 +71,7 @@
2
    uint32_t n_params;          /**< number of elements in params */
3
 };
4
 
5
-#define SPA_DEVICE_INFO_INIT() (struct spa_device_info){ SPA_VERSION_DEVICE_INFO, }
6
+#define SPA_DEVICE_INFO_INIT() ((struct spa_device_info){ SPA_VERSION_DEVICE_INFO, })
7
 
8
 /**
9
  * Information about a device object
10
@@ -92,7 +92,7 @@
11
    const struct spa_dict *props;       /**< extra object properties */
12
 };
13
 
14
-#define SPA_DEVICE_OBJECT_INFO_INIT()  (struct spa_device_object_info){ SPA_VERSION_DEVICE_OBJECT_INFO, }
15
+#define SPA_DEVICE_OBJECT_INFO_INIT()  ((struct spa_device_object_info){ SPA_VERSION_DEVICE_OBJECT_INFO, })
16
 
17
 /** the result of spa_device_enum_params() */
18
 #define SPA_RESULT_TYPE_DEVICE_PARAMS  1
19
@@ -243,10 +243,10 @@
20
 #define spa_device_method(o,method,version,...)                \
21
 ({                                 \
22
    int _res = -ENOTSUP;                        \
23
-   struct spa_device *_o = o;                  \
24
+   struct spa_device *_o = (o);                    \
25
    spa_interface_call_res(&_o->iface,              \
26
            struct spa_device_methods, _res,        \
27
-           method, version, ##__VA_ARGS__);        \
28
+           method, (version), ##__VA_ARGS__);      \
29
    _res;                               \
30
 })
31
 
32
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
19
 
1
@@ -100,7 +100,7 @@
2
    uint32_t buffer_id;     /**< a buffer id */
3
 };
4
 
5
-#define SPA_IO_BUFFERS_INIT  (struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, }
6
+#define SPA_IO_BUFFERS_INIT  ((struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, })
7
 
8
 /**
9
  * IO area to exchange a memory region
10
@@ -110,7 +110,7 @@
11
    uint32_t size;          /**< the size of \a data */
12
    void *data;         /**< a memory pointer */
13
 };
14
-#define SPA_IO_MEMORY_INIT  (struct spa_io_memory) { SPA_STATUS_OK, 0, NULL, }
15
+#define SPA_IO_MEMORY_INIT  ((struct spa_io_memory) { SPA_STATUS_OK, 0, NULL, })
16
 
17
 /** A range, suitable for input ports that can suggest a range to output ports */
18
 struct spa_io_range {
19
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
19
 
1
@@ -85,7 +85,7 @@
2
    uint32_t n_params;          /**< number of items in \a params */
3
 };
4
 
5
-#define SPA_NODE_INFO_INIT()   (struct spa_node_info) { 0, }
6
+#define SPA_NODE_INFO_INIT()   ((struct spa_node_info) { 0, })
7
 
8
 /**
9
  * Port information structure
10
@@ -124,7 +124,7 @@
11
    uint32_t n_params;          /**< number of items in \a params */
12
 };
13
 
14
-#define SPA_PORT_INFO_INIT()   (struct spa_port_info) { 0, }
15
+#define SPA_PORT_INFO_INIT()   ((struct spa_port_info) { 0, })
16
 
17
 #define SPA_RESULT_TYPE_NODE_ERROR 1
18
 #define SPA_RESULT_TYPE_NODE_PARAMS    2
19
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
10
 
1
@@ -68,7 +68,7 @@
2
    uint32_t positionSPA_AUDIO_MAX_CHANNELS;    /*< channel position from enum spa_audio_channel */
3
 };
4
 
5
-#define SPA_AUDIO_INFO_DSD_INIT(...)       (struct spa_audio_info_dsd) { __VA_ARGS__ }
6
+#define SPA_AUDIO_INFO_DSD_INIT(...)       ((struct spa_audio_info_dsd) { __VA_ARGS__ })
7
 
8
 /**
9
  * \}
10
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
10
 
1
@@ -56,7 +56,7 @@
2
    uint32_t rate;              /*< sample rate */
3
 };
4
 
5
-#define SPA_AUDIO_INFO_IEC958_INIT(...)        (struct spa_audio_info_iec958) { __VA_ARGS__ }
6
+#define SPA_AUDIO_INFO_IEC958_INIT(...)        ((struct spa_audio_info_iec958) { __VA_ARGS__ })
7
 
8
 /**
9
  * \}
10
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
19
 
1
@@ -294,7 +294,7 @@
2
    uint32_t positionSPA_AUDIO_MAX_CHANNELS;    /*< channel position from enum spa_audio_channel */
3
 };
4
 
5
-#define SPA_AUDIO_INFO_RAW_INIT(...)       (struct spa_audio_info_raw) { __VA_ARGS__ }
6
+#define SPA_AUDIO_INFO_RAW_INIT(...)       ((struct spa_audio_info_raw) { __VA_ARGS__ })
7
 
8
 #define SPA_KEY_AUDIO_FORMAT       "audio.format"      /**< an audio format as string,
9
                                  *  Ex. "S16LE" */
10
@@ -311,7 +311,7 @@
11
    enum spa_audio_format format;       /*< format, one of the DSP formats in enum spa_audio_format_dsp */
12
 };
13
 
14
-#define SPA_AUDIO_INFO_DSP_INIT(...)       (struct spa_audio_info_dsp) { __VA_ARGS__ }
15
+#define SPA_AUDIO_INFO_DSP_INIT(...)       ((struct spa_audio_info_dsp) { __VA_ARGS__ })
16
 
17
 /**
18
  * \}
19
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
11
 
1
@@ -58,6 +58,9 @@
2
    /* HFP */
3
    SPA_BLUETOOTH_AUDIO_CODEC_CVSD = 0x100,
4
    SPA_BLUETOOTH_AUDIO_CODEC_MSBC,
5
+
6
+   /* BAP */
7
+   SPA_BLUETOOTH_AUDIO_CODEC_LC3 = 0x200,
8
 };
9
 
10
 /**
11
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
10
 
1
@@ -62,6 +62,8 @@
2
    { SPA_BLUETOOTH_AUDIO_CODEC_CVSD, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "cvsd", NULL },
3
    { SPA_BLUETOOTH_AUDIO_CODEC_MSBC, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "msbc", NULL },
4
 
5
+   { SPA_BLUETOOTH_AUDIO_CODEC_LC3, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "lc3", NULL },
6
+
7
    { 0, 0, NULL, NULL },
8
 };
9
 
10
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
19
 
1
@@ -50,7 +50,7 @@
2
    uint64_t max_ns;
3
 };
4
 
5
-#define SPA_LATENCY_INFO(dir,...) (struct spa_latency_info) { .direction = (dir), ## __VA_ARGS__ }
6
+#define SPA_LATENCY_INFO(dir,...) ((struct spa_latency_info) { .direction = (dir), ## __VA_ARGS__ })
7
 
8
 static inline int
9
 spa_latency_info_compare(const struct spa_latency_info *a, struct spa_latency_info *b)
10
@@ -146,7 +146,7 @@
11
    uint64_t ns;
12
 };
13
 
14
-#define SPA_PROCESS_LATENCY_INFO_INIT(...) (struct spa_process_latency_info) { __VA_ARGS__ }
15
+#define SPA_PROCESS_LATENCY_INFO_INIT(...) ((struct spa_process_latency_info) { __VA_ARGS__ })
16
 
17
 static inline int
18
 spa_process_latency_parse(const struct spa_pod *latency, struct spa_process_latency_info *info)
19
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
10
 
1
@@ -75,7 +75,7 @@
2
    uint32_t padding5;
3
 };
4
 
5
-#define SPA_PARAM_INFO(id,flags) (struct spa_param_info){ (id), (flags) }
6
+#define SPA_PARAM_INFO(id,flags) ((struct spa_param_info){ (id), (flags) })
7
 
8
 /** properties for SPA_TYPE_OBJECT_ParamBuffers */
9
 enum spa_param_buffers {
10
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
18
 
1
@@ -206,14 +206,14 @@
2
    enum spa_video_color_primaries color_primaries;     /**< color primaries. used to convert between R'G'B' and CIE XYZ */
3
 };
4
 
5
-#define SPA_VIDEO_INFO_RAW_INIT(...)   (struct spa_video_info_raw) { __VA_ARGS__ }
6
+#define SPA_VIDEO_INFO_RAW_INIT(...)   ((struct spa_video_info_raw) { __VA_ARGS__ })
7
 
8
 struct spa_video_info_dsp {
9
    enum spa_video_format format;
10
    int64_t modifier;
11
 };
12
 
13
-#define SPA_VIDEO_INFO_DSP_INIT(...)   (struct spa_video_info_dsp) { __VA_ARGS__ }
14
+#define SPA_VIDEO_INFO_DSP_INIT(...)   ((struct spa_video_info_dsp) { __VA_ARGS__ })
15
 
16
 /**
17
  * \}
18
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
201
 
1
@@ -69,7 +69,7 @@
2
    struct spa_callbacks callbacks;
3
 };
4
 
5
-#define SPA_POD_BUILDER_INIT(buffer,size)  (struct spa_pod_builder){ buffer, size, 0, {}, {} }
6
+#define SPA_POD_BUILDER_INIT(buffer,size)  ((struct spa_pod_builder){ (buffer), (size), 0, {}, {} })
7
 
8
 static inline void
9
 spa_pod_builder_get_state(struct spa_pod_builder *builder, struct spa_pod_builder_state *state)
10
@@ -143,8 +143,10 @@
11
 
12
    if (offset + size > builder->size) {
13
        res = -ENOSPC;
14
-       spa_callbacks_call_res(&builder->callbacks, struct spa_pod_builder_callbacks, res,
15
-               overflow, 0, offset + size);
16
+       if (offset <= builder->size)
17
+           spa_callbacks_call_res(&builder->callbacks,
18
+                   struct spa_pod_builder_callbacks, res,
19
+                   overflow, 0, offset + size);
20
    }
21
    if (res == 0 && data)
22
        memcpy(SPA_PTROFF(builder->data, offset, void), data, size);
23
@@ -212,7 +214,7 @@
24
    return res;
25
 }
26
 
27
-#define SPA_POD_INIT(size,type) (struct spa_pod) { size, type }
28
+#define SPA_POD_INIT(size,type) ((struct spa_pod) { (size), (type) })
29
 
30
 #define SPA_POD_INIT_None() SPA_POD_INIT(0, SPA_TYPE_None)
31
 
32
@@ -229,7 +231,7 @@
33
    return spa_pod_builder_raw(builder, &p, sizeof(p));
34
 }
35
 
36
-#define SPA_POD_INIT_Bool(val) (struct spa_pod_bool){ { sizeof(uint32_t), SPA_TYPE_Bool }, val ? 1 : 0, 0 }
37
+#define SPA_POD_INIT_Bool(val) ((struct spa_pod_bool){ { sizeof(uint32_t), SPA_TYPE_Bool }, (val) ? 1 : 0, 0 })
38
 
39
 static inline int spa_pod_builder_bool(struct spa_pod_builder *builder, bool val)
40
 {
41
@@ -237,7 +239,7 @@
42
    return spa_pod_builder_primitive(builder, &p.pod);
43
 }
44
 
45
-#define SPA_POD_INIT_Id(val) (struct spa_pod_id){ { sizeof(uint32_t), SPA_TYPE_Id }, (uint32_t)val, 0 }
46
+#define SPA_POD_INIT_Id(val) ((struct spa_pod_id){ { sizeof(uint32_t), SPA_TYPE_Id }, (val), 0 })
47
 
48
 static inline int spa_pod_builder_id(struct spa_pod_builder *builder, uint32_t val)
49
 {
50
@@ -245,7 +247,7 @@
51
    return spa_pod_builder_primitive(builder, &p.pod);
52
 }
53
 
54
-#define SPA_POD_INIT_Int(val) (struct spa_pod_int){ { sizeof(int32_t), SPA_TYPE_Int }, (int32_t)val, 0 }
55
+#define SPA_POD_INIT_Int(val) ((struct spa_pod_int){ { sizeof(int32_t), SPA_TYPE_Int }, (val), 0 })
56
 
57
 static inline int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t val)
58
 {
59
@@ -253,7 +255,7 @@
60
    return spa_pod_builder_primitive(builder, &p.pod);
61
 }
62
 
63
-#define SPA_POD_INIT_Long(val) (struct spa_pod_long){ { sizeof(int64_t), SPA_TYPE_Long }, (int64_t)val }
64
+#define SPA_POD_INIT_Long(val) ((struct spa_pod_long){ { sizeof(int64_t), SPA_TYPE_Long }, (val) })
65
 
66
 static inline int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t val)
67
 {
68
@@ -261,7 +263,7 @@
69
    return spa_pod_builder_primitive(builder, &p.pod);
70
 }
71
 
72
-#define SPA_POD_INIT_Float(val) (struct spa_pod_float){ { sizeof(float), SPA_TYPE_Float }, val, 0 }
73
+#define SPA_POD_INIT_Float(val) ((struct spa_pod_float){ { sizeof(float), SPA_TYPE_Float }, (val), 0 })
74
 
75
 static inline int spa_pod_builder_float(struct spa_pod_builder *builder, float val)
76
 {
77
@@ -269,7 +271,7 @@
78
    return spa_pod_builder_primitive(builder, &p.pod);
79
 }
80
 
81
-#define SPA_POD_INIT_Double(val) (struct spa_pod_double){ { sizeof(double), SPA_TYPE_Double }, val }
82
+#define SPA_POD_INIT_Double(val) ((struct spa_pod_double){ { sizeof(double), SPA_TYPE_Double }, (val) })
83
 
84
 static inline int spa_pod_builder_double(struct spa_pod_builder *builder, double val)
85
 {
86
@@ -277,7 +279,7 @@
87
    return spa_pod_builder_primitive(builder, &p.pod);
88
 }
89
 
90
-#define SPA_POD_INIT_String(len) (struct spa_pod_string){ { len, SPA_TYPE_String } }
91
+#define SPA_POD_INIT_String(len) ((struct spa_pod_string){ { (len), SPA_TYPE_String } })
92
 
93
 static inline int
94
 spa_pod_builder_write_string(struct spa_pod_builder *builder, const char *str, uint32_t len)
95
@@ -307,7 +309,7 @@
96
    return spa_pod_builder_string_len(builder, str ? str : "", len);
97
 }
98
 
99
-#define SPA_POD_INIT_Bytes(len) (struct spa_pod_bytes){ { len, SPA_TYPE_Bytes } }
100
+#define SPA_POD_INIT_Bytes(len) ((struct spa_pod_bytes){ { (len), SPA_TYPE_Bytes } })
101
 
102
 static inline int
103
 spa_pod_builder_bytes(struct spa_pod_builder *builder, const void *bytes, uint32_t len)
104
@@ -327,7 +329,7 @@
105
    return SPA_POD_BODY(spa_pod_builder_deref(builder, offset));
106
 }
107
 
108
-#define SPA_POD_INIT_Pointer(type,value) (struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { type, 0, value } }
109
+#define SPA_POD_INIT_Pointer(type,value) ((struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { (type), 0, (value) } })
110
 
111
 static inline int
112
 spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, const void *val)
113
@@ -336,7 +338,7 @@
114
    return spa_pod_builder_primitive(builder, &p.pod);
115
 }
116
 
117
-#define SPA_POD_INIT_Fd(fd) (struct spa_pod_fd){ { sizeof(int64_t), SPA_TYPE_Fd }, fd }
118
+#define SPA_POD_INIT_Fd(fd) ((struct spa_pod_fd){ { sizeof(int64_t), SPA_TYPE_Fd }, (fd) })
119
 
120
 static inline int spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd)
121
 {
122
@@ -344,7 +346,7 @@
123
    return spa_pod_builder_primitive(builder, &p.pod);
124
 }
125
 
126
-#define SPA_POD_INIT_Rectangle(val) (struct spa_pod_rectangle){ { sizeof(struct spa_rectangle), SPA_TYPE_Rectangle }, val }
127
+#define SPA_POD_INIT_Rectangle(val) ((struct spa_pod_rectangle){ { sizeof(struct spa_rectangle), SPA_TYPE_Rectangle }, (val) })
128
 
129
 static inline int
130
 spa_pod_builder_rectangle(struct spa_pod_builder *builder, uint32_t width, uint32_t height)
131
@@ -353,7 +355,7 @@
132
    return spa_pod_builder_primitive(builder, &p.pod);
133
 }
134
 
135
-#define SPA_POD_INIT_Fraction(val) (struct spa_pod_fraction){ { sizeof(struct spa_fraction), SPA_TYPE_Fraction }, val }
136
+#define SPA_POD_INIT_Fraction(val) ((struct spa_pod_fraction){ { sizeof(struct spa_fraction), SPA_TYPE_Fraction }, (val) })
137
 
138
 static inline int
139
 spa_pod_builder_fraction(struct spa_pod_builder *builder, uint32_t num, uint32_t denom)
140
@@ -389,12 +391,12 @@
141
 }
142
 
143
 #define SPA_POD_INIT_CHOICE_BODY(type, flags, child_size, child_type)              \
144
-   (struct spa_pod_choice_body) { type, flags, { child_size, child_type }}
145
+   ((struct spa_pod_choice_body) { (type), (flags), { (child_size), (child_type) }})
146
 
147
 #define SPA_POD_INIT_Choice(type, ctype, child_type, n_vals, ...)              \
148
-   (struct { struct spa_pod_choice choice; ctype valsn_vals;})             \
149
-   { { { n_vals * sizeof(ctype) + sizeof(struct spa_pod_choice_body), SPA_TYPE_Choice },   \
150
-       { type, 0, { sizeof(ctype), child_type } } }, { __VA_ARGS__ } }
151
+   ((struct { struct spa_pod_choice choice; ctype vals(n_vals);})          \
152
+   { { { (n_vals) * sizeof(ctype) + sizeof(struct spa_pod_choice_body), SPA_TYPE_Choice }, \
153
+       { (type), 0, { sizeof(ctype), (child_type) } } }, { __VA_ARGS__ } })
154
 
155
 static inline int
156
 spa_pod_builder_push_choice(struct spa_pod_builder *builder, struct spa_pod_frame *frame,
157
@@ -409,7 +411,7 @@
158
    return res;
159
 }
160
 
161
-#define SPA_POD_INIT_Struct(size) (struct spa_pod_struct){ { size, SPA_TYPE_Struct } }
162
+#define SPA_POD_INIT_Struct(size) ((struct spa_pod_struct){ { (size), SPA_TYPE_Struct } })
163
 
164
 static inline int
165
 spa_pod_builder_push_struct(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
166
@@ -421,7 +423,7 @@
167
    return res;
168
 }
169
 
170
-#define SPA_POD_INIT_Object(size,type,id,...)  (struct spa_pod_object){ { size, SPA_TYPE_Object }, { type, id }, ##__VA_ARGS__ }
171
+#define SPA_POD_INIT_Object(size,type,id,...)  ((struct spa_pod_object){ { (size), SPA_TYPE_Object }, { (type), (id) }, ##__VA_ARGS__ })
172
 
173
 static inline int
174
 spa_pod_builder_push_object(struct spa_pod_builder *builder, struct spa_pod_frame *frame,
175
@@ -436,7 +438,7 @@
176
 }
177
 
178
 #define SPA_POD_INIT_Prop(key,flags,size,type) \
179
-   (struct spa_pod_prop){ key, flags, { size, type } }
180
+   ((struct spa_pod_prop){ (key), (flags), { (size), (type) } })
181
 
182
 static inline int
183
 spa_pod_builder_prop(struct spa_pod_builder *builder, uint32_t key, uint32_t flags)
184
@@ -446,7 +448,7 @@
185
 }
186
 
187
 #define SPA_POD_INIT_Sequence(size,unit)   \
188
-   (struct spa_pod_sequence){ { size, SPA_TYPE_Sequence}, {unit, 0 } }
189
+   ((struct spa_pod_sequence){ { (size), SPA_TYPE_Sequence}, {(unit), 0 } })
190
 
191
 static inline int
192
 spa_pod_builder_push_sequence(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t unit)
193
@@ -650,26 +652,29 @@
194
 
195
 #define spa_pod_builder_add_object(b,type,id,...)              \
196
 ({                                     \
197
+   struct spa_pod_builder *_b = (b);                   \
198
    struct spa_pod_frame _f;                        \
199
-   spa_pod_builder_push_object(b, &_f, type, id);              \
200
-   spa_pod_builder_add(b, ##__VA_ARGS__, 0);               \
201
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
18
 
1
@@ -47,12 +47,12 @@
2
 };
3
 
4
 #define SPA_COMMAND_TYPE(cmd)      ((cmd)->body.body.type)
5
-#define SPA_COMMAND_ID(cmd,type)   (SPA_COMMAND_TYPE(cmd) == type ? \
6
+#define SPA_COMMAND_ID(cmd,type)   (SPA_COMMAND_TYPE(cmd) == (type) ? \
7
                        (cmd)->body.body.id : SPA_ID_INVALID)
8
 
9
-#define SPA_COMMAND_INIT_FULL(t,size,type,id,...) (t)          \
10
-   { { size, SPA_TYPE_Object },                    \
11
-     { { type, id }, ##__VA_ARGS__ } }             \
12
+#define SPA_COMMAND_INIT_FULL(t,size,type,id,...) ((t)         \
13
+   { { (size), SPA_TYPE_Object },                  \
14
+     { { (type), (id) }, ##__VA_ARGS__ } })
15
 
16
 #define SPA_COMMAND_INIT(type,id)                  \
17
    SPA_COMMAND_INIT_FULL(struct spa_command,           \
18
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
10
 
1
@@ -46,7 +46,7 @@
2
 };
3
 
4
 #define SPA_EVENT_TYPE(ev) ((ev)->body.body.type)
5
-#define SPA_EVENT_ID(ev,type)  (SPA_EVENT_TYPE(ev) == type ? \
6
+#define SPA_EVENT_ID(ev,type)  (SPA_EVENT_TYPE(ev) == (type) ? \
7
                    (ev)->body.body.id : SPA_ID_INVALID)
8
 
9
 #define SPA_EVENT_INIT_FULL(t,size,type,id,...) (t)            \
10
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
94
 
1
@@ -53,7 +53,7 @@
2
    struct spa_pod_parser_state state;
3
 };
4
 
5
-#define SPA_POD_PARSER_INIT(buffer,size)  (struct spa_pod_parser){ buffer, size, 0, {} }
6
+#define SPA_POD_PARSER_INIT(buffer,size)  ((struct spa_pod_parser){ (buffer), (size), 0, {} })
7
 
8
 static inline void spa_pod_parser_init(struct spa_pod_parser *parser,
9
                       const void *data, uint32_t size)
10
@@ -82,12 +82,20 @@
11
 static inline struct spa_pod *
12
 spa_pod_parser_deref(struct spa_pod_parser *parser, uint32_t offset, uint32_t size)
13
 {
14
-   if (offset + 8 <= size) {
15
-       struct spa_pod *pod = SPA_PTROFF(parser->data, offset, struct spa_pod);
16
-       if (offset + SPA_POD_SIZE(pod) <= size)
17
-           return pod;
18
+   /* Cast to uint64_t to avoid wraparound.  Add 8 for the pod itself. */
19
+   const uint64_t long_offset = (uint64_t)offset + 8;
20
+   if (long_offset <= size && (offset & 7) == 0) {
21
+       /* Use void* because creating a misaligned pointer is undefined. */
22
+       void *pod = SPA_PTROFF(parser->data, offset, void);
23
+       /*
24
+        * Check that the pointer is aligned and that the size (rounded
25
+        * to the next multiple of 8) is in bounds.
26
+        */
27
+       if (SPA_IS_ALIGNED(pod, __alignof__(struct spa_pod)) &&
28
+           long_offset + SPA_ROUND_UP_N((uint64_t)SPA_POD_BODY_SIZE(pod), 8) <= size)
29
+           return (struct spa_pod *)pod;
30
    }
31
-        return NULL;
32
+   return NULL;
33
 }
34
 
35
 static inline struct spa_pod *spa_pod_parser_frame(struct spa_pod_parser *parser, struct spa_pod_frame *frame)
36
@@ -285,10 +293,15 @@
37
    if (pod == NULL)
38
        return false;
39
 
40
-   if (spa_pod_is_choice(pod) &&
41
-       SPA_POD_CHOICE_TYPE(pod) == SPA_CHOICE_None &&
42
-       spa_pod_parser_can_collect(SPA_POD_CHOICE_CHILD(pod), type))
43
-       return true;
44
+   if (SPA_POD_TYPE(pod) == SPA_TYPE_Choice) {
45
+       if (!spa_pod_is_choice(pod))
46
+           return false;
47
+       if (type == 'V')
48
+           return true;
49
+       if (SPA_POD_CHOICE_TYPE(pod) != SPA_CHOICE_None)
50
+           return false;
51
+       pod = SPA_POD_CHOICE_CHILD(pod);
52
+   }
53
 
54
    switch (type) {
55
    case 'P':
56
@@ -328,7 +341,6 @@
57
    case 'O':
58
        return spa_pod_is_object(pod) || spa_pod_is_none(pod);
59
    case 'V':
60
-       return spa_pod_is_choice(pod);
61
    default:
62
        return false;
63
    }
64
@@ -355,7 +367,7 @@
65
        break;                                  \
66
    case 's':                                   \
67
        *va_arg(args, char**) =                         \
68
-           (pod == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None)        \
69
+           ((pod) == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None)      \
70
                ? NULL                          \
71
                : (char *)SPA_POD_CONTENTS(struct spa_pod_string, pod));    \
72
        break;                                  \
73
@@ -407,8 +419,8 @@
74
    {                                       \
75
        const struct spa_pod **d = va_arg(args, const struct spa_pod**);    \
76
        if (d)                                  \
77
-           *d = (pod == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None)   \
78
-               ? NULL : pod);                      \
79
+           *d = ((pod) == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None) \
80
+               ? NULL : (pod));                        \
81
        break;                                  \
82
    }                                       \
83
    default:                                    \
84
@@ -493,8 +505,7 @@
85
            }
86
            SPA_POD_PARSER_SKIP(*format, args);
87
        } else {
88
-           if (pod->type == SPA_TYPE_Choice && *format != 'V' &&
89
-               SPA_POD_CHOICE_TYPE(pod) == SPA_CHOICE_None)
90
+           if (pod->type == SPA_TYPE_Choice && *format != 'V')
91
                pod = SPA_POD_CHOICE_CHILD(pod);
92
 
93
            SPA_POD_PARSER_COLLECT(pod, *format, args);
94
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
19
 
1
@@ -39,7 +39,7 @@
2
 
3
 #define SPA_POD_BODY_SIZE(pod)         (((struct spa_pod*)(pod))->size)
4
 #define SPA_POD_TYPE(pod)          (((struct spa_pod*)(pod))->type)
5
-#define SPA_POD_SIZE(pod)          (sizeof(struct spa_pod) + SPA_POD_BODY_SIZE(pod))
6
+#define SPA_POD_SIZE(pod)          ((uint64_t)sizeof(struct spa_pod) + SPA_POD_BODY_SIZE(pod))
7
 #define SPA_POD_CONTENTS_SIZE(type,pod)        (SPA_POD_SIZE(pod)-sizeof(type))
8
 
9
 #define SPA_POD_CONTENTS(type,pod)     SPA_PTROFF((pod),sizeof(type),void)
10
@@ -52,7 +52,7 @@
11
    uint32_t type;      /* a basic id of enum spa_type */
12
 };
13
 
14
-#define SPA_POD_VALUE(type,pod)            (((type*)pod)->value)
15
+#define SPA_POD_VALUE(type,pod)            (((type*)(pod))->value)
16
 
17
 struct spa_pod_bool {
18
    struct spa_pod pod;
19
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
10
 
1
@@ -121,7 +121,7 @@
2
 
3
 #define SPA_LOG_IMPL_INIT(name)                \
4
    { { { SPA_TYPE_INTERFACE_Log, SPA_VERSION_LOG,  \
5
-         SPA_CALLBACKS_INIT(&name.methods, &name) },   \
6
+         SPA_CALLBACKS_INIT(&(name).methods, &(name)) },   \
7
        SPA_LOG_LEVEL_INFO, },          \
8
      { SPA_VERSION_LOG_METHODS,            \
9
        spa_log_impl_log,               \
10
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
91
 
1
@@ -212,7 +212,7 @@
2
 
3
 
4
 #define SPA_LOG_TOPIC(v, t) \
5
-   (struct spa_log_topic){ .version = v, .topic = (t)}
6
+   (struct spa_log_topic){ .version = (v), .topic = (t)}
7
 
8
 #define spa_log_topic_init(l, topic)               \
9
 do {                               \
10
@@ -231,10 +231,10 @@
11
 ({                             \
12
    struct spa_log *_log = l;               \
13
    enum spa_log_level _lev = _log ? _log->level : SPA_LOG_LEVEL_NONE;      \
14
-   struct spa_log_topic *_t = (struct spa_log_topic *)topic; \
15
+   struct spa_log_topic *_t = (struct spa_log_topic *)(topic); \
16
    if (_t && _t->has_custom_level)                         \
17
        _lev = _t->level;               \
18
-   _lev >= lev;                        \
19
+   _lev >= (lev);                      \
20
 })
21
 
22
 /* Transparently calls to version 0 log if v1 is not supported */
23
@@ -269,26 +269,32 @@
24
    }                               \
25
 })
26
 
27
+#define spa_logt_lev(l,lev,t,...)                  \
28
+   spa_log_logt(l,lev,t,__FILE__,__LINE__,__func__,__VA_ARGS__)
29
+
30
+#define spa_log_lev(l,lev,...)                 \
31
+   spa_logt_lev(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__)
32
+
33
 #define spa_log_log(l,lev,...)                 \
34
    spa_log_logt(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__)
35
 
36
 #define spa_log_logv(l,lev,...)                    \
37
    spa_log_logtv(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__)
38
 
39
-#define spa_log_error(l,...)   spa_log_log(l,SPA_LOG_LEVEL_ERROR,__FILE__,__LINE__,__func__,__VA_ARGS__)
40
-#define spa_log_warn(l,...)    spa_log_log(l,SPA_LOG_LEVEL_WARN,__FILE__,__LINE__,__func__,__VA_ARGS__)
41
-#define spa_log_info(l,...)    spa_log_log(l,SPA_LOG_LEVEL_INFO,__FILE__,__LINE__,__func__,__VA_ARGS__)
42
-#define spa_log_debug(l,...)   spa_log_log(l,SPA_LOG_LEVEL_DEBUG,__FILE__,__LINE__,__func__,__VA_ARGS__)
43
-#define spa_log_trace(l,...)   spa_log_log(l,SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__)
44
+#define spa_log_error(l,...)   spa_log_lev(l,SPA_LOG_LEVEL_ERROR,__VA_ARGS__)
45
+#define spa_log_warn(l,...)    spa_log_lev(l,SPA_LOG_LEVEL_WARN,__VA_ARGS__)
46
+#define spa_log_info(l,...)    spa_log_lev(l,SPA_LOG_LEVEL_INFO,__VA_ARGS__)
47
+#define spa_log_debug(l,...)   spa_log_lev(l,SPA_LOG_LEVEL_DEBUG,__VA_ARGS__)
48
+#define spa_log_trace(l,...)   spa_log_lev(l,SPA_LOG_LEVEL_TRACE,__VA_ARGS__)
49
 
50
-#define spa_logt_error(l,t,...)    spa_log_logt(l,SPA_LOG_LEVEL_ERROR,t,__FILE__,__LINE__,__func__,__VA_ARGS__)
51
-#define spa_logt_warn(l,t,...) spa_log_logt(l,SPA_LOG_LEVEL_WARN,t,__FILE__,__LINE__,__func__,__VA_ARGS__)
52
-#define spa_logt_info(l,t,...) spa_log_logt(l,SPA_LOG_LEVEL_INFO,t,__FILE__,__LINE__,__func__,__VA_ARGS__)
53
-#define spa_logt_debug(l,t,...)    spa_log_logt(l,SPA_LOG_LEVEL_DEBUG,t,__FILE__,__LINE__,__func__,__VA_ARGS__)
54
-#define spa_logt_trace(l,t,...)    spa_log_logt(l,SPA_LOG_LEVEL_TRACE,t,__FILE__,__LINE__,__func__,__VA_ARGS__)
55
+#define spa_logt_error(l,t,...)    spa_logt_lev(l,SPA_LOG_LEVEL_ERROR,t,__VA_ARGS__)
56
+#define spa_logt_warn(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_WARN,t,__VA_ARGS__)
57
+#define spa_logt_info(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_INFO,t,__VA_ARGS__)
58
+#define spa_logt_debug(l,t,...)    spa_logt_lev(l,SPA_LOG_LEVEL_DEBUG,t,__VA_ARGS__)
59
+#define spa_logt_trace(l,t,...)    spa_logt_lev(l,SPA_LOG_LEVEL_TRACE,t,__VA_ARGS__)
60
 
61
 #ifndef FASTPATH
62
-#define spa_log_trace_fp(l,...)    spa_log_log(l,SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__)
63
+#define spa_log_trace_fp(l,...)    spa_log_lev(l,SPA_LOG_LEVEL_TRACE,__VA_ARGS__)
64
 #else
65
 #define spa_log_trace_fp(l,...)
66
 #endif
67
@@ -296,18 +302,16 @@
68
 #define spa_log_hexdump(l,lev,indent,data,len)                     \
69
 ({                                         \
70
    char str512;                                    \
71
-   uint8_t *buf = (uint8_t *)data;                         \
72
-   size_t i;                                   \
73
+   uint8_t *buf = (uint8_t *)(data);                       \
74
+   size_t i, j = (len);                                \
75
    int pos = 0;                                    \
76
                                            \
77
-   for (i = 0; i < len; i++) {                         \
78
+   for (i = 0; i < j; i++) {                           \
79
        if (i % 16 == 0)                            \
80
            pos = 0;                            \
81
        pos += sprintf(str + pos, "%02x ", bufi);               \
82
-       if (i % 16 == 15 || i == len - 1) {                 \
83
-           spa_log_log(l,lev,__FILE__,__LINE__,__func__,           \
84
-                       "%*s" "%s",indent,"", str);             \
85
-       }                                   \
86
+       if (i % 16 == 15 || i == j - 1)                     \
87
+           spa_log_lev(l,lev, "%*s" "%s",indent,"", str);          \
88
    }                                       \
89
 })
90
 
91
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
10
 
1
@@ -105,7 +105,7 @@
2
    return NULL;
3
 }
4
 
5
-#define SPA_SUPPORT_INIT(type,data) (struct spa_support) { (type), (data) }
6
+#define SPA_SUPPORT_INIT(type,data) ((struct spa_support) { (type), (data) })
7
 
8
 struct spa_handle_factory {
9
    /** The version of this structure */
10
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
10
 
1
@@ -119,7 +119,7 @@
2
 
3
 #define spa_system_method_r(o,method,version,...)          \
4
 ({                                 \
5
-   int _res = -ENOTSUP;                        \
6
+   volatile int _res = -ENOTSUP;                   \
7
    struct spa_system *_o = o;                  \
8
    spa_interface_call_res(&_o->iface,              \
9
            struct spa_system_methods, _res,        \
10
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
125
 
1
@@ -27,8 +27,18 @@
2
 
3
 #ifdef __cplusplus
4
 extern "C" {
5
+# if __cplusplus >= 201103L
6
+#  define SPA_STATIC_ASSERT static_assert
7
+# endif
8
 #else
9
-#include <stdbool.h>
10
+# include <stdbool.h>
11
+# if __STDC_VERSION__ >= 201112L
12
+#  define SPA_STATIC_ASSERT _Static_assert
13
+# endif
14
+#endif
15
+#ifndef SPA_STATIC_ASSERT
16
+#define SPA_STATIC_ASSERT(a, b)                        \
17
+   ((void)sizeof(struct { int spa_static_assertion_failed : 2 * !!(a) - 1; }))
18
 #endif
19
 #include <inttypes.h>
20
 #include <signal.h>
21
@@ -74,8 +84,16 @@
22
 #define SPA_FLAG_MASK(field,mask,flag) (((field) & (mask)) == (flag))
23
 #define SPA_FLAG_IS_SET(field,flag)    SPA_FLAG_MASK(field,flag,flag)
24
 #define SPA_FLAG_SET(field,flag)   ((field) |= (flag))
25
-#define SPA_FLAG_CLEAR(field,flag) ((field) &= ~(flag))
26
-#define SPA_FLAG_UPDATE(field,flag,val)    ((val) ? SPA_FLAG_SET(field,flag) : SPA_FLAG_CLEAR(field,flag))
27
+#define SPA_FLAG_CLEAR(field, flag)                    \
28
+({                                 \
29
+   SPA_STATIC_ASSERT(__builtin_constant_p(flag) ?          \
30
+                 (__typeof__(flag))(__typeof__(field))(__typeof__(flag))(flag) == (flag) : \
31
+             sizeof(field) >= sizeof(flag),            \
32
+           "truncation problem when masking " #field   \
33
+           " with ~" #flag);               \
34
+   ((field) &= ~(__typeof__(field))(flag));            \
35
+})
36
+#define SPA_FLAG_UPDATE(field,flag,val)    ((val) ? SPA_FLAG_SET((field),(flag)) : SPA_FLAG_CLEAR((field),(flag)))
37
 
38
 enum spa_direction {
39
    SPA_DIRECTION_INPUT = 0,
40
@@ -84,25 +102,25 @@
41
 
42
 #define SPA_DIRECTION_REVERSE(d)   ((d) ^ 1)
43
 
44
-#define SPA_RECTANGLE(width,height) (struct spa_rectangle){ width, height }
45
+#define SPA_RECTANGLE(width,height) ((struct spa_rectangle){ (width), (height) })
46
 struct spa_rectangle {
47
    uint32_t width;
48
    uint32_t height;
49
 };
50
 
51
-#define SPA_POINT(x,y) (struct spa_point){ x, y }
52
+#define SPA_POINT(x,y) ((struct spa_point){ (x), (y) })
53
 struct spa_point {
54
    int32_t x;
55
    int32_t y;
56
 };
57
 
58
-#define SPA_REGION(x,y,width,height) (struct spa_region){ SPA_POINT(x,y), SPA_RECTANGLE(width,height) }
59
+#define SPA_REGION(x,y,width,height) ((struct spa_region){ SPA_POINT(x,y), SPA_RECTANGLE(width,height) })
60
 struct spa_region {
61
    struct spa_point position;
62
    struct spa_rectangle size;
63
 };
64
 
65
-#define SPA_FRACTION(num,denom) (struct spa_fraction){ num, denom }
66
+#define SPA_FRACTION(num,denom) ((struct spa_fraction){ (num), (denom) })
67
 struct spa_fraction {
68
    uint32_t num;
69
    uint32_t denom;
70
@@ -120,7 +138,7 @@
71
  * ```
72
  */
73
 #define SPA_FOR_EACH_ELEMENT(arr, ptr) \
74
-   for (ptr = arr; (void*)ptr < SPA_PTROFF(arr, sizeof(arr), void); ptr++)
75
+   for ((ptr) = arr; (void*)(ptr) < SPA_PTROFF(arr, sizeof(arr), void); (ptr)++)
76
 
77
 #define SPA_ABS(a)         \
78
 ({                 \
79
@@ -156,7 +174,7 @@
80
 #define SPA_SWAP(a,b)                  \
81
 ({                         \
82
    __typeof__(a) _t = (a);             \
83
-   a = b; b = _t;                  \
84
+   (a) = b; (b) = _t;                  \
85
 })
86
 
87
 #define SPA_TYPECHECK(type,x)      \
88
@@ -180,7 +198,7 @@
89
 #define SPA_MEMBER(b,o,t) SPA_PTROFF(b,o,t)
90
 #define SPA_MEMBER_ALIGN(b,o,a,t) SPA_PTROFF_ALIGN(b,o,a,t)
91
 
92
-#define SPA_CONTAINER_OF(p,t,m) ((t*)((uintptr_t)p - offsetof(t,m)))
93
+#define SPA_CONTAINER_OF(p,t,m) ((t*)((uintptr_t)(p) - offsetof(t,m)))
94
 
95
 #define SPA_PTRDIFF(p1,p2) ((intptr_t)(p1) - (intptr_t)(p2))
96
 
97
@@ -194,7 +212,7 @@
98
 #define SPA_IDX_INVALID  ((unsigned int)-1)
99
 #define SPA_ID_INVALID  ((uint32_t)0xffffffff)
100
 
101
-#define SPA_NSEC_PER_SEC  (1000000000ll)
102
+#define SPA_NSEC_PER_SEC  (1000000000LL)
103
 #define SPA_NSEC_PER_MSEC (1000000ll)
104
 #define SPA_NSEC_PER_USEC (1000ll)
105
 #define SPA_USEC_PER_SEC  (1000000ll)
106
@@ -239,7 +257,17 @@
107
 #define SPA_ROUND_DOWN(num,value)  ((num) - ((num) % (value)))
108
 #define SPA_ROUND_UP(num,value)        ((((num) + (value) - 1) / (value)) * (value))
109
 
110
-#define SPA_ROUND_DOWN_N(num,align)    ((num) & ~((align) - 1))
111
+#define SPA_MASK_NEGATED(num1, num2)                   \
112
+({                                 \
113
+   SPA_STATIC_ASSERT(__builtin_constant_p(num2) ?          \
114
+                 (__typeof__(num2))(__typeof__(num1))(__typeof__(num2))(num2) == (num2) : \
115
+             sizeof(num1) >= sizeof(num2),         \
116
+           "truncation problem when masking " #num1    \
117
+           " with ~" #num2);               \
118
+   ((num1) & ~(__typeof__(num1))(num2));               \
119
+})
120
+
121
+#define SPA_ROUND_DOWN_N(num,align)    SPA_MASK_NEGATED((num), (align) - 1)
122
 #define SPA_ROUND_UP_N(num,align)  SPA_ROUND_DOWN_N((num) + ((align) - 1),align)
123
 
124
 #define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1))
125
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
21
 
1
@@ -48,7 +48,7 @@
2
    const char *value;
3
 };
4
 
5
-#define SPA_DICT_ITEM_INIT(key,value) (struct spa_dict_item) { key, value }
6
+#define SPA_DICT_ITEM_INIT(key,value) ((struct spa_dict_item) { (key), (value) })
7
 
8
 struct spa_dict {
9
 #define SPA_DICT_FLAG_SORTED   (1<<0)      /**< items are sorted */
10
@@ -57,8 +57,8 @@
11
    const struct spa_dict_item *items;
12
 };
13
 
14
-#define SPA_DICT_INIT(items,n_items) (struct spa_dict) { 0, n_items, items }
15
-#define SPA_DICT_INIT_ARRAY(items) (struct spa_dict) { 0, SPA_N_ELEMENTS(items), items }
16
+#define SPA_DICT_INIT(items,n_items) ((struct spa_dict) { 0, (n_items), (items) })
17
+#define SPA_DICT_INIT_ARRAY(items) ((struct spa_dict) { 0, SPA_N_ELEMENTS(items), (items) })
18
 
19
 #define spa_dict_for_each(item, dict)              \
20
    for ((item) = (dict)->items;                \
21
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
10
 
1
@@ -142,7 +142,7 @@
2
  * Initialize the set of functions \a funcs as a \ref spa_callbacks, together
3
  * with \a _data.
4
  */
5
-#define SPA_CALLBACKS_INIT(_funcs,_data) (struct spa_callbacks){ _funcs, _data, }
6
+#define SPA_CALLBACKS_INIT(_funcs,_data) ((struct spa_callbacks){ (_funcs), (_data), })
7
 
8
 /** \struct spa_interface
9
  */
10
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
25
 
1
@@ -58,20 +58,20 @@
2
    uint32_t depth;
3
 };
4
 
5
-#define SPA_JSON_INIT(data,size) (struct spa_json) { (data), (data)+(size), }
6
+#define SPA_JSON_INIT(data,size) ((struct spa_json) { (data), (data)+(size), })
7
 
8
 static inline void spa_json_init(struct spa_json * iter, const char *data, size_t size)
9
 {
10
    *iter =  SPA_JSON_INIT(data, size);
11
 }
12
-#define SPA_JSON_ENTER(iter) (struct spa_json) { (iter)->cur, (iter)->end, (iter), }
13
+#define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), })
14
 
15
 static inline void spa_json_enter(struct spa_json * iter, struct spa_json * sub)
16
 {
17
    *sub = SPA_JSON_ENTER(iter);
18
 }
19
 
20
-#define SPA_JSON_SAVE(iter) (struct spa_json) { (iter)->cur, (iter)->end, }
21
+#define SPA_JSON_SAVE(iter) ((struct spa_json) { (iter)->cur, (iter)->end, })
22
 
23
 /** Get the next token. \a value points to the token and the return value
24
  * is the length. */
25
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
81
 
1
@@ -44,7 +44,7 @@
2
    struct spa_list *prev;
3
 };
4
 
5
-#define SPA_LIST_INIT(list) (struct spa_list){ list, list }
6
+#define SPA_LIST_INIT(list) ((struct spa_list){ (list), (list) })
7
 
8
 static inline void spa_list_init(struct spa_list *list)
9
 {
10
@@ -98,25 +98,25 @@
11
    (&(pos)->member == (head))
12
 
13
 #define spa_list_next(pos, member)                 \
14
-   SPA_CONTAINER_OF((pos)->member.next, __typeof__(*pos), member)
15
+   SPA_CONTAINER_OF((pos)->member.next, __typeof__(*(pos)), member)
16
 
17
 #define spa_list_prev(pos, member)                 \
18
-   SPA_CONTAINER_OF((pos)->member.prev, __typeof__(*pos), member)
19
+   SPA_CONTAINER_OF((pos)->member.prev, __typeof__(*(pos)), member)
20
 
21
 #define spa_list_consume(pos, head, member)                \
22
-   for (pos = spa_list_first(head, __typeof__(*pos), member);  \
23
+   for ((pos) = spa_list_first(head, __typeof__(*(pos)), member);  \
24
         !spa_list_is_empty(head);                  \
25
-        pos = spa_list_first(head, __typeof__(*pos), member))
26
+        (pos) = spa_list_first(head, __typeof__(*(pos)), member))
27
 
28
 #define spa_list_for_each_next(pos, head, curr, member)            \
29
-   for (pos = spa_list_first(curr, __typeof__(*pos), member);  \
30
+   for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member);  \
31
         !spa_list_is_end(pos, head, member);           \
32
-        pos = spa_list_next(pos, member))
33
+        (pos) = spa_list_next(pos, member))
34
 
35
 #define spa_list_for_each_prev(pos, head, curr, member)            \
36
-   for (pos = spa_list_last(curr, __typeof__(*pos), member);   \
37
+   for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member);   \
38
         !spa_list_is_end(pos, head, member);           \
39
-        pos = spa_list_prev(pos, member))
40
+        (pos) = spa_list_prev(pos, member))
41
 
42
 #define spa_list_for_each(pos, head, member)               \
43
    spa_list_for_each_next(pos, head, head, member)
44
@@ -125,16 +125,16 @@
45
    spa_list_for_each_prev(pos, head, head, member)
46
 
47
 #define spa_list_for_each_safe_next(pos, tmp, head, curr, member)  \
48
-   for (pos = spa_list_first(curr, __typeof__(*pos), member);  \
49
-        tmp = spa_list_next(pos, member),              \
50
+   for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member);  \
51
+        (tmp) = spa_list_next(pos, member),                \
52
         !spa_list_is_end(pos, head, member);           \
53
-        pos = tmp)
54
+        (pos) = (tmp))
55
 
56
 #define spa_list_for_each_safe_prev(pos, tmp, head, curr, member)  \
57
-   for (pos = spa_list_last(curr, __typeof__(*pos), member);   \
58
-        tmp = spa_list_prev(pos, member),              \
59
+   for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member);   \
60
+        (tmp) = spa_list_prev(pos, member),                \
61
         !spa_list_is_end(pos, head, member);           \
62
-        pos = tmp)
63
+        (pos) = (tmp))
64
 
65
 #define spa_list_for_each_safe(pos, tmp, head, member)         \
66
    spa_list_for_each_safe_next(pos, tmp, head, head, member)
67
@@ -146,11 +146,11 @@
68
         spa_list_prepend(head, &(cursor).member)
69
 
70
 #define spa_list_for_each_cursor(pos, cursor, head, member)             \
71
-        for(pos = spa_list_first(&(cursor).member, __typeof__(*(pos)), member); \
72
+        for((pos) = spa_list_first(&(cursor).member, __typeof__(*(pos)), member); \
73
             spa_list_remove(&(pos)->member),                            \
74
             spa_list_append(&(cursor).member, &(pos)->member),          \
75
             !spa_list_is_end(pos, head, member);                        \
76
-            pos = spa_list_next(&cursor, member))
77
+            (pos) = spa_list_next(&(cursor), member))
78
 
79
 #define spa_list_cursor_end(cursor, member)                             \
80
         spa_list_remove(&(cursor).member)
81
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
20
 
1
@@ -114,13 +114,15 @@
2
 /** keys for bluez5 factory names */
3
 #define SPA_NAME_API_BLUEZ5_ENUM_DBUS  "api.bluez5.enum.dbus"      /**< a dbus Device interface */
4
 #define SPA_NAME_API_BLUEZ5_DEVICE "api.bluez5.device"     /**< a Device interface */
5
-#define SPA_NAME_API_BLUEZ5_A2DP_SINK  "api.bluez5.a2dp.sink"      /**< a playback Node interface for A2DP profiles */
6
-#define SPA_NAME_API_BLUEZ5_A2DP_SOURCE    "api.bluez5.a2dp.source"    /**< a capture Node interface for A2DP profiles */
7
+#define SPA_NAME_API_BLUEZ5_MEDIA_SINK "api.bluez5.media.sink"     /**< a playback Node interface for A2DP/BAP profiles */
8
+#define SPA_NAME_API_BLUEZ5_MEDIA_SOURCE   "api.bluez5.media.source"   /**< a capture Node interface for A2DP/BAP profiles */
9
+#define SPA_NAME_API_BLUEZ5_A2DP_SINK  "api.bluez5.a2dp.sink"      /**< alias for media.sink */
10
+#define SPA_NAME_API_BLUEZ5_A2DP_SOURCE    "api.bluez5.a2dp.source"    /**< alias for media.source */
11
 #define SPA_NAME_API_BLUEZ5_SCO_SINK   "api.bluez5.sco.sink"       /**< a playback Node interface for HSP/HFP profiles */
12
 #define SPA_NAME_API_BLUEZ5_SCO_SOURCE "api.bluez5.sco.source"     /**< a capture Node interface for HSP/HFP profiles */
13
 
14
 /** keys for codec factory names */
15
-#define SPA_NAME_API_CODEC_BLUEZ5_A2DP "api.codec.bluez5.a2dp"     /**< Bluez5 A2DP codec plugin */
16
+#define SPA_NAME_API_CODEC_BLUEZ5_MEDIA    "api.codec.bluez5.media"    /**< Bluez5 Media codec plugin */
17
 
18
 /** keys for v4l2 factory names */
19
 #define SPA_NAME_API_V4L2_ENUM_UDEV    "api.v4l2.enum.udev"        /**< a v4l2 udev Device interface */
20
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
10
 
1
@@ -55,7 +55,7 @@
2
 
3
 #define spa_strerror(err)      \
4
 ({                 \
5
-   int _err = -err;        \
6
+   int _err = -(err);      \
7
    if (SPA_RESULT_IS_ASYNC(err))   \
8
        _err = EINPROGRESS; \
9
    strerror(_err);         \
10
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
10
 
1
@@ -53,7 +53,7 @@
2
    uint32_t writeindex;    /*< the current write index */
3
 };
4
 
5
-#define SPA_RINGBUFFER_INIT()  (struct spa_ringbuffer) { 0, 0 }
6
+#define SPA_RINGBUFFER_INIT()  ((struct spa_ringbuffer) { 0, 0 })
7
 
8
 /**
9
  * Initialize a spa_ringbuffer with \a size.
10
pipewire-0.3.58.tar.gz/spa/meson.build -> pipewire-0.3.59.tar.gz/spa/meson.build Changed
10
 
1
@@ -64,6 +64,8 @@
2
     summary({'LC3plus': lc3plus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
3
     opus_dep = dependency('opus', required : get_option('bluez5-codec-opus'))
4
     summary({'Opus': opus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
5
+    lc3_dep = dependency('lc3', required : get_option('bluez5-codec-lc3'))
6
+    summary({'LC3': lc3_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
7
   endif
8
   avcodec_dep = dependency('libavcodec', required: get_option('ffmpeg'))
9
   jack_dep = dependency('jack', version : '>= 1.9.10', required: get_option('jack'))
10
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
11
 
1
@@ -181,6 +181,9 @@
2
 # have any digital outputs.
3
 ATTRS{idVendor}=="0a12", ATTRS{idProduct}=="4007", ENV{ACP_PROFILE_SET}="analog-only.conf"
4
 
5
+# Asus Xonar SE
6
+ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="189d", ENV{ACP_PROFILE_SET}="asus-xonar-se.conf"
7
+
8
 GOTO="pipewire_end"
9
 
10
 LABEL="pipewire_check_pci"
11
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
26
 
1
@@ -584,6 +584,9 @@
2
        return -errno;
3
    bufr = 0;
4
 
5
+   if (r == 0)
6
+       return -EPIPE;
7
+
8
    if ((p = strchr(buf, '#')))
9
                 *p = '\0';
10
 
11
@@ -679,8 +682,12 @@
12
        if (err < 0)
13
            return -errno;
14
 
15
-       if (pfds0.revents & POLLIN)
16
-           handle_input(data);
17
+       if (pfds0.revents & POLLIN) {
18
+           if ((err = handle_input(data)) < 0) {
19
+               if (err == -EPIPE)
20
+                   break;
21
+           }
22
+       }
23
 
24
        if (count < 2)
25
            continue;
26
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
21
 
1
@@ -49,7 +49,7 @@
2
    const char *key;
3
    const char *value;
4
 };
5
-#define ACP_DICT_ITEM_INIT(key,value) (struct acp_dict_item) { key, value }
6
+#define ACP_DICT_ITEM_INIT(key,value) ((struct acp_dict_item) { (key), (value) })
7
 
8
 struct acp_dict {
9
    uint32_t flags;
10
@@ -115,8 +115,8 @@
11
    uint32_t mapACP_MAX_CHANNELS;
12
 };
13
 
14
-#define ACP_DICT_INIT(items,n_items) (struct acp_dict) { 0, n_items, items }
15
-#define ACP_DICT_INIT_ARRAY(items) (struct acp_dict) { 0, sizeof(items)/sizeof((items)0), items }
16
+#define ACP_DICT_INIT(items,n_items) ((struct acp_dict) { 0, (n_items), (items) })
17
+#define ACP_DICT_INIT_ARRAY(items) ((struct acp_dict) { 0, sizeof(items)/sizeof((items)0), (items) })
18
 
19
 #define acp_dict_for_each(item, dict)              \
20
    for ((item) = (dict)->items;                \
21
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
10
 
1
@@ -39,7 +39,7 @@
2
    size_t extend;      /**< number of bytes to extend with */
3
 } pa_array;
4
 
5
-#define PW_ARRAY_INIT(extend) (struct pa_array) { NULL, 0, 0, extend }
6
+#define PW_ARRAY_INIT(extend) ((struct pa_array) { NULL, 0, 0, (extend) })
7
 
8
 #define pa_array_get_len_s(a,s)            ((a)->size / (s))
9
 #define pa_array_get_unchecked_s(a,idx,s,t)    (t*)((uint8_t*)(a)->data + (int)((idx)*(s)))
10
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
177
 
1
@@ -511,6 +511,9 @@
2
    }
3
    CHECK(snd_output_stdio_attach(&state->output, state->log_file, 0), "attach failed");
4
 
5
+   state->rate_limit.interval = 2 * SPA_NSEC_PER_SEC;
6
+   state->rate_limit.burst = 1;
7
+
8
    return 0;
9
 }
10
 
11
@@ -1779,15 +1782,17 @@
12
 
13
 static int get_avail(struct state *state, uint64_t current_time)
14
 {
15
-   int res;
16
+   int res, missed;
17
    snd_pcm_sframes_t avail;
18
 
19
    if (SPA_UNLIKELY((avail = snd_pcm_avail(state->hndl)) < 0)) {
20
        if ((res = alsa_recover(state, avail)) < 0)
21
            return res;
22
        if ((avail = snd_pcm_avail(state->hndl)) < 0) {
23
-           spa_log_warn(state->log, "%s: snd_pcm_avail after recover: %s",
24
-                   state->props.device, snd_strerror(avail));
25
+           if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
26
+               spa_log_warn(state->log, "%s: (%d missed) snd_pcm_avail after recover: %s",
27
+                       state->props.device, missed, snd_strerror(avail));
28
+           }
29
            avail = state->threshold * 2;
30
        }
31
    } else {
32
@@ -1799,7 +1804,7 @@
33
 #if 0
34
 static int get_avail_htimestamp(struct state *state, uint64_t current_time)
35
 {
36
-   int res;
37
+   int res, missed;
38
    snd_pcm_uframes_t avail;
39
    snd_htimestamp_t tstamp;
40
    uint64_t then;
41
@@ -1808,8 +1813,10 @@
42
        if ((res = alsa_recover(state, avail)) < 0)
43
            return res;
44
        if ((res = snd_pcm_htimestamp(state->hndl, &avail, &tstamp)) < 0) {
45
-           spa_log_warn(state->log, "%s: snd_pcm_htimestamp error: %s",
46
-               state->props.device, snd_strerror(res));
47
+           if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
48
+               spa_log_warn(state->log, "%s: (%d missed) snd_pcm_htimestamp error: %s",
49
+                   state->props.device, missed, snd_strerror(res));
50
+           }
51
            avail = state->threshold * 2;
52
        }
53
    } else {
54
@@ -1880,15 +1887,14 @@
55
                state, follower, state->last_threshold, state->threshold, diff, err);
56
        state->last_threshold = state->threshold;
57
        state->alsa_sync = true;
58
+       state->alsa_sync_warning = false;
59
    }
60
    if (err > state->max_error) {
61
        err = state->max_error;
62
        state->alsa_sync = true;
63
-       state->alsa_sync_warning = (diff == 0);
64
    } else if (err < -state->max_error) {
65
        err = -state->max_error;
66
        state->alsa_sync = true;
67
-       state->alsa_sync_warning = (diff == 0);
68
    }
69
 
70
    if (!follower || state->matching)
71
@@ -1985,7 +1991,7 @@
72
    const snd_pcm_channel_area_t *my_areas;
73
    snd_pcm_uframes_t written, frames, offset, off, to_write, total_written, max_write;
74
    snd_pcm_sframes_t commitres;
75
-   int res = 0;
76
+   int res = 0, missed;
77
    size_t frame_size = state->frame_size;
78
 
79
    check_position_config(state);
80
@@ -2005,13 +2011,18 @@
81
            return res;
82
 
83
        if (SPA_UNLIKELY(state->alsa_sync)) {
84
-           if (SPA_UNLIKELY(state->alsa_sync_warning)) {
85
-               spa_log_warn(state->log, "%s: follower delay:%ld target:%ld thr:%u, resync",
86
-                       state->props.device, delay, target, state->threshold);
87
-               state->alsa_sync_warning = false;
88
-           } else
89
-               spa_log_info(state->log, "%s: follower delay:%ld target:%ld thr:%u, resync",
90
-                       state->props.device, delay, target, state->threshold);
91
+           enum spa_log_level lev;
92
+
93
+           if (SPA_UNLIKELY(state->alsa_sync_warning))
94
+               lev = SPA_LOG_LEVEL_WARN;
95
+           else
96
+               lev = SPA_LOG_LEVEL_INFO;
97
+
98
+           if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
99
+               spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u, "
100
+                       "resync (%d missed)", state->props.device, delay,
101
+                       target, state->threshold, missed);
102
+           }
103
 
104
            if (delay > target)
105
                snd_pcm_rewind(state->hndl, delay - target);
106
@@ -2019,7 +2030,8 @@
107
                spa_alsa_silence(state, target - delay);
108
            delay = target;
109
            state->alsa_sync = false;
110
-       }
111
+       } else
112
+           state->alsa_sync_warning = true;
113
    }
114
 
115
    total_written = 0;
116
@@ -2212,7 +2224,7 @@
117
    const snd_pcm_channel_area_t *my_areas;
118
    snd_pcm_uframes_t read, frames, offset;
119
    snd_pcm_sframes_t commitres;
120
-   int res = 0;
121
+   int res = 0, missed;
122
 
123
    check_position_config(state);
124
 
125
@@ -2221,7 +2233,6 @@
126
    if (state->following && state->alsa_started) {
127
        uint64_t current_time;
128
        snd_pcm_uframes_t avail, delay, target;
129
-       uint32_t threshold = state->threshold;
130
 
131
        current_time = state->position->clock.nsec;
132
 
133
@@ -2234,13 +2245,18 @@
134
            return res;
135
 
136
        if (state->alsa_sync) {
137
-           if (SPA_UNLIKELY(state->alsa_sync_warning)) {
138
-               spa_log_warn(state->log, "%s: follower delay:%lu target:%lu thr:%u, resync",
139
-                       state->props.device, delay, target, threshold);
140
-               state->alsa_sync_warning = false;
141
-           } else
142
-               spa_log_info(state->log, "%s: follower delay:%lu target:%lu thr:%u, resync",
143
-                       state->props.device, delay, target, threshold);
144
+           enum spa_log_level lev;
145
+
146
+           if (SPA_UNLIKELY(state->alsa_sync_warning))
147
+               lev = SPA_LOG_LEVEL_WARN;
148
+           else
149
+               lev = SPA_LOG_LEVEL_INFO;
150
+
151
+           if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
152
+               spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u, "
153
+                       "resync (%d missed)", state->props.device, delay,
154
+                       target, state->threshold, missed);
155
+           }
156
 
157
            if (delay < target)
158
                max_read = target - delay;
159
@@ -2248,7 +2264,8 @@
160
                snd_pcm_forward(state->hndl, delay - target);
161
            delay = target;
162
            state->alsa_sync = false;
163
-       }
164
+       } else
165
+           state->alsa_sync_warning = true;
166
 
167
        if (avail < state->read_size)
168
            max_read = 0;
169
@@ -2537,6 +2554,7 @@
170
 
171
    reset_buffers(state);
172
    state->alsa_sync = true;
173
+   state->alsa_sync_warning = false;
174
    state->alsa_recovering = false;
175
    state->alsa_started = false;
176
 
177
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
55
 
1
@@ -87,7 +87,6 @@
2
    uint32_t posSPA_AUDIO_MAX_CHANNELS;
3
 };
4
 
5
-
6
 struct card {
7
    struct spa_list link;
8
    int ref;
9
@@ -98,6 +97,13 @@
10
    uint32_t rate;
11
 };
12
 
13
+struct ratelimit {
14
+   uint64_t interval;
15
+   uint64_t begin;
16
+   unsigned burst;
17
+   unsigned n_printed, n_missed;
18
+};
19
+
20
 struct state {
21
    struct spa_handle handle;
22
    struct spa_node node;
23
@@ -107,6 +113,7 @@
24
    struct spa_loop *data_loop;
25
 
26
    FILE *log_file;
27
+   struct ratelimit rate_limit;
28
 
29
    uint32_t card_index;
30
    struct card *card;
31
@@ -342,6 +349,23 @@
32
    return i;
33
 }
34
 
35
+static inline int ratelimit_test(struct ratelimit *r, uint64_t now)
36
+{
37
+   unsigned missed = 0;
38
+   if (r->begin + r->interval < now) {
39
+       missed = r->n_missed;
40
+       r->begin = now;
41
+       r->n_printed = 0;
42
+       r->n_missed = 0;
43
+   } else if (r->n_printed >= r->burst) {
44
+       r->n_missed++;
45
+       return -1;
46
+   }
47
+   r->n_printed++;
48
+   return missed;
49
+}
50
+
51
+
52
 #ifdef __cplusplus
53
 } /* extern "C" */
54
 #endif
55
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
19
 
1
@@ -256,7 +256,7 @@
2
    /* Check device class */
3
    spa_scnprintf(path, sizeof(path), "/sys/class/sound/%s/pcm_class",
4
            devname);
5
-   f = fopen(path, "r");
6
+   f = fopen(path, "re");
7
    if (f == NULL)
8
        return -errno;
9
    sz = fread(buf, 1, sizeof(buf) - 1, f);
10
@@ -361,7 +361,7 @@
11
            spa_scnprintf(path, sizeof(path), "/proc/asound/card%u/%s/%s/status",
12
                    (unsigned int)device->id, entry->d_name, entry_pcm->d_name);
13
 
14
-           f = fopen(path, "r");
15
+           f = fopen(path, "re");
16
            if (f == NULL)
17
                goto done;
18
            sz = fread(buf, 1, 6, f);
19
pipewire-0.3.59.tar.gz/spa/plugins/alsa/mixer/profile-sets/asus-xonar-se.conf Added
82
 
1
@@ -0,0 +1,79 @@
2
+# This file is part of PulseAudio.
3
+#
4
+# PulseAudio is free software; you can redistribute it and/or modify
5
+# it under the terms of the GNU Lesser General Public License as
6
+# published by the Free Software Foundation; either version 2.1 of the
7
+# License, or (at your option) any later version.
8
+#
9
+# PulseAudio is distributed in the hope that it will be useful, but
10
+# WITHOUT ANY WARRANTY; without even the implied warranty of
11
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+# General Public License for more details.
13
+#
14
+# You should have received a copy of the GNU Lesser General Public License
15
+# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
16
+
17
+; ASUS Xonar SE card.
18
+; This card has two devices for each rear and front panel jacks.
19
+;
20
+; See default.conf for an explanation on the directives used here.
21
+
22
+General
23
+auto-profiles = yes
24
+
25
+Mapping analog-stereo-front
26
+description = Analog Stereo Front
27
+device-strings = hw:%f,1
28
+channel-map = left,right
29
+paths-output = analog-output analog-output-headphones
30
+paths-input = analog-input-mic analog-input-headphone-mic analog-input-headset-mic
31
+priority = 15
32
+
33
+Mapping analog-stereo-rear
34
+description = Analog Stereo Rear
35
+device-strings = hw:%f,0
36
+channel-map = left,right
37
+paths-output = analog-output analog-output-speaker
38
+paths-input = analog-input analog-input-mic analog-input-linein
39
+priority = 14
40
+
41
+Mapping analog-surround-21
42
+device-strings = surround21:%f
43
+channel-map = front-left,front-right,lfe
44
+paths-output = analog-output-speaker
45
+priority = 13
46
+direction = output
47
+
48
+Mapping analog-surround-40
49
+device-strings = surround40:%f
50
+channel-map = front-left,front-right,rear-left,rear-right
51
+paths-output = analog-output-speaker
52
+priority = 12
53
+direction = output
54
+
55
+Mapping analog-surround-41
56
+device-strings = surround41:%f
57
+channel-map = front-left,front-right,rear-left,rear-right,lfe
58
+paths-output = analog-output-speaker
59
+priority = 13
60
+direction = output
61
+
62
+Mapping analog-surround-50
63
+device-strings = surround50:%f
64
+channel-map = front-left,front-right,rear-left,rear-right,front-center
65
+paths-output = analog-output-speaker
66
+priority = 12
67
+direction = output
68
+
69
+Mapping analog-surround-51
70
+device-strings = surround51:%f
71
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
72
+paths-output = analog-output-speaker
73
+priority = 13
74
+direction = output
75
+
76
+Mapping iec958-stereo
77
+device-strings = iec958:%f
78
+channel-map = left,right
79
+paths-output = iec958-stereo-output
80
+priority = 5
81
\ No newline at end of file
82
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioadapter.c Changed
72
 
1
@@ -336,7 +336,7 @@
2
    struct spa_data *datas;
3
    uint32_t follower_flags, conv_flags;
4
 
5
-   spa_log_debug(this->log, "%p: %d", this, this->n_buffers);
6
+   spa_log_debug(this->log, "%p: n_buffers:%d", this, this->n_buffers);
7
 
8
    if (this->target == this->follower)
9
        return 0;
10
@@ -738,6 +738,8 @@
11
    struct spa_pod_builder b = { 0 };
12
    int res;
13
 
14
+   spa_log_debug(this->log, "%p: have_format:%d", this, this->have_format);
15
+
16
    if (this->have_format)
17
        return 0;
18
 
19
@@ -746,7 +748,6 @@
20
 
21
    spa_pod_builder_init(&b, buffer, sizeof(buffer));
22
 
23
-   spa_log_debug(this->log, "%p: negiotiate", this);
24
 
25
    spa_node_send_command(this->follower,
26
            &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_ParamBegin));
27
@@ -813,6 +814,8 @@
28
 
29
    switch (SPA_NODE_COMMAND_ID(command)) {
30
    case SPA_NODE_COMMAND_Start:
31
+       if (this->started)
32
+           return 0;
33
        if ((res = negotiate_format(this)) < 0)
34
            return res;
35
        if ((res = negotiate_buffers(this)) < 0)
36
@@ -821,11 +824,12 @@
37
    case SPA_NODE_COMMAND_Suspend:
38
        configure_format(this, 0, NULL);
39
        SPA_FALLTHROUGH
40
-   case SPA_NODE_COMMAND_Flush:
41
-       this->io_buffers.status = SPA_STATUS_OK;
42
-       SPA_FALLTHROUGH
43
    case SPA_NODE_COMMAND_Pause:
44
        this->started = false;
45
+       spa_log_debug(this->log, "%p: stopped", this);
46
+       break;
47
+   case SPA_NODE_COMMAND_Flush:
48
+       this->io_buffers.status = SPA_STATUS_OK;
49
        break;
50
    default:
51
        break;
52
@@ -849,6 +853,7 @@
53
    switch (SPA_NODE_COMMAND_ID(command)) {
54
    case SPA_NODE_COMMAND_Start:
55
        this->started = true;
56
+       spa_log_debug(this->log, "%p: started", this);
57
        break;
58
    }
59
    return res;
60
@@ -1396,6 +1401,11 @@
61
    struct impl *this = object;
62
    int status = 0, fstatus, retry = 8;
63
 
64
+   if (!this->started) {
65
+       spa_log_warn(this->log, "%p: scheduling stopped node", this);
66
+       return -EIO;
67
+   }
68
+
69
    spa_log_trace_fp(this->log, "%p: process convert:%p driver:%d",
70
            this, this->convert, this->driver);
71
 
72
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioconvert.c Changed
146
 
1
@@ -90,8 +90,8 @@
2
    struct volumes monitor;
3
    unsigned int have_soft_volume:1;
4
    unsigned int mix_disabled:1;
5
-   unsigned int resample_quality;
6
    unsigned int resample_disabled:1;
7
+   unsigned int resample_quality;
8
    double rate;
9
 };
10
 
11
@@ -105,10 +105,11 @@
12
    init_volumes(&props->channel);
13
    init_volumes(&props->soft);
14
    init_volumes(&props->monitor);
15
+   props->have_soft_volume = false;
16
    props->mix_disabled = false;
17
-   props->rate = 1.0;
18
-   props->resample_quality = RESAMPLE_DEFAULT_QUALITY;
19
    props->resample_disabled = false;
20
+   props->resample_quality = RESAMPLE_DEFAULT_QUALITY;
21
+   props->rate = 1.0;
22
 }
23
 
24
 struct buffer {
25
@@ -215,7 +216,8 @@
26
    uint32_t in_offset;
27
    uint32_t out_offset;
28
    unsigned int started:1;
29
-   unsigned int peaks:1;
30
+   unsigned int setup:1;
31
+   unsigned int resample_peaks:1;
32
    unsigned int is_passthrough:1;
33
    unsigned int drained:1;
34
 
35
@@ -834,6 +836,8 @@
36
            snprintf(value, sizeof(value), "%s",
37
                    SPA_POD_VALUE(struct spa_pod_bool, pod) ?
38
                    "true" : "false");
39
+       } else if (spa_pod_is_none(pod)) {
40
+           spa_zero(value);
41
        } else
42
            continue;
43
 
44
@@ -1353,7 +1357,7 @@
45
    this->resample.quality = this->props.resample_quality;
46
    this->resample.cpu_flags = this->cpu_flags;
47
 
48
-   if (this->peaks)
49
+   if (this->resample_peaks)
50
        res = resample_peaks_init(&this->resample);
51
    else
52
        res = resample_native_init(&this->resample);
53
@@ -1463,6 +1467,12 @@
54
    in = &this->dirSPA_DIRECTION_INPUT;
55
    out = &this->dirSPA_DIRECTION_OUTPUT;
56
 
57
+   spa_log_debug(this->log, "%p: setup:%d in_format:%d out_format:%d", this,
58
+           this->setup, in->have_format, out->have_format);
59
+
60
+   if (this->setup)
61
+       return 0;
62
+
63
    if (!in->have_format || !out->have_format)
64
        return -EINVAL;
65
 
66
@@ -1506,6 +1516,7 @@
67
        this->tmp_datas1i = SPA_PTROFF(this->tmp1, this->empty_size * i, void);
68
        this->tmp_datas1i = SPA_PTR_ALIGN(this->tmp_datas1i, MAX_ALIGN, void);
69
    }
70
+   this->setup = true;
71
 
72
    emit_node_info(this, false);
73
 
74
@@ -1537,13 +1548,14 @@
75
        this->started = true;
76
        break;
77
    case SPA_NODE_COMMAND_Suspend:
78
-       SPA_FALLTHROUGH;
79
-   case SPA_NODE_COMMAND_Flush:
80
-       reset_node(this);
81
+       this->setup = false;
82
        SPA_FALLTHROUGH;
83
    case SPA_NODE_COMMAND_Pause:
84
        this->started = false;
85
        break;
86
+   case SPA_NODE_COMMAND_Flush:
87
+       reset_node(this);
88
+       break;
89
    default:
90
        return -ENOTSUP;
91
    }
92
@@ -2467,6 +2479,7 @@
93
                            volume, mon_max);
94
 
95
                    bd->chunk->size = mon_max * port->stride;
96
+                   bd->chunk->stride = port->stride;
97
 
98
                    spa_log_trace_fp(this->log, "%p: monitor %d %d", this,
99
                            remap, mon_max);
100
@@ -2667,9 +2680,10 @@
101
            for (j = 0; j < port->blocks; j++) {
102
                bd = &buf->buf->datasj;
103
                bd->chunk->size = this->out_offset * port->stride;
104
+               bd->chunk->stride = port->stride;
105
                SPA_FLAG_UPDATE(bd->chunk->flags, SPA_CHUNK_FLAG_EMPTY, in_empty);
106
-               spa_log_trace_fp(this->log, "out: %d %d %d", this->out_offset,
107
-                       port->stride, bd->chunk->size);
108
+               spa_log_trace_fp(this->log, "out: offs:%d stride:%d size:%d",
109
+                       this->out_offset, port->stride, bd->chunk->size);
110
            }
111
            io->status = SPA_STATUS_HAVE_DATA;
112
            io->buffer_id = buf->id;
113
@@ -2678,7 +2692,7 @@
114
        this->drained = draining;
115
        this->out_offset = 0;
116
    }
117
-   else if (n_samples == 0 && this->peaks) {
118
+   else if (n_samples == 0 && this->resample_peaks) {
119
        for (i = 0; i < dir->n_ports; i++) {
120
            port = GET_OUT_PORT(this, i);
121
            if (port->is_monitor || port->is_control)
122
@@ -2841,15 +2855,20 @@
123
        if (spa_streq(k, "clock.quantum-limit"))
124
            spa_atou32(s, &this->quantum_limit, 0);
125
        else if (spa_streq(k, "resample.peaks"))
126
-           this->peaks = spa_atob(s);
127
+           this->resample_peaks = spa_atob(s);
128
+       else if (spa_streq(k, "resample.prefill"))
129
+           SPA_FLAG_UPDATE(this->resample.options,
130
+               RESAMPLE_OPTION_PREFILL, spa_atob(s));
131
        else if (spa_streq(k, "factory.mode")) {
132
            if (spa_streq(s, "merge"))
133
                this->direction = SPA_DIRECTION_OUTPUT;
134
            else
135
                this->direction = SPA_DIRECTION_INPUT;
136
        }
137
-       else if (spa_streq(k, SPA_KEY_AUDIO_POSITION))
138
-                        this->props.n_channels = parse_position(this->props.channel_map, s, strlen(s));
139
+       else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) {
140
+           if (s != NULL)
141
+                           this->props.n_channels = parse_position(this->props.channel_map, s, strlen(s));
142
+       }
143
        else
144
            audioconvert_set_param(this, k, s);
145
    }
146
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
63
 
1
@@ -46,6 +46,16 @@
2
            dn = sn * vol;
3
    }
4
 }
5
+static inline void conv_c(float *d, const float **s, float *c, uint32_t n_c, uint32_t n_samples)
6
+{
7
+   uint32_t n, j;
8
+   for (n = 0; n < n_samples; n++) {
9
+       float sum = 0.0f;
10
+       for (j = 0; j < n_c; j++)
11
+           sum += sjn * cj;
12
+       dn = sum;
13
+   }
14
+}
15
 
16
 static inline void avg_c(float *d, const float *s0, const float *s1, uint32_t n_samples)
17
 {
18
@@ -78,7 +88,7 @@
19
 channelmix_f32_n_m_c(struct channelmix *mix, void * SPA_RESTRICT dst,
20
        const void * SPA_RESTRICT src, uint32_t n_samples)
21
 {
22
-   uint32_t i, j, n, n_dst = mix->dst_chan, n_src = mix->src_chan;
23
+   uint32_t i, j, n_dst = mix->dst_chan, n_src = mix->src_chan;
24
    float **d = (float **) dst;
25
    const float **s = (const float **) src;
26
 
27
@@ -94,16 +104,27 @@
28
            clear_c(di, n_samples);
29
    }
30
    else {
31
-       for (n = 0; n < n_samples; n++) {
32
-           for (i = 0; i < n_dst; i++) {
33
-               float sum = 0.0f;
34
-               for (j = 0; j < n_src; j++)
35
-                   sum += sjn * mix->matrixij;
36
-               din = sum;
37
+       for (i = 0; i < n_dst; i++) {
38
+           float *di = di;
39
+           float mjn_src;
40
+           const float *sjn_src;
41
+           uint32_t n_j = 0;
42
+
43
+           for (j = 0; j < n_src; j++) {
44
+               if (mix->matrixij == 0.0f)
45
+                   continue;
46
+               mjn_j = mix->matrixij;
47
+               sjn_j++ = sj;
48
+           }
49
+           if (n_j == 0) {
50
+               clear_c(di, n_samples);
51
+           } else if (n_j == 1) {
52
+               lr4_process(&mix->lr4i, di, sj0, mj0, n_samples);
53
+           } else {
54
+               conv_c(di, sj, mj, n_j, n_samples);
55
+               lr4_process(&mix->lr4i, di, di, 1.0f, n_samples);
56
            }
57
        }
58
-       for (i = 0; i < n_dst; i++)
59
-           lr4_process(&mix->lr4i, di, di, 1.0f, n_samples);
60
    }
61
 }
62
 
63
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
82
 
1
@@ -68,6 +68,39 @@
2
    }
3
 }
4
 
5
+static inline void conv_sse(float *d, const float **s, float *c, uint32_t n_c, uint32_t n_samples)
6
+{
7
+   __m128 min_c, sum2;
8
+   uint32_t n, j, unrolled;
9
+   bool aligned = true;
10
+
11
+   for (j = 0; j < n_c; j++) {
12
+       mij = _mm_set1_ps(cj);
13
+       aligned &= SPA_IS_ALIGNED(sj, 16);
14
+   }
15
+
16
+   if (aligned && SPA_IS_ALIGNED(d, 16))
17
+       unrolled = n_samples & ~7;
18
+   else
19
+       unrolled = 0;
20
+
21
+   for (n = 0; n < unrolled; n += 8) {
22
+       sum0 = sum1 = _mm_setzero_ps();
23
+       for (j = 0; j < n_c; j++) {
24
+           sum0 = _mm_add_ps(sum0, _mm_mul_ps(_mm_load_ps(&sjn + 0), mij));
25
+           sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_load_ps(&sjn + 4), mij));
26
+       }
27
+       _mm_store_ps(&dn + 0, sum0);
28
+       _mm_store_ps(&dn + 4, sum1);
29
+   }
30
+   for (; n < n_samples; n++) {
31
+       sum0 = _mm_setzero_ps();
32
+       for (j = 0; j < n_c; j++)
33
+           sum0 = _mm_add_ss(sum0, _mm_mul_ss(_mm_load_ss(&sjn), mij));
34
+       _mm_store_ss(&dn, sum0);
35
+   }
36
+}
37
+
38
 void channelmix_copy_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
39
        const void * SPA_RESTRICT src, uint32_t n_samples)
40
 {
41
@@ -78,6 +111,40 @@
42
        vol_sse(di, si, mix->matrixii, n_samples);
43
 }
44
 
45
+void
46
+channelmix_f32_n_m_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
47
+          const void * SPA_RESTRICT src, uint32_t n_samples)
48
+{
49
+   float **d = (float **) dst;
50
+   const float **s = (const float **) src;
51
+   uint32_t i, j, n_dst = mix->dst_chan, n_src = mix->src_chan;
52
+
53
+   for (i = 0; i < n_dst; i++) {
54
+       float *di = di;
55
+       float mjn_src;
56
+       const float *sjn_src;
57
+       uint32_t n_j = 0;
58
+
59
+       for (j = 0; j < n_src; j++) {
60
+           if (mix->matrixij == 0.0f)
61
+               continue;
62
+           mjn_j = mix->matrixij;
63
+           sjn_j++ = sj;
64
+       }
65
+       if (n_j == 0) {
66
+           clear_sse(di, n_samples);
67
+       } else if (n_j == 1) {
68
+           if (mix->lr4i.active)
69
+               lr4_process(&mix->lr4i, di, sj0, mj0, n_samples);
70
+           else
71
+               vol_sse(di, sj0, mj0, n_samples);
72
+       } else {
73
+           conv_sse(di, sj, mj, n_j, n_samples);
74
+           lr4_process(&mix->lr4i, di, di, 1.0f, n_samples);
75
+       }
76
+   }
77
+}
78
+
79
 /* FL+FR+FC+LFE -> FL+FR */
80
 void
81
 channelmix_f32_3p1_2_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
82
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
201
 
1
@@ -94,6 +94,9 @@
2
    MAKE(8, MASK_7_1, 4, MASK_QUAD, channelmix_f32_7p1_4_c),
3
    MAKE(8, MASK_7_1, 4, MASK_3_1, channelmix_f32_7p1_3p1_c),
4
 
5
+#if defined (HAVE_SSE)
6
+   MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_sse),
7
+#endif
8
    MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_c),
9
 };
10
 #undef MAKE
11
@@ -142,6 +145,8 @@
12
    float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS = {{ 0.0f }};
13
    uint64_t src_mask = mix->src_mask;
14
    uint64_t dst_mask = mix->dst_mask;
15
+   uint32_t src_chan = mix->src_chan;
16
+   uint32_t dst_chan = mix->dst_chan;
17
    uint64_t unassigned, keep;
18
    uint32_t i, j, ic, jc, matrix_encoding = MATRIX_NORMAL;
19
    float clev = SQRT1_2;
20
@@ -157,7 +162,7 @@
21
    /* move the MONO mask to FRONT so that the lower bits can be shifted
22
     * away. */
23
    if ((src_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0) {
24
-       if (mix->src_chan == 1)
25
+       if (src_chan == 1)
26
            src_mask = 0;
27
        else
28
            src_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
29
@@ -171,19 +176,19 @@
30
 
31
    /* unknown channels or just 1 channel */
32
    if (src_mask == 0 || dst_mask == 0) {
33
-       if (mix->src_chan == 1) {
34
+       if (src_chan == 1) {
35
            /* one FC/MONO src goes everywhere */
36
-           spa_log_debug(mix->log, "distribute FC/MONO");
37
+           spa_log_debug(mix->log, "distribute FC/MONO (%f)", 1.0f);
38
            for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
39
                matrixi0= 1.0f;
40
-       } else if (mix->dst_chan == 1) {
41
+       } else if (dst_chan == 1) {
42
            /* one FC/MONO dst get average of everything */
43
-           spa_log_debug(mix->log, "average FC/MONO");
44
+           spa_log_debug(mix->log, "average FC/MONO (%f)", 1.0f / src_chan);
45
            for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
46
-               matrix0i= 1.0f / mix->src_chan;
47
+               matrix0i= 1.0f / src_chan;
48
        } else {
49
            /* just pair channels */
50
-           spa_log_debug(mix->log, "pairing channels");
51
+           spa_log_debug(mix->log, "pairing channels (%f)", 1.0f);
52
            for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
53
                matrixii= 1.0f;
54
        }
55
@@ -197,7 +202,7 @@
56
        spa_log_debug(mix->log, "matching channels");
57
        for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) {
58
            if ((src_mask & dst_mask & (1ULL << i))) {
59
-               spa_log_debug(mix->log, "matched %u", i);
60
+               spa_log_debug(mix->log, "matched channel %u (%f)", i, 1.0f);
61
                matrixii= 1.0f;
62
            }
63
        }
64
@@ -222,11 +227,12 @@
65
 
66
    if (unassigned & FRONT){
67
        if ((dst_mask & STEREO) == STEREO){
68
-           spa_log_debug(mix->log, "assign FC to STEREO");
69
            if(src_mask & STEREO) {
70
+               spa_log_debug(mix->log, "assign FC to STEREO (%f)", clev);
71
                _MATRIX(FL,FC) += clev;
72
                _MATRIX(FR,FC) += clev;
73
            } else {
74
+               spa_log_debug(mix->log, "assign FC to STEREO (%f)", SQRT1_2);
75
                _MATRIX(FL,FC) += SQRT1_2;
76
                _MATRIX(FR,FC) += SQRT1_2;
77
            }
78
@@ -237,11 +243,13 @@
79
 
80
    if (unassigned & STEREO){
81
        if (dst_mask & FRONT) {
82
-           spa_log_debug(mix->log, "assign STEREO to FC");
83
+           spa_log_debug(mix->log, "assign STEREO to FC (%f)", SQRT1_2);
84
            _MATRIX(FC,FL) += SQRT1_2;
85
            _MATRIX(FC,FR) += SQRT1_2;
86
-           if (src_mask & FRONT)
87
+           if (src_mask & FRONT) {
88
+               spa_log_debug(mix->log, "assign FC to FC (%f)", clev * SQRT2);
89
                _MATRIX(FC,FC) = clev * SQRT2;
90
+           }
91
            keep &= ~FRONT;
92
        } else {
93
            spa_log_warn(mix->log, "can't assign STEREO");
94
@@ -250,11 +258,11 @@
95
 
96
    if (unassigned & _MASK(RC)) {
97
        if (dst_mask & REAR){
98
-           spa_log_debug(mix->log, "assign RC to RL+RR");
99
+           spa_log_debug(mix->log, "assign RC to RL+RR (%f)", SQRT1_2);
100
            _MATRIX(RL,RC) += SQRT1_2;
101
            _MATRIX(RR,RC) += SQRT1_2;
102
        } else if (dst_mask & SIDE) {
103
-           spa_log_debug(mix->log, "assign RC to SL+SR");
104
+           spa_log_debug(mix->log, "assign RC to SL+SR (%f)", SQRT1_2);
105
            _MATRIX(SL,RC) += SQRT1_2;
106
            _MATRIX(SR,RC) += SQRT1_2;
107
        } else if(dst_mask & STEREO) {
108
@@ -273,7 +281,7 @@
109
                _MATRIX(FR,RC) += slev * SQRT1_2;
110
            }
111
        } else if (dst_mask & FRONT) {
112
-           spa_log_debug(mix->log, "assign RC to FC");
113
+           spa_log_debug(mix->log, "assign RC to FC (%f)", slev * SQRT1_2);
114
            _MATRIX(FC,RC) += slev * SQRT1_2;
115
        } else {
116
            spa_log_warn(mix->log, "can't assign RC");
117
@@ -295,7 +303,7 @@
118
                _MATRIX(SR,RR) += 1.0f;
119
            }
120
        } else if (dst_mask & STEREO) {
121
-           spa_log_debug(mix->log, "assign RL+RR to FL+FR %f", slev);
122
+           spa_log_debug(mix->log, "assign RL+RR to FL+FR (%f)", slev);
123
            if (matrix_encoding == MATRIX_DOLBY) {
124
                _MATRIX(FL,RL) -= slev * SQRT1_2;
125
                _MATRIX(FL,RR) -= slev * SQRT1_2;
126
@@ -311,7 +319,8 @@
127
                _MATRIX(FR,RR) += slev;
128
            }
129
        } else if (dst_mask & FRONT) {
130
-           spa_log_debug(mix->log, "assign RL+RR to FC");
131
+           spa_log_debug(mix->log, "assign RL+RR to FC (%f)",
132
+                   slev * SQRT1_2);
133
            _MATRIX(FC,RL)+= slev * SQRT1_2;
134
            _MATRIX(FC,RR)+= slev * SQRT1_2;
135
        } else {
136
@@ -321,36 +330,41 @@
137
 
138
    if (unassigned & SIDE) {
139
        if (dst_mask & REAR) {
140
-           spa_log_debug(mix->log, "assign SL+SR to RL+RR");
141
            if (src_mask & _MASK(RL)) {
142
+               spa_log_debug(mix->log, "assign SL+SR to RL+RR (%f)", SQRT1_2);
143
                _MATRIX(RL,SL) += SQRT1_2;
144
                _MATRIX(RR,SR) += SQRT1_2;
145
            } else {
146
+               spa_log_debug(mix->log, "assign SL+SR to RL+RR (%f)", 1.0f);
147
                _MATRIX(RL,SL) += 1.0f;
148
                _MATRIX(RR,SR) += 1.0f;
149
            }
150
        } else if (dst_mask & _MASK(RC)) {
151
-           spa_log_debug(mix->log, "assign SL+SR to RC");
152
+           spa_log_debug(mix->log, "assign SL+SR to RC (%f)", SQRT1_2);
153
            _MATRIX(RC,SL)+= SQRT1_2;
154
            _MATRIX(RC,SR)+= SQRT1_2;
155
        } else if (dst_mask & STEREO) {
156
-           spa_log_debug(mix->log, "assign SL+SR to FL+FR");
157
            if (matrix_encoding == MATRIX_DOLBY) {
158
+               spa_log_debug(mix->log, "assign SL+SR to FL+FR (%f)",
159
+                       slev * SQRT1_2);
160
                _MATRIX(FL,SL) -= slev * SQRT1_2;
161
                _MATRIX(FL,SR) -= slev * SQRT1_2;
162
                _MATRIX(FR,SL) += slev * SQRT1_2;
163
                _MATRIX(FR,SR) += slev * SQRT1_2;
164
            } else if (matrix_encoding == MATRIX_DPLII) {
165
+               spa_log_debug(mix->log, "assign SL+SR to FL+FR (%f / %f)",
166
+                       slev * SQRT3_2, slev * SQRT1_2);
167
                _MATRIX(FL,SL) -= slev * SQRT3_2;
168
                _MATRIX(FL,SR) -= slev * SQRT1_2;
169
                _MATRIX(FR,SL) += slev * SQRT1_2;
170
                _MATRIX(FR,SR) += slev * SQRT3_2;
171
            } else {
172
+               spa_log_debug(mix->log, "assign SL+SR to FL+FR (%f)", slev);
173
                _MATRIX(FL,SL) += slev;
174
                _MATRIX(FR,SR) += slev;
175
            }
176
        } else if (dst_mask & FRONT) {
177
-           spa_log_debug(mix->log, "assign SL+SR to FC");
178
+           spa_log_debug(mix->log, "assign SL+SR to FC (%f)", slev * SQRT1_2);
179
            _MATRIX(FC,SL) += slev * SQRT1_2;
180
            _MATRIX(FC,SR) += slev * SQRT1_2;
181
        } else {
182
@@ -360,11 +374,11 @@
183
 
184
    if (unassigned & _MASK(FLC)) {
185
        if (dst_mask & STEREO) {
186
-           spa_log_debug(mix->log, "assign FLC+FRC to FL+FR");
187
+           spa_log_debug(mix->log, "assign FLC+FRC to FL+FR (%f)", 1.0f);
188
            _MATRIX(FL,FLC)+= 1.0f;
189
            _MATRIX(FR,FRC)+= 1.0f;
190
        } else if(dst_mask & FRONT) {
191
-           spa_log_debug(mix->log, "assign FLC+FRC to FC");
192
+           spa_log_debug(mix->log, "assign FLC+FRC to FC (%f)", SQRT1_2);
193
            _MATRIX(FC,FLC)+= SQRT1_2;
194
            _MATRIX(FC,FRC)+= SQRT1_2;
195
        } else {
196
@@ -374,10 +388,11 @@
197
    if (unassigned & _MASK(LFE) &&
198
        SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_MIX_LFE)) {
199
        if (dst_mask & FRONT) {
200
-           spa_log_debug(mix->log, "assign LFE to FC");
201
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
9
 
1
@@ -147,6 +147,7 @@
2
 
3
 #if defined (HAVE_SSE)
4
 DEFINE_FUNCTION(copy, sse);
5
+DEFINE_FUNCTION(f32_n_m, sse);
6
 DEFINE_FUNCTION(f32_3p1_2, sse);
7
 DEFINE_FUNCTION(f32_5p1_2, sse);
8
 DEFINE_FUNCTION(f32_5p1_3p1, sse);
9
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
129
 
1
@@ -230,38 +230,57 @@
2
         return (int32_t)(*state);
3
 }
4
 
5
-static inline void update_noise_c(struct convert *conv, uint32_t n_samples)
6
+void conv_noise_none_c(struct convert *conv, float *noise, uint32_t n_samples)
7
+{
8
+   memset(noise, 0, n_samples * sizeof(float));
9
+}
10
+
11
+void conv_noise_rect_c(struct convert *conv, float *noise, uint32_t n_samples)
12
+{
13
+   uint32_t n;
14
+   uint32_t *state = &conv->random0;
15
+   const float scale = conv->scale;
16
+
17
+   for (n = 0; n < n_samples; n++)
18
+       noisen = lcnoise(state) * scale;
19
+}
20
+
21
+void conv_noise_tri_c(struct convert *conv, float *noise, uint32_t n_samples)
22
+{
23
+   uint32_t n;
24
+   const float scale = conv->scale;
25
+   uint32_t *state = &conv->random0;
26
+
27
+   for (n = 0; n < n_samples; n++)
28
+       noisen = (lcnoise(state) - lcnoise(state)) * scale;
29
+}
30
+
31
+void conv_noise_tri_hf_c(struct convert *conv, float *noise, uint32_t n_samples)
32
 {
33
    uint32_t n;
34
-   float *noise = conv->noise, scale = conv->scale;
35
+   const float scale = conv->scale;
36
    uint32_t *state = &conv->random0;
37
    int32_t *prev = &conv->prev0, old, new;
38
 
39
-   switch (conv->noise_method) {
40
-   case NOISE_METHOD_RECTANGULAR:
41
-       for (n = 0; n < n_samples; n++)
42
-           noisen = lcnoise(state) * scale;
43
-       break;
44
-   case NOISE_METHOD_TRIANGULAR:
45
-       for (n = 0; n < n_samples; n++)
46
-           noisen = (lcnoise(state) - lcnoise(state)) * scale;
47
-       break;
48
-   case NOISE_METHOD_TRIANGULAR_HF:
49
-       old = *prev;
50
-       for (n = 0; n < n_samples; n++) {
51
-           new = lcnoise(state);
52
-           noisen = (new - old) * scale;
53
-           old = new;
54
-       }
55
-       *prev = old;
56
-       break;
57
-   case NOISE_METHOD_PATTERN:
58
-       old = *prev;
59
-       for (n = 0; n < n_samples; n++)
60
-           noisen = conv->scale * (1-((old++>>10)&1));
61
-       *prev = old;
62
-       break;
63
+   old = *prev;
64
+   for (n = 0; n < n_samples; n++) {
65
+       new = lcnoise(state);
66
+       noisen = (new - old) * scale;
67
+       old = new;
68
    }
69
+   *prev = old;
70
+}
71
+
72
+void conv_noise_pattern_c(struct convert *conv, float *noise, uint32_t n_samples)
73
+{
74
+   uint32_t n;
75
+   const float scale = conv->scale;
76
+   int32_t *prev = &conv->prev0, old;
77
+
78
+   old = *prev;
79
+   for (n = 0; n < n_samples; n++)
80
+       noisen = scale * (1-((old++>>10)&1));
81
+   *prev = old;
82
 }
83
 
84
 #define MAKE_D_noise(dname,dtype,func)                     \
85
@@ -271,7 +290,7 @@
86
 {                                      \
87
    uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size;  \
88
    float *noise = conv->noise;                     \
89
-   update_noise_c(conv, SPA_MIN(n_samples, noise_size));           \
90
+   convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size));  \
91
    for (i = 0; i < n_channels; i++) {                  \
92
        const float *s = srci;                  \
93
        dtype *d = dsti;                        \
94
@@ -292,7 +311,7 @@
95
    dtype *d = dst0;                            \
96
    uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size;  \
97
    float *noise = conv->noise;                     \
98
-   update_noise_c(conv, SPA_MIN(n_samples, noise_size));           \
99
+   convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size));  \
100
    for (j = 0; j < n_samples;) {                       \
101
        chunk = SPA_MIN(n_samples - j, noise_size);         \
102
        for (k = 0; k < chunk; k++, j++) {              \
103
@@ -342,9 +361,10 @@
104
                 uint32_t n_samples)                        \
105
 {                                      \
106
    uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size;  \
107
-   const float *noise = conv->noise, *ns = conv->ns;           \
108
+   float *noise = conv->noise;                     \
109
+   const float *ns = conv->ns;                     \
110
    uint32_t n, n_ns = conv->n_ns;                      \
111
-   update_noise_c(conv, SPA_MIN(n_samples, noise_size));           \
112
+   convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size));  \
113
    for (i = 0; i < n_channels; i++) {                  \
114
        const float *s = srci;                  \
115
        dtype *d = dsti;                        \
116
@@ -366,9 +386,10 @@
117
 {                                      \
118
    dtype *d0 = dst0;                           \
119
    uint32_t i, j, k, chunk, n_channels = conv->n_channels, noise_size = conv->noise_size;  \
120
-   const float *noise = conv->noise, *ns = conv->ns;           \
121
+   float *noise = conv->noise;                     \
122
+   const float *ns = conv->ns;                     \
123
    uint32_t n, n_ns = conv->n_ns;                      \
124
-   update_noise_c(conv, SPA_MIN(n_samples, noise_size));           \
125
+   convert_update_noise(conv, noise, SPA_MIN(n_samples, noise_size));  \
126
    for (i = 0; i < n_channels; i++) {                  \
127
        const float *s = srci;                  \
128
        dtype *d = &d0i;                        \
129
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
189
 
1
@@ -576,61 +576,64 @@
2
    i;                      \
3
 })
4
 
5
+void conv_noise_rect_sse2(struct convert *conv, float *noise, uint32_t n_samples)
6
+{
7
+   uint32_t n;
8
+   const uint32_t *r = conv->random;
9
+   __m128 scale = _mm_set1_ps(conv->scale);
10
+   __m128i in1;
11
+   __m128 out1;
12
+
13
+   for (n = 0; n < n_samples; n += 4) {
14
+       in0 = _MM_XORSHIFT_EPI32(r);
15
+       out0 = _mm_cvtepi32_ps(in0);
16
+       out0 = _mm_mul_ps(out0, scale);
17
+       _mm_store_ps(&noisen, out0);
18
+   }
19
+}
20
 
21
-static inline void update_noise_sse2(struct convert *conv, uint32_t n_samples)
22
+void conv_noise_tri_sse2(struct convert *conv, float *noise, uint32_t n_samples)
23
 {
24
    uint32_t n;
25
-   const uint32_t *r = SPA_PTR_ALIGN(conv->random, 16, uint32_t);
26
-   int32_t *p = SPA_PTR_ALIGN(conv->prev, 16, int32_t), op;
27
+   const uint32_t *r = conv->random;
28
    __m128 scale = _mm_set1_ps(conv->scale);
29
+   __m128i in1;
30
    __m128 out1;
31
-   float *noise = SPA_PTR_ALIGN(conv->noise, 16, float);
32
+
33
+   for (n = 0; n < n_samples; n += 4) {
34
+       in0 = _mm_sub_epi32( _MM_XORSHIFT_EPI32(r), _MM_XORSHIFT_EPI32(r));
35
+       out0 = _mm_cvtepi32_ps(in0);
36
+       out0 = _mm_mul_ps(out0, scale);
37
+       _mm_store_ps(&noisen, out0);
38
+   }
39
+}
40
+
41
+void conv_noise_tri_hf_sse2(struct convert *conv, float *noise, uint32_t n_samples)
42
+{
43
+   uint32_t n;
44
+   int32_t *p = conv->prev;
45
+   const uint32_t *r = conv->random;
46
+   __m128 scale = _mm_set1_ps(conv->scale);
47
    __m128i in1, old1, new1;
48
+   __m128 out1;
49
 
50
-   switch (conv->noise_method) {
51
-   case DITHER_METHOD_RECTANGULAR:
52
-       for (n = 0; n < n_samples; n += 4) {
53
-           in0 = _MM_XORSHIFT_EPI32(r);
54
-           out0 = _mm_cvtepi32_ps(_MM_XORSHIFT_EPI32(r));
55
-           out0 = _mm_mul_ps(out0, scale);
56
-           _mm_store_ps(&noisen, out0);
57
-       }
58
-       break;
59
-   case DITHER_METHOD_TRIANGULAR:
60
-       for (n = 0; n < n_samples; n += 4) {
61
-           in0 = _mm_sub_epi32( _MM_XORSHIFT_EPI32(r), _MM_XORSHIFT_EPI32(r));
62
-           out0 = _mm_cvtepi32_ps(in0);
63
-           out0 = _mm_mul_ps(out0, scale);
64
-           _mm_store_ps(&noisen, out0);
65
-       }
66
-       break;
67
-   case DITHER_METHOD_TRIANGULAR_HF:
68
-       old0 = _mm_load_si128((__m128i*)p);
69
-       for (n = 0; n < n_samples; n += 4) {
70
-           new0 = _MM_XORSHIFT_EPI32(r);
71
-           in0 = _mm_sub_epi32(old0, new0);
72
-           old0 = new0;
73
-           out0 = _mm_cvtepi32_ps(in0);
74
-           out0 = _mm_mul_ps(out0, scale);
75
-           _mm_store_ps(&noisen, out0);
76
-       }
77
-       _mm_store_si128((__m128i*)p, old0);
78
-       break;
79
-   case NOISE_METHOD_PATTERN:
80
-       op = *p;
81
-       for (n = 0; n < n_samples; n++)
82
-           noisen = conv->scale * (1-((op++>>10)&1));
83
-       *p = op;
84
-       break;
85
+   old0 = _mm_load_si128((__m128i*)p);
86
+   for (n = 0; n < n_samples; n += 4) {
87
+       new0 = _MM_XORSHIFT_EPI32(r);
88
+       in0 = _mm_sub_epi32(old0, new0);
89
+       old0 = new0;
90
+       out0 = _mm_cvtepi32_ps(in0);
91
+       out0 = _mm_mul_ps(out0, scale);
92
+       _mm_store_ps(&noisen, out0);
93
    }
94
+   _mm_store_si128((__m128i*)p, old0);
95
 }
96
 
97
 static void
98
 conv_f32d_to_s32_1s_noise_sse2(struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
99
-       uint32_t n_channels, uint32_t n_samples)
100
+       float *noise, uint32_t n_channels, uint32_t n_samples)
101
 {
102
    const float *s = src;
103
-   float *noise = SPA_PTR_ALIGN(conv->noise, 16, float);
104
    int32_t *d = dst;
105
    uint32_t n, unrolled;
106
    __m128 in1;
107
@@ -676,14 +679,16 @@
108
 {
109
    int32_t *d = dst0;
110
    uint32_t i, k, chunk, n_channels = conv->n_channels;
111
+   float *noise = conv->noise;
112
 
113
-   update_noise_sse2(conv, SPA_MIN(n_samples, conv->noise_size));
114
+   convert_update_noise(conv, noise, SPA_MIN(n_samples, conv->noise_size));
115
 
116
    for(i = 0; i < n_channels; i++) {
117
        const float *s = srci;
118
        for(k = 0; k < n_samples; k += chunk) {
119
            chunk = SPA_MIN(n_samples - k, conv->noise_size);
120
-           conv_f32d_to_s32_1s_noise_sse2(conv, &di + k*n_channels, &sk, n_channels, chunk);
121
+           conv_f32d_to_s32_1s_noise_sse2(conv, &di + k*n_channels,
122
+                   &sk, noise, n_channels, chunk);
123
        }
124
    }
125
 }
126
@@ -1261,11 +1266,10 @@
127
 
128
 static void
129
 conv_f32d_to_s16_1s_noise_sse2(struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
130
-       uint32_t n_channels, uint32_t n_samples)
131
+       const float *noise, uint32_t n_channels, uint32_t n_samples)
132
 {
133
    const float *s0 = src;
134
    int16_t *d = dst;
135
-   float *noise = SPA_PTR_ALIGN(conv->noise, 16, float);
136
    uint32_t n, unrolled;
137
    __m128 in2;
138
    __m128i out2;
139
@@ -1312,25 +1316,26 @@
140
 {
141
    int16_t *d = dst0;
142
    uint32_t i, k, chunk, n_channels = conv->n_channels;
143
+   float *noise = conv->noise;
144
 
145
-   update_noise_sse2(conv, SPA_MIN(n_samples, conv->noise_size));
146
+   convert_update_noise(conv, noise, SPA_MIN(n_samples, conv->noise_size));
147
 
148
    for(i = 0; i < n_channels; i++) {
149
        const float *s = srci;
150
        for(k = 0; k < n_samples; k += chunk) {
151
            chunk = SPA_MIN(n_samples - k, conv->noise_size);
152
-           conv_f32d_to_s16_1s_noise_sse2(conv, &di + k*n_channels, &sk, n_channels, chunk);
153
+           conv_f32d_to_s16_1s_noise_sse2(conv, &di + k*n_channels,
154
+                   &sk, noise, n_channels, chunk);
155
        }
156
    }
157
 }
158
 
159
 static void
160
 conv_f32_to_s16_1_noise_sse2(struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
161
-       uint32_t n_samples)
162
+       const float *noise, uint32_t n_samples)
163
 {
164
    const float *s = src;
165
    int16_t *d = dst;
166
-   float *noise = SPA_PTR_ALIGN(conv->noise, 16, float);
167
    uint32_t n, unrolled;
168
    __m128 in2;
169
    __m128i out2;
170
@@ -1366,15 +1371,16 @@
171
        uint32_t n_samples)
172
 {
173
    uint32_t i, k, chunk, n_channels = conv->n_channels;
174
+   float *noise = conv->noise;
175
 
176
-   update_noise_sse2(conv, SPA_MIN(n_samples, conv->noise_size));
177
+   convert_update_noise(conv, noise, SPA_MIN(n_samples, conv->noise_size));
178
 
179
    for(i = 0; i < n_channels; i++) {
180
        const float *s = srci;
181
        int16_t *d = dsti;
182
        for(k = 0; k < n_samples; k += chunk) {
183
            chunk = SPA_MIN(n_samples - k, conv->noise_size);
184
-           conv_f32_to_s16_1_noise_sse2(conv, &dk, &sk, chunk);
185
+           conv_f32_to_s16_1_noise_sse2(conv, &dk, &sk, noise, chunk);
186
        }
187
    }
188
 }
189
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
121
 
1
@@ -32,7 +32,8 @@
2
 
3
 #include "fmt-ops.h"
4
 
5
-#define DITHER_SIZE    (1<<10)
6
+#define NOISE_SIZE (1<<10)
7
+#define RANDOM_SIZE    (16)
8
 
9
 typedef void (*convert_func_t) (struct convert *conv, void * SPA_RESTRICT dst,
10
        const void * SPA_RESTRICT src, uint32_t n_samples);
11
@@ -359,7 +360,6 @@
12
        uint32_t n_channels, uint32_t cpu_flags, uint32_t conv_flags)
13
 {
14
    size_t i;
15
-
16
    for (i = 0; i < SPA_N_ELEMENTS(conv_table); i++) {
17
        if (conv_tablei.src_fmt == src_fmt &&
18
            conv_tablei.dst_fmt == dst_fmt &&
19
@@ -371,11 +371,52 @@
20
    return NULL;
21
 }
22
 
23
+typedef void (*noise_func_t) (struct convert *conv, float * noise, uint32_t n_samples);
24
+
25
+struct noise_info {
26
+   uint32_t method;
27
+
28
+   noise_func_t noise;
29
+   const char *name;
30
+
31
+   uint32_t cpu_flags;
32
+};
33
+
34
+#define MAKE(method,func,...) \
35
+   {  NOISE_METHOD_ ##method, func, #func , __VA_ARGS__ }
36
+
37
+static struct noise_info noise_table =
38
+{
39
+#if defined (HAVE_SSE2)
40
+   MAKE(RECTANGULAR, conv_noise_rect_sse2, SPA_CPU_FLAG_SSE2),
41
+   MAKE(TRIANGULAR, conv_noise_tri_sse2, SPA_CPU_FLAG_SSE2),
42
+   MAKE(TRIANGULAR_HF, conv_noise_tri_hf_sse2, SPA_CPU_FLAG_SSE2),
43
+#endif
44
+   MAKE(NONE, conv_noise_none_c),
45
+   MAKE(RECTANGULAR, conv_noise_rect_c),
46
+   MAKE(TRIANGULAR, conv_noise_tri_c),
47
+   MAKE(TRIANGULAR_HF, conv_noise_tri_hf_c),
48
+   MAKE(PATTERN, conv_noise_pattern_c),
49
+};
50
+#undef MAKE
51
+
52
+static const struct noise_info *find_noise_info(uint32_t method,
53
+       uint32_t cpu_flags)
54
+{
55
+   size_t i;
56
+   for (i = 0; i < SPA_N_ELEMENTS(noise_table); i++) {
57
+       if (noise_tablei.method == method &&
58
+           MATCH_CPU_FLAGS(noise_tablei.cpu_flags, cpu_flags))
59
+           return &noise_tablei;
60
+   }
61
+   return NULL;
62
+}
63
+
64
 static void impl_convert_free(struct convert *conv)
65
 {
66
    conv->process = NULL;
67
-   free(conv->noise);
68
-   conv->noise = NULL;
69
+   free(conv->data);
70
+   conv->data = NULL;
71
 }
72
 
73
 static bool need_dither(uint32_t format)
74
@@ -449,7 +490,8 @@
75
 {
76
    const struct conv_info *info;
77
    const struct dither_info *dinfo;
78
-   uint32_t i, conv_flags;
79
+   const struct noise_info *ninfo;
80
+   uint32_t i, conv_flags, data_size3;
81
 
82
    conv->scale = 1.0f / (float)(INT32_MAX);
83
 
84
@@ -494,17 +536,31 @@
85
    if (info == NULL)
86
        return -ENOTSUP;
87
 
88
-   conv->noise_size = DITHER_SIZE;
89
-   conv->noise = calloc(conv->noise_size + 16 +
90
-           FMT_OPS_MAX_ALIGN / sizeof(float), sizeof(float));
91
-   if (conv->noise == NULL)
92
+   ninfo = find_noise_info(conv->noise_method, conv->cpu_flags);
93
+   if (ninfo == NULL)
94
+       return -ENOTSUP;
95
+
96
+   conv->noise_size = NOISE_SIZE;
97
+
98
+   data_size0 = SPA_ROUND_UP(conv->noise_size * sizeof(float), FMT_OPS_MAX_ALIGN);
99
+   data_size1 = SPA_ROUND_UP(RANDOM_SIZE * sizeof(uint32_t), FMT_OPS_MAX_ALIGN);
100
+   data_size2 = SPA_ROUND_UP(RANDOM_SIZE * sizeof(int32_t), FMT_OPS_MAX_ALIGN);
101
+
102
+   conv->data = calloc(FMT_OPS_MAX_ALIGN +
103
+           data_size0 + data_size1 + data_size2, 1);
104
+   if (conv->data == NULL)
105
        return -errno;
106
 
107
-   for (i = 0; i < SPA_N_ELEMENTS(conv->random); i++)
108
+   conv->noise = SPA_PTR_ALIGN(conv->data, FMT_OPS_MAX_ALIGN, float);
109
+   conv->random = SPA_PTROFF(conv->noise, data_size0, uint32_t);
110
+   conv->prev = SPA_PTROFF(conv->random, data_size1, int32_t);
111
+
112
+   for (i = 0; i < RANDOM_SIZE; i++)
113
        conv->randomi = random();
114
 
115
    conv->is_passthrough = conv->src_fmt == conv->dst_fmt;
116
    conv->cpu_flags = info->cpu_flags;
117
+   conv->update_noise = ninfo->noise;
118
    conv->process = info->process;
119
    conv->free = impl_convert_free;
120
    conv->func_name = info->name;
121
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
58
 
1
@@ -226,8 +226,8 @@
2
    unsigned int is_passthrough:1;
3
 
4
    float scale;
5
-   uint32_t random16 + FMT_OPS_MAX_ALIGN/4;
6
-   int32_t prev16 + FMT_OPS_MAX_ALIGN/4;
7
+   uint32_t *random;
8
+   int32_t *prev;
9
 #define NOISE_METHOD_NONE      0
10
 #define NOISE_METHOD_RECTANGULAR   1
11
 #define NOISE_METHOD_TRIANGULAR        2
12
@@ -240,9 +240,12 @@
13
    uint32_t n_ns;
14
    struct shaper shaper64;
15
 
16
+   void (*update_noise) (struct convert *conv, float *noise, uint32_t n_samples);
17
    void (*process) (struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
18
            uint32_t n_samples);
19
    void (*free) (struct convert *conv);
20
+
21
+   void *data;
22
 };
23
 
24
 int convert_init(struct convert *conv);
25
@@ -276,12 +279,30 @@
26
    return DITHER_METHOD_NONE;
27
 }
28
 
29
+#define convert_update_noise(conv,...) (conv)->update_noise(conv, __VA_ARGS__)
30
 #define convert_process(conv,...)  (conv)->process(conv, __VA_ARGS__)
31
 #define convert_free(conv)     (conv)->free(conv)
32
 
33
-#define DEFINE_FUNCTION(name,arch) \
34
+#define DEFINE_NOISE_FUNCTION(name,arch)               \
35
+void conv_noise_##name##_##arch(struct convert *conv, float *noise,    \
36
+                   uint32_t n_samples)
37
+
38
+DEFINE_NOISE_FUNCTION(none, c);
39
+DEFINE_NOISE_FUNCTION(rect, c);
40
+DEFINE_NOISE_FUNCTION(tri, c);
41
+DEFINE_NOISE_FUNCTION(tri_hf, c);
42
+DEFINE_NOISE_FUNCTION(pattern, c);
43
+#if defined(HAVE_SSE2)
44
+DEFINE_NOISE_FUNCTION(rect, sse2);
45
+DEFINE_NOISE_FUNCTION(tri, sse2);
46
+DEFINE_NOISE_FUNCTION(tri_hf, sse2);
47
+#endif
48
+
49
+#undef DEFINE_NOISE_FUNCTION
50
+
51
+#define DEFINE_FUNCTION(name,arch)                     \
52
 void conv_##name##_##arch(struct convert *conv, void * SPA_RESTRICT dst,   \
53
-       const void * SPA_RESTRICT src, uint32_t n_samples)      \
54
+       const void * SPA_RESTRICT src, uint32_t n_samples)
55
 
56
 DEFINE_FUNCTION(copy8d, c);
57
 DEFINE_FUNCTION(copy8, c);
58
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/meson.build -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/meson.build Changed
37
 
1
@@ -12,8 +12,8 @@
2
     'biquad.c',
3
     'crossover.c',
4
     'volume-ops-c.c',
5
+    'peaks-ops-c.c',
6
     'resample-native-c.c',
7
-    'resample-peaks-c.c',
8
     'fmt-ops-c.c' ,
9
   c_args : '-Ofast', '-ffast-math',
10
   dependencies :  spa_dep ,
11
@@ -24,8 +24,8 @@
12
 if have_sse
13
   audioconvert_sse = static_library('audioconvert_sse',
14
     'resample-native-sse.c',
15
-      'resample-peaks-sse.c',
16
       'volume-ops-sse.c',
17
+      'peaks-ops-sse.c',
18
       'channelmix-ops-sse.c' ,
19
     c_args : sse_args, '-Ofast', '-DHAVE_SSE',
20
     dependencies :  spa_dep ,
21
@@ -101,6 +101,7 @@
22
 audioconvert_lib = static_library('audioconvert',
23
   'fmt-ops.c',
24
     'channelmix-ops.c',
25
+    'peaks-ops.c',
26
     'resample-native.c',
27
     'resample-peaks.c',
28
     'volume-ops.c' ,
29
@@ -132,6 +133,7 @@
30
   'test-audioconvert',
31
   'test-channelmix',
32
   'test-fmt-ops',
33
+  'test-peaks',
34
   'test-resample',
35
   
36
 
37
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops-c.c Added
52
 
1
@@ -0,0 +1,50 @@
2
+/* Spa
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <math.h>
27
+
28
+#include "peaks-ops.h"
29
+
30
+void peaks_min_max_c(struct peaks *peaks, const float * SPA_RESTRICT src,
31
+       uint32_t n_samples, float *min, float *max)
32
+{
33
+   uint32_t n;
34
+   float t, mi = *min, ma = *max;
35
+   for (n = 0; n < n_samples; n++) {
36
+       t = srcn;
37
+       mi = fminf(mi, t);
38
+       ma = fmaxf(ma, t);
39
+   }
40
+   *min = mi;
41
+   *max = ma;
42
+}
43
+
44
+float peaks_abs_max_c(struct peaks *peaks, const float * SPA_RESTRICT src,
45
+       uint32_t n_samples, float max)
46
+{
47
+   uint32_t n;
48
+   for (n = 0; n < n_samples; n++)
49
+       max = fmaxf(fabsf(srcn), max);
50
+   return max;
51
+}
52
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops-sse.c Added
124
 
1
@@ -0,0 +1,122 @@
2
+/* Spa
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <math.h>
27
+
28
+#include <xmmintrin.h>
29
+
30
+#include "peaks-ops.h"
31
+
32
+static inline float hmin_ps(__m128 val)
33
+{
34
+   __m128 t = _mm_movehl_ps(val, val);
35
+   t = _mm_min_ps(t, val);
36
+   val = _mm_shuffle_ps(t, t, 0x55);
37
+   val = _mm_min_ss(t, val);
38
+   return _mm_cvtss_f32(val);
39
+}
40
+
41
+static inline float hmax_ps(__m128 val)
42
+{
43
+   __m128 t = _mm_movehl_ps(val, val);
44
+   t = _mm_max_ps(t, val);
45
+   val = _mm_shuffle_ps(t, t, 0x55);
46
+   val = _mm_max_ss(t, val);
47
+   return _mm_cvtss_f32(val);
48
+}
49
+
50
+void peaks_min_max_sse(struct peaks *peaks, const float * SPA_RESTRICT src,
51
+       uint32_t n_samples, float *min, float *max)
52
+{
53
+   uint32_t n;
54
+   __m128 in;
55
+   __m128 mi = _mm_set1_ps(*min);
56
+   __m128 ma = _mm_set1_ps(*max);
57
+
58
+   for (n = 0; n < n_samples; n++) {
59
+       if (SPA_IS_ALIGNED(&srcn, 16))
60
+           break;
61
+       in = _mm_set1_ps(srcn);
62
+       mi = _mm_min_ps(mi, in);
63
+       ma = _mm_max_ps(ma, in);
64
+   }
65
+   for (; n + 15 < n_samples; n += 16) {
66
+       in = _mm_load_ps(&srcn + 0);
67
+       mi = _mm_min_ps(mi, in);
68
+       ma = _mm_max_ps(ma, in);
69
+       in = _mm_load_ps(&srcn + 4);
70
+       mi = _mm_min_ps(mi, in);
71
+       ma = _mm_max_ps(ma, in);
72
+       in = _mm_load_ps(&srcn + 8);
73
+       mi = _mm_min_ps(mi, in);
74
+       ma = _mm_max_ps(ma, in);
75
+       in = _mm_load_ps(&srcn + 12);
76
+       mi = _mm_min_ps(mi, in);
77
+       ma = _mm_max_ps(ma, in);
78
+   }
79
+   for (; n < n_samples; n++) {
80
+       in = _mm_set1_ps(srcn);
81
+       mi = _mm_min_ps(mi, in);
82
+       ma = _mm_max_ps(ma, in);
83
+   }
84
+   *min = hmin_ps(mi);
85
+   *max = hmax_ps(ma);
86
+}
87
+
88
+float peaks_abs_max_sse(struct peaks *peaks, const float * SPA_RESTRICT src,
89
+       uint32_t n_samples, float max)
90
+{
91
+   uint32_t n;
92
+   __m128 in;
93
+   __m128 ma = _mm_set1_ps(max);
94
+   const __m128 mask = _mm_set1_ps(-0.0f);
95
+
96
+   for (n = 0; n < n_samples; n++) {
97
+       if (SPA_IS_ALIGNED(&srcn, 16))
98
+           break;
99
+       in = _mm_set1_ps(srcn);
100
+       in = _mm_andnot_ps(mask, in);
101
+       ma = _mm_max_ps(ma, in);
102
+   }
103
+   for (; n + 15 < n_samples; n += 16) {
104
+       in = _mm_load_ps(&srcn + 0);
105
+       in = _mm_andnot_ps(mask, in);
106
+       ma = _mm_max_ps(ma, in);
107
+       in = _mm_load_ps(&srcn + 4);
108
+       in = _mm_andnot_ps(mask, in);
109
+       ma = _mm_max_ps(ma, in);
110
+       in = _mm_load_ps(&srcn + 8);
111
+       in = _mm_andnot_ps(mask, in);
112
+       ma = _mm_max_ps(ma, in);
113
+       in = _mm_load_ps(&srcn + 12);
114
+       in = _mm_andnot_ps(mask, in);
115
+       ma = _mm_max_ps(ma, in);
116
+   }
117
+   for (; n < n_samples; n++) {
118
+       in = _mm_set1_ps(srcn);
119
+       in = _mm_andnot_ps(mask, in);
120
+       ma = _mm_max_ps(ma, in);
121
+   }
122
+   return hmax_ps(ma);
123
+}
124
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops.c Added
93
 
1
@@ -0,0 +1,91 @@
2
+/* Spa
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <string.h>
27
+#include <stdio.h>
28
+#include <math.h>
29
+#include <errno.h>
30
+
31
+#include <spa/support/cpu.h>
32
+#include <spa/support/log.h>
33
+#include <spa/utils/defs.h>
34
+
35
+#include "peaks-ops.h"
36
+
37
+typedef void (*peaks_min_max_func_t) (struct peaks *peaks, const float * SPA_RESTRICT src,
38
+       uint32_t n_samples, float *min, float *max);
39
+typedef float (*peaks_abs_max_func_t) (struct peaks *peaks, const float * SPA_RESTRICT src,
40
+           uint32_t n_samples, float max);
41
+
42
+#define MAKE(min_max,abs_max,...) \
43
+   { min_max, abs_max, #min_max , __VA_ARGS__ }
44
+
45
+static const struct peaks_info {
46
+   peaks_min_max_func_t min_max;
47
+   peaks_abs_max_func_t abs_max;
48
+   const char *name;
49
+   uint32_t cpu_flags;
50
+} peaks_table =
51
+{
52
+#if defined (HAVE_SSE)
53
+   MAKE(peaks_min_max_sse, peaks_abs_max_sse, SPA_CPU_FLAG_SSE),
54
+#endif
55
+   MAKE(peaks_min_max_c, peaks_abs_max_c),
56
+};
57
+#undef MAKE
58
+
59
+#define MATCH_CPU_FLAGS(a,b)   ((a) == 0 || ((a) & (b)) == a)
60
+
61
+static const struct peaks_info *find_peaks_info(uint32_t cpu_flags)
62
+{
63
+   size_t i;
64
+   for (i = 0; i < SPA_N_ELEMENTS(peaks_table); i++) {
65
+       if (!MATCH_CPU_FLAGS(peaks_tablei.cpu_flags, cpu_flags))
66
+           continue;
67
+       return &peaks_tablei;
68
+   }
69
+   return NULL;
70
+}
71
+
72
+static void impl_peaks_free(struct peaks *peaks)
73
+{
74
+   peaks->min_max = NULL;
75
+   peaks->abs_max = NULL;
76
+}
77
+
78
+int peaks_init(struct peaks *peaks)
79
+{
80
+   const struct peaks_info *info;
81
+
82
+   info = find_peaks_info(peaks->cpu_flags);
83
+   if (info == NULL)
84
+       return -ENOTSUP;
85
+
86
+   peaks->cpu_flags = info->cpu_flags;
87
+   peaks->func_name = info->name;
88
+   peaks->free = impl_peaks_free;
89
+   peaks->min_max = info->min_max;
90
+   peaks->abs_max = info->abs_max;
91
+   return 0;
92
+}
93
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops.h Added
74
 
1
@@ -0,0 +1,72 @@
2
+/* Spa
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <string.h>
27
+#include <stdio.h>
28
+
29
+#include <spa/utils/defs.h>
30
+
31
+struct peaks {
32
+   uint32_t cpu_flags;
33
+   const char *func_name;
34
+
35
+   struct spa_log *log;
36
+
37
+   uint32_t flags;
38
+
39
+   void (*min_max) (struct peaks *peaks, const float * SPA_RESTRICT src,
40
+       uint32_t n_samples, float *min, float *max);
41
+   float (*abs_max) (struct peaks *peaks, const float * SPA_RESTRICT src,
42
+           uint32_t n_samples, float max);
43
+
44
+   void (*free) (struct peaks *peaks);
45
+};
46
+
47
+int peaks_init(struct peaks *peaks);
48
+
49
+#define peaks_min_max(peaks,...)   (peaks)->min_max(peaks, __VA_ARGS__)
50
+#define peaks_abs_max(peaks,...)   (peaks)->abs_max(peaks, __VA_ARGS__)
51
+#define peaks_free(peaks)      (peaks)->free(peaks)
52
+
53
+#define DEFINE_MIN_MAX_FUNCTION(arch)              \
54
+void peaks_min_max_##arch(struct peaks *peaks,         \
55
+       const float * SPA_RESTRICT src,         \
56
+       uint32_t n_samples, float *min, float *max);
57
+
58
+#define DEFINE_ABS_MAX_FUNCTION(arch)              \
59
+float peaks_abs_max_##arch(struct peaks *peaks,            \
60
+       const float * SPA_RESTRICT src,         \
61
+       uint32_t n_samples, float max);
62
+
63
+#define PEAKS_OPS_MAX_ALIGN    16
64
+
65
+DEFINE_MIN_MAX_FUNCTION(c);
66
+DEFINE_ABS_MAX_FUNCTION(c);
67
+
68
+#if defined (HAVE_SSE)
69
+DEFINE_MIN_MAX_FUNCTION(sse);
70
+DEFINE_ABS_MAX_FUNCTION(sse);
71
+#endif
72
+
73
+#undef DEFINE_FUNCTION
74
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
13
 
1
@@ -304,7 +304,10 @@
2
    if (d == NULL)
3
        return;
4
    memset(d->hist_mem, 0, r->channels * sizeof(float) * d->n_taps * 2);
5
-   d->hist = (d->n_taps / 2) - 1;
6
+   if (r->options & RESAMPLE_OPTION_PREFILL)
7
+       d->hist = d->n_taps - 1;
8
+   else
9
+       d->hist = (d->n_taps / 2) - 1;
10
    d->phase = 0;
11
 }
12
 
13
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
139
 
1
@@ -27,40 +27,70 @@
2
 
3
 #include <spa/param/audio/format.h>
4
 
5
-#include "resample-peaks-impl.h"
6
-
7
-struct resample_info {
8
-   uint32_t format;
9
-   uint32_t cpu_flags;
10
-   void (*process) (struct resample *r,
11
-           const void * SPA_RESTRICT src, uint32_t *in_len,
12
-           void * SPA_RESTRICT dst, uint32_t *out_len);
13
+#include "peaks-ops.h"
14
+#include "resample.h"
15
+
16
+struct peaks_data {
17
+   uint32_t o_count;
18
+   uint32_t i_count;
19
+   struct peaks peaks;
20
+   float max_f;
21
 };
22
 
23
-static struct resample_info resample_table =
24
+static void resample_peaks_process(struct resample *r,
25
+   const void * SPA_RESTRICT src, uint32_t *in_len,
26
+   void * SPA_RESTRICT dst, uint32_t *out_len)
27
 {
28
-#if defined (HAVE_SSE)
29
-   { SPA_AUDIO_FORMAT_F32, SPA_CPU_FLAG_SSE, resample_peaks_process_sse, },
30
-#endif
31
-   { SPA_AUDIO_FORMAT_F32, 0, resample_peaks_process_c, },
32
-};
33
+   struct peaks_data *pd = r->data;
34
+   uint32_t c, i, o, end, chunk, i_count, o_count;
35
 
36
-#define MATCH_CPU_FLAGS(a,b)   ((a) == 0 || ((a) & (b)) == a)
37
-static const struct resample_info *find_resample_info(uint32_t format, uint32_t cpu_flags)
38
-{
39
-   size_t i;
40
-   for (i = 0; i < SPA_N_ELEMENTS(resample_table); i++) {
41
-       if (resample_tablei.format == format &&
42
-           MATCH_CPU_FLAGS(resample_tablei.cpu_flags, cpu_flags)) {
43
-           return &resample_tablei;
44
+   if (SPA_UNLIKELY(r->channels == 0))
45
+       return;
46
+
47
+   for (c = 0; c < r->channels; c++) {
48
+       const float *s = srcc;
49
+       float *d = dstc, m = pd->max_fc;
50
+
51
+       o_count = pd->o_count;
52
+       i_count = pd->i_count;
53
+       o = i = 0;
54
+
55
+       while (i < *in_len && o < *out_len) {
56
+           end = ((uint64_t) (o_count + 1)
57
+               * r->i_rate) / r->o_rate;
58
+           end = end > i_count ? end - i_count : 0;
59
+           chunk = SPA_MIN(end, *in_len);
60
+
61
+           m = peaks_abs_max(&pd->peaks, &si, chunk - i, m);
62
+
63
+           i += chunk;
64
+
65
+           if (i == end) {
66
+               do++ = m;
67
+               m = 0.0f;
68
+               o_count++;
69
+           }
70
        }
71
+       pd->max_fc = m;
72
+   }
73
+   *out_len = o;
74
+   *in_len = i;
75
+   pd->o_count = o_count;
76
+   pd->i_count = i_count + i;
77
+
78
+   while (pd->i_count >= r->i_rate) {
79
+       pd->i_count -= r->i_rate;
80
+       pd->o_count -= r->o_rate;
81
    }
82
-   return NULL;
83
 }
84
 
85
 static void impl_peaks_free(struct resample *r)
86
 {
87
-   free(r->data);
88
+   struct peaks_data *d = r->data;
89
+   if (d != NULL) {
90
+       peaks_free(&d->peaks);
91
+       free(d);
92
+   }
93
    r->data = NULL;
94
 }
95
 
96
@@ -87,27 +117,32 @@
97
 int resample_peaks_init(struct resample *r)
98
 {
99
    struct peaks_data *d;
100
-   const struct resample_info *info;
101
+   int res;
102
 
103
    r->free = impl_peaks_free;
104
    r->update_rate = impl_peaks_update_rate;
105
 
106
-   if ((info = find_resample_info(SPA_AUDIO_FORMAT_F32, r->cpu_flags)) == NULL)
107
-       return -ENOTSUP;
108
+   d = calloc(1, sizeof(struct peaks_data) + sizeof(float) * r->channels);
109
+   if (d == NULL)
110
+       return -errno;
111
+
112
+   d->peaks.log = r->log;
113
+   d->peaks.cpu_flags = r->cpu_flags;
114
+   if ((res = peaks_init(&d->peaks)) < 0) {
115
+       free(d);
116
+       return res;
117
+   }
118
 
119
-   r->process = info->process;
120
+   r->data = d;
121
+   r->process = resample_peaks_process;
122
    r->reset = impl_peaks_reset;
123
    r->delay = impl_peaks_delay;
124
    r->in_len = impl_peaks_in_len;
125
 
126
-   d = r->data = calloc(1, sizeof(struct peaks_data) + sizeof(float) * r->channels);
127
-   if (r->data == NULL)
128
-       return -errno;
129
-
130
    spa_log_debug(r->log, "peaks %p: in:%d out:%d features:%08x:%08x", r,
131
-           r->i_rate, r->o_rate, r->cpu_flags, info->cpu_flags);
132
+           r->i_rate, r->o_rate, r->cpu_flags, d->peaks.cpu_flags);
133
 
134
-   r->cpu_flags = info->cpu_flags;
135
+   r->cpu_flags = d->peaks.cpu_flags;
136
    d->i_count = d->o_count = 0;
137
    return 0;
138
 }
139
pipewire-0.3.58.tar.gz/spa/plugins/audioconvert/resample.h -> pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/resample.h Changed
10
 
1
@@ -32,6 +32,8 @@
2
 
3
 struct resample {
4
    struct spa_log *log;
5
+#define RESAMPLE_OPTION_PREFILL        (1<<0)
6
+   uint32_t options;
7
    uint32_t cpu_flags;
8
    const char *func_name;
9
 
10
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
145
 
1
@@ -22,6 +22,8 @@
2
  * DEALINGS IN THE SOFTWARE.
3
  */
4
 
5
+#include "config.h"
6
+
7
 #include <string.h>
8
 #include <stdio.h>
9
 #include <stdlib.h>
10
@@ -32,20 +34,26 @@
11
 #include <spa/support/log-impl.h>
12
 #include <spa/debug/mem.h>
13
 
14
+static uint32_t cpu_flags;
15
+
16
 SPA_LOG_IMPL(logger);
17
 
18
 #define MATRIX(...) (float) { __VA_ARGS__ }
19
 
20
+#include "test-helper.h"
21
 #include "channelmix-ops.c"
22
+
23
+#define CLOSE_ENOUGH(a,b)  (fabs((a)-(b)) < 0.000001f)
24
+
25
 static void dump_matrix(struct channelmix *mix, float *coeff)
26
 {
27
    uint32_t i, j;
28
 
29
    for (i = 0; i < mix->dst_chan; i++) {
30
        for (j = 0; j < mix->src_chan; j++) {
31
-           float v = mix->matrix_origij;
32
+           float v = mix->matrixij;
33
            spa_log_debug(mix->log, "%d %d: %f <-> %f", i, j, v, *coeff);
34
-           spa_assert_se(fabs(v - *coeff) < 0.000001);
35
+           spa_assert_se(CLOSE_ENOUGH(v, *coeff));
36
            coeff++;
37
        }
38
    }
39
@@ -65,7 +73,8 @@
40
    mix.dst_mask = dst_mask;
41
    mix.log = &logger.log;
42
 
43
-   channelmix_init(&mix);
44
+   spa_assert_se(channelmix_init(&mix) == 0);
45
+   channelmix_set_volume(&mix, 1.0f, false, 0, NULL);
46
    dump_matrix(&mix, coeff);
47
 }
48
 
49
@@ -220,10 +229,87 @@
50
                   0.0, 1.0, 0.707107, 0.0, 0.0, 0.707107, 0.0, 0.707107));
51
 }
52
 
53
+static void run_n_m_impl(struct channelmix *mix, const void **src, uint32_t n_samples)
54
+{
55
+   uint32_t dst_chan = mix->dst_chan, i, j;
56
+   float dst_c_datadst_chann_samples;
57
+   float dst_x_datadst_chann_samples;
58
+   void *dst_cdst_chan, *dst_xdst_chan;
59
+
60
+   for (i = 0; i < dst_chan; i++) {
61
+       dst_ci = dst_c_datai;
62
+       dst_xi = dst_x_datai;
63
+   }
64
+
65
+   channelmix_f32_n_m_c(mix, dst_c, src, n_samples);
66
+
67
+#if defined(HAVE_SSE)
68
+   if (cpu_flags & SPA_CPU_FLAG_SSE) {
69
+       channelmix_f32_n_m_sse(mix, dst_x, src, n_samples);
70
+       for (i = 0; i < mix->dst_chan; i++) {
71
+           for (j = 0; j < n_samples; j++) {
72
+               spa_assert_se(CLOSE_ENOUGH(dst_c_dataij, dst_x_dataij));
73
+           }
74
+       }
75
+   }
76
+#endif
77
+}
78
+
79
+static void test_n_m_impl(void)
80
+{
81
+   struct channelmix mix;
82
+   unsigned int i, j;
83
+#define N_SAMPLES  251
84
+   float src_data16N_SAMPLES, *src16;
85
+
86
+   spa_log_debug(&logger.log, "start");
87
+
88
+   for (i = 0; i < 16; i++) {
89
+       for (j = 0; j < N_SAMPLES; j++)
90
+           src_dataij = (drand48() - 0.5f) * 2.5f;
91
+       srci = src_datai;
92
+   }
93
+
94
+   spa_zero(mix);
95
+   mix.src_chan = 16;
96
+   mix.dst_chan = 12;
97
+   mix.log = &logger.log;
98
+   mix.cpu_flags = cpu_flags;
99
+   spa_assert_se(channelmix_init(&mix) == 0);
100
+   channelmix_set_volume(&mix, 1.0f, false, 0, NULL);
101
+
102
+   /* identity matrix */
103
+   run_n_m_impl(&mix, (const void**)src, N_SAMPLES);
104
+
105
+   /* some zero destination */
106
+   mix.matrix_orig22 = 0.0f;
107
+   mix.matrix_orig77 = 0.0f;
108
+   channelmix_set_volume(&mix, 1.0f, false, 0, NULL);
109
+   run_n_m_impl(&mix, (const void**)src, N_SAMPLES);
110
+
111
+   /* random matrix */
112
+   for (i = 0; i < mix.dst_chan; i++) {
113
+       for (j = 0; j < mix.src_chan; j++) {
114
+           mix.matrix_origij = drand48() - 0.5f;
115
+       }
116
+   }
117
+   channelmix_set_volume(&mix, 1.0f, false, 0, NULL);
118
+
119
+   run_n_m_impl(&mix, (const void**)src, N_SAMPLES);
120
+}
121
+
122
 int main(int argc, char *argv)
123
 {
124
+   struct timespec ts;
125
+
126
+   clock_gettime(CLOCK_MONOTONIC, &ts);
127
+   srand48(SPA_TIMESPEC_TO_NSEC(&ts));
128
+
129
    logger.log.level = SPA_LOG_LEVEL_TRACE;
130
 
131
+   cpu_flags = get_cpu_flags();
132
+   printf("got CPU flags %d\n", cpu_flags);
133
+
134
    test_1_N_MONO();
135
    test_1_N_FC();
136
    test_N_1();
137
@@ -232,5 +318,7 @@
138
    test_5p1_N();
139
    test_7p1_N();
140
 
141
+   test_n_m_impl();
142
+
143
    return 0;
144
 }
145
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-peaks.c Added
130
 
1
@@ -0,0 +1,128 @@
2
+/* Spa
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include "config.h"
27
+
28
+#include <string.h>
29
+#include <stdio.h>
30
+#include <stdlib.h>
31
+#include <unistd.h>
32
+#include <errno.h>
33
+#include <time.h>
34
+
35
+#include <spa/support/log-impl.h>
36
+#include <spa/debug/mem.h>
37
+
38
+SPA_LOG_IMPL(logger);
39
+
40
+static uint32_t cpu_flags;
41
+
42
+#include "test-helper.h"
43
+
44
+#include "peaks-ops.c"
45
+
46
+static void test_impl(void)
47
+{
48
+   struct peaks peaks;
49
+   unsigned int i;
50
+   float vals1038;
51
+   float min2 = { 0.0f, 0.0f }, max2 = { 0.0f, 0.0f }, absmax2 = { 0.0f, 0.0f };
52
+
53
+   for (i = 0; i < SPA_N_ELEMENTS(vals); i++)
54
+       valsi = (drand48() - 0.5f) * 2.5f;
55
+
56
+   peaks_min_max_c(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, &min0, &max0);
57
+   printf("c peaks min:%f max:%f\n", min0, max0);
58
+
59
+   absmax0 = peaks_abs_max_c(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, 0.0f);
60
+   printf("c peaks abs-max:%f\n", absmax0);
61
+
62
+#if defined(HAVE_SSE)
63
+   if (cpu_flags & SPA_CPU_FLAG_SSE) {
64
+       peaks_min_max_sse(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, &min1, &max1);
65
+       printf("sse peaks min:%f max:%f\n", min1, max1);
66
+
67
+       absmax1 = peaks_abs_max_sse(&peaks, &vals1, SPA_N_ELEMENTS(vals) - 1, 0.0f);
68
+       printf("sse peaks abs-max:%f\n", absmax1);
69
+
70
+       spa_assert(min0 == min1);
71
+       spa_assert(max0 == max1);
72
+       spa_assert(absmax0 == absmax1);
73
+   }
74
+#endif
75
+
76
+}
77
+
78
+static void test_min_max(void)
79
+{
80
+   struct peaks peaks;
81
+   const float vals = { 0.0f, 0.5f, -0.5f, 0.0f, 0.6f, -0.8f, -0.5f, 0.0f };
82
+   float min = 0.0f, max = 0.0f;
83
+
84
+   spa_zero(peaks);
85
+   peaks.log = &logger.log;
86
+   peaks.cpu_flags = cpu_flags;
87
+   peaks_init(&peaks);
88
+
89
+   peaks_min_max(&peaks, vals, SPA_N_ELEMENTS(vals), &min, &max);
90
+
91
+   spa_assert(min == -0.8f);
92
+   spa_assert(max == 0.6f);
93
+}
94
+
95
+static void test_abs_max(void)
96
+{
97
+   struct peaks peaks;
98
+   const float vals = { 0.0f, 0.5f, -0.5f, 0.0f, 0.6f, -0.8f, -0.5f, 0.0f };
99
+   float max = 0.0f;
100
+
101
+   spa_zero(peaks);
102
+   peaks.log = &logger.log;
103
+   peaks.cpu_flags = cpu_flags;
104
+   peaks_init(&peaks);
105
+
106
+   max = peaks_abs_max(&peaks, vals, SPA_N_ELEMENTS(vals), max);
107
+
108
+   spa_assert(max == 0.8f);
109
+}
110
+
111
+int main(int argc, char *argv)
112
+{
113
+   struct timespec ts;
114
+
115
+   clock_gettime(CLOCK_MONOTONIC, &ts);
116
+   srand48(SPA_TIMESPEC_TO_NSEC(&ts));
117
+
118
+   logger.log.level = SPA_LOG_LEVEL_TRACE;
119
+
120
+   cpu_flags = get_cpu_flags();
121
+   printf("got CPU flags %d\n", cpu_flags);
122
+
123
+   test_impl();
124
+
125
+   test_min_max();
126
+   test_abs_max();
127
+
128
+   return 0;
129
+}
130
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
10
 
1
@@ -877,7 +877,7 @@
2
        SPA_AVBTP_PACKET_AAF_SET_SEQ_NUM(pdu, state->pdu_seq++);
3
        SPA_AVBTP_PACKET_AAF_SET_TIMESTAMP(pdu, ptime);
4
 
5
-       n = sendmsg(state->sockfd, &state->msg, 0);
6
+       n = sendmsg(state->sockfd, &state->msg, MSG_NOSIGNAL);
7
        if (n < 0 || n != (ssize_t)state->pdu_size) {
8
            spa_log_error(state->log, "sendmdg() failed: %m");
9
        }
10
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
121
 
1
@@ -34,7 +34,7 @@
2
 #include <fdk-aac/aacdecoder_lib.h>
3
 
4
 #include "rtp.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 static struct spa_log *log;
9
 static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.aac");
10
@@ -65,7 +65,7 @@
11
    int samplesize;
12
 };
13
 
14
-static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags,
15
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
16
        uint8_t capsA2DP_MAX_CAPS_SIZE)
17
 {
18
    static const a2dp_aac_t a2dp_aac = {
19
@@ -98,7 +98,7 @@
20
    return sizeof(a2dp_aac);
21
 }
22
 
23
-static const struct a2dp_codec_config
24
+static const struct media_codec_config
25
 aac_frequencies = {
26
    { AAC_SAMPLING_FREQ_48000, 48000, 11 },
27
    { AAC_SAMPLING_FREQ_44100, 44100, 10 },
28
@@ -114,7 +114,7 @@
29
    { AAC_SAMPLING_FREQ_8000,  8000,  0 },
30
 };
31
 
32
-static const struct a2dp_codec_config
33
+static const struct media_codec_config
34
 aac_channel_modes = {
35
    { AAC_CHANNELS_2, 2, 1 },
36
    { AAC_CHANNELS_1, 1, 0 },
37
@@ -130,9 +130,9 @@
38
    }
39
 }
40
 
41
-static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags,
42
+static int codec_select_config(const struct media_codec *codec, uint32_t flags,
43
        const void *caps, size_t caps_size,
44
-       const struct a2dp_codec_audio_info *info,
45
+       const struct media_codec_audio_info *info,
46
        const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE)
47
 {
48
    a2dp_aac_t conf;
49
@@ -154,7 +154,7 @@
50
    else
51
        return -ENOTSUP;
52
 
53
-   if ((i = a2dp_codec_select_config(aac_frequencies,
54
+   if ((i = media_codec_select_config(aac_frequencies,
55
                      SPA_N_ELEMENTS(aac_frequencies),
56
                      AAC_GET_FREQUENCY(conf),
57
                          info ? info->rate : A2DP_CODEC_DEFAULT_RATE
58
@@ -162,7 +162,7 @@
59
        return -ENOTSUP;
60
    AAC_SET_FREQUENCY(conf, aac_frequenciesi.config);
61
 
62
-   if ((i = a2dp_codec_select_config(aac_channel_modes,
63
+   if ((i = media_codec_select_config(aac_channel_modes,
64
                      SPA_N_ELEMENTS(aac_channel_modes),
65
                      conf.channels,
66
                          info ? info->channels : A2DP_CODEC_DEFAULT_CHANNELS
67
@@ -177,7 +177,7 @@
68
    return sizeof(conf);
69
 }
70
 
71
-static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
72
+static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
73
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
74
        struct spa_pod_builder *b, struct spa_pod **param)
75
 {
76
@@ -246,7 +246,7 @@
77
    return *param == NULL ? -EIO : 1;
78
 }
79
 
80
-static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags,
81
+static int codec_validate_config(const struct media_codec *codec, uint32_t flags,
82
            const void *caps, size_t caps_size,
83
            struct spa_audio_info *info)
84
 {
85
@@ -296,7 +296,7 @@
86
    return 0;
87
 }
88
 
89
-static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings)
90
+static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings)
91
 {
92
    struct props *p = calloc(1, sizeof(struct props));
93
    const char *str;
94
@@ -316,7 +316,7 @@
95
    free(props);
96
 }
97
 
98
-static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
99
+static void *codec_init(const struct media_codec *codec, uint32_t flags,
100
        void *config, size_t config_len, const struct spa_audio_info *info,
101
        void *props, size_t mtu)
102
 {
103
@@ -630,7 +630,7 @@
104
    spa_log_topic_init(log, &log_topic);
105
 }
106
 
107
-const struct a2dp_codec a2dp_codec_aac = {
108
+const struct media_codec a2dp_codec_aac = {
109
    .id = SPA_BLUETOOTH_AUDIO_CODEC_AAC,
110
    .codec_id = A2DP_CODEC_MPEG24,
111
    .name = "aac",
112
@@ -654,7 +654,7 @@
113
    .set_log = codec_set_log,
114
 };
115
 
116
-A2DP_CODEC_EXPORT_DEF(
117
+MEDIA_CODEC_EXPORT_DEF(
118
    "aac",
119
    &a2dp_codec_aac
120
 );
121
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
201
 
1
@@ -35,7 +35,7 @@
2
 #include <freeaptx.h>
3
 
4
 #include "rtp.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 #define APTX_LL_LEVEL1(level) (((level) >> 8) & 0xFF)
9
 #define APTX_LL_LEVEL2(level) (((level) >> 0) & 0xFF)
10
@@ -71,19 +71,19 @@
11
    sbc_t msbc;
12
 };
13
 
14
-static inline bool codec_is_hd(const struct a2dp_codec *codec)
15
+static inline bool codec_is_hd(const struct media_codec *codec)
16
 {
17
    return codec->vendor.codec_id == APTX_HD_CODEC_ID
18
        && codec->vendor.vendor_id == APTX_HD_VENDOR_ID;
19
 }
20
 
21
-static inline bool codec_is_ll(const struct a2dp_codec *codec)
22
+static inline bool codec_is_ll(const struct media_codec *codec)
23
 {
24
    return (codec->id == SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL) ||
25
        (codec->id == SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX);
26
 }
27
 
28
-static inline size_t codec_get_caps_size(const struct a2dp_codec *codec)
29
+static inline size_t codec_get_caps_size(const struct media_codec *codec)
30
 {
31
    if (codec_is_hd(codec))
32
        return sizeof(a2dp_aptx_hd_t);
33
@@ -93,7 +93,7 @@
34
        return sizeof(a2dp_aptx_t);
35
 }
36
 
37
-static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags,
38
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
39
        uint8_t capsA2DP_MAX_CAPS_SIZE)
40
 {
41
    size_t actual_conf_size = codec_get_caps_size(codec);
42
@@ -119,7 +119,7 @@
43
    return actual_conf_size;
44
 }
45
 
46
-static const struct a2dp_codec_config
47
+static const struct media_codec_config
48
 aptx_frequencies = {
49
    { APTX_SAMPLING_FREQ_48000, 48000, 3 },
50
    { APTX_SAMPLING_FREQ_44100, 44100, 2 },
51
@@ -127,9 +127,9 @@
52
    { APTX_SAMPLING_FREQ_16000, 16000, 0 },
53
 };
54
 
55
-static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags,
56
+static int codec_select_config(const struct media_codec *codec, uint32_t flags,
57
        const void *caps, size_t caps_size,
58
-       const struct a2dp_codec_audio_info *info,
59
+       const struct media_codec_audio_info *info,
60
        const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE)
61
 {
62
    a2dp_aptx_t conf;
63
@@ -145,7 +145,7 @@
64
        codec->vendor.codec_id != conf.info.codec_id)
65
        return -ENOTSUP;
66
 
67
-   if ((i = a2dp_codec_select_config(aptx_frequencies,
68
+   if ((i = media_codec_select_config(aptx_frequencies,
69
                      SPA_N_ELEMENTS(aptx_frequencies),
70
                      conf.frequency,
71
                          info ? info->rate : A2DP_CODEC_DEFAULT_RATE
72
@@ -163,9 +163,9 @@
73
    return actual_conf_size;
74
 }
75
 
76
-static int codec_select_config_ll(const struct a2dp_codec *codec, uint32_t flags,
77
+static int codec_select_config_ll(const struct media_codec *codec, uint32_t flags,
78
        const void *caps, size_t caps_size,
79
-       const struct a2dp_codec_audio_info *info,
80
+       const struct media_codec_audio_info *info,
81
        const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE)
82
 {
83
    a2dp_aptx_ll_ext_t conf = { 0 };
84
@@ -218,7 +218,7 @@
85
    return actual_conf_size;
86
 }
87
 
88
-static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
89
+static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
90
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
91
        struct spa_pod_builder *b, struct spa_pod **param)
92
 {
93
@@ -315,7 +315,7 @@
94
    return this->codesize;
95
 }
96
 
97
-static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
98
+static void *codec_init(const struct media_codec *codec, uint32_t flags,
99
        void *config, size_t config_len, const struct spa_audio_info *info,
100
        void *props, size_t mtu)
101
 {
102
@@ -458,7 +458,7 @@
103
  * When connected as SRC to SNK, aptX-LL sink may send back mSBC data.
104
  */
105
 
106
-static int msbc_enum_config(const struct a2dp_codec *codec, uint32_t flags,
107
+static int msbc_enum_config(const struct media_codec *codec, uint32_t flags,
108
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
109
        struct spa_pod_builder *b, struct spa_pod **param)
110
 {
111
@@ -479,7 +479,7 @@
112
    return *param == NULL ? -EIO : 1;
113
 }
114
 
115
-static int msbc_validate_config(const struct a2dp_codec *codec, uint32_t flags,
116
+static int msbc_validate_config(const struct media_codec *codec, uint32_t flags,
117
            const void *caps, size_t caps_size,
118
            struct spa_audio_info *info)
119
 {
120
@@ -508,7 +508,7 @@
121
    return MSBC_DECODED_SIZE;
122
 }
123
 
124
-static void *msbc_init(const struct a2dp_codec *codec, uint32_t flags,
125
+static void *msbc_init(const struct media_codec *codec, uint32_t flags,
126
        void *config, size_t config_len, const struct spa_audio_info *info,
127
        void *props, size_t mtu)
128
 {
129
@@ -610,7 +610,7 @@
130
 }
131
 
132
 
133
-const struct a2dp_codec a2dp_codec_aptx = {
134
+const struct media_codec a2dp_codec_aptx = {
135
    .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX,
136
    .codec_id = A2DP_CODEC_VENDOR,
137
    .vendor = { .vendor_id = APTX_VENDOR_ID,
138
@@ -633,7 +633,7 @@
139
 };
140
 
141
 
142
-const struct a2dp_codec a2dp_codec_aptx_hd = {
143
+const struct media_codec a2dp_codec_aptx_hd = {
144
    .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD,
145
    .codec_id = A2DP_CODEC_VENDOR,
146
    .vendor = { .vendor_id = APTX_HD_VENDOR_ID,
147
@@ -671,7 +671,7 @@
148
    .increase_bitpool = codec_increase_bitpool
149
 
150
 
151
-const struct a2dp_codec a2dp_codec_aptx_ll_0 = {
152
+const struct media_codec a2dp_codec_aptx_ll_0 = {
153
    APTX_LL_COMMON_DEFS,
154
    .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL,
155
    .vendor = { .vendor_id = APTX_LL_VENDOR_ID,
156
@@ -680,7 +680,7 @@
157
    .endpoint_name = "aptx_ll_0",
158
 };
159
 
160
-const struct a2dp_codec a2dp_codec_aptx_ll_1 = {
161
+const struct media_codec a2dp_codec_aptx_ll_1 = {
162
    APTX_LL_COMMON_DEFS,
163
    .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL,
164
    .vendor = { .vendor_id = APTX_LL_VENDOR_ID2,
165
@@ -690,7 +690,7 @@
166
 };
167
 
168
 /* Voice channel mSBC, not a real A2DP codec */
169
-static const struct a2dp_codec aptx_ll_msbc = {
170
+static const struct media_codec aptx_ll_msbc = {
171
    .codec_id = A2DP_CODEC_VENDOR,
172
    .name = "aptx_ll_msbc",
173
    .description = "aptX-LL mSBC",
174
@@ -715,7 +715,7 @@
175
 };
176
 static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items);
177
 
178
-const struct a2dp_codec a2dp_codec_aptx_ll_duplex_0 = {
179
+const struct media_codec a2dp_codec_aptx_ll_duplex_0 = {
180
    APTX_LL_COMMON_DEFS,
181
    .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX,
182
    .vendor = { .vendor_id = APTX_LL_VENDOR_ID,
183
@@ -726,7 +726,7 @@
184
    .info = &duplex_info,
185
 };
186
 
187
-const struct a2dp_codec a2dp_codec_aptx_ll_duplex_1 = {
188
+const struct media_codec a2dp_codec_aptx_ll_duplex_1 = {
189
    APTX_LL_COMMON_DEFS,
190
    .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX,
191
    .vendor = { .vendor_id = APTX_LL_VENDOR_ID2,
192
@@ -737,7 +737,7 @@
193
    .info = &duplex_info,
194
 };
195
 
196
-A2DP_CODEC_EXPORT_DEF(
197
+MEDIA_CODEC_EXPORT_DEF(
198
    "aptx",
199
    &a2dp_codec_aptx_hd,
200
    &a2dp_codec_aptx,
201
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
143
 
1
@@ -36,7 +36,7 @@
2
 
3
 #include <sbc/sbc.h>
4
 
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 struct impl {
9
    sbc_t sbc;
10
@@ -51,7 +51,7 @@
11
    sbc_t sbc;
12
 };
13
 
14
-static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags,
15
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
16
        uint8_t capsA2DP_MAX_CAPS_SIZE)
17
 {
18
    const a2dp_faststream_t a2dp_faststream = {
19
@@ -69,20 +69,20 @@
20
    return sizeof(a2dp_faststream);
21
 }
22
 
23
-static const struct a2dp_codec_config
24
+static const struct media_codec_config
25
 frequencies = {
26
    { FASTSTREAM_SINK_SAMPLING_FREQ_48000, 48000, 1 },
27
    { FASTSTREAM_SINK_SAMPLING_FREQ_44100, 44100, 0 },
28
 };
29
 
30
-static const struct a2dp_codec_config
31
+static const struct media_codec_config
32
 duplex_frequencies = {
33
    { FASTSTREAM_SOURCE_SAMPLING_FREQ_16000, 16000, 0 },
34
 };
35
 
36
-static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags,
37
+static int codec_select_config(const struct media_codec *codec, uint32_t flags,
38
        const void *caps, size_t caps_size,
39
-       const struct a2dp_codec_audio_info *info,
40
+       const struct media_codec_audio_info *info,
41
        const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE)
42
 {
43
    a2dp_faststream_t conf;
44
@@ -108,7 +108,7 @@
45
    if (codec->duplex_codec)
46
        conf.direction |= FASTSTREAM_DIRECTION_SOURCE;
47
 
48
-   if ((i = a2dp_codec_select_config(frequencies,
49
+   if ((i = media_codec_select_config(frequencies,
50
            SPA_N_ELEMENTS(frequencies),
51
            conf.sink_frequency,
52
            info ? info->rate : A2DP_CODEC_DEFAULT_RATE
53
@@ -116,7 +116,7 @@
54
        return -ENOTSUP;
55
    conf.sink_frequency = frequenciesi.config;
56
 
57
-   if ((i = a2dp_codec_select_config(duplex_frequencies,
58
+   if ((i = media_codec_select_config(duplex_frequencies,
59
            SPA_N_ELEMENTS(duplex_frequencies),
60
            conf.source_frequency,
61
            16000
62
@@ -129,7 +129,7 @@
63
    return sizeof(conf);
64
 }
65
 
66
-static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
67
+static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
68
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
69
        struct spa_pod_builder *b, struct spa_pod **param)
70
 {
71
@@ -209,7 +209,7 @@
72
    return v;
73
 }
74
 
75
-static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
76
+static void *codec_init(const struct media_codec *codec, uint32_t flags,
77
        void *config, size_t config_len, const struct spa_audio_info *info,
78
        void *props, size_t mtu)
79
 {
80
@@ -372,7 +372,7 @@
81
  * When connected as SRC to SNK, FastStream sink may send back SBC data.
82
  */
83
 
84
-static int duplex_enum_config(const struct a2dp_codec *codec, uint32_t flags,
85
+static int duplex_enum_config(const struct media_codec *codec, uint32_t flags,
86
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
87
        struct spa_pod_builder *b, struct spa_pod **param)
88
 {
89
@@ -411,7 +411,7 @@
90
    return *param == NULL ? -EIO : 1;
91
 }
92
 
93
-static int duplex_validate_config(const struct a2dp_codec *codec, uint32_t flags,
94
+static int duplex_validate_config(const struct media_codec *codec, uint32_t flags,
95
            const void *caps, size_t caps_size,
96
            struct spa_audio_info *info)
97
 {
98
@@ -441,7 +441,7 @@
99
    return 0;
100
 }
101
 
102
-static void *duplex_init(const struct a2dp_codec *codec, uint32_t flags,
103
+static void *duplex_init(const struct media_codec *codec, uint32_t flags,
104
        void *config, size_t config_len, const struct spa_audio_info *info,
105
        void *props, size_t mtu)
106
 {
107
@@ -577,7 +577,7 @@
108
 }
109
 
110
 /* Voice channel SBC, not a real A2DP codec */
111
-static const struct a2dp_codec duplex_codec = {
112
+static const struct media_codec duplex_codec = {
113
    .codec_id = A2DP_CODEC_VENDOR,
114
    .name = "faststream_sbc",
115
    .description = "FastStream duplex SBC",
116
@@ -614,7 +614,7 @@
117
    .reduce_bitpool = codec_reduce_bitpool,     \
118
    .increase_bitpool = codec_increase_bitpool
119
 
120
-static const struct a2dp_codec a2dp_codec_faststream = {
121
+const struct media_codec a2dp_codec_faststream = {
122
    FASTSTREAM_COMMON_DEFS,
123
    .id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM,
124
    .name = "faststream",
125
@@ -625,7 +625,7 @@
126
 };
127
 static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items);
128
 
129
-const struct a2dp_codec a2dp_codec_faststream_duplex = {
130
+const struct media_codec a2dp_codec_faststream_duplex = {
131
    FASTSTREAM_COMMON_DEFS,
132
    .id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX,
133
    .name = "faststream_duplex",
134
@@ -633,7 +633,7 @@
135
    .info = &duplex_info,
136
 };
137
 
138
-A2DP_CODEC_EXPORT_DEF(
139
+MEDIA_CODEC_EXPORT_DEF(
140
    "faststream",
141
    &a2dp_codec_faststream,
142
    &a2dp_codec_faststream_duplex
143
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
96
 
1
@@ -41,7 +41,7 @@
2
 #endif
3
 
4
 #include "rtp.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 #define BITRATE_MIN 96000
9
 #define BITRATE_MAX 512000
10
@@ -86,7 +86,7 @@
11
    int32_t buf2LC3PLUS_MAX_SAMPLES;
12
 };
13
 
14
-static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags,
15
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
16
        uint8_t capsA2DP_MAX_CAPS_SIZE)
17
 {
18
    const a2dp_lc3plus_hr_t a2dp_lc3plus_hr = {
19
@@ -102,9 +102,9 @@
20
    return sizeof(a2dp_lc3plus_hr);
21
 }
22
 
23
-static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags,
24
+static int codec_select_config(const struct media_codec *codec, uint32_t flags,
25
        const void *caps, size_t caps_size,
26
-       const struct a2dp_codec_audio_info *info,
27
+       const struct media_codec_audio_info *info,
28
        const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE)
29
 {
30
    a2dp_lc3plus_hr_t conf;
31
@@ -150,8 +150,8 @@
32
    return sizeof(conf);
33
 }
34
 
35
-static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
36
-       const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings)
37
+static int codec_caps_preference_cmp(const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
38
+       const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info, const struct spa_dict *global_settings)
39
 {
40
    a2dp_lc3plus_hr_t conf1, conf2;
41
    a2dp_lc3plus_hr_t *conf;
42
@@ -160,7 +160,7 @@
43
 
44
    /* Order selected configurations by preference */
45
    res1 = codec->select_config(codec, 0, caps1, caps1_size, info, NULL, (uint8_t *)&conf1);
46
-   res2 = codec->select_config(codec, 0, caps2, caps2_size, info, NULL, (uint8_t *)&conf2);
47
+   res2 = codec->select_config(codec, 0, caps2, caps2_size, info , NULL, (uint8_t *)&conf2);
48
 
49
 #define PREFER_EXPR(expr)          \
50
        do {                \
51
@@ -190,7 +190,7 @@
52
 #undef PREFER_BOOL
53
 }
54
 
55
-static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
56
+static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
57
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
58
        struct spa_pod_builder *b, struct spa_pod **param)
59
 {
60
@@ -263,7 +263,7 @@
61
    return *param == NULL ? -EIO : 1;
62
 }
63
 
64
-static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags,
65
+static int codec_validate_config(const struct media_codec *codec, uint32_t flags,
66
            const void *caps, size_t caps_size,
67
            struct spa_audio_info *info)
68
 {
69
@@ -342,7 +342,7 @@
70
    return (size_t)this->mtu >= header_size + ceildiv(payload_size, max_fragments);
71
 }
72
 
73
-static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
74
+static void *codec_init(const struct media_codec *codec, uint32_t flags,
75
        void *config, size_t config_len, const struct spa_audio_info *info,
76
        void *props, size_t mtu)
77
 {
78
@@ -758,7 +758,7 @@
79
    return 0;
80
 }
81
 
82
-const struct a2dp_codec a2dp_codec_lc3plus_hr = {
83
+const struct media_codec a2dp_codec_lc3plus_hr = {
84
    .id = SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR,
85
    .name = "lc3plus_hr",
86
    .codec_id = A2DP_CODEC_VENDOR,
87
@@ -782,7 +782,7 @@
88
    .increase_bitpool = codec_increase_bitpool
89
 };
90
 
91
-A2DP_CODEC_EXPORT_DEF(
92
+MEDIA_CODEC_EXPORT_DEF(
93
    "lc3plus",
94
    &a2dp_codec_lc3plus_hr
95
 );
96
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
111
 
1
@@ -40,7 +40,7 @@
2
 #endif
3
 
4
 #include "rtp.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 #define LDACBT_EQMID_AUTO -1
9
 
10
@@ -79,7 +79,7 @@
11
    int frame_count;
12
 };
13
 
14
-static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE)
15
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE)
16
 {
17
    static const a2dp_ldac_t a2dp_ldac = {
18
        .info.vendor_id = LDAC_VENDOR_ID,
19
@@ -97,7 +97,7 @@
20
    return sizeof(a2dp_ldac);
21
 }
22
 
23
-static const struct a2dp_codec_config
24
+static const struct media_codec_config
25
 ldac_frequencies = {
26
    { LDACBT_SAMPLING_FREQ_044100, 44100, 3 },
27
    { LDACBT_SAMPLING_FREQ_048000, 48000, 2 },
28
@@ -105,16 +105,16 @@
29
    { LDACBT_SAMPLING_FREQ_096000, 96000, 0 },
30
 };
31
 
32
-static const struct a2dp_codec_config
33
+static const struct media_codec_config
34
 ldac_channel_modes = {
35
    { LDACBT_CHANNEL_MODE_STEREO,       2, 2 },
36
    { LDACBT_CHANNEL_MODE_DUAL_CHANNEL, 2, 1 },
37
    { LDACBT_CHANNEL_MODE_MONO,         1, 0 },
38
 };
39
 
40
-static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags,
41
+static int codec_select_config(const struct media_codec *codec, uint32_t flags,
42
        const void *caps, size_t caps_size,
43
-       const struct a2dp_codec_audio_info *info,
44
+       const struct media_codec_audio_info *info,
45
        const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE)
46
 {
47
    a2dp_ldac_t conf;
48
@@ -129,7 +129,7 @@
49
        codec->vendor.codec_id != conf.info.codec_id)
50
        return -ENOTSUP;
51
 
52
-   if ((i = a2dp_codec_select_config(ldac_frequencies,
53
+   if ((i = media_codec_select_config(ldac_frequencies,
54
                      SPA_N_ELEMENTS(ldac_frequencies),
55
                      conf.frequency,
56
                          info ? info->rate : A2DP_CODEC_DEFAULT_RATE
57
@@ -137,7 +137,7 @@
58
        return -ENOTSUP;
59
    conf.frequency = ldac_frequenciesi.config;
60
 
61
-   if ((i = a2dp_codec_select_config(ldac_channel_modes,
62
+   if ((i = media_codec_select_config(ldac_channel_modes,
63
                      SPA_N_ELEMENTS(ldac_channel_modes),
64
                          conf.channel_mode,
65
                          info ? info->channels : A2DP_CODEC_DEFAULT_CHANNELS
66
@@ -150,7 +150,7 @@
67
         return sizeof(conf);
68
 }
69
 
70
-static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
71
+static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
72
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
73
        struct spa_pod_builder *b, struct spa_pod **param)
74
 {
75
@@ -284,7 +284,7 @@
76
        return LDACBT_EQMID_AUTO;
77
 }
78
 
79
-static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings)
80
+static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings)
81
 {
82
    struct props *p = calloc(1, sizeof(struct props));
83
    const char *str;
84
@@ -385,7 +385,7 @@
85
    return prev_eqmid != p->eqmid;
86
 }
87
 
88
-static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
89
+static void *codec_init(const struct media_codec *codec, uint32_t flags,
90
        void *config, size_t config_len, const struct spa_audio_info *info,
91
        void *props, size_t mtu)
92
 {
93
@@ -570,7 +570,7 @@
94
    return src_used;
95
 }
96
 
97
-const struct a2dp_codec a2dp_codec_ldac = {
98
+const struct media_codec a2dp_codec_ldac = {
99
    .id = SPA_BLUETOOTH_AUDIO_CODEC_LDAC,
100
    .codec_id = A2DP_CODEC_VENDOR,
101
    .vendor = { .vendor_id = LDAC_VENDOR_ID,
102
@@ -598,7 +598,7 @@
103
    .increase_bitpool = codec_increase_bitpool,
104
 };
105
 
106
-A2DP_CODEC_EXPORT_DEF(
107
+MEDIA_CODEC_EXPORT_DEF(
108
    "ldac",
109
    &a2dp_codec_ldac
110
 );
111
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
195
 
1
@@ -44,7 +44,7 @@
2
 #include <opus_multistream.h>
3
 
4
 #include "rtp.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 static struct spa_log *log;
9
 static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.opus");
10
@@ -395,7 +395,7 @@
11
        props->bidi_application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
12
 }
13
 
14
-static int set_channel_conf(const struct a2dp_codec *codec, a2dp_opus_05_t *caps, const struct props *props)
15
+static int set_channel_conf(const struct media_codec *codec, a2dp_opus_05_t *caps, const struct props *props)
16
 {
17
    /*
18
     * Predefined codec profiles
19
@@ -469,7 +469,7 @@
20
    return 0;
21
 }
22
 
23
-static void get_default_bitrates(const struct a2dp_codec *codec, bool bidi, int *min, int *max, int *init)
24
+static void get_default_bitrates(const struct media_codec *codec, bool bidi, int *min, int *max, int *init)
25
 {
26
    int tmp;
27
 
28
@@ -514,7 +514,7 @@
29
    };
30
 }
31
 
32
-static int get_mapping(const struct a2dp_codec *codec, const a2dp_opus_05_direction_t *conf,
33
+static int get_mapping(const struct media_codec *codec, const a2dp_opus_05_direction_t *conf,
34
        bool use_surround_encoder, uint8_t *streams_ret, uint8_t *coupled_streams_ret,
35
        const uint8_t **surround_mapping, uint32_t *positions)
36
 {
37
@@ -576,7 +576,7 @@
38
    return 0;
39
 }
40
 
41
-static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags,
42
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
43
        uint8_t capsA2DP_MAX_CAPS_SIZE)
44
 {
45
    a2dp_opus_05_t a2dp_opus_05 = {
46
@@ -613,9 +613,9 @@
47
    return sizeof(a2dp_opus_05);
48
 }
49
 
50
-static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags,
51
+static int codec_select_config(const struct media_codec *codec, uint32_t flags,
52
        const void *caps, size_t caps_size,
53
-       const struct a2dp_codec_audio_info *info,
54
+       const struct media_codec_audio_info *info,
55
        const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE)
56
 {
57
    struct props props;
58
@@ -715,8 +715,8 @@
59
    return sizeof(conf);
60
 }
61
 
62
-static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
63
-       const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info,
64
+static int codec_caps_preference_cmp(const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
65
+       const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info,
66
        const struct spa_dict *global_settings)
67
 {
68
    a2dp_opus_05_t conf1, conf2, cap1, cap2;
69
@@ -768,12 +768,12 @@
70
 #undef PREFER_BOOL
71
 }
72
 
73
-static bool is_duplex_codec(const struct a2dp_codec *codec)
74
+static bool is_duplex_codec(const struct media_codec *codec)
75
 {
76
    return codec->id == 0;
77
 }
78
 
79
-static bool use_surround_encoder(const struct a2dp_codec *codec, bool is_sink)
80
+static bool use_surround_encoder(const struct media_codec *codec, bool is_sink)
81
 {
82
    if (codec->id == SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO)
83
        return false;
84
@@ -784,11 +784,11 @@
85
        return !is_sink;
86
 }
87
 
88
-static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
89
+static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
90
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
91
        struct spa_pod_builder *b, struct spa_pod **param)
92
 {
93
-   const bool surround_encoder = use_surround_encoder(codec, flags & A2DP_CODEC_FLAG_SINK);
94
+   const bool surround_encoder = use_surround_encoder(codec, flags & MEDIA_CODEC_FLAG_SINK);
95
    a2dp_opus_05_t conf;
96
    a2dp_opus_05_direction_t *dir;
97
    struct spa_pod_frame f1;
98
@@ -823,11 +823,11 @@
99
    return *param == NULL ? -EIO : 1;
100
 }
101
 
102
-static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags,
103
+static int codec_validate_config(const struct media_codec *codec, uint32_t flags,
104
            const void *caps, size_t caps_size,
105
            struct spa_audio_info *info)
106
 {
107
-   const bool surround_encoder = use_surround_encoder(codec, flags & A2DP_CODEC_FLAG_SINK);
108
+   const bool surround_encoder = use_surround_encoder(codec, flags & MEDIA_CODEC_FLAG_SINK);
109
    const a2dp_opus_05_direction_t *dir1, *dir2;
110
    const a2dp_opus_05_t *conf;
111
 
112
@@ -898,7 +898,7 @@
113
    }
114
 }
115
 
116
-static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings)
117
+static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings)
118
 {
119
    struct props *p;
120
 
121
@@ -919,11 +919,11 @@
122
    free(props);
123
 }
124
 
125
-static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
126
+static void *codec_init(const struct media_codec *codec, uint32_t flags,
127
        void *config, size_t config_len, const struct spa_audio_info *info,
128
        void *props, size_t mtu)
129
 {
130
-   const bool surround_encoder = use_surround_encoder(codec, flags & A2DP_CODEC_FLAG_SINK);
131
+   const bool surround_encoder = use_surround_encoder(codec, flags & MEDIA_CODEC_FLAG_SINK);
132
    a2dp_opus_05_t *conf = config;
133
    a2dp_opus_05_direction_t *dir;
134
    struct impl *this = NULL;
135
@@ -1380,21 +1380,21 @@
136
    .start_decode = codec_start_decode,         \
137
    .decode = codec_decode
138
 
139
-const struct a2dp_codec a2dp_codec_opus_05 = {
140
+const struct media_codec a2dp_codec_opus_05 = {
141
    OPUS_05_COMMON_FULL_DEFS,
142
    .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05,
143
    .name = "opus_05",
144
    .description = "Opus",
145
 };
146
 
147
-const struct a2dp_codec a2dp_codec_opus_05_51 = {
148
+const struct media_codec a2dp_codec_opus_05_51 = {
149
    OPUS_05_COMMON_DEFS,
150
    .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51,
151
    .name = "opus_05_51",
152
    .description = "Opus 5.1 Surround",
153
 };
154
 
155
-const struct a2dp_codec a2dp_codec_opus_05_71 = {
156
+const struct media_codec a2dp_codec_opus_05_71 = {
157
    OPUS_05_COMMON_DEFS,
158
    .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71,
159
    .name = "opus_05_71",
160
@@ -1402,14 +1402,14 @@
161
 };
162
 
163
 /* Bidi return channel codec: doesn't have endpoints */
164
-const struct a2dp_codec a2dp_codec_opus_05_return = {
165
+const struct media_codec a2dp_codec_opus_05_return = {
166
    OPUS_05_COMMON_FULL_DEFS,
167
    .id = 0,
168
    .name = "opus_05_duplex_bidi",
169
    .description = "Opus Duplex Bidi channel",
170
 };
171
 
172
-const struct a2dp_codec a2dp_codec_opus_05_duplex = {
173
+const struct media_codec a2dp_codec_opus_05_duplex = {
174
    OPUS_05_COMMON_FULL_DEFS,
175
    .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX,
176
    .name = "opus_05_duplex",
177
@@ -1417,7 +1417,7 @@
178
    .duplex_codec = &a2dp_codec_opus_05_return,
179
 };
180
 
181
-const struct a2dp_codec a2dp_codec_opus_05_pro = {
182
+const struct media_codec a2dp_codec_opus_05_pro = {
183
    OPUS_05_COMMON_DEFS,
184
    .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO,
185
    .name = "opus_05_pro",
186
@@ -1427,7 +1427,7 @@
187
    .duplex_codec = &a2dp_codec_opus_05_return,
188
 };
189
 
190
-A2DP_CODEC_EXPORT_DEF(
191
+MEDIA_CODEC_EXPORT_DEF(
192
    "opus",
193
    &a2dp_codec_opus_05,
194
    &a2dp_codec_opus_05_51,
195
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
154
 
1
@@ -33,7 +33,7 @@
2
 #include <sbc/sbc.h>
3
 
4
 #include "rtp.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 #define MAX_FRAME_COUNT 16
9
 
10
@@ -51,7 +51,7 @@
11
    int max_bitpool;
12
 };
13
 
14
-static int codec_fill_caps(const struct a2dp_codec *codec, uint32_t flags,
15
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
16
        uint8_t capsA2DP_MAX_CAPS_SIZE)
17
 {
18
    static const a2dp_sbc_t a2dp_sbc = {
19
@@ -121,7 +121,7 @@
20
 }
21
 
22
 
23
-static const struct a2dp_codec_config
24
+static const struct media_codec_config
25
 sbc_frequencies = {
26
    { SBC_SAMPLING_FREQ_48000, 48000, 3 },
27
    { SBC_SAMPLING_FREQ_44100, 44100, 2 },
28
@@ -129,13 +129,13 @@
29
    { SBC_SAMPLING_FREQ_16000, 16000, 0 },
30
 };
31
 
32
-static const struct a2dp_codec_config
33
+static const struct media_codec_config
34
 sbc_xq_frequencies = {
35
    { SBC_SAMPLING_FREQ_44100, 44100, 1 },
36
    { SBC_SAMPLING_FREQ_48000, 48000, 0 },
37
 };
38
 
39
-static const struct a2dp_codec_config
40
+static const struct media_codec_config
41
 sbc_channel_modes = {
42
    { SBC_CHANNEL_MODE_JOINT_STEREO, 2, 3 },
43
    { SBC_CHANNEL_MODE_STEREO,       2, 2 },
44
@@ -143,22 +143,22 @@
45
    { SBC_CHANNEL_MODE_MONO,         1, 0 },
46
 };
47
 
48
-static const struct a2dp_codec_config
49
+static const struct media_codec_config
50
 sbc_xq_channel_modes = {
51
    { SBC_CHANNEL_MODE_DUAL_CHANNEL, 2, 2 },
52
    { SBC_CHANNEL_MODE_JOINT_STEREO, 2, 1 },
53
    { SBC_CHANNEL_MODE_STEREO,       2, 0 },
54
 };
55
 
56
-static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags,
57
+static int codec_select_config(const struct media_codec *codec, uint32_t flags,
58
        const void *caps, size_t caps_size,
59
-       const struct a2dp_codec_audio_info *info,
60
+       const struct media_codec_audio_info *info,
61
        const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE)
62
 {
63
    a2dp_sbc_t conf;
64
    int bitpool, i;
65
    size_t n;
66
-   const struct a2dp_codec_config *configs;
67
+   const struct media_codec_config *configs;
68
    bool xq = false;
69
 
70
 
71
@@ -176,7 +176,7 @@
72
        configs = sbc_frequencies;
73
        n = SPA_N_ELEMENTS(sbc_frequencies);
74
    }
75
-   if ((i = a2dp_codec_select_config(configs, n, conf.frequency,
76
+   if ((i = media_codec_select_config(configs, n, conf.frequency,
77
                      info ? info->rate : A2DP_CODEC_DEFAULT_RATE
78
                      )) < 0)
79
        return -ENOTSUP;
80
@@ -189,7 +189,7 @@
81
        configs = sbc_channel_modes;
82
        n = SPA_N_ELEMENTS(sbc_channel_modes);
83
    }
84
-   if ((i = a2dp_codec_select_config(configs, n, conf.channel_mode,
85
+   if ((i = media_codec_select_config(configs, n, conf.channel_mode,
86
                      info ? info->channels : A2DP_CODEC_DEFAULT_CHANNELS
87
                      )) < 0)
88
        return -ENOTSUP;
89
@@ -229,8 +229,8 @@
90
    return sizeof(conf);
91
 }
92
 
93
-static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
94
-       const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings)
95
+static int codec_caps_preference_cmp(const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
96
+       const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info, const struct spa_dict *global_settings)
97
 {
98
    a2dp_sbc_t conf1, conf2;
99
    a2dp_sbc_t *conf;
100
@@ -275,7 +275,7 @@
101
 #undef PREFER_BOOL
102
 }
103
 
104
-static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags,
105
+static int codec_validate_config(const struct media_codec *codec, uint32_t flags,
106
            const void *caps, size_t caps_size,
107
            struct spa_audio_info *info)
108
 {
109
@@ -356,7 +356,7 @@
110
    return this->sbc.bitpool;
111
 }
112
 
113
-static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
114
+static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
115
        const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
116
        struct spa_pod_builder *b, struct spa_pod **param)
117
 {
118
@@ -453,7 +453,7 @@
119
    return this->codesize;
120
 }
121
 
122
-static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
123
+static void *codec_init(const struct media_codec *codec, uint32_t flags,
124
        void *config, size_t config_len, const struct spa_audio_info *info,
125
        void *props, size_t mtu)
126
 {
127
@@ -638,7 +638,7 @@
128
    return res;
129
 }
130
 
131
-const struct a2dp_codec a2dp_codec_sbc = {
132
+const struct media_codec a2dp_codec_sbc = {
133
    .id = SPA_BLUETOOTH_AUDIO_CODEC_SBC,
134
    .codec_id = A2DP_CODEC_SBC,
135
    .name = "sbc",
136
@@ -660,7 +660,7 @@
137
    .increase_bitpool = codec_increase_bitpool,
138
 };
139
 
140
-const struct a2dp_codec a2dp_codec_sbc_xq = {
141
+const struct media_codec a2dp_codec_sbc_xq = {
142
    .id = SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ,
143
    .codec_id = A2DP_CODEC_SBC,
144
    .name = "sbc_xq",
145
@@ -682,7 +682,7 @@
146
    .increase_bitpool = codec_increase_bitpool,
147
 };
148
 
149
-A2DP_CODEC_EXPORT_DEF(
150
+MEDIA_CODEC_EXPORT_DEF(
151
    "sbc",
152
    &a2dp_codec_sbc,
153
    &a2dp_codec_sbc_xq
154
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
170
 
1
@@ -78,7 +78,7 @@
2
    struct spa_dbus *dbus;
3
    DBusConnection *conn;
4
 
5
-#define DEFAULT_ENABLED_PROFILES (SPA_BT_PROFILE_HSP_HS | SPA_BT_PROFILE_HFP_AG)
6
+#define DEFAULT_ENABLED_PROFILES (SPA_BT_PROFILE_HFP_HF | SPA_BT_PROFILE_HFP_AG)
7
    enum spa_bt_profile enabled_profiles;
8
 
9
    struct spa_source sco;
10
@@ -259,6 +259,7 @@
11
 
12
 #define RFCOMM_MESSAGE_MAX_LENGTH 256
13
 
14
+/* from HF/HS to AG */
15
 SPA_PRINTF_FUNC(2, 3)
16
 static ssize_t rfcomm_send_cmd(const struct rfcomm *rfcomm, const char *format, ...)
17
 {
18
@@ -279,7 +280,14 @@
19
 
20
    spa_log_debug(backend->log, "RFCOMM >> %s", message);
21
 
22
-   messagelen = '\n';
23
+   /*
24
+    * The format of an AT command from the HF to the AG shall be: <AT command><cr>
25
+    * - HFP 1.8, 4.34.1
26
+    *
27
+    * The format for a command from the HS to the AG is thus: AT<cmd>=<value><cr>
28
+    * - HSP 1.2, 4.8.1
29
+    */
30
+   messagelen = '\r';
31
    /* `message` is no longer null-terminated */
32
 
33
    len = write(rfcomm->source.fd, message, len + 1);
34
@@ -293,6 +301,7 @@
35
    return len;
36
 }
37
 
38
+/* from AG to HF/HS */
39
 SPA_PRINTF_FUNC(2, 3)
40
 static ssize_t rfcomm_send_reply(const struct rfcomm *rfcomm, const char *format, ...)
41
 {
42
@@ -313,6 +322,18 @@
43
 
44
    spa_log_debug(backend->log, "RFCOMM >> %s", &message2);
45
 
46
+   /*
47
+    * The format of the OK code from the AG to the HF shall be: <cr><lf>OK<cr><lf>
48
+    * The format of the generic ERROR code from the AG to the HF shall be: <cr><lf>ERROR<cr><lf>
49
+    * The format of an unsolicited result code from the AG to the HF shall be: <cr><lf><result code><cr><lf>
50
+    * - HFP 1.8, 4.34.1
51
+    *
52
+    * If the command is processed successfully, the resulting response from the AG to the HS is: <cr><lf>OK<cr><lf>
53
+    * If the command is not processed successfully, or is not recognized,
54
+    * the resulting response from the AG to the HS is: <cr><lf>ERROR<cr><lf>
55
+    * The format for an unsolicited result code (such as RING) from the AG to the HS is: <cr><lf><result code><cr><lf>
56
+    * - HSP 1.2, 4.8.1
57
+    */
58
    message0 = '\r';
59
    message1 = '\n';
60
    messagelen + 2 = '\r';
61
@@ -747,26 +768,21 @@
62
        /* retrieve supported codecs */
63
        /* response has the form AT+BAC=<codecID1>,<codecID2>,<codecIDx>
64
           strategy: split the string into tokens */
65
-       static const char separators = "=,";
66
 
67
        char* token;
68
        int cntr = 0;
69
 
70
-       token = strtok (buf, separators);
71
-       while (token != NULL)
72
-       {
73
+       while ((token = strsep(&buf, "=,"))) {
74
+           unsigned int codec_id;
75
+
76
            /* skip token 0 i.e. the "AT+BAC=" part */
77
-           if (cntr > 0) {
78
-               int codec_id;
79
-               sscanf (token, "%u", &codec_id);
80
+           if (cntr > 0 && sscanf(token, "%u", &codec_id) == 1) {
81
                spa_log_debug(backend->log, "RFCOMM AT+BAC found codec %u", codec_id);
82
                if (codec_id == HFP_AUDIO_CODEC_MSBC) {
83
                    rfcomm->msbc_supported_by_hfp = true;
84
                    spa_log_debug(backend->log, "RFCOMM headset supports mSBC codec");
85
                }
86
            }
87
-           /* get next token */
88
-           token = strtok (NULL, separators);
89
            cntr++;
90
        }
91
 
92
@@ -809,7 +825,7 @@
93
    } else if (!rfcomm->slc_configured) {
94
        spa_log_warn(backend->log, "RFCOMM receive command before SLC completed: %s", buf);
95
        rfcomm_send_reply(rfcomm, "ERROR");
96
-       return false;
97
+       return true;
98
    } else if (sscanf(buf, "AT+BCS=%u", &selected_codec) == 1) {
99
        /* parse BCS(=Bluetooth Codec Selection) reply */
100
        bool was_switching_codec = rfcomm->hfp_ag_switching_codec && (rfcomm->device != NULL);
101
@@ -918,29 +934,18 @@
102
 
103
 static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* buf)
104
 {
105
-   static const char separators = "\r\n:";
106
-
107
    struct impl *backend = rfcomm->backend;
108
    unsigned int features;
109
    unsigned int gain;
110
    unsigned int selected_codec;
111
    char* token;
112
 
113
-   token = strtok(buf, separators);
114
-   while (token != NULL)
115
-   {
116
-       if (spa_strstartswith(token, "+BRSF")) {
117
-           /* get next token */
118
-           token = strtok(NULL, separators);
119
-           features = atoi(token);
120
+   while ((token = strsep(&buf, "\r\n"))) {
121
+       if (sscanf(token, "+BRSF:%u", &features) == 1) {
122
            if (((features & (SPA_BT_HFP_AG_FEATURE_CODEC_NEGOTIATION)) != 0) &&
123
                rfcomm->msbc_supported_by_hfp)
124
                rfcomm->codec_negotiation_supported = true;
125
-       } else if (spa_strstartswith(token, "+BCS") && rfcomm->codec_negotiation_supported) {
126
-           /* get next token */
127
-           token = strtok(NULL, separators);
128
-           selected_codec = atoi(token);
129
-
130
+       } else if (sscanf(token, "+BCS:%u", &selected_codec) == 1 && rfcomm->codec_negotiation_supported) {
131
            if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC) {
132
                spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec);
133
            } else {
134
@@ -965,24 +970,13 @@
135
                    }
136
                }
137
            }
138
-       } else if (spa_strstartswith(token, "+CIND")) {
139
-           /* get next token and discard it */
140
-           token = strtok(NULL, separators);
141
-       } else if (spa_strstartswith(token, "+VGM")) {
142
-           /* get next token */
143
-           token = strtok(NULL, separators);
144
-           gain = atoi(token);
145
-
146
+       } else if (sscanf(token, "+VGM%*1:=%u", &gain) == 1) {
147
            if (gain <= SPA_BT_VOLUME_HS_MAX) {
148
                rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_TX, gain);
149
            } else {
150
                spa_log_debug(backend->log, "RFCOMM receive unsupported VGM gain: %s", token);
151
            }
152
-       } else if (spa_strstartswith(token, "+VGS")) {
153
-           /* get next token */
154
-           token = strtok(NULL, separators);
155
-           gain = atoi(token);
156
-
157
+       } else if (sscanf(token, "+VGS%*1:=%u", &gain) == 1) {
158
            if (gain <= SPA_BT_VOLUME_HS_MAX) {
159
                rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_RX, gain);
160
            } else {
161
@@ -1041,8 +1035,6 @@
162
                    break;
163
            }
164
        }
165
-       /* get next token */
166
-       token = strtok(NULL, separators);
167
    }
168
 
169
    return true;
170
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-caps.h Added
115
 
1
@@ -0,0 +1,113 @@
2
+/* Spa BAP codec API
3
+ *
4
+ * Copyright © 2022 Collabora
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+#ifndef SPA_BLUEZ5_BAP_CODEC_CAPS_H_
26
+#define SPA_BLUEZ5_BAP_CODEC_CAPS_H_
27
+
28
+#define BAP_CODEC_LC3           0x06
29
+
30
+#define LC3_TYPE_FREQ           0x01
31
+#define LC3_FREQ_8KHZ           (1 << 0)
32
+#define LC3_FREQ_11KHZ          (1 << 1)
33
+#define LC3_FREQ_16KHZ          (1 << 2)
34
+#define LC3_FREQ_22KHZ          (1 << 3)
35
+#define LC3_FREQ_24KHZ          (1 << 4)
36
+#define LC3_FREQ_32KHZ          (1 << 5)
37
+#define LC3_FREQ_44KHZ          (1 << 6)
38
+#define LC3_FREQ_48KHZ          (1 << 7)
39
+#define LC3_FREQ_ANY            (LC3_FREQ_8KHZ | \
40
+                                 LC3_FREQ_11KHZ | \
41
+                                 LC3_FREQ_16KHZ | \
42
+                                 LC3_FREQ_22KHZ | \
43
+                                 LC3_FREQ_24KHZ | \
44
+                                 LC3_FREQ_32KHZ | \
45
+                                 LC3_FREQ_44KHZ | \
46
+                                 LC3_FREQ_48KHZ)
47
+
48
+#define LC3_TYPE_DUR            0x02
49
+#define LC3_DUR_7_5             (1 << 0)
50
+#define LC3_DUR_10              (1 << 1)
51
+#define LC3_DUR_ANY             (LC3_DUR_7_5 | \
52
+                                 LC3_DUR_10)
53
+
54
+#define LC3_TYPE_CHAN           0x03
55
+#define LC3_CHAN_1              (1 << 0)
56
+#define LC3_CHAN_2              (1 << 1)
57
+
58
+#define LC3_TYPE_FRAMELEN       0x04
59
+#define LC3_TYPE_BLKS           0x05
60
+
61
+/* LC3 config parameters */
62
+#define LC3_CONFIG_FREQ_8KHZ    0x01
63
+#define LC3_CONFIG_FREQ_11KHZ   0x02
64
+#define LC3_CONFIG_FREQ_16KHZ   0x03
65
+#define LC3_CONFIG_FREQ_22KHZ   0x04
66
+#define LC3_CONFIG_FREQ_24KHZ   0x05
67
+#define LC3_CONFIG_FREQ_32KHZ   0x06
68
+#define LC3_CONFIG_FREQ_44KHZ   0x07
69
+#define LC3_CONFIG_FREQ_48KHZ   0x08
70
+
71
+#define LC3_CONFIG_DURATION_7_5 0x00
72
+#define LC3_CONFIG_DURATION_10  0x01
73
+
74
+#define LC3_CONFIG_CHNL_NOT_ALLOWED 0x00000000
75
+#define LC3_CONFIG_CHNL_FL          0x00000001 /* front left */
76
+#define LC3_CONFIG_CHNL_FR          0x00000002 /* front right */
77
+#define LC3_CONFIG_CHNL_FC          0x00000004 /* front center */
78
+#define LC3_CONFIG_CHNL_LFE         0x00000008 /* LFE */
79
+#define LC3_CONFIG_CHNL_BL          0x00000010 /* back left */
80
+#define LC3_CONFIG_CHNL_BR          0x00000020 /* back right */
81
+#define LC3_CONFIG_CHNL_FLC         0x00000040 /* front left center */
82
+#define LC3_CONFIG_CHNL_FRC         0x00000080 /* front right center */
83
+#define LC3_CONFIG_CHNL_BC          0x00000100 /* back center */
84
+#define LC3_CONFIG_CHNL_LFE2       0x00000200 /* LFE 2 */
85
+#define LC3_CONFIG_CHNL_SL          0x00000400 /* side left */
86
+#define LC3_CONFIG_CHNL_SR          0x00000800 /* side right */
87
+#define LC3_CONFIG_CHNL_TFL         0x00001000 /* top front left */
88
+#define LC3_CONFIG_CHNL_TFR         0x00002000 /* top front right */
89
+#define LC3_CONFIG_CHNL_TFC         0x00004000 /* top front center */
90
+#define LC3_CONFIG_CHNL_TC          0x00008000 /* top center */
91
+#define LC3_CONFIG_CHNL_TBL         0x00010000 /* top back left */
92
+#define LC3_CONFIG_CHNL_TBR         0x00020000 /* top back right */
93
+#define LC3_CONFIG_CHNL_TSL         0x00040000 /* top side left */
94
+#define LC3_CONFIG_CHNL_TSR         0x00080000 /* top side right */
95
+#define LC3_CONFIG_CHNL_TBC         0x00100000 /* top back center */
96
+#define LC3_CONFIG_CHNL_BFC         0x00200000 /* bottom front center */
97
+#define LC3_CONFIG_CHNL_BFL         0x00400000 /* bottom front left */
98
+#define LC3_CONFIG_CHNL_BFR         0x00800000 /* bottom front right */
99
+#define LC3_CONFIG_CHNL_FLW         0x01000000 /* front left wide */
100
+#define LC3_CONFIG_CHNL_FRW         0x02000000 /* front right wide */
101
+#define LC3_CONFIG_CHNL_LS          0x04000000 /* left surround */
102
+#define LC3_CONFIG_CHNL_RS          0x08000000 /* right surround */
103
+
104
+#define LC3_MAX_CHANNELS 28
105
+
106
+typedef struct {
107
+    uint8_t rate;
108
+   uint8_t frame_duration;
109
+   uint32_t channels;
110
+   uint16_t framelen;
111
+   uint8_t n_blks;
112
+} __attribute__ ((packed)) bap_lc3_t;
113
+
114
+#endif
115
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c Added
201
 
1
@@ -0,0 +1,772 @@
2
+/* Spa BAP LC3 codec
3
+ *
4
+ * Copyright © 2020 Wim Taymans
5
+ * Copyright © 2022 Pauli Virtanen
6
+ * Copyright © 2022 Collabora
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a
9
+ * copy of this software and associated documentation files (the "Software"),
10
+ * to deal in the Software without restriction, including without limitation
11
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ * and/or sell copies of the Software, and to permit persons to whom the
13
+ * Software is furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice (including the next
16
+ * paragraph) shall be included in all copies or substantial portions of the
17
+ * Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ * DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+#include <bits/stdint-uintn.h>
29
+#include <string.h>
30
+#include <unistd.h>
31
+#include <stddef.h>
32
+#include <errno.h>
33
+#include <arpa/inet.h>
34
+#include <bluetooth/bluetooth.h>
35
+
36
+#include <spa/param/audio/format.h>
37
+#include <spa/param/audio/format-utils.h>
38
+
39
+#include <lc3.h>
40
+
41
+#include "media-codecs.h"
42
+#include "bap-codec-caps.h"
43
+
44
+struct impl {
45
+   lc3_encoder_t encLC3_MAX_CHANNELS;
46
+   lc3_decoder_t decLC3_MAX_CHANNELS;
47
+
48
+   int mtu;
49
+   int samplerate;
50
+   int channels;
51
+   int frame_dus;
52
+   int framelen;
53
+   int samples;
54
+   unsigned int codesize;
55
+};
56
+
57
+struct ltv {
58
+   uint8_t  len;
59
+   uint8_t  type;
60
+   uint8_t  value0;
61
+} __packed;
62
+
63
+static int write_ltv(uint8_t *dest, uint8_t type, void* value, size_t len)
64
+{
65
+   struct ltv *ltv = (struct ltv *)dest;
66
+
67
+   ltv->len = len + 1;
68
+   ltv->type = type;
69
+   memcpy(ltv->value, value, len);
70
+
71
+   return len + 2;
72
+}
73
+
74
+static int write_ltv_uint8(uint8_t *dest, uint8_t type, uint8_t value)
75
+{
76
+   return write_ltv(dest, type, &value, sizeof(value));
77
+}
78
+
79
+static int write_ltv_uint16(uint8_t *dest, uint8_t type, uint16_t value)
80
+{
81
+   return write_ltv(dest, type, &value, sizeof(value));
82
+}
83
+
84
+static int write_ltv_uint32(uint8_t *dest, uint8_t type, uint32_t value)
85
+{
86
+   return write_ltv(dest, type, &value, sizeof(value));
87
+}
88
+
89
+static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
90
+       uint8_t capsA2DP_MAX_CAPS_SIZE)
91
+{
92
+   uint8_t *data = caps;
93
+   uint16_t framelen2 = {htobs(LC3_MIN_FRAME_BYTES), htobs(LC3_MAX_FRAME_BYTES)};
94
+
95
+   data += write_ltv_uint16(data, LC3_TYPE_FREQ,
96
+                            htobs(LC3_FREQ_48KHZ | LC3_FREQ_24KHZ | LC3_FREQ_16KHZ | LC3_FREQ_8KHZ));
97
+   data += write_ltv_uint8(data, LC3_TYPE_DUR, LC3_DUR_ANY);
98
+   data += write_ltv_uint8(data, LC3_TYPE_CHAN, LC3_CHAN_1 | LC3_CHAN_2);
99
+   data += write_ltv(data, LC3_TYPE_FRAMELEN, framelen, sizeof(framelen));
100
+   data += write_ltv_uint8(data, LC3_TYPE_BLKS, 2);
101
+
102
+   return data - caps;
103
+}
104
+
105
+static bool parse_capabilities(bap_lc3_t *conf, const uint8_t *data, size_t data_size)
106
+{
107
+   uint16_t framelen_min = 0, framelen_max = 0;
108
+
109
+   if (!data_size)
110
+       return false;
111
+   memset(conf, 0, sizeof(*conf));
112
+
113
+   conf->frame_duration = 0xFF;
114
+
115
+   while (data_size > 0) {
116
+       struct ltv *ltv = (struct ltv *)data;
117
+
118
+       if (ltv->len > data_size)
119
+           return false;
120
+
121
+       switch (ltv->type) {
122
+       case LC3_TYPE_FREQ:
123
+           spa_return_val_if_fail(ltv->len == 3, false);
124
+           {
125
+               uint16_t rate = ltv->value0 + (ltv->value1 << 8);
126
+               if (rate & LC3_FREQ_48KHZ)
127
+                   conf->rate = LC3_CONFIG_FREQ_48KHZ;
128
+               else if (rate & LC3_FREQ_24KHZ)
129
+                   conf->rate = LC3_CONFIG_FREQ_24KHZ;
130
+               else if (rate & LC3_FREQ_16KHZ)
131
+                   conf->rate = LC3_CONFIG_FREQ_16KHZ;
132
+               else if (rate & LC3_FREQ_8KHZ)
133
+                   conf->rate = LC3_CONFIG_FREQ_8KHZ;
134
+               else
135
+                   return false;
136
+           }
137
+           break;
138
+       case LC3_TYPE_DUR:
139
+           spa_return_val_if_fail(ltv->len == 2, false);
140
+           {
141
+               uint8_t duration = ltv->value0;
142
+               if (duration & LC3_DUR_10)
143
+                   conf->frame_duration = LC3_CONFIG_DURATION_10;
144
+               else if (duration & LC3_DUR_7_5)
145
+                   conf->frame_duration = LC3_CONFIG_DURATION_7_5;
146
+               else
147
+                   return false;
148
+           }
149
+           break;
150
+       case LC3_TYPE_CHAN:
151
+           spa_return_val_if_fail(ltv->len == 2, false);
152
+           {
153
+               uint8_t channels = ltv->value0;
154
+               /* Only mono or stereo streams are currently supported,
155
+                * in both case Audio location is defined as both Front Left
156
+                * and Front Right, difference is done by the n_blks parameter.
157
+                */
158
+               if ((channels & LC3_CHAN_2) || (channels & LC3_CHAN_1))
159
+                   conf->channels = LC3_CONFIG_CHNL_FR | LC3_CONFIG_CHNL_FL;
160
+               else
161
+                   return false;
162
+           }
163
+           break;
164
+       case LC3_TYPE_FRAMELEN:
165
+           spa_return_val_if_fail(ltv->len == 5, false);
166
+           framelen_min = ltv->value0 + (ltv->value1 << 8);
167
+           framelen_max = ltv->value2 + (ltv->value3 << 8);
168
+           break;
169
+       case LC3_TYPE_BLKS:
170
+           spa_return_val_if_fail(ltv->len == 2, false);
171
+           conf->n_blks = ltv->value0;
172
+           if (!conf->n_blks)
173
+               return false;
174
+           break;
175
+       default:
176
+           return false;
177
+       }
178
+       data_size -= ltv->len + 1;
179
+       data += ltv->len + 1;
180
+   }
181
+
182
+   if (framelen_min < LC3_MIN_FRAME_BYTES || framelen_max > LC3_MAX_FRAME_BYTES)
183
+       return false;
184
+   if (conf->frame_duration == 0xFF || !conf->rate)
185
+       return false;
186
+   if (!conf->channels)
187
+       conf->channels = LC3_CONFIG_CHNL_FL;
188
+
189
+   switch (conf->rate) {
190
+   case LC3_CONFIG_FREQ_48KHZ:
191
+       if (conf->frame_duration == LC3_CONFIG_DURATION_7_5)
192
+           conf->framelen = 117;
193
+       else
194
+           conf->framelen = 120;
195
+       break;
196
+   case LC3_CONFIG_FREQ_24KHZ:
197
+       if (conf->frame_duration == LC3_CONFIG_DURATION_7_5)
198
+           conf->framelen = 45;
199
+       else
200
+           conf->framelen = 60;
201
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
201
 
1
@@ -100,7 +100,7 @@
2
 
3
    uint32_t id;
4
 
5
-   const struct a2dp_codec * const * a2dp_codecs;
6
+   const struct media_codec * const * media_codecs;
7
 
8
    /*
9
     * Lists of BlueZ objects, kept up-to-date by following DBus events
10
@@ -130,7 +130,9 @@
11
    struct spa_dict global_settings;
12
 
13
    /* A reference audio info for A2DP codec configuration. */
14
-   struct a2dp_codec_audio_info default_audio_info;
15
+   struct media_codec_audio_info default_audio_info;
16
+
17
+   bool le_audio_supported;
18
 };
19
 
20
 /* Stream endpoints owned by BlueZ for each device */
21
@@ -146,6 +148,7 @@
22
    uint8_t *capabilities;
23
    int capabilities_len;
24
    bool delay_reporting;
25
+   bool acceptor;
26
 };
27
 
28
 /*
29
@@ -155,7 +158,7 @@
30
  * with the desired capabilities.
31
  * The codec switch struct tracks candidates still to be tried.
32
  */
33
-struct spa_bt_a2dp_codec_switch {
34
+struct spa_bt_media_codec_switch {
35
    struct spa_bt_device *device;
36
    struct spa_list device_link;
37
 
38
@@ -172,10 +175,10 @@
39
     * Called asynchronously, so endpoint paths instead of pointers (which may be
40
     * invalidated in the meantime).
41
     */
42
-   const struct a2dp_codec **codecs;
43
+   const struct media_codec **codecs;
44
    char **paths;
45
 
46
-   const struct a2dp_codec **codec_iter;   /**< outer iterator over codecs */
47
+   const struct media_codec **codec_iter;  /**< outer iterator over codecs */
48
    char **path_iter;           /**< inner iterator over endpoint paths */
49
 
50
    uint16_t retries;
51
@@ -430,10 +433,17 @@
52
    }
53
 }
54
 
55
-static int a2dp_codec_to_endpoint(const struct a2dp_codec *codec,
56
-                  const char * endpoint,
57
+static int media_codec_to_endpoint(const struct media_codec *codec,
58
+                  enum spa_bt_media_direction direction,
59
                   char** object_path)
60
 {
61
+   const char * endpoint;
62
+
63
+   if (direction == SPA_BT_MEDIA_SOURCE)
64
+       endpoint = codec->bap ? BAP_SOURCE_ENDPOINT : A2DP_SOURCE_ENDPOINT;
65
+   else
66
+       endpoint = codec->bap ? BAP_SINK_ENDPOINT : A2DP_SINK_ENDPOINT;
67
+
68
    *object_path = spa_aprintf("%s/%s", endpoint,
69
        codec->endpoint_name ? codec->endpoint_name : codec->name);
70
    if (*object_path == NULL)
71
@@ -441,10 +451,10 @@
72
    return 0;
73
 }
74
 
75
-static const struct a2dp_codec *a2dp_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink)
76
+static const struct media_codec *media_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink)
77
 {
78
    const char *ep_name;
79
-   const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs;
80
+   const struct media_codec * const * const media_codecs = monitor->media_codecs;
81
    int i;
82
 
83
    if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) {
84
@@ -453,12 +463,19 @@
85
    } else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/")) {
86
        ep_name = endpoint + strlen(A2DP_SOURCE_ENDPOINT "/");
87
        *sink = false;
88
+   } else if (spa_strstartswith(endpoint, BAP_SOURCE_ENDPOINT "/")) {
89
+       ep_name = endpoint + strlen(BAP_SOURCE_ENDPOINT "/");
90
+       *sink = false;
91
+   } else if (spa_strstartswith(endpoint, BAP_SINK_ENDPOINT "/")) {
92
+       ep_name = endpoint + strlen(BAP_SINK_ENDPOINT "/");
93
+       *sink = true;
94
    } else {
95
+       *sink = true;
96
        return NULL;
97
    }
98
 
99
-   for (i = 0; a2dp_codecsi; i++) {
100
-       const struct a2dp_codec *codec = a2dp_codecsi;
101
+   for (i = 0; media_codecsi; i++) {
102
+       const struct media_codec *codec = media_codecsi;
103
        const char *codec_ep_name =
104
            codec->endpoint_name ? codec->endpoint_name : codec->name;
105
        if (spa_streq(ep_name, codec_ep_name))
106
@@ -467,18 +484,22 @@
107
    return NULL;
108
 }
109
 
110
-static int a2dp_endpoint_to_profile(const char *endpoint)
111
+static int media_endpoint_to_profile(const char *endpoint)
112
 {
113
 
114
    if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/"))
115
        return SPA_BT_PROFILE_A2DP_SOURCE;
116
    else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/"))
117
        return SPA_BT_PROFILE_A2DP_SINK;
118
+   else if (spa_strstartswith(endpoint, BAP_SINK_ENDPOINT "/"))
119
+       return SPA_BT_PROFILE_BAP_SOURCE;
120
+   else if (spa_strstartswith(endpoint, BAP_SOURCE_ENDPOINT "/"))
121
+       return SPA_BT_PROFILE_BAP_SINK;
122
    else
123
        return SPA_BT_PROFILE_NULL;
124
 }
125
 
126
-static bool is_a2dp_codec_enabled(struct spa_bt_monitor *monitor, const struct a2dp_codec *codec)
127
+static bool is_media_codec_enabled(struct spa_bt_monitor *monitor, const struct media_codec *codec)
128
 {
129
    return spa_dict_lookup(&monitor->enabled_codecs, codec->name) != NULL;
130
 }
131
@@ -492,7 +513,7 @@
132
    DBusMessage *r;
133
    DBusError err;
134
    int size, res;
135
-   const struct a2dp_codec *codec;
136
+   const struct media_codec *codec;
137
    bool sink;
138
 
139
    dbus_error_init(&err);
140
@@ -508,14 +529,14 @@
141
    spa_log_info(monitor->log, "%p: %s select conf %d", monitor, path, size);
142
    spa_log_hexdump(monitor->log, SPA_LOG_LEVEL_DEBUG, 2, cap, (size_t)size);
143
 
144
-   codec = a2dp_endpoint_to_codec(monitor, path, &sink);
145
+   codec = media_endpoint_to_codec(monitor, path, &sink);
146
    if (codec != NULL)
147
        /* FIXME: We can't determine which device the SelectConfiguration()
148
         * call is associated with, therefore device settings are not passed.
149
         * This causes inconsistency with SelectConfiguration() triggered
150
         * by codec switching.
151
          */
152
-       res = codec->select_config(codec, sink ? A2DP_CODEC_FLAG_SINK : 0, cap, size, &monitor->default_audio_info,
153
+       res = codec->select_config(codec, sink ? MEDIA_CODEC_FLAG_SINK : 0, cap, size, &monitor->default_audio_info,
154
                &monitor->global_settings, config);
155
    else
156
        res = -ENOTSUP;
157
@@ -545,6 +566,171 @@
158
    return DBUS_HANDLER_RESULT_HANDLED;
159
 }
160
 
161
+static void append_basic_variant_dict_entry(DBusMessageIter *dict, const char* key, int variant_type_int, const char* variant_type_str, void* variant);
162
+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);
163
+static struct spa_bt_remote_endpoint *remote_endpoint_find(struct spa_bt_monitor *monitor, const char *path);
164
+
165
+static DBusHandlerResult endpoint_select_properties(DBusConnection *conn, DBusMessage *m, void *userdata)
166
+{
167
+   struct spa_bt_monitor *monitor = userdata;
168
+   const char *path;
169
+   const char *object_path;
170
+   DBusMessageIter args, props, iter;
171
+   DBusMessage *r = NULL;
172
+   int size, res;
173
+   const struct media_codec *codec;
174
+   bool sink;
175
+
176
+   if (!dbus_message_iter_init(m, &args) || !spa_streq(dbus_message_get_signature(m), "a{sv}")) {
177
+       spa_log_error(monitor->log, "Invalid signature for method SelectProperties()");
178
+       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
179
+   }
180
+
181
+   dbus_message_iter_recurse(&args, &props);
182
+   if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
183
+       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
184
+
185
+   path = dbus_message_get_path(m);
186
+
187
+   codec = media_endpoint_to_codec(monitor, path, &sink);
188
+   if (!codec) {
189
+       res = -ENOTSUP;
190
+       spa_log_error(monitor->log, "Unsupported codec: %d (%s)",
191
+               res, spa_strerror(res));
192
+       if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments",
193
+               "Unsupported codec")) == NULL)
194
+           return DBUS_HANDLER_RESULT_NEED_MEMORY;
195
+       goto exit_send;
196
+   }
197
+
198
+   /* Read transport properties */
199
+   while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
200
+       const char *key;
201
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
201
 
1
@@ -51,7 +51,7 @@
2
 #include <spa/debug/pod.h>
3
 
4
 #include "defs.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
 static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.device");
9
 #undef SPA_LOG_TOPIC_DEFAULT
10
@@ -73,6 +73,7 @@
11
    DEVICE_PROFILE_AG = 1,
12
    DEVICE_PROFILE_A2DP = 2,
13
    DEVICE_PROFILE_HSP_HFP = 3,
14
+   DEVICE_PROFILE_BAP = 4,
15
 };
16
 
17
 struct props {
18
@@ -140,11 +141,11 @@
19
    unsigned int save_profile:1;
20
    uint32_t prev_bt_connected_profiles;
21
 
22
-   const struct a2dp_codec **supported_codecs;
23
+   const struct media_codec **supported_codecs;
24
    size_t supported_codec_count;
25
 
26
-   struct dynamic_node dyn_a2dp_source;
27
-   struct dynamic_node dyn_a2dp_sink;
28
+   struct dynamic_node dyn_media_source;
29
+   struct dynamic_node dyn_media_sink;
30
    struct dynamic_node dyn_sco_source;
31
    struct dynamic_node dyn_sco_sink;
32
 
33
@@ -167,9 +168,9 @@
34
    }
35
 }
36
 
37
-static void get_a2dp_codecs(struct impl *this, enum spa_bluetooth_audio_codec id, const struct a2dp_codec **codecs, size_t size)
38
+static void get_media_codecs(struct impl *this, enum spa_bluetooth_audio_codec id, const struct media_codec **codecs, size_t size)
39
 {
40
-   const struct a2dp_codec * const *c;
41
+   const struct media_codec * const *c;
42
 
43
    spa_assert(size > 0);
44
    spa_assert(this->supported_codecs);
45
@@ -184,18 +185,18 @@
46
    *codecs = NULL;
47
 }
48
 
49
-static const struct a2dp_codec *get_supported_a2dp_codec(struct impl *this, enum spa_bluetooth_audio_codec id, size_t *idx)
50
+static const struct media_codec *get_supported_media_codec(struct impl *this, enum spa_bluetooth_audio_codec id, size_t *idx)
51
 {
52
-   const struct a2dp_codec *a2dp_codec = NULL;
53
+   const struct media_codec *media_codec = NULL;
54
    size_t i;
55
    for (i = 0; i < this->supported_codec_count; ++i) {
56
        if (this->supported_codecsi->id == id) {
57
-           a2dp_codec = this->supported_codecsi;
58
+           media_codec = this->supported_codecsi;
59
            if (idx)
60
                *idx = i;
61
        }
62
    }
63
-   return a2dp_codec;
64
+   return media_codec;
65
 }
66
 
67
 static unsigned int get_hfp_codec(enum spa_bluetooth_audio_codec id)
68
@@ -245,10 +246,10 @@
69
 
70
 static const char *get_codec_name(struct spa_bt_transport *t, bool a2dp_duplex)
71
 {
72
-   if (t->a2dp_codec != NULL) {
73
-       if (a2dp_duplex && t->a2dp_codec->duplex_codec)
74
-           return t->a2dp_codec->duplex_codec->name;
75
-       return t->a2dp_codec->name;
76
+   if (t->media_codec != NULL) {
77
+       if (a2dp_duplex && t->media_codec->duplex_codec)
78
+           return t->media_codec->duplex_codec->name;
79
+       return t->media_codec->name;
80
    }
81
    return get_hfp_codec_name(t->codec);
82
 }
83
@@ -301,7 +302,7 @@
84
 
85
 static float get_soft_volume_boost(struct node *node)
86
 {
87
-   const struct a2dp_codec *codec = node->transport ? node->transport->a2dp_codec : NULL;
88
+   const struct media_codec *codec = node->transport ? node->transport->media_codec : NULL;
89
 
90
    /*
91
     * For A2DP duplex, the duplex microphone channel sometimes does not appear
92
@@ -351,6 +352,7 @@
93
 
94
    /* PW is the controller for remote device. */
95
    if (impl->profile != DEVICE_PROFILE_A2DP
96
+       && impl->profile != DEVICE_PROFILE_BAP
97
        && impl->profile !=  DEVICE_PROFILE_HSP_HFP)
98
        return false;
99
 
100
@@ -406,16 +408,16 @@
101
 
102
 static void get_channels(struct spa_bt_transport *t, bool a2dp_duplex, uint32_t *n_channels, uint32_t *channels)
103
 {
104
-   const struct a2dp_codec *codec;
105
+   const struct media_codec *codec;
106
    struct spa_audio_info info = { 0 };
107
 
108
-   if (!a2dp_duplex || !t->a2dp_codec || !t->a2dp_codec->duplex_codec) {
109
+   if (!a2dp_duplex || !t->media_codec || !t->media_codec->duplex_codec) {
110
        *n_channels = t->n_channels;
111
        memcpy(channels, t->channels, t->n_channels * sizeof(uint32_t));
112
        return;
113
    }
114
 
115
-   codec = t->a2dp_codec->duplex_codec;
116
+   codec = t->media_codec->duplex_codec;
117
 
118
    if (!codec->validate_config ||
119
            codec->validate_config(codec, 0,
120
@@ -514,7 +516,7 @@
121
 
122
    spa_list_for_each(t, &device->transport_list, device_link) {
123
        bool codec_ok = codec == 0 ||
124
-           (t->a2dp_codec != NULL && t->a2dp_codec->id == codec) ||
125
+           (t->media_codec != NULL && t->media_codec->id == codec) ||
126
            get_hfp_codec_id(t->codec) == codec;
127
 
128
        if ((t->profile & device->connected_profiles) &&
129
@@ -676,15 +678,15 @@
130
                        1, SPA_NAME_API_BLUEZ5_SCO_SINK, false);
131
            }
132
        }
133
-       if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE) {
134
+       if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_A2DP_SOURCE)) {
135
            t = find_transport(this, SPA_BT_PROFILE_A2DP_SOURCE, 0);
136
            if (t) {
137
-               this->props.codec = t->a2dp_codec->id;
138
-               emit_dynamic_node(&this->dyn_a2dp_source, this, t,
139
+               this->props.codec = t->media_codec->id;
140
+               emit_dynamic_node(&this->dyn_media_source, this, t,
141
                        2, SPA_NAME_API_BLUEZ5_A2DP_SOURCE, false);
142
 
143
-               if (t->a2dp_codec->duplex_codec) {
144
-                   emit_dynamic_node(&this->dyn_a2dp_sink, this, t,
145
+               if (t->media_codec->duplex_codec) {
146
+                   emit_dynamic_node(&this->dyn_media_sink, this, t,
147
                        3, SPA_NAME_API_BLUEZ5_A2DP_SINK, true);
148
                }
149
            }
150
@@ -694,11 +696,11 @@
151
        if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE) {
152
            t = find_transport(this, SPA_BT_PROFILE_A2DP_SOURCE, 0);
153
            if (t) {
154
-               this->props.codec = t->a2dp_codec->id;
155
-               emit_dynamic_node(&this->dyn_a2dp_source, this, t,
156
+               this->props.codec = t->media_codec->id;
157
+               emit_dynamic_node(&this->dyn_media_source, this, t,
158
                    DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_A2DP_SOURCE, false);
159
 
160
-               if (t->a2dp_codec->duplex_codec) {
161
+               if (t->media_codec->duplex_codec) {
162
                    emit_node(this, t,
163
                        DEVICE_ID_SINK, SPA_NAME_API_BLUEZ5_A2DP_SINK, true);
164
                }
165
@@ -708,17 +710,45 @@
166
        if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) {
167
            t = find_transport(this, SPA_BT_PROFILE_A2DP_SINK, this->props.codec);
168
            if (t) {
169
-               this->props.codec = t->a2dp_codec->id;
170
+               this->props.codec = t->media_codec->id;
171
                emit_node(this, t, DEVICE_ID_SINK, SPA_NAME_API_BLUEZ5_A2DP_SINK, false);
172
 
173
-               if (t->a2dp_codec->duplex_codec) {
174
+               if (t->media_codec->duplex_codec) {
175
                    emit_node(this, t,
176
                        DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_A2DP_SOURCE, true);
177
                }
178
            }
179
        }
180
 
181
-       if (get_supported_a2dp_codec(this, this->props.codec, NULL) == NULL)
182
+       if (get_supported_media_codec(this, this->props.codec, NULL) == NULL)
183
+           this->props.codec = 0;
184
+       break;
185
+   case DEVICE_PROFILE_BAP:
186
+       if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_BAP_SOURCE)) {
187
+           t = find_transport(this, SPA_BT_PROFILE_BAP_SOURCE, 0);
188
+           if (t) {
189
+               this->props.codec = t->media_codec->id;
190
+               if (t->bap_initiator)
191
+                   emit_node(this, t, DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_MEDIA_SOURCE, false);
192
+               else
193
+                   emit_dynamic_node(&this->dyn_media_source, this, t,
194
+                       DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_MEDIA_SOURCE, false);
195
+           }
196
+       }
197
+
198
+       if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_BAP_SINK)) {
199
+           t = find_transport(this, SPA_BT_PROFILE_BAP_SINK, this->props.codec);
200
+           if (t) {
201
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
164
 
1
@@ -29,7 +29,7 @@
2
 #include "defs.h"
3
 #include "codec-loader.h"
4
 
5
-#define A2DP_CODEC_LIB_BASE    "bluez5/libspa-codec-bluez5-"
6
+#define MEDIA_CODEC_LIB_BASE   "bluez5/libspa-codec-bluez5-"
7
 
8
 /* AVDTP allows 0x3E endpoints, can't have more codecs than that */
9
 #define MAX_CODECS 0x3E
10
@@ -40,7 +40,7 @@
11
 #define SPA_LOG_TOPIC_DEFAULT &log_topic
12
 
13
 struct impl {
14
-   const struct a2dp_codec *codecsMAX_CODECS + 1;
15
+   const struct media_codec *codecsMAX_CODECS + 1;
16
    struct spa_handle *handlesMAX_HANDLES;
17
    size_t n_codecs;
18
    size_t n_handles;
19
@@ -48,9 +48,10 @@
20
    struct spa_log *log;
21
 };
22
 
23
-static int codec_order(const struct a2dp_codec *c)
24
+static int codec_order(const struct media_codec *c)
25
 {
26
    static const enum spa_bluetooth_audio_codec order = {
27
+       SPA_BLUETOOTH_AUDIO_CODEC_LC3,
28
        SPA_BLUETOOTH_AUDIO_CODEC_LDAC,
29
        SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD,
30
        SPA_BLUETOOTH_AUDIO_CODEC_APTX,
31
@@ -78,8 +79,8 @@
32
 
33
 static int codec_order_cmp(const void *a, const void *b)
34
 {
35
-   const struct a2dp_codec * const *ca = a;
36
-   const struct a2dp_codec * const *cb = b;
37
+   const struct media_codec * const *ca = a;
38
+   const struct media_codec * const *cb = b;
39
    int ia = codec_order(*ca);
40
    int ib = codec_order(*cb);
41
    if (*ca == *cb)
42
@@ -87,7 +88,7 @@
43
    return (ia == ib) ? (*ca < *cb ? -1 : 1) : ia - ib;
44
 }
45
 
46
-static int load_a2dp_codecs_from(struct impl *impl, const char *factory_name, const char *libname)
47
+static int load_media_codecs_from(struct impl *impl, const char *factory_name, const char *libname)
48
 {
49
    struct spa_handle *handle = NULL;
50
    void *iface;
51
@@ -108,7 +109,7 @@
52
 
53
    spa_log_debug(impl->log, "loading codecs from %s", factory_name);
54
 
55
-   if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Bluez5CodecA2DP, &iface)) < 0) {
56
+   if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Bluez5CodecMedia, &iface)) < 0) {
57
        spa_log_warn(impl->log, "Bluetooth codec plugin %s has no codec interface",
58
                factory_name);
59
        goto fail;
60
@@ -116,15 +117,15 @@
61
 
62
    bluez5_codec_a2dp = iface;
63
 
64
-   if (bluez5_codec_a2dp->iface.version != SPA_VERSION_BLUEZ5_CODEC_A2DP) {
65
+   if (bluez5_codec_a2dp->iface.version != SPA_VERSION_BLUEZ5_CODEC_MEDIA) {
66
        spa_log_warn(impl->log, "codec plugin %s has incompatible ABI version (%d != %d)",
67
-               factory_name, bluez5_codec_a2dp->iface.version, SPA_VERSION_BLUEZ5_CODEC_A2DP);
68
+               factory_name, bluez5_codec_a2dp->iface.version, SPA_VERSION_BLUEZ5_CODEC_MEDIA);
69
        res = -ENOENT;
70
        goto fail;
71
    }
72
 
73
    for (i = 0; bluez5_codec_a2dp->codecsi; ++i) {
74
-       const struct a2dp_codec *c = bluez5_codec_a2dp->codecsi;
75
+       const struct media_codec *c = bluez5_codec_a2dp->codecsi;
76
        size_t j;
77
 
78
        if (impl->n_codecs >= MAX_CODECS) {
79
@@ -134,14 +135,14 @@
80
 
81
        /* Don't load duplicate endpoints */
82
        for (j = 0; j < impl->n_codecs; ++j) {
83
-           const struct a2dp_codec *c2 = impl->codecsj;
84
+           const struct media_codec *c2 = impl->codecsj;
85
            const char *ep1 = c->endpoint_name ? c->endpoint_name : c->name;
86
            const char *ep2 = c2->endpoint_name ? c2->endpoint_name : c2->name;
87
            if (spa_streq(ep1, ep2))
88
                goto next_codec;
89
        }
90
 
91
-       spa_log_debug(impl->log, "loaded A2DP codec %s from %s", c->name, factory_name);
92
+       spa_log_debug(impl->log, "loaded media codec %s from %s", c->name, factory_name);
93
 
94
        if (c->set_log)
95
            c->set_log(impl->log);
96
@@ -166,22 +167,23 @@
97
    return res;
98
 }
99
 
100
-const struct a2dp_codec * const *load_a2dp_codecs(struct spa_plugin_loader *loader, struct spa_log *log)
101
+const struct media_codec * const *load_media_codecs(struct spa_plugin_loader *loader, struct spa_log *log)
102
 {
103
    struct impl *impl;
104
    bool has_sbc;
105
    size_t i;
106
    const struct { const char *factory; const char *lib; } plugins = {
107
-#define A2DP_CODEC_FACTORY_LIB(basename) \
108
-       { A2DP_CODEC_FACTORY_NAME(basename), A2DP_CODEC_LIB_BASE basename }
109
-       A2DP_CODEC_FACTORY_LIB("aac"),
110
-       A2DP_CODEC_FACTORY_LIB("aptx"),
111
-       A2DP_CODEC_FACTORY_LIB("faststream"),
112
-       A2DP_CODEC_FACTORY_LIB("ldac"),
113
-       A2DP_CODEC_FACTORY_LIB("sbc"),
114
-       A2DP_CODEC_FACTORY_LIB("lc3plus"),
115
-       A2DP_CODEC_FACTORY_LIB("opus")
116
-#undef A2DP_CODEC_FACTORY_LIB
117
+#define MEDIA_CODEC_FACTORY_LIB(basename) \
118
+       { MEDIA_CODEC_FACTORY_NAME(basename), MEDIA_CODEC_LIB_BASE basename }
119
+       MEDIA_CODEC_FACTORY_LIB("aac"),
120
+       MEDIA_CODEC_FACTORY_LIB("aptx"),
121
+       MEDIA_CODEC_FACTORY_LIB("faststream"),
122
+       MEDIA_CODEC_FACTORY_LIB("ldac"),
123
+       MEDIA_CODEC_FACTORY_LIB("sbc"),
124
+       MEDIA_CODEC_FACTORY_LIB("lc3plus"),
125
+       MEDIA_CODEC_FACTORY_LIB("opus"),
126
+       MEDIA_CODEC_FACTORY_LIB("lc3")
127
+#undef MEDIA_CODEC_FACTORY_LIB
128
    };
129
 
130
    impl = calloc(sizeof(struct impl), 1);
131
@@ -194,7 +196,7 @@
132
    spa_log_topic_init(impl->log, &log_topic);
133
 
134
    for (i = 0; i < SPA_N_ELEMENTS(plugins); ++i)
135
-       load_a2dp_codecs_from(impl, pluginsi.factory, pluginsi.lib);
136
+       load_media_codecs_from(impl, pluginsi.factory, pluginsi.lib);
137
 
138
    has_sbc = false;
139
    for (i = 0; i < impl->n_codecs; ++i)
140
@@ -203,19 +205,19 @@
141
 
142
    if (!has_sbc) {
143
        spa_log_error(impl->log, "failed to load A2DP SBC codec from plugins");
144
-       free_a2dp_codecs(impl->codecs);
145
+       free_media_codecs(impl->codecs);
146
        errno = ENOENT;
147
        return NULL;
148
    }
149
 
150
-   qsort(impl->codecs, impl->n_codecs, sizeof(const struct a2dp_codec *), codec_order_cmp);
151
+   qsort(impl->codecs, impl->n_codecs, sizeof(const struct media_codec *), codec_order_cmp);
152
 
153
    return impl->codecs;
154
 }
155
 
156
-void free_a2dp_codecs(const struct a2dp_codec * const *a2dp_codecs)
157
+void free_media_codecs(const struct media_codec * const *media_codecs)
158
 {
159
-   struct impl *impl = SPA_CONTAINER_OF(a2dp_codecs, struct impl, codecs);
160
+   struct impl *impl = SPA_CONTAINER_OF(media_codecs, struct impl, codecs);
161
    size_t i;
162
 
163
    for (i = 0; i < impl->n_handles; ++i)
164
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
14
 
1
@@ -31,9 +31,9 @@
2
 #include <spa/support/plugin-loader.h>
3
 
4
 #include "a2dp-codec-caps.h"
5
-#include "a2dp-codecs.h"
6
+#include "media-codecs.h"
7
 
8
-const struct a2dp_codec * const *load_a2dp_codecs(struct spa_plugin_loader *loader, struct spa_log *log);
9
-void free_a2dp_codecs(const struct a2dp_codec * const *a2dp_codecs);
10
+const struct media_codec * const *load_media_codecs(struct spa_plugin_loader *loader, struct spa_log *log);
11
+void free_media_codecs(const struct media_codec * const *media_codecs);
12
 
13
 #endif
14
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/defs.h Changed
133
 
1
@@ -141,6 +141,9 @@
2
 #define SPA_BT_UUID_HSP_AG      "00001112-0000-1000-8000-00805f9b34fb"
3
 #define SPA_BT_UUID_HFP_HF      "0000111e-0000-1000-8000-00805f9b34fb"
4
 #define SPA_BT_UUID_HFP_AG      "0000111f-0000-1000-8000-00805f9b34fb"
5
+#define SPA_BT_UUID_PACS        "00001850-0000-1000-8000-00805f9b34fb"
6
+#define SPA_BT_UUID_BAP_SINK    "00002bc9-0000-1000-8000-00805f9b34fb"
7
+#define SPA_BT_UUID_BAP_SOURCE  "00002bcb-0000-1000-8000-00805f9b34fb"
8
 
9
 #define PROFILE_HSP_AG "/Profile/HSPAG"
10
 #define PROFILE_HSP_HS "/Profile/HSPHS"
11
@@ -158,9 +161,12 @@
12
 #define HFP_AUDIO_CODEC_CVSD    0x01
13
 #define HFP_AUDIO_CODEC_MSBC    0x02
14
 
15
-#define A2DP_OBJECT_MANAGER_PATH "/MediaEndpoint"
16
-#define A2DP_SINK_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSink"
17
-#define A2DP_SOURCE_ENDPOINT   A2DP_OBJECT_MANAGER_PATH "/A2DPSource"
18
+#define MEDIA_OBJECT_MANAGER_PATH "/MediaEndpoint"
19
+#define A2DP_SINK_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/A2DPSink"
20
+#define A2DP_SOURCE_ENDPOINT   MEDIA_OBJECT_MANAGER_PATH "/A2DPSource"
21
+
22
+#define BAP_SINK_ENDPOINT  MEDIA_OBJECT_MANAGER_PATH "/BAPSink"
23
+#define BAP_SOURCE_ENDPOINT    MEDIA_OBJECT_MANAGER_PATH "/BAPSource"
24
 
25
 #define SPA_BT_UNKNOWN_DELAY           0
26
 
27
@@ -172,19 +178,30 @@
28
 #define MSBC_ENCODED_SIZE       60  /* 2 bytes header + 57 mSBC payload + 1 byte padding */
29
 #define MSBC_PAYLOAD_SIZE       57
30
 
31
+enum spa_bt_media_direction {
32
+   SPA_BT_MEDIA_SOURCE,
33
+   SPA_BT_MEDIA_SINK,
34
+};
35
+
36
 enum spa_bt_profile {
37
    SPA_BT_PROFILE_NULL =       0,
38
-   SPA_BT_PROFILE_A2DP_SINK =  (1 << 0),
39
-   SPA_BT_PROFILE_A2DP_SOURCE =    (1 << 1),
40
-   SPA_BT_PROFILE_HSP_HS =     (1 << 2),
41
-   SPA_BT_PROFILE_HSP_AG =     (1 << 3),
42
-   SPA_BT_PROFILE_HFP_HF =     (1 << 4),
43
-   SPA_BT_PROFILE_HFP_AG =     (1 << 5),
44
+   SPA_BT_PROFILE_BAP_SINK =   (1 << 0),
45
+   SPA_BT_PROFILE_BAP_SOURCE = (1 << 1),
46
+   SPA_BT_PROFILE_A2DP_SINK =  (1 << 2),
47
+   SPA_BT_PROFILE_A2DP_SOURCE =    (1 << 3),
48
+   SPA_BT_PROFILE_HSP_HS =     (1 << 4),
49
+   SPA_BT_PROFILE_HSP_AG =     (1 << 5),
50
+   SPA_BT_PROFILE_HFP_HF =     (1 << 6),
51
+   SPA_BT_PROFILE_HFP_AG =     (1 << 7),
52
 
53
    SPA_BT_PROFILE_A2DP_DUPLEX =    (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_A2DP_SOURCE),
54
+   SPA_BT_PROFILE_BAP_DUPLEX =     (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE),
55
    SPA_BT_PROFILE_HEADSET_HEAD_UNIT = (SPA_BT_PROFILE_HSP_HS | SPA_BT_PROFILE_HFP_HF),
56
    SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY = (SPA_BT_PROFILE_HSP_AG | SPA_BT_PROFILE_HFP_AG),
57
    SPA_BT_PROFILE_HEADSET_AUDIO =  (SPA_BT_PROFILE_HEADSET_HEAD_UNIT | SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY),
58
+
59
+   SPA_BT_PROFILE_MEDIA_SINK =     (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_BAP_SINK),
60
+   SPA_BT_PROFILE_MEDIA_SOURCE =   (SPA_BT_PROFILE_A2DP_SOURCE | SPA_BT_PROFILE_BAP_SOURCE),
61
 };
62
 
63
 static inline enum spa_bt_profile spa_bt_profile_from_uuid(const char *uuid)
64
@@ -203,6 +220,10 @@
65
        return SPA_BT_PROFILE_HFP_HF;
66
    else if (strcasecmp(uuid, SPA_BT_UUID_HFP_AG) == 0)
67
        return SPA_BT_PROFILE_HFP_AG;
68
+   else if (strcasecmp(uuid, SPA_BT_UUID_BAP_SINK) == 0)
69
+       return SPA_BT_PROFILE_BAP_SINK;
70
+   else if (strcasecmp(uuid, SPA_BT_UUID_BAP_SOURCE) == 0)
71
+       return SPA_BT_PROFILE_BAP_SOURCE;
72
    else
73
        return 0;
74
 }
75
@@ -303,6 +324,12 @@
76
    return "headset-audio-gateway";
77
       case SPA_BT_PROFILE_HEADSET_AUDIO:
78
    return "headset-audio";
79
+      case SPA_BT_PROFILE_BAP_SOURCE:
80
+        return "bap-source";
81
+      case SPA_BT_PROFILE_BAP_SINK:
82
+        return "bap-sink";
83
+      case SPA_BT_PROFILE_BAP_DUPLEX:
84
+        return "bap-duplex";
85
       default:
86
         break;
87
       }
88
@@ -412,7 +439,7 @@
89
    return SPA_BT_FORM_FACTOR_UNKNOWN;
90
 }
91
 
92
-struct spa_bt_a2dp_codec_switch;
93
+struct spa_bt_media_codec_switch;
94
 struct spa_bt_transport;
95
 
96
 struct spa_bt_device_events {
97
@@ -482,16 +509,16 @@
98
    DBusPendingCall *battery_pending_call;
99
 };
100
 
101
-struct a2dp_codec;
102
+struct media_codec;
103
 
104
 struct spa_bt_device *spa_bt_device_find(struct spa_bt_monitor *monitor, const char *path);
105
 struct spa_bt_device *spa_bt_device_find_by_address(struct spa_bt_monitor *monitor, const char *remote_address, const char *local_address);
106
 int spa_bt_device_add_profile(struct spa_bt_device *device, enum spa_bt_profile profile);
107
 int spa_bt_device_connect_profile(struct spa_bt_device *device, enum spa_bt_profile profile);
108
 int spa_bt_device_check_profiles(struct spa_bt_device *device, bool force);
109
-int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec * const *codecs);
110
-bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink);
111
-const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink);
112
+int spa_bt_device_ensure_media_codec(struct spa_bt_device *device, const struct media_codec * const *codecs);
113
+bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const struct media_codec *codec, bool sink);
114
+const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_bt_device *device, size_t *count, bool sink);
115
 int spa_bt_device_ensure_hfp_codec(struct spa_bt_device *device, unsigned int codec);
116
 int spa_bt_device_supports_hfp_codec(struct spa_bt_device *device, unsigned int codec);
117
 int spa_bt_device_release_transports(struct spa_bt_device *device);
118
@@ -570,11 +597,13 @@
119
    struct spa_list device_link;
120
    enum spa_bt_profile profile;
121
    enum spa_bt_transport_state state;
122
-   const struct a2dp_codec *a2dp_codec;
123
+   const struct media_codec *media_codec;
124
    unsigned int codec;
125
    void *configuration;
126
    int configuration_len;
127
    char *endpoint_path;
128
+   bool bap_initiator;
129
+   struct spa_list bap_transport_linked;
130
 
131
    uint32_t n_channels;
132
    uint32_t channels64;
133
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-codecs.c Added
201
 
1
@@ -0,0 +1,209 @@
2
+/*
3
+ * BlueALSA - bluez-a2dp.c
4
+ * Copyright (c) 2016-2017 Arkadiusz Bokowy
5
+ *
6
+ * This file is a part of bluez-alsa.
7
+ *
8
+ * This project is licensed under the terms of the MIT license.
9
+ *
10
+ */
11
+
12
+#include <spa/utils/string.h>
13
+
14
+#include "media-codecs.h"
15
+
16
+int media_codec_select_config(const struct media_codec_config configs, size_t n,
17
+                uint32_t cap, int preferred_value)
18
+{
19
+   size_t i;
20
+   int *scores, res;
21
+   unsigned int max_priority;
22
+
23
+   if (n == 0)
24
+       return -EINVAL;
25
+
26
+   scores = calloc(n, sizeof(int));
27
+   if (scores == NULL)
28
+       return -errno;
29
+
30
+   max_priority = configs0.priority;
31
+   for (i = 1; i < n; ++i) {
32
+       if (configsi.priority > max_priority)
33
+           max_priority = configsi.priority;
34
+   }
35
+
36
+   for (i = 0; i < n; ++i) {
37
+       if (!(configsi.config & cap)) {
38
+           scoresi = -1;
39
+           continue;
40
+       }
41
+       if (configsi.value == preferred_value)
42
+           scoresi = 100 * (max_priority + 1);
43
+       else if (configsi.value > preferred_value)
44
+           scoresi = 10 * (max_priority + 1);
45
+       else
46
+           scoresi = 1;
47
+
48
+       scoresi *= configsi.priority + 1;
49
+   }
50
+
51
+   res = 0;
52
+   for (i = 1; i < n; ++i) {
53
+       if (scoresi > scoresres)
54
+           res = i;
55
+   }
56
+
57
+   if (scoresres < 0)
58
+       res = -EINVAL;
59
+
60
+   free(scores);
61
+   return res;
62
+}
63
+
64
+bool media_codec_check_caps(const struct media_codec *codec, unsigned int codec_id,
65
+              const void *caps, size_t caps_size,
66
+              const struct media_codec_audio_info *info,
67
+              const struct spa_dict *global_settings)
68
+{
69
+   uint8_t configA2DP_MAX_CAPS_SIZE;
70
+   int res;
71
+
72
+   if (codec_id != codec->codec_id)
73
+       return false;
74
+
75
+   if (caps == NULL)
76
+       return false;
77
+
78
+   res = codec->select_config(codec, 0, caps, caps_size, info, global_settings, config);
79
+   if (res < 0)
80
+       return false;
81
+
82
+   return ((size_t)res == caps_size);
83
+}
84
+
85
+#ifdef CODEC_PLUGIN
86
+
87
+struct impl {
88
+   struct spa_handle handle;
89
+   struct spa_bluez5_codec_a2dp bluez5_codec_a2dp;
90
+};
91
+
92
+static int
93
+impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
94
+{
95
+   struct impl *this;
96
+
97
+   spa_return_val_if_fail(handle != NULL, -EINVAL);
98
+   spa_return_val_if_fail(interface != NULL, -EINVAL);
99
+
100
+   this = (struct impl *) handle;
101
+
102
+   if (spa_streq(type, SPA_TYPE_INTERFACE_Bluez5CodecMedia))
103
+       *interface = &this->bluez5_codec_a2dp;
104
+   else
105
+       return -ENOENT;
106
+
107
+   return 0;
108
+}
109
+
110
+static int
111
+impl_clear(struct spa_handle *handle)
112
+{
113
+   spa_return_val_if_fail(handle != NULL, -EINVAL);
114
+   return 0;
115
+}
116
+
117
+static size_t
118
+impl_get_size(const struct spa_handle_factory *factory, const struct spa_dict *params)
119
+{
120
+   return sizeof(struct impl);
121
+}
122
+
123
+static int
124
+impl_init(const struct spa_handle_factory *factory,
125
+       struct spa_handle *handle,
126
+       const struct spa_dict *info,
127
+       const struct spa_support *support,
128
+       uint32_t n_support)
129
+{
130
+   struct impl *this;
131
+
132
+   spa_return_val_if_fail(factory != NULL, -EINVAL);
133
+   spa_return_val_if_fail(handle != NULL, -EINVAL);
134
+
135
+   handle->get_interface = impl_get_interface;
136
+   handle->clear = impl_clear;
137
+
138
+   this = (struct impl *) handle;
139
+
140
+   this->bluez5_codec_a2dp.codecs = codec_plugin_media_codecs;
141
+   this->bluez5_codec_a2dp.iface = SPA_INTERFACE_INIT(
142
+       SPA_TYPE_INTERFACE_Bluez5CodecMedia,
143
+       SPA_VERSION_BLUEZ5_CODEC_MEDIA,
144
+       NULL,
145
+       this);
146
+
147
+   return 0;
148
+}
149
+
150
+static const struct spa_interface_info impl_interfaces = {
151
+        {SPA_TYPE_INTERFACE_Bluez5CodecMedia,},
152
+};
153
+
154
+static int
155
+impl_enum_interface_info(const struct spa_handle_factory *factory,
156
+            const struct spa_interface_info **info,
157
+            uint32_t *index)
158
+{
159
+   spa_return_val_if_fail(factory != NULL, -EINVAL);
160
+   spa_return_val_if_fail(info != NULL, -EINVAL);
161
+   spa_return_val_if_fail(index != NULL, -EINVAL);
162
+
163
+   switch (*index) {
164
+   case 0:
165
+       *info = &impl_interfaces*index;
166
+       break;
167
+   default:
168
+       return 0;
169
+   }
170
+   (*index)++;
171
+
172
+   return 1;
173
+}
174
+
175
+static const struct spa_dict_item handle_info_items = {
176
+        { SPA_KEY_FACTORY_DESCRIPTION, "Bluetooth codec plugin" },
177
+};
178
+
179
+static const struct spa_dict handle_info = SPA_DICT_INIT_ARRAY(handle_info_items);
180
+
181
+static struct spa_handle_factory handle_factory = {
182
+   SPA_VERSION_HANDLE_FACTORY,
183
+   NULL,
184
+   &handle_info,
185
+   impl_get_size,
186
+   impl_init,
187
+   impl_enum_interface_info,
188
+};
189
+
190
+SPA_EXPORT
191
+int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
192
+{
193
+   spa_return_val_if_fail(factory != NULL, -EINVAL);
194
+   spa_return_val_if_fail(index != NULL, -EINVAL);
195
+
196
+   if (handle_factory.name == NULL)
197
+       handle_factory.name = codec_plugin_factory_name;
198
+
199
+   switch (*index) {
200
+   case 0:
201
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-codecs.h Added
186
 
1
@@ -0,0 +1,184 @@
2
+/* Spa A2DP codec API
3
+ *
4
+ * Copyright © 2020 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+#ifndef SPA_BLUEZ5_A2DP_CODECS_H_
26
+#define SPA_BLUEZ5_A2DP_CODECS_H_
27
+
28
+#include <stdint.h>
29
+#include <stddef.h>
30
+
31
+#include <spa/param/audio/format.h>
32
+#include <spa/param/bluetooth/audio.h>
33
+#include <spa/utils/names.h>
34
+#include <spa/support/plugin.h>
35
+#include <spa/pod/pod.h>
36
+#include <spa/pod/builder.h>
37
+#include <spa/support/log.h>
38
+
39
+#include "a2dp-codec-caps.h"
40
+
41
+/*
42
+ * The codec plugin SPA interface is private.  The version should be incremented
43
+ * when any of the structs or semantics change.
44
+ */
45
+
46
+#define SPA_TYPE_INTERFACE_Bluez5CodecMedia    SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:Media:Private"
47
+
48
+#define SPA_VERSION_BLUEZ5_CODEC_MEDIA     5
49
+
50
+struct spa_bluez5_codec_a2dp {
51
+   struct spa_interface iface;
52
+   const struct media_codec * const *codecs;   /**< NULL terminated array */
53
+};
54
+
55
+#define MEDIA_CODEC_FACTORY_NAME(basename)     (SPA_NAME_API_CODEC_BLUEZ5_MEDIA "." basename)
56
+
57
+#ifdef CODEC_PLUGIN
58
+#define MEDIA_CODEC_EXPORT_DEF(basename,...)   \
59
+   const char *codec_plugin_factory_name = MEDIA_CODEC_FACTORY_NAME(basename); \
60
+   static const struct media_codec * const codec_plugin_media_codec_list = { __VA_ARGS__, NULL };  \
61
+   const struct media_codec * const * const codec_plugin_media_codecs = codec_plugin_media_codec_list;
62
+
63
+extern const struct media_codec * const * const codec_plugin_media_codecs;
64
+extern const char *codec_plugin_factory_name;
65
+#endif
66
+
67
+#define MEDIA_CODEC_FLAG_SINK      (1 << 0)
68
+
69
+#define A2DP_CODEC_DEFAULT_RATE        48000
70
+#define A2DP_CODEC_DEFAULT_CHANNELS    2
71
+
72
+enum {
73
+   NEED_FLUSH_NO = 0,
74
+   NEED_FLUSH_ALL = 1,
75
+   NEED_FLUSH_FRAGMENT = 2,
76
+};
77
+
78
+struct media_codec_audio_info {
79
+   uint32_t rate;
80
+   uint32_t channels;
81
+};
82
+
83
+struct codec_qos {
84
+    uint32_t interval;
85
+    bool framing;
86
+    char *phy;
87
+    uint16_t sdu;
88
+    uint8_t retransmission;
89
+    uint16_t latency;
90
+    uint32_t delay;
91
+};
92
+
93
+struct media_codec {
94
+   enum spa_bluetooth_audio_codec id;
95
+   uint8_t codec_id;
96
+   a2dp_vendor_codec_t vendor;
97
+
98
+   bool bap;
99
+
100
+   const char *name;
101
+   const char *description;
102
+   const char *endpoint_name;  /**< Endpoint name. If NULL, same as name */
103
+   const struct spa_dict *info;
104
+
105
+   const size_t send_buf_size;
106
+
107
+   const struct media_codec *duplex_codec; /**< Codec for non-standard A2DP duplex channel */
108
+
109
+   struct spa_log *log;
110
+
111
+   int (*fill_caps) (const struct media_codec *codec, uint32_t flags,
112
+           uint8_t capsA2DP_MAX_CAPS_SIZE);
113
+   int (*select_config) (const struct media_codec *codec, uint32_t flags,
114
+           const void *caps, size_t caps_size,
115
+           const struct media_codec_audio_info *info,
116
+           const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE);
117
+   int (*enum_config) (const struct media_codec *codec, uint32_t flags,
118
+           const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
119
+           struct spa_pod_builder *builder, struct spa_pod **param);
120
+   int (*validate_config) (const struct media_codec *codec, uint32_t flags,
121
+           const void *caps, size_t caps_size,
122
+           struct spa_audio_info *info);
123
+   void (*get_qos)(const struct media_codec *codec,
124
+           const void *config, size_t config_size,
125
+           struct codec_qos *qos);
126
+
127
+   /** qsort comparison sorting caps in order of preference for the codec.
128
+    * Used in codec switching to select best remote endpoints.
129
+    * The caps handed in correspond to this codec_id, but are
130
+    * otherwise not checked beforehand.
131
+    */
132
+   int (*caps_preference_cmp) (const struct media_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
133
+           const void *caps2, size_t caps2_size, const struct media_codec_audio_info *info,
134
+           const struct spa_dict *global_settings);
135
+
136
+   void *(*init_props) (const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings);
137
+   void (*clear_props) (void *);
138
+   int (*enum_props) (void *props, const struct spa_dict *settings, uint32_t id, uint32_t idx,
139
+           struct spa_pod_builder *builder, struct spa_pod **param);
140
+   int (*set_props) (void *props, const struct spa_pod *param);
141
+
142
+   void *(*init) (const struct media_codec *codec, uint32_t flags, void *config, size_t config_size,
143
+           const struct spa_audio_info *info, void *props, size_t mtu);
144
+   void (*deinit) (void *data);
145
+
146
+   int (*update_props) (void *data, void *props);
147
+
148
+   int (*get_block_size) (void *data);
149
+
150
+   int (*abr_process) (void *data, size_t unsent);
151
+
152
+   int (*start_encode) (void *data,
153
+       void *dst, size_t dst_size, uint16_t seqnum, uint32_t timestamp);
154
+   int (*encode) (void *data,
155
+       const void *src, size_t src_size,
156
+       void *dst, size_t dst_size,
157
+       size_t *dst_out, int *need_flush);
158
+
159
+   int (*start_decode) (void *data,
160
+       const void *src, size_t src_size, uint16_t *seqnum, uint32_t *timestamp);
161
+   int (*decode) (void *data,
162
+       const void *src, size_t src_size,
163
+       void *dst, size_t dst_size,
164
+       size_t *dst_out);
165
+
166
+   int (*reduce_bitpool) (void *data);
167
+   int (*increase_bitpool) (void *data);
168
+
169
+   void (*set_log) (struct spa_log *global_log);
170
+};
171
+
172
+struct media_codec_config {
173
+   uint32_t config;
174
+   int value;
175
+   unsigned int priority;
176
+};
177
+
178
+int media_codec_select_config(const struct media_codec_config configs, size_t n,
179
+   uint32_t cap, int preferred_value);
180
+
181
+bool media_codec_check_caps(const struct media_codec *codec, unsigned int codec_id,
182
+   const void *caps, size_t caps_size, const struct media_codec_audio_info *info,
183
+   const struct spa_dict *global_settings);
184
+
185
+#endif
186
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-sink.c Added
201
 
1
@@ -0,0 +1,1854 @@
2
+/* Spa Media Sink
3
+ *
4
+ * Copyright © 2018 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <unistd.h>
27
+#include <stddef.h>
28
+#include <stdio.h>
29
+#include <arpa/inet.h>
30
+#include <sys/ioctl.h>
31
+
32
+#include <spa/support/plugin.h>
33
+#include <spa/support/loop.h>
34
+#include <spa/support/log.h>
35
+#include <spa/support/system.h>
36
+#include <spa/utils/list.h>
37
+#include <spa/utils/keys.h>
38
+#include <spa/utils/names.h>
39
+#include <spa/utils/result.h>
40
+#include <spa/utils/string.h>
41
+#include <spa/monitor/device.h>
42
+
43
+#include <spa/node/node.h>
44
+#include <spa/node/utils.h>
45
+#include <spa/node/io.h>
46
+#include <spa/node/keys.h>
47
+#include <spa/param/param.h>
48
+#include <spa/param/latency-utils.h>
49
+#include <spa/param/audio/format.h>
50
+#include <spa/param/audio/format-utils.h>
51
+#include <spa/pod/filter.h>
52
+
53
+#include <sbc/sbc.h>
54
+
55
+#include "defs.h"
56
+#include "rtp.h"
57
+#include "media-codecs.h"
58
+
59
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.sink.media");
60
+#undef SPA_LOG_TOPIC_DEFAULT
61
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
62
+
63
+#define DEFAULT_CLOCK_NAME "clock.system.monotonic"
64
+
65
+struct props {
66
+   uint32_t min_latency;
67
+   uint32_t max_latency;
68
+   int64_t latency_offset;
69
+   char clock_name64;
70
+};
71
+
72
+#define FILL_FRAMES 2
73
+#define MAX_BUFFERS 32
74
+#define MIN_LATENCY    128
75
+#define MAX_LATENCY    8192
76
+#define BUFFER_SIZE    (MAX_LATENCY*8)
77
+
78
+struct buffer {
79
+   uint32_t id;
80
+#define BUFFER_FLAG_OUT    (1<<0)
81
+   uint32_t flags;
82
+   struct spa_buffer *buf;
83
+   struct spa_meta_header *h;
84
+   struct spa_list link;
85
+};
86
+
87
+struct port {
88
+   struct spa_audio_info current_format;
89
+   uint32_t frame_size;
90
+   unsigned int have_format:1;
91
+
92
+   uint64_t info_all;
93
+   struct spa_port_info info;
94
+   struct spa_io_buffers *io;
95
+   struct spa_latency_info latency;
96
+#define IDX_EnumFormat 0
97
+#define IDX_Meta   1
98
+#define IDX_IO     2
99
+#define IDX_Format 3
100
+#define IDX_Buffers    4
101
+#define IDX_Latency    5
102
+#define N_PORT_PARAMS  6
103
+   struct spa_param_info paramsN_PORT_PARAMS;
104
+
105
+   struct buffer buffersMAX_BUFFERS;
106
+   uint32_t n_buffers;
107
+
108
+   struct spa_list free;
109
+   struct spa_list ready;
110
+
111
+   size_t ready_offset;
112
+};
113
+
114
+struct impl {
115
+   struct spa_handle handle;
116
+   struct spa_node node;
117
+
118
+   struct spa_log *log;
119
+   struct spa_loop *data_loop;
120
+   struct spa_system *data_system;
121
+
122
+   struct spa_hook_list hooks;
123
+   struct spa_callbacks callbacks;
124
+
125
+   uint64_t info_all;
126
+   struct spa_node_info info;
127
+#define IDX_PropInfo   0
128
+#define IDX_Props  1
129
+#define N_NODE_PARAMS  2
130
+   struct spa_param_info paramsN_NODE_PARAMS;
131
+   struct props props;
132
+
133
+   struct spa_bt_transport *transport;
134
+   struct spa_hook transport_listener;
135
+
136
+   struct port port;
137
+
138
+   unsigned int started:1;
139
+   unsigned int following:1;
140
+   unsigned int is_output:1;
141
+
142
+   unsigned int is_duplex:1;
143
+
144
+   struct spa_source source;
145
+   int timerfd;
146
+   struct spa_source flush_source;
147
+   struct spa_source flush_timer_source;
148
+   int flush_timerfd;
149
+
150
+   struct spa_io_clock *clock;
151
+   struct spa_io_position *position;
152
+
153
+   uint64_t current_time;
154
+   uint64_t next_time;
155
+   uint64_t last_error;
156
+
157
+   const struct media_codec *codec;
158
+   bool codec_props_changed;
159
+   void *codec_props;
160
+   void *codec_data;
161
+   struct spa_audio_info codec_format;
162
+
163
+   int need_flush;
164
+   bool fragment;
165
+   uint64_t fragment_timeout;
166
+   uint32_t block_size;
167
+   uint8_t bufferBUFFER_SIZE;
168
+   uint32_t buffer_used;
169
+   uint32_t header_size;
170
+   uint32_t frame_count;
171
+   uint16_t seqnum;
172
+   uint32_t timestamp;
173
+   uint64_t sample_count;
174
+   uint8_t tmp_bufferBUFFER_SIZE;
175
+   uint32_t tmp_buffer_used;
176
+   uint32_t fd_buffer_size;
177
+
178
+   /* Times */
179
+   uint64_t start_time;
180
+   uint64_t total_samples;
181
+};
182
+
183
+#define CHECK_PORT(this,d,p)    ((d) == SPA_DIRECTION_INPUT && (p) == 0)
184
+
185
+static void reset_props(struct impl *this, struct props *props)
186
+{
187
+   props->min_latency = MIN_LATENCY;
188
+   props->max_latency = MAX_LATENCY;
189
+   props->latency_offset = 0;
190
+   strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name));
191
+}
192
+
193
+static int impl_node_enum_params(void *object, int seq,
194
+           uint32_t id, uint32_t start, uint32_t num,
195
+           const struct spa_pod *filter)
196
+{
197
+   struct impl *this = object;
198
+   struct spa_pod *param;
199
+   struct spa_pod_builder b = { 0 };
200
+   uint8_t buffer1024;
201
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-source.c Added
201
 
1
@@ -0,0 +1,1663 @@
2
+/* Spa Media Source
3
+ *
4
+ * Copyright © 2018 Wim Taymans
5
+ * Copyright © 2019 Collabora Ltd.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a
8
+ * copy of this software and associated documentation files (the "Software"),
9
+ * to deal in the Software without restriction, including without limitation
10
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ * and/or sell copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice (including the next
15
+ * paragraph) shall be included in all copies or substantial portions of the
16
+ * Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ * DEALINGS IN THE SOFTWARE.
25
+ */
26
+
27
+#include <unistd.h>
28
+#include <stddef.h>
29
+#include <stdio.h>
30
+#include <time.h>
31
+#include <fcntl.h>
32
+#include <sys/types.h>
33
+#include <sys/socket.h>
34
+
35
+#include <spa/support/plugin.h>
36
+#include <spa/support/loop.h>
37
+#include <spa/support/log.h>
38
+#include <spa/support/system.h>
39
+#include <spa/utils/list.h>
40
+#include <spa/utils/keys.h>
41
+#include <spa/utils/names.h>
42
+#include <spa/utils/result.h>
43
+#include <spa/utils/string.h>
44
+#include <spa/monitor/device.h>
45
+
46
+#include <spa/node/node.h>
47
+#include <spa/node/utils.h>
48
+#include <spa/node/io.h>
49
+#include <spa/node/keys.h>
50
+#include <spa/param/param.h>
51
+#include <spa/param/latency-utils.h>
52
+#include <spa/param/audio/format.h>
53
+#include <spa/param/audio/format-utils.h>
54
+#include <spa/pod/filter.h>
55
+
56
+#include "defs.h"
57
+#include "rtp.h"
58
+#include "media-codecs.h"
59
+
60
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.source.media");
61
+#undef SPA_LOG_TOPIC_DEFAULT
62
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
63
+
64
+#include "decode-buffer.h"
65
+
66
+#define DEFAULT_CLOCK_NAME "clock.system.monotonic"
67
+
68
+struct props {
69
+   char clock_name64;
70
+};
71
+
72
+#define FILL_FRAMES 2
73
+#define MAX_BUFFERS 32
74
+
75
+struct buffer {
76
+   uint32_t id;
77
+   unsigned int outstanding:1;
78
+   struct spa_buffer *buf;
79
+   struct spa_meta_header *h;
80
+   struct spa_list link;
81
+};
82
+
83
+struct port {
84
+   struct spa_audio_info current_format;
85
+   uint32_t frame_size;
86
+   unsigned int have_format:1;
87
+
88
+   uint64_t info_all;
89
+   struct spa_port_info info;
90
+   struct spa_io_buffers *io;
91
+   struct spa_io_rate_match *rate_match;
92
+   struct spa_latency_info latency;
93
+#define IDX_EnumFormat 0
94
+#define IDX_Meta   1
95
+#define IDX_IO     2
96
+#define IDX_Format 3
97
+#define IDX_Buffers    4
98
+#define IDX_Latency    5
99
+#define N_PORT_PARAMS  6
100
+   struct spa_param_info paramsN_PORT_PARAMS;
101
+
102
+   struct buffer buffersMAX_BUFFERS;
103
+   uint32_t n_buffers;
104
+
105
+   struct spa_list free;
106
+   struct spa_list ready;
107
+
108
+   struct spa_bt_decode_buffer buffer;
109
+};
110
+
111
+struct impl {
112
+   struct spa_handle handle;
113
+   struct spa_node node;
114
+
115
+   struct spa_log *log;
116
+   struct spa_loop *data_loop;
117
+   struct spa_system *data_system;
118
+
119
+   struct spa_hook_list hooks;
120
+   struct spa_callbacks callbacks;
121
+
122
+   uint32_t quantum_limit;
123
+
124
+   uint64_t info_all;
125
+   struct spa_node_info info;
126
+#define IDX_PropInfo   0
127
+#define IDX_Props  1
128
+#define IDX_NODE_IO    2
129
+#define N_NODE_PARAMS  3
130
+   struct spa_param_info paramsN_NODE_PARAMS;
131
+   struct props props;
132
+
133
+   struct spa_bt_transport *transport;
134
+   struct spa_hook transport_listener;
135
+
136
+   struct port port;
137
+
138
+   unsigned int started:1;
139
+   unsigned int transport_acquired:1;
140
+   unsigned int following:1;
141
+   unsigned int matching:1;
142
+   unsigned int resampling:1;
143
+
144
+   unsigned int is_input:1;
145
+   unsigned int is_duplex:1;
146
+   unsigned int use_duplex_source:1;
147
+
148
+   int fd;
149
+   struct spa_source source;
150
+
151
+   struct spa_source timer_source;
152
+   int timerfd;
153
+
154
+   struct spa_io_clock *clock;
155
+        struct spa_io_position *position;
156
+
157
+   uint64_t current_time;
158
+   uint64_t next_time;
159
+
160
+   const struct media_codec *codec;
161
+   bool codec_props_changed;
162
+   void *codec_props;
163
+   void *codec_data;
164
+   struct spa_audio_info codec_format;
165
+
166
+   uint8_t buffer_read4096;
167
+   struct timespec now;
168
+   uint64_t sample_count;
169
+
170
+   int duplex_timerfd;
171
+   uint64_t duplex_timeout;
172
+};
173
+
174
+#define CHECK_PORT(this,d,p)    ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
175
+
176
+static void reset_props(struct props *props)
177
+{
178
+   strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name));
179
+}
180
+
181
+static int impl_node_enum_params(void *object, int seq,
182
+           uint32_t id, uint32_t start, uint32_t num,
183
+           const struct spa_pod *filter)
184
+{
185
+   struct impl *this = object;
186
+   struct spa_pod *param;
187
+   struct spa_pod_builder b = { 0 };
188
+   uint8_t buffer1024;
189
+   struct spa_result_node_params result;
190
+   uint32_t count = 0, index_offset = 0;
191
+   bool enum_codec = false;
192
+
193
+   spa_return_val_if_fail(this != NULL, -EINVAL);
194
+   spa_return_val_if_fail(num != 0, -EINVAL);
195
+
196
+        result.id = id;
197
+   result.next = start;
198
+      next:
199
+        result.index = result.next++;
200
+
201
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/meson.build Changed
90
 
1
@@ -17,9 +17,9 @@
2
 bluez5_sources = 
3
   'plugin.c',
4
   'codec-loader.c',
5
-  'a2dp-codecs.c',
6
-  'a2dp-sink.c',
7
-  'a2dp-source.c',
8
+  'media-codecs.c',
9
+  'media-sink.c',
10
+  'media-source.c',
11
   'sco-sink.c',
12
   'sco-source.c',
13
   'sco-io.c',
14
@@ -59,7 +59,7 @@
15
 codec_args =  '-DCODEC_PLUGIN' 
16
 
17
 bluez_codec_sbc = shared_library('spa-codec-bluez5-sbc',
18
-   'a2dp-codec-sbc.c', 'a2dp-codecs.c' ,
19
+   'a2dp-codec-sbc.c', 'media-codecs.c' ,
20
   include_directories :  configinc ,
21
   c_args : codec_args,
22
   dependencies :  spa_dep, sbc_dep ,
23
@@ -67,7 +67,7 @@
24
   install_dir : spa_plugindir / 'bluez5')
25
 
26
 bluez_codec_faststream = shared_library('spa-codec-bluez5-faststream',
27
-   'a2dp-codec-faststream.c', 'a2dp-codecs.c' ,
28
+   'a2dp-codec-faststream.c', 'media-codecs.c' ,
29
   include_directories :  configinc ,
30
   c_args : codec_args,
31
   dependencies :  spa_dep, sbc_dep ,
32
@@ -76,7 +76,7 @@
33
 
34
 if fdk_aac_dep.found()
35
   bluez_codec_aac = shared_library('spa-codec-bluez5-aac',
36
-     'a2dp-codec-aac.c', 'a2dp-codecs.c' ,
37
+     'a2dp-codec-aac.c', 'media-codecs.c' ,
38
     include_directories :  configinc ,
39
     c_args : codec_args,
40
     dependencies :  spa_dep, fdk_aac_dep ,
41
@@ -86,7 +86,7 @@
42
 
43
 if aptx_dep.found()
44
   bluez_codec_aptx = shared_library('spa-codec-bluez5-aptx',
45
-     'a2dp-codec-aptx.c', 'a2dp-codecs.c' ,
46
+     'a2dp-codec-aptx.c', 'media-codecs.c' ,
47
     include_directories :  configinc ,
48
     c_args : codec_args,
49
     dependencies :  spa_dep, aptx_dep, sbc_dep ,
50
@@ -102,7 +102,7 @@
51
     ldac_dep += ldac_abr_dep
52
   endif
53
   bluez_codec_ldac = shared_library('spa-codec-bluez5-ldac',
54
-     'a2dp-codec-ldac.c', 'a2dp-codecs.c' ,
55
+     'a2dp-codec-ldac.c', 'media-codecs.c' ,
56
     include_directories :  configinc ,
57
     c_args : ldac_args,
58
     dependencies :  spa_dep, ldac_dep ,
59
@@ -112,7 +112,7 @@
60
 
61
 if get_option('bluez5-codec-lc3plus').allowed() and lc3plus_dep.found()
62
   bluez_codec_lc3plus = shared_library('spa-codec-bluez5-lc3plus',
63
-     'a2dp-codec-lc3plus.c', 'a2dp-codecs.c' ,
64
+     'a2dp-codec-lc3plus.c', 'media-codecs.c' ,
65
     include_directories :  configinc ,
66
     c_args : codec_args,
67
     dependencies :  spa_dep, lc3plus_dep, mathlib ,
68
@@ -124,10 +124,20 @@
69
   opus_args = codec_args
70
   opus_dep =  opus_dep 
71
   bluez_codec_opus = shared_library('spa-codec-bluez5-opus',
72
-     'a2dp-codec-opus.c', 'a2dp-codecs.c' ,
73
+     'a2dp-codec-opus.c', 'media-codecs.c' ,
74
     include_directories :  configinc ,
75
     c_args : opus_args,
76
     dependencies :  spa_dep, opus_dep, mathlib ,
77
     install : true,
78
     install_dir : spa_plugindir / 'bluez5')
79
 endif
80
+
81
+if get_option('bluez5-codec-lc3').allowed() and lc3_dep.found()
82
+  bluez_codec_lc3 = shared_library('spa-codec-bluez5-lc3',
83
+     'bap-codec-lc3.c', 'media-codecs.c' ,
84
+    include_directories :  configinc ,
85
+    c_args : codec_args,
86
+    dependencies :  spa_dep, lc3_dep, mathlib ,
87
+    install : true,
88
+    install_dir : spa_plugindir / 'bluez5')
89
+endif
90
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/plugin.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/plugin.c Changed
42
 
1
@@ -29,10 +29,12 @@
2
 
3
 extern const struct spa_handle_factory spa_bluez5_dbus_factory;
4
 extern const struct spa_handle_factory spa_bluez5_device_factory;
5
-extern const struct spa_handle_factory spa_a2dp_sink_factory;
6
-extern const struct spa_handle_factory spa_a2dp_source_factory;
7
+extern const struct spa_handle_factory spa_media_sink_factory;
8
+extern const struct spa_handle_factory spa_media_source_factory;
9
 extern const struct spa_handle_factory spa_sco_sink_factory;
10
 extern const struct spa_handle_factory spa_sco_source_factory;
11
+extern const struct spa_handle_factory spa_a2dp_sink_factory;
12
+extern const struct spa_handle_factory spa_a2dp_source_factory;
13
 
14
 SPA_EXPORT
15
 int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
16
@@ -48,10 +50,10 @@
17
        *factory = &spa_bluez5_device_factory;
18
        break;
19
    case 2:
20
-       *factory = &spa_a2dp_sink_factory;
21
+       *factory = &spa_media_sink_factory;
22
        break;
23
    case 3:
24
-       *factory = &spa_a2dp_source_factory;
25
+       *factory = &spa_media_source_factory;
26
        break;
27
    case 4:
28
        *factory = &spa_sco_sink_factory;
29
@@ -59,6 +61,12 @@
30
    case 5:
31
        *factory = &spa_sco_source_factory;
32
        break;
33
+   case 6:
34
+       *factory = &spa_a2dp_sink_factory;
35
+       break;
36
+   case 7:
37
+       *factory = &spa_a2dp_source_factory;
38
+       break;
39
    default:
40
        return 0;
41
    }
42
pipewire-0.3.58.tar.gz/spa/plugins/bluez5/quirks.c -> pipewire-0.3.59.tar.gz/spa/plugins/bluez5/quirks.c Changed
9
 
1
@@ -56,7 +56,6 @@
2
 #include <spa/utils/json.h>
3
 #include <spa/utils/string.h>
4
 
5
-#include "a2dp-codecs.h"
6
 #include "defs.h"
7
 
8
 static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.quirks");
9
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
160
 
1
@@ -54,30 +54,29 @@
2
 
3
 using namespace libcamera;
4
 
5
-struct props {
6
-   char device128;
7
-   char device_name128;
8
-};
9
-
10
-static void reset_props(struct props *props)
11
-{
12
-   spa_zero(*props);
13
-}
14
+namespace {
15
 
16
 struct impl {
17
    struct spa_handle handle;
18
-   struct spa_device device;
19
+   struct spa_device device = {};
20
 
21
    struct spa_log *log;
22
 
23
-   struct props props;
24
+   std::string device_id;
25
 
26
    struct spa_hook_list hooks;
27
 
28
-   CameraManager *manager;
29
+   std::shared_ptr<CameraManager> manager;
30
    std::shared_ptr<Camera> camera;
31
+
32
+   impl(spa_log *log,
33
+        std::shared_ptr<CameraManager> manager,
34
+        std::shared_ptr<Camera> camera,
35
+        std::string device_id);
36
 };
37
 
38
+}
39
+
40
 static std::string cameraModel(const Camera *camera)
41
 {
42
    const ControlList &props = camera->properties();
43
@@ -120,11 +119,11 @@
44
    info.change_mask = SPA_DEVICE_CHANGE_MASK_PROPS;
45
 
46
 #define ADD_ITEM(key, value) itemsn_items++ = SPA_DICT_ITEM_INIT(key, value)
47
-   snprintf(path, sizeof(path), "libcamera:%s", impl->props.device);
48
+   snprintf(path, sizeof(path), "libcamera:%s", impl->device_id.c_str());
49
    ADD_ITEM(SPA_KEY_OBJECT_PATH, path);
50
    ADD_ITEM(SPA_KEY_DEVICE_API, "libcamera");
51
    ADD_ITEM(SPA_KEY_MEDIA_CLASS, "Video/Device");
52
-   ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, impl->props.device);
53
+   ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, impl->device_id.c_str());
54
 
55
    if (auto location = cameraLoc(impl->camera.get()))
56
        ADD_ITEM(SPA_KEY_API_LIBCAMERA_LOCATION, location);
57
@@ -132,7 +131,7 @@
58
    snprintf(model, sizeof(model), "%s", cameraModel(impl->camera.get()).c_str());
59
    ADD_ITEM(SPA_KEY_DEVICE_PRODUCT_NAME, model);
60
    ADD_ITEM(SPA_KEY_DEVICE_DESCRIPTION, model);
61
-   snprintf(name, sizeof(name), "libcamera_device.%s", impl->props.device);
62
+   snprintf(name, sizeof(name), "libcamera_device.%s", impl->device_id.c_str());
63
    ADD_ITEM(SPA_KEY_DEVICE_NAME, name);
64
 #undef ADD_ITEM
65
 
66
@@ -235,13 +234,30 @@
67
 
68
 static int impl_clear(struct spa_handle *handle)
69
 {
70
-   struct impl *impl = (struct impl *) handle;
71
-   if (impl->manager)
72
-       libcamera_manager_release(impl->manager);
73
-   impl->manager = NULL;
74
+   std::destroy_at(reinterpret_cast<impl *>(handle));
75
    return 0;
76
 }
77
 
78
+impl::impl(spa_log *log,
79
+      std::shared_ptr<CameraManager> manager,
80
+      std::shared_ptr<Camera> camera,
81
+      std::string device_id)
82
+   : handle({ SPA_VERSION_HANDLE, impl_get_interface, impl_clear }),
83
+     log(log),
84
+     device_id(std::move(device_id)),
85
+     manager(std::move(manager)),
86
+     camera(std::move(camera))
87
+{
88
+   libcamera_log_topic_init(log);
89
+
90
+   spa_hook_list_init(&hooks);
91
+
92
+   device.iface = SPA_INTERFACE_INIT(
93
+           SPA_TYPE_INTERFACE_Device,
94
+           SPA_VERSION_DEVICE,
95
+           &impl_device, this);
96
+}
97
+
98
 static size_t
99
 impl_get_size(const struct spa_handle_factory *factory,
100
          const struct spa_dict *params)
101
@@ -256,44 +272,32 @@
102
      const struct spa_support *support,
103
      uint32_t n_support)
104
 {
105
-   struct impl *impl;
106
    const char *str;
107
    int res;
108
 
109
    spa_return_val_if_fail(factory != NULL, -EINVAL);
110
    spa_return_val_if_fail(handle != NULL, -EINVAL);
111
 
112
-   handle->get_interface = impl_get_interface;
113
-   handle->clear = impl_clear, impl = (struct impl *) handle;
114
-
115
-   impl->log = (struct spa_log*) spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
116
-   libcamera_log_topic_init(impl->log);
117
-
118
-   spa_hook_list_init(&impl->hooks);
119
-
120
-   impl->device.iface = SPA_INTERFACE_INIT(
121
-           SPA_TYPE_INTERFACE_Device,
122
-           SPA_VERSION_DEVICE,
123
-           &impl_device, impl);
124
+   auto log = static_cast<spa_log *>(spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log));
125
 
126
-   reset_props(&impl->props);
127
+   auto manager = libcamera_manager_acquire(res);
128
+   if (!manager) {
129
+       spa_log_error(log, "can't start camera manager: %s", spa_strerror(res));
130
+       return res;
131
+   }
132
 
133
+   std::string device_id;
134
    if (info && (str = spa_dict_lookup(info, SPA_KEY_API_LIBCAMERA_PATH)))
135
-       strncpy(impl->props.device, str, sizeof(impl->props.device));
136
-
137
-   impl->manager = libcamera_manager_acquire();
138
-   if (impl->manager == NULL) {
139
-       res = -errno;
140
-       spa_log_error(impl->log, "can't start camera manager: %s", spa_strerror(res));
141
-                return res;
142
-   }
143
+       device_id = str;
144
 
145
-   impl->camera = impl->manager->get(impl->props.device);
146
-   if (impl->camera == NULL) {
147
-       spa_log_error(impl->log, "unknown camera id %s", impl->props.device);
148
-       libcamera_manager_release(impl->manager);
149
+   auto camera = manager->get(device_id);
150
+   if (!camera) {
151
+       spa_log_error(log, "unknown camera id %s", device_id.c_str());
152
        return -ENOENT;
153
    }
154
+
155
+   new (handle) impl(log, std::move(manager), std::move(camera), std::move(device_id));
156
+
157
    return 0;
158
 }
159
 
160
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
201
 
1
@@ -29,7 +29,10 @@
2
 #include <sys/types.h>
3
 #include <sys/stat.h>
4
 #include <fcntl.h>
5
-
6
+#include <utility>
7
+#include <mutex>
8
+#include <optional>
9
+#include <queue>
10
 
11
 #include <libcamera/camera.h>
12
 #include <libcamera/camera_manager.h>
13
@@ -54,67 +57,65 @@
14
 
15
 #define MAX_DEVICES    64
16
 
17
-struct global {
18
-   int ref;
19
-   CameraManager *manager;
20
-};
21
-
22
-static struct global global;
23
+namespace {
24
 
25
 struct device {
26
    uint32_t id;
27
    std::shared_ptr<Camera> camera;
28
 };
29
 
30
-typedef struct impl {
31
+struct impl {
32
    struct spa_handle handle;
33
-   struct spa_device device;
34
+   struct spa_device device = {};
35
 
36
    struct spa_log *log;
37
-   struct spa_loop *main_loop;
38
+   struct spa_loop_utils *loop_utils;
39
 
40
    struct spa_hook_list hooks;
41
 
42
-   uint64_t info_all;
43
-   struct spa_device_info info;
44
+   static constexpr uint64_t info_all = SPA_DEVICE_CHANGE_MASK_FLAGS | SPA_DEVICE_CHANGE_MASK_PROPS;
45
+   struct spa_device_info info = SPA_DEVICE_INFO_INIT();
46
 
47
-   CameraManager *manager;
48
+   std::shared_ptr<CameraManager> manager;
49
    void addCamera(std::shared_ptr<libcamera::Camera> camera);
50
-        void removeCamera(std::shared_ptr<libcamera::Camera> camera);
51
+   void removeCamera(std::shared_ptr<libcamera::Camera> camera);
52
 
53
    struct device devicesMAX_DEVICES;
54
-        uint32_t n_devices;
55
-} Impl;
56
+   uint32_t n_devices = 0;
57
 
58
-int libcamera_manager_release(CameraManager *manager)
59
-{
60
-   if (global.manager != manager)
61
-       return -EINVAL;
62
+   struct hotplug_event {
63
+       enum class type { add, remove } type;
64
+       std::shared_ptr<Camera> camera;
65
+   };
66
 
67
-   if (--global.ref == 0) {
68
-       global.manager->stop();
69
-       delete global.manager;
70
-       global.manager = NULL;
71
+   std::mutex hotplug_events_lock;
72
+   std::queue<hotplug_event> hotplug_events;
73
+   struct spa_source *hotplug_event_source;
74
+
75
+   impl(spa_log *log, spa_loop_utils *loop_utils, spa_source *hotplug_event_source);
76
+
77
+   ~impl()
78
+   {
79
+       spa_loop_utils_destroy_source(loop_utils, hotplug_event_source);
80
    }
81
-   return 0;
82
+};
83
+
84
 }
85
 
86
-CameraManager *libcamera_manager_acquire(void)
87
+static std::weak_ptr<CameraManager> global_manager;
88
+
89
+std::shared_ptr<CameraManager> libcamera_manager_acquire(int& res)
90
 {
91
-   int res;
92
+   if (auto manager = global_manager.lock())
93
+       return manager;
94
 
95
-   if (global.ref++ == 0) {
96
-       global.manager = new CameraManager();
97
-       if (global.manager == NULL)
98
-           return NULL;
99
+   auto manager = std::make_shared<CameraManager>();
100
+   if ((res = manager->start()) < 0)
101
+       return {};
102
 
103
-       if ((res = global.manager->start()) < 0) {
104
-           libcamera_manager_release(global.manager);
105
-           errno = -res;
106
-           return NULL;
107
-       }
108
-   }
109
-   return global.manager;
110
+   global_manager = manager;
111
+
112
+   return manager;
113
 }
114
 
115
 static struct device *add_device(struct impl *impl, std::shared_ptr<Camera> camera)
116
@@ -127,15 +128,15 @@
117
    id = impl->n_devices++;
118
    device = &impl->devicesid;
119
    device->id = id;
120
-   device->camera = camera;
121
+   device->camera = std::move(camera);
122
    return device;
123
 }
124
 
125
-static struct device *find_device(struct impl *impl, std::shared_ptr<Camera> camera)
126
+static struct device *find_device(struct impl *impl, const Camera *camera)
127
 {
128
    uint32_t i;
129
    for (i = 0; i < impl->n_devices; i++) {
130
-       if (impl->devicesi.camera == camera)
131
+       if (impl->devicesi.camera.get() == camera)
132
            return &impl->devicesi;
133
    }
134
    return NULL;
135
@@ -143,12 +144,14 @@
136
 
137
 static void remove_device(struct impl *impl, struct device *device)
138
 {
139
-   *device = impl->devices--impl->n_devices;
140
+   device->camera.reset();
141
+   *device = std::move(impl->devices--impl->n_devices);
142
 }
143
 
144
 static void clear_devices(struct impl *impl)
145
 {
146
-   impl->n_devices = 0;
147
+   while (impl->n_devices > 0)
148
+       impl->devices--impl->n_devices.camera.reset();
149
 }
150
 
151
 static int emit_object_info(struct impl *impl, struct device *device)
152
@@ -176,66 +179,119 @@
153
    ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, path);
154
 #undef ADD_ITEM
155
 
156
-        dict = SPA_DICT_INIT(items, n_items);
157
-        info.props = &dict;
158
-        spa_device_emit_object_info(&impl->hooks, id, &info);
159
+   dict = SPA_DICT_INIT(items, n_items);
160
+   info.props = &dict;
161
+   spa_device_emit_object_info(&impl->hooks, id, &info);
162
 
163
    return 1;
164
 }
165
 
166
-void Impl::addCamera(std::shared_ptr<Camera> camera)
167
+static void try_add_camera(struct impl *impl, std::shared_ptr<Camera> camera)
168
 {
169
-   struct impl *impl = this;
170
    struct device *device;
171
 
172
-   spa_log_info(impl->log, "new camera");
173
-
174
-   if ((device = find_device(impl, camera)) != NULL)
175
+   if ((device = find_device(impl, camera.get())) != NULL)
176
        return;
177
 
178
-   if ((device = add_device(impl, camera)) == NULL)
179
+   if ((device = add_device(impl, std::move(camera))) == NULL)
180
        return;
181
 
182
+   spa_log_info(impl->log, "camera added: %s", device->camera->id().c_str());
183
    emit_object_info(impl, device);
184
 }
185
 
186
-void Impl::removeCamera(std::shared_ptr<Camera> camera)
187
+static void try_remove_camera(struct impl *impl, const Camera *camera)
188
 {
189
-   struct impl *impl = this;
190
    struct device *device;
191
 
192
-   spa_log_info(impl->log, "camera removed");
193
    if ((device = find_device(impl, camera)) == NULL)
194
        return;
195
 
196
+   spa_log_info(impl->log, "camera removed: %s", device->camera->id().c_str());
197
    remove_device(impl, device);
198
 }
199
 
200
-static int start_monitor(struct impl *impl)
201
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
16
 
1
@@ -22,11 +22,8 @@
2
  * DEALINGS IN THE SOFTWARE.
3
  */
4
 
5
-#include <libcamera/camera_manager.h>
6
-
7
-#include <linux/media.h>
8
+#include <memory>
9
 
10
-using namespace libcamera;
11
+#include <libcamera/camera_manager.h>
12
 
13
-CameraManager *libcamera_manager_acquire(void);
14
-int libcamera_manager_release(CameraManager *manager);
15
+std::shared_ptr<libcamera::CameraManager> libcamera_manager_acquire(int& res);
16
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
201
 
1
@@ -31,6 +31,7 @@
2
 #include <sys/stat.h>
3
 #include <fcntl.h>
4
 #include <deque>
5
+#include <optional>
6
 
7
 #include <spa/support/plugin.h>
8
 #include <spa/support/log.h>
9
@@ -60,15 +61,9 @@
10
 #include "libcamera.h"
11
 #include "libcamera-manager.hpp"
12
 
13
-struct props {
14
-   char device128;
15
-   char device_name128;
16
-};
17
+using namespace libcamera;
18
 
19
-static void reset_props(struct props *props)
20
-{
21
-   spa_zero(*props);
22
-}
23
+namespace {
24
 
25
 #define MAX_BUFFERS    32
26
 #define MASK_BUFFERS   31
27
@@ -97,75 +92,97 @@
28
 struct port {
29
    struct impl *impl;
30
 
31
-   bool have_format;
32
-   struct spa_video_info current_format;
33
-   struct spa_fraction rate;
34
+   std::optional<spa_video_info> current_format;
35
+
36
+   struct spa_fraction rate = {};
37
    StreamConfiguration streamConfig;
38
 
39
-   uint32_t memtype;
40
+   uint32_t memtype = 0;
41
 
42
    struct control controlsMAX_CONTROLS;
43
-   uint32_t n_controls;
44
+   uint32_t n_controls = 0;
45
 
46
    struct buffer buffersMAX_BUFFERS;
47
-   uint32_t n_buffers;
48
+   uint32_t n_buffers = 0;
49
    struct spa_list queue;
50
-   struct spa_ringbuffer ring;
51
+   struct spa_ringbuffer ring = SPA_RINGBUFFER_INIT();
52
    uint32_t ring_idsMAX_BUFFERS;
53
 
54
-   uint64_t info_all;
55
-   struct spa_port_info info;
56
-   struct spa_io_buffers *io;
57
-   struct spa_io_sequence *control;
58
+   static constexpr uint64_t info_all = SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_PARAMS;
59
+   struct spa_port_info info = SPA_PORT_INFO_INIT();
60
+   struct spa_io_buffers *io = nullptr;
61
+   struct spa_io_sequence *control = nullptr;
62
    struct spa_param_info params8;
63
 
64
-   uint32_t fmt_index;
65
-   bool next_fmt;
66
+   uint32_t fmt_index = 0;
67
    PixelFormat enum_fmt;
68
-   uint32_t size_index;
69
-   bool next_size;
70
+   uint32_t size_index = 0;
71
+
72
+   port(struct impl *impl)
73
+       : impl(impl)
74
+   {
75
+       spa_list_init(&queue);
76
+
77
+       params0 = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ);
78
+       params1 = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
79
+       params2 = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
80
+       params3 = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
81
+       params4 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
82
+       params5 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
83
+
84
+       info.flags = SPA_PORT_FLAG_LIVE | SPA_PORT_FLAG_PHYSICAL | SPA_PORT_FLAG_TERMINAL;
85
+       info.params = params;
86
+       info.n_params = 6;
87
+   }
88
 };
89
 
90
 struct impl {
91
    struct spa_handle handle;
92
-   struct spa_node node;
93
+   struct spa_node node = {};
94
 
95
    struct spa_log *log;
96
    struct spa_loop *data_loop;
97
    struct spa_system *system;
98
 
99
-   uint64_t info_all;
100
-   struct spa_node_info info;
101
+   static constexpr uint64_t info_all =
102
+       SPA_NODE_CHANGE_MASK_FLAGS |
103
+       SPA_NODE_CHANGE_MASK_PROPS |
104
+       SPA_NODE_CHANGE_MASK_PARAMS;
105
+   struct spa_node_info info = SPA_NODE_INFO_INIT();
106
    struct spa_param_info params8;
107
-   struct props props;
108
+
109
+   std::string device_id;
110
+   std::string device_name;
111
 
112
    struct spa_hook_list hooks;
113
-   struct spa_callbacks callbacks;
114
+   struct spa_callbacks callbacks = {};
115
 
116
-   struct port out_ports1;
117
+   std::array<port, 1> out_ports;
118
 
119
-   struct spa_io_position *position;
120
-   struct spa_io_clock *clock;
121
+   struct spa_io_position *position = nullptr;
122
+   struct spa_io_clock *clock = nullptr;
123
 
124
-   CameraManager *manager;
125
+   std::shared_ptr<CameraManager> manager;
126
    std::shared_ptr<Camera> camera;
127
 
128
-   FrameBufferAllocator *allocator;
129
+   FrameBufferAllocator *allocator = nullptr;
130
    std::vector<std::unique_ptr<libcamera::Request>> requestPool;
131
    std::deque<libcamera::Request *> pendingRequests;
132
 
133
    void requestComplete(libcamera::Request *request);
134
 
135
-   unsigned int have_config;
136
    std::unique_ptr<CameraConfiguration> config;
137
 
138
-   struct spa_source source;
139
+   struct spa_source source = {};
140
 
141
-   unsigned int active:1;
142
-   unsigned int acquired:1;
143
+   bool active = false;
144
+   bool acquired = false;
145
+
146
+   impl(spa_log *log, spa_loop *data_loop, spa_system *system,
147
+        std::shared_ptr<CameraManager> manager, std::shared_ptr<Camera> camera, std::string device_id);
148
 };
149
 
150
-typedef struct impl Impl;
151
+}
152
 
153
 #define CHECK_PORT(impl,direction,port_id)  ((direction) == SPA_DIRECTION_OUTPUT && (port_id) == 0)
154
 
155
@@ -198,22 +215,20 @@
156
    switch (id) {
157
    case SPA_PARAM_PropInfo:
158
    {
159
-       struct props *p = &impl->props;
160
-
161
        switch (result.index) {
162
        case 0:
163
            param = (struct spa_pod*)spa_pod_builder_add_object(&b,
164
                SPA_TYPE_OBJECT_PropInfo, id,
165
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_device),
166
                SPA_PROP_INFO_description, SPA_POD_String("The libcamera device"),
167
-               SPA_PROP_INFO_type, SPA_POD_String(p->device));
168
+               SPA_PROP_INFO_type, SPA_POD_String(impl->device_id.c_str()));
169
            break;
170
        case 1:
171
            param = (struct spa_pod*)spa_pod_builder_add_object(&b,
172
                SPA_TYPE_OBJECT_PropInfo, id,
173
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_deviceName),
174
                SPA_PROP_INFO_description, SPA_POD_String("The libcamera device name"),
175
-               SPA_PROP_INFO_type, SPA_POD_String(p->device_name));
176
+               SPA_PROP_INFO_type, SPA_POD_String(impl->device_name.c_str()));
177
            break;
178
        default:
179
            return 0;
180
@@ -222,14 +237,12 @@
181
    }
182
    case SPA_PARAM_Props:
183
    {
184
-       struct props *p = &impl->props;
185
-
186
        switch (result.index) {
187
        case 0:
188
            param = (struct spa_pod*)spa_pod_builder_add_object(&b,
189
                SPA_TYPE_OBJECT_Props, id,
190
-               SPA_PROP_device,     SPA_POD_String(p->device),
191
-               SPA_PROP_deviceName, SPA_POD_String(p->device_name));
192
+               SPA_PROP_device,     SPA_POD_String(impl->device_id.c_str()),
193
+               SPA_PROP_deviceName, SPA_POD_String(impl->device_name.c_str()));
194
            break;
195
        default:
196
            return 0;
197
@@ -262,15 +275,22 @@
198
    switch (id) {
199
    case SPA_PARAM_Props:
200
    {
201
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
152
 
1
@@ -40,7 +40,7 @@
2
    if (impl->acquired)
3
        return 0;
4
 
5
-   spa_log_info(impl->log, "open camera %s", impl->props.device);
6
+   spa_log_info(impl->log, "open camera %s", impl->device_id.c_str());
7
    impl->camera->acquire();
8
 
9
    impl->allocator = new FrameBufferAllocator(impl->camera);
10
@@ -54,10 +54,10 @@
11
    struct port *port = &impl->out_ports0;
12
    if (!impl->acquired)
13
        return 0;
14
-   if (impl->active || port->have_format)
15
+   if (impl->active || port->current_format)
16
        return 0;
17
 
18
-   spa_log_info(impl->log, "close camera %s", impl->props.device);
19
+   spa_log_info(impl->log, "close camera %s", impl->device_id.c_str());
20
    delete impl->allocator;
21
    impl->allocator = nullptr;
22
 
23
@@ -69,13 +69,12 @@
24
 
25
 static void spa_libcamera_get_config(struct impl *impl)
26
 {
27
-   if (impl->have_config)
28
+   if (impl->config)
29
        return;
30
 
31
    StreamRoles roles;
32
    roles.push_back(VideoRecording);
33
    impl->config = impl->camera->generateConfiguration(roles);
34
-   impl->have_config = true;
35
 }
36
 
37
 static int spa_libcamera_buffer_recycle(struct impl *impl, struct port *port, uint32_t buffer_id)
38
@@ -91,10 +90,10 @@
39
    if (buffer_id >= impl->requestPool.size()) {
40
        spa_log_warn(impl->log, "invalid buffer_id %u >= %zu",
41
                buffer_id, impl->requestPool.size());
42
-                return -EINVAL;
43
-        }
44
+       return -EINVAL;
45
+   }
46
    Request *request = impl->requestPoolbuffer_id.get();
47
-        Stream *stream = port->streamConfig.stream();
48
+   Stream *stream = port->streamConfig.stream();
49
    FrameBuffer *buffer = impl->allocator->buffers(stream)buffer_id.get();
50
    if ((res = request->addBuffer(stream, buffer)) < 0) {
51
        spa_log_warn(impl->log, "can't add buffer %u for request: %s",
52
@@ -104,7 +103,7 @@
53
    if (!impl->active) {
54
        impl->pendingRequests.push_back(request);
55
        return 0;
56
-        } else {
57
+   } else {
58
        if ((res = impl->camera->queueRequest(request)) < 0) {
59
            spa_log_warn(impl->log, "can't queue buffer %u: %s",
60
                buffer_id, spa_strerror(res));
61
@@ -119,7 +118,7 @@
62
    int res;
63
 
64
    if ((res = impl->allocator->allocate(port->streamConfig.stream())) < 0)
65
-                return res;
66
+       return res;
67
 
68
    for (unsigned int i = 0; i < count; i++) {
69
        std::unique_ptr<Request> request = impl->camera->createRequest(i);
70
@@ -129,7 +128,7 @@
71
        }
72
        impl->requestPool.push_back(std::move(request));
73
    }
74
-        return res;
75
+   return res;
76
 }
77
 
78
 static void freeBuffers(struct impl *impl, struct port *port)
79
@@ -419,8 +418,6 @@
80
    if ((res = allocBuffers(impl, port, port->streamConfig.bufferCount)) < 0)
81
        goto error;
82
 
83
-   port->have_format = true;
84
-
85
    port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_RATE;
86
    port->info.flags = SPA_PORT_FLAG_CAN_ALLOC_BUFFERS |
87
        SPA_PORT_FLAG_LIVE |
88
@@ -607,7 +604,7 @@
89
 }
90
 
91
 
92
-void Impl::requestComplete(libcamera::Request *request)
93
+void impl::requestComplete(libcamera::Request *request)
94
 {
95
    struct impl *impl = this;
96
    struct port *port = &impl->out_ports0;
97
@@ -618,12 +615,12 @@
98
    spa_log_debug(impl->log, "request complete");
99
 
100
    if ((request->status() == Request::RequestCancelled)) {
101
-                spa_log_debug(impl->log, "Request was cancelled");
102
-                return;
103
-        }
104
+       spa_log_debug(impl->log, "Request was cancelled");
105
+       return;
106
+   }
107
    FrameBuffer *buffer = request->findBuffer(stream);
108
    if (buffer == nullptr) {
109
-                spa_log_warn(impl->log, "unknown buffer");
110
+       spa_log_warn(impl->log, "unknown buffer");
111
        return;
112
    }
113
    const FrameMetadata &fmd = buffer->metadata();
114
@@ -664,7 +661,7 @@
115
    struct port *port = &impl->out_ports0;
116
    int res;
117
 
118
-   if (!port->have_format) {
119
+   if (!port->current_format) {
120
        spa_log_error(impl->log, "Exting %s with -EIO", __FUNCTION__);
121
        return -EIO;
122
    }
123
@@ -674,15 +671,15 @@
124
 
125
    impl->camera->requestCompleted.connect(impl, &impl::requestComplete);
126
 
127
-   spa_log_info(impl->log, "starting camera %s", impl->props.device);
128
+   spa_log_info(impl->log, "starting camera %s", impl->device_id.c_str());
129
    if ((res = impl->camera->start()) < 0)
130
        return res == -EACCES ? -EBUSY : res;
131
 
132
    for (Request *req : impl->pendingRequests) {
133
-                if ((res = impl->camera->queueRequest(req)) < 0)
134
+       if ((res = impl->camera->queueRequest(req)) < 0)
135
            return res == -EACCES ? -EBUSY : res;
136
-        }
137
-        impl->pendingRequests.clear();
138
+   }
139
+   impl->pendingRequests.clear();
140
 
141
    impl->source.func = libcamera_on_fd_events;
142
    impl->source.data = impl;
143
@@ -724,7 +721,7 @@
144
        return 0;
145
    }
146
 
147
-   spa_log_info(impl->log, "stopping camera %s", impl->props.device);
148
+   spa_log_info(impl->log, "stopping camera %s", impl->device_id.c_str());
149
    impl->pendingRequests.clear();
150
 
151
    if ((res = impl->camera->stop()) < 0)
152
pipewire-0.3.58.tar.gz/spa/plugins/support/logger.c -> pipewire-0.3.59.tar.gz/spa/plugins/support/logger.c Changed
10
 
1
@@ -357,7 +357,7 @@
2
        if ((str = spa_dict_lookup(info, SPA_KEY_LOG_LEVEL)) != NULL)
3
            this->log.level = atoi(str);
4
        if ((str = spa_dict_lookup(info, SPA_KEY_LOG_FILE)) != NULL) {
5
-           this->file = fopen(str, "w");
6
+           this->file = fopen(str, "we");
7
            if (this->file == NULL)
8
                fprintf(stderr, "Warning: failed to open file %s: (%m)", str);
9
            else
10
pipewire-0.3.58.tar.gz/spa/plugins/videoconvert/videoadapter.c -> pipewire-0.3.59.tar.gz/spa/plugins/videoconvert/videoadapter.c Changed
17
 
1
@@ -823,12 +823,12 @@
2
    case SPA_NODE_COMMAND_Suspend:
3
        configure_format(this, 0, NULL);
4
        SPA_FALLTHROUGH
5
-   case SPA_NODE_COMMAND_Flush:
6
-       this->io_buffers.status = SPA_STATUS_OK;
7
-       SPA_FALLTHROUGH
8
    case SPA_NODE_COMMAND_Pause:
9
        this->started = false;
10
        break;
11
+   case SPA_NODE_COMMAND_Flush:
12
+       this->io_buffers.status = SPA_STATUS_OK;
13
+       break;
14
    default:
15
        break;
16
    }
17
pipewire-0.3.59.tar.gz/src/examples/audio-capture.c Added
201
 
1
@@ -0,0 +1,206 @@
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+/*
27
+ title
28
+ Audio capture using \ref pw_stream "pw_stream".
29
+ title
30
+ */
31
+
32
+#include <stdio.h>
33
+#include <errno.h>
34
+#include <math.h>
35
+#include <signal.h>
36
+
37
+#include <spa/param/audio/format-utils.h>
38
+
39
+#include <pipewire/pipewire.h>
40
+
41
+struct data {
42
+   struct pw_main_loop *loop;
43
+   struct pw_stream *stream;
44
+
45
+   struct spa_audio_info format;
46
+};
47
+
48
+/* our data processing function is in general:
49
+ *
50
+ *  struct pw_buffer *b;
51
+ *  b = pw_stream_dequeue_buffer(stream);
52
+ *
53
+ *  .. consume stuff in the buffer ...
54
+ *
55
+ *  pw_stream_queue_buffer(stream, b);
56
+ */
57
+static void on_process(void *userdata)
58
+{
59
+   struct data *data = userdata;
60
+   struct pw_buffer *b;
61
+   struct spa_buffer *buf;
62
+   float *samples, max;
63
+   uint32_t c, n, n_channels, n_samples, peak;
64
+
65
+   if ((b = pw_stream_dequeue_buffer(data->stream)) == NULL) {
66
+       pw_log_warn("out of buffers: %m");
67
+       return;
68
+   }
69
+
70
+   buf = b->buffer;
71
+   if ((samples = buf->datas0.data) == NULL)
72
+       return;
73
+
74
+   n_channels = data->format.info.raw.channels;
75
+   n_samples = buf->datas0.chunk->size / sizeof(float);
76
+
77
+   fprintf(stdout, "captured %d samples\n", n_samples / n_channels);
78
+   for (c = 0; c < data->format.info.raw.channels; c++) {
79
+       max = 0.0f;
80
+       for (n = c; n < n_samples; n += n_channels)
81
+           max = fmaxf(max, fabsf(samplesn));
82
+
83
+       peak = SPA_CLAMP(max * 30, 0, 39);
84
+
85
+       fprintf(stdout, "channel %d: |%*s%*s| peak:%f\n",
86
+               c, peak+1, "*", 40 - peak, "", max);
87
+   }
88
+   /* move cursor up */
89
+   fprintf(stdout, "%c%dA", 0x1b, n_channels + 1);
90
+   fflush(stdout);
91
+
92
+   pw_stream_queue_buffer(data->stream, b);
93
+}
94
+
95
+/* Be notified when the stream param changes. We're only looking at the
96
+ * format changes.
97
+ */
98
+static void
99
+on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
100
+{
101
+   struct data *data = _data;
102
+
103
+   /* NULL means to clear the format */
104
+   if (param == NULL || id != SPA_PARAM_Format)
105
+       return;
106
+
107
+   if (spa_format_parse(param, &data->format.media_type, &data->format.media_subtype) < 0)
108
+       return;
109
+
110
+   /* only accept raw audio */
111
+   if (data->format.media_type != SPA_MEDIA_TYPE_audio ||
112
+       data->format.media_subtype != SPA_MEDIA_SUBTYPE_raw)
113
+       return;
114
+
115
+   /* call a helper function to parse the format for us. */
116
+   spa_format_audio_raw_parse(param, &data->format.info.raw);
117
+
118
+   fprintf(stdout, "capturing rate:%d channels:%d\n",
119
+           data->format.info.raw.rate, data->format.info.raw.channels);
120
+
121
+}
122
+
123
+static const struct pw_stream_events stream_events = {
124
+   PW_VERSION_STREAM_EVENTS,
125
+   .param_changed = on_stream_param_changed,
126
+   .process = on_process,
127
+};
128
+
129
+static void do_quit(void *userdata, int signal_number)
130
+{
131
+   struct data *data = userdata;
132
+   pw_main_loop_quit(data->loop);
133
+}
134
+
135
+int main(int argc, char *argv)
136
+{
137
+   struct data data = { 0, };
138
+   const struct spa_pod *params1;
139
+   uint8_t buffer1024;
140
+   struct pw_properties *props;
141
+   struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
142
+
143
+   pw_init(&argc, &argv);
144
+
145
+   /* make a main loop. If you already have another main loop, you can add
146
+    * the fd of this pipewire mainloop to it. */
147
+   data.loop = pw_main_loop_new(NULL);
148
+
149
+   pw_loop_add_signal(pw_main_loop_get_loop(data.loop), SIGINT, do_quit, &data);
150
+   pw_loop_add_signal(pw_main_loop_get_loop(data.loop), SIGTERM, do_quit, &data);
151
+
152
+   /* Create a simple stream, the simple stream manages the core and remote
153
+    * objects for you if you don't need to deal with them.
154
+    *
155
+    * If you plan to autoconnect your stream, you need to provide at least
156
+    * media, category and role properties.
157
+    *
158
+    * Pass your events and a user_data pointer as the last arguments. This
159
+    * will inform you about the stream state. The most important event
160
+    * you need to listen to is the process event where you need to produce
161
+    * the data.
162
+    */
163
+   props = pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio",
164
+           PW_KEY_MEDIA_CATEGORY, "Capture",
165
+           PW_KEY_MEDIA_ROLE, "Music",
166
+           NULL);
167
+   if (argc > 1)
168
+       /* Set stream target if given on command line */
169
+       pw_properties_set(props, PW_KEY_TARGET_OBJECT, argv1);
170
+
171
+   /* uncomment if you want to capture from the sink monitor ports */
172
+   /* pw_properties_set(props, PW_KEY_STREAM_CAPTURE_SINK, "true"); */
173
+
174
+   data.stream = pw_stream_new_simple(
175
+           pw_main_loop_get_loop(data.loop),
176
+           "audio-capture",
177
+           props,
178
+           &stream_events,
179
+           &data);
180
+
181
+   /* Make one parameter with the supported formats. The SPA_PARAM_EnumFormat
182
+    * id means that this is a format enumeration (of 1 value).
183
+    * We leave the channels and rate empty to accept the native graph
184
+    * rate and channels. */
185
+   params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat,
186
+           &SPA_AUDIO_INFO_RAW_INIT(
187
+               .format = SPA_AUDIO_FORMAT_F32));
188
+
189
+   /* Now connect this stream. We ask that our process function is
190
+    * called in a realtime thread. */
191
+   pw_stream_connect(data.stream,
192
+             PW_DIRECTION_INPUT,
193
+             PW_ID_ANY,
194
+             PW_STREAM_FLAG_AUTOCONNECT |
195
+             PW_STREAM_FLAG_MAP_BUFFERS |
196
+             PW_STREAM_FLAG_RT_PROCESS,
197
+             params, 1);
198
+
199
+   /* and wait while we let things run */
200
+   pw_main_loop_run(data.loop);
201
pipewire-0.3.58.tar.gz/src/examples/meson.build -> pipewire-0.3.59.tar.gz/src/examples/meson.build Changed
9
 
1
@@ -3,6 +3,7 @@
2
   'audio-src',
3
   'audio-dsp-src',
4
   'audio-dsp-filter',
5
+  'audio-capture',
6
   'video-play',
7
   'video-src',
8
   'video-dsp-play',
9
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
10
 
1
@@ -136,7 +136,7 @@
2
        p->timestamp = ptime;
3
        p->dbc = dbc;
4
 
5
-       n = sendmsg(stream->source->fd, &stream->msg, 0);
6
+       n = sendmsg(stream->source->fd, &stream->msg, MSG_NOSIGNAL);
7
        if (n < 0 || n != (ssize_t)stream->pdu_size) {
8
            pw_log_error("sendmsg() failed %zd != %zd: %m",
9
                    n, stream->pdu_size);
10
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
13
 
1
@@ -140,9 +140,9 @@
2
 
3
 #define PW_CLIENT_NODE0_MESSAGE_TYPE(message)  (((struct pw_client_node0_message*)(message))->body.type.value)
4
 
5
-#define PW_CLIENT_NODE0_MESSAGE_INIT(message) (struct pw_client_node0_message)         \
6
+#define PW_CLIENT_NODE0_MESSAGE_INIT(message) ((struct pw_client_node0_message)            \
7
    { { { sizeof(struct pw_client_node0_message_body), SPA_TYPE_Struct } },         \
8
-     { SPA_POD_INIT_Int(message) } }
9
+     { SPA_POD_INIT_Int(message) } })
10
 
11
 #define PW_CLIENT_NODE0_MESSAGE_INIT_FULL(type,size,message,...) (type)                \
12
    { { { size, SPA_TYPE_Struct } },                            \
13
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
201
 
1
@@ -519,13 +519,13 @@
2
 
3
 struct graph_port {
4
    const struct fc_descriptor *desc;
5
-   void *hndl;
6
+   void **hndl;
7
    uint32_t port;
8
 };
9
 
10
 struct graph_hndl {
11
    const struct fc_descriptor *desc;
12
-   void *hndl;
13
+   void **hndl;
14
 };
15
 
16
 struct graph {
17
@@ -577,6 +577,10 @@
18
    struct graph graph;
19
 };
20
 
21
+static int graph_instantiate(struct graph *graph);
22
+static void graph_cleanup(struct graph *graph);
23
+
24
+
25
 static void capture_destroy(void *d)
26
 {
27
    struct impl *impl = d;
28
@@ -587,18 +591,24 @@
29
 static void capture_process(void *d)
30
 {
31
    struct impl *impl = d;
32
+   pw_stream_trigger_process(impl->playback);
33
+}
34
+
35
+static void playback_process(void *d)
36
+{
37
+   struct impl *impl = d;
38
    struct pw_buffer *in, *out;
39
    struct graph *graph = &impl->graph;
40
-   uint32_t i, outsize = 0, n_hndl = graph->n_hndl;
41
+   uint32_t i, insize = 0, outsize = 0, n_hndl = graph->n_hndl;
42
    int32_t stride = 0;
43
    struct graph_port *port;
44
    struct spa_data *bd;
45
 
46
    if ((in = pw_stream_dequeue_buffer(impl->capture)) == NULL)
47
-       pw_log_debug("out of capture buffers: %m");
48
+       pw_log_debug("%p: out of capture buffers: %m", impl);
49
 
50
    if ((out = pw_stream_dequeue_buffer(impl->playback)) == NULL)
51
-       pw_log_debug("out of playback buffers: %m");
52
+       pw_log_debug("%p: out of playback buffers: %m", impl);
53
 
54
    if (in == NULL || out == NULL)
55
        goto done;
56
@@ -614,12 +624,14 @@
57
        port = i < graph->n_input ? &graph->inputi : NULL;
58
 
59
        if (port && port->desc)
60
-           port->desc->connect_port(port->hndl, port->port,
61
+           port->desc->connect_port(*port->hndl, port->port,
62
                SPA_PTROFF(bd->data, offs, void));
63
 
64
-       outsize = i == 0 ? size : SPA_MIN(outsize, size);
65
+       insize = i == 0 ? size : SPA_MIN(insize, size);
66
        stride = SPA_MAX(stride, bd->chunk->stride);
67
    }
68
+   outsize = insize;
69
+
70
    for (i = 0; i < out->buffer->n_datas; i++) {
71
        bd = &out->buffer->datasi;
72
 
73
@@ -628,7 +640,7 @@
74
        port = i < graph->n_output ? &graph->outputi : NULL;
75
 
76
        if (port && port->desc)
77
-           port->desc->connect_port(port->hndl, port->port, bd->data);
78
+           port->desc->connect_port(*port->hndl, port->port, bd->data);
79
        else
80
            memset(bd->data, 0, outsize);
81
 
82
@@ -636,9 +648,13 @@
83
        bd->chunk->size = outsize;
84
        bd->chunk->stride = stride;
85
    }
86
+
87
+   pw_log_trace_fp("%p: stride:%d in:%d out:%d requested:%"PRIu64" (%"PRIu64")", impl,
88
+           stride, insize, outsize, out->requested, out->requested * stride);
89
+
90
    for (i = 0; i < n_hndl; i++) {
91
        struct graph_hndl *hndl = &graph->hndli;
92
-       hndl->desc->run(hndl->hndl, outsize / sizeof(float));
93
+       hndl->desc->run(*hndl->hndl, outsize / sizeof(float));
94
    }
95
 
96
 done:
97
@@ -646,8 +662,6 @@
98
        pw_stream_queue_buffer(impl->capture, in);
99
    if (out != NULL)
100
        pw_stream_queue_buffer(impl->playback, out);
101
-
102
-   pw_stream_trigger_process(impl->playback);
103
 }
104
 
105
 static float get_default(struct impl *impl, struct descriptor *desc, uint32_t p)
106
@@ -746,11 +760,12 @@
107
    struct fc_port *p = &d->portsport->p;
108
    float def, min, max;
109
    char name512;
110
+   uint32_t rate = impl->rate ? impl->rate : 48000;
111
 
112
    if (p->hint & FC_HINT_SAMPLE_RATE) {
113
-       def = p->def * impl->rate;
114
-       min = p->min * impl->rate;
115
-       max = p->max * impl->rate;
116
+       def = p->def * rate;
117
+       min = p->min * rate;
118
+       max = p->max * rate;
119
    } else {
120
        def = p->def;
121
        min = p->min;
122
@@ -908,13 +923,14 @@
123
    for (i = 0; i < graph->n_hndl; i++) {
124
        struct graph_hndl *hndl = &graph->hndli;
125
        const struct fc_descriptor *d = hndl->desc;
126
+       if (hndl->hndl == NULL || *hndl->hndl == NULL)
127
+           continue;
128
        if (d->deactivate)
129
-           d->deactivate(hndl->hndl);
130
+           d->deactivate(*hndl->hndl);
131
        if (d->activate)
132
-           d->activate(hndl->hndl);
133
+           d->activate(*hndl->hndl);
134
    }
135
 }
136
-
137
 static void param_props_changed(struct impl *impl, const struct spa_pod *param)
138
 {
139
    struct spa_pod_object *obj = (struct spa_pod_object *) param;
140
@@ -989,8 +1005,15 @@
141
 
142
    switch (id) {
143
    case SPA_PARAM_Format:
144
-       if (param == NULL)
145
-           graph_reset(graph);
146
+       if (param == NULL) {
147
+           graph_cleanup(graph);
148
+       } else {
149
+           struct spa_audio_info_raw info;
150
+           spa_zero(info);
151
+           spa_format_audio_raw_parse(param, &info);
152
+           impl->rate = info.rate;
153
+           graph_instantiate(graph);
154
+       }
155
        break;
156
    case SPA_PARAM_Props:
157
        if (param != NULL)
158
@@ -1020,6 +1043,7 @@
159
 static const struct pw_stream_events out_stream_events = {
160
    PW_VERSION_STREAM_EVENTS,
161
    .destroy = playback_destroy,
162
+   .process = playback_process,
163
    .state_changed = state_changed,
164
    .param_changed = param_changed
165
 };
166
@@ -1477,6 +1501,7 @@
167
    bool have_config = false;
168
    uint32_t i;
169
    int res;
170
+   float *data;
171
 
172
    while (spa_json_get_string(json, key, sizeof(key)) > 0) {
173
        if (spa_streq("type", key)) {
174
@@ -1551,6 +1576,14 @@
175
        port->idx = i;
176
        port->external = SPA_ID_INVALID;
177
        port->p = desc->outputi;
178
+       if ((data = port->audio_datai) == NULL) {
179
+           data = calloc(1, MAX_SAMPLES * sizeof(float));
180
+           if (data == NULL) {
181
+               pw_log_error("cannot create port data: %m");
182
+               return -errno;
183
+           }
184
+       }
185
+       port->audio_datai = data;
186
        spa_list_init(&port->link_list);
187
    }
188
    for (i = 0; i < desc->n_control; i++) {
189
@@ -1581,21 +1614,31 @@
190
    return 0;
191
 }
192
 
193
-static void node_free(struct node *node)
194
+static void node_cleanup(struct node *node)
195
 {
196
-   uint32_t i, j;
197
    const struct fc_descriptor *d = node->desc->desc;
198
+   uint32_t i;
199
 
200
-   spa_list_remove(&node->link);
201
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
78
 
1
@@ -52,7 +52,7 @@
2
 };
3
 
4
 static void *builtin_instantiate(const struct fc_descriptor * Descriptor,
5
-       unsigned long *SampleRate, int index, const char *config)
6
+       unsigned long SampleRate, int index, const char *config)
7
 {
8
    struct builtin *impl;
9
 
10
@@ -60,7 +60,7 @@
11
    if (impl == NULL)
12
        return NULL;
13
 
14
-   impl->rate = *SampleRate;
15
+   impl->rate = SampleRate;
16
 
17
    return impl;
18
 }
19
@@ -576,7 +576,7 @@
20
 }
21
 
22
 static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
23
-       unsigned long *SampleRate, int index, const char *config)
24
+       unsigned long SampleRate, int index, const char *config)
25
 {
26
    struct convolver_impl *impl;
27
    float *samples;
28
@@ -588,6 +588,7 @@
29
    int blocksize = 0, tailsize = 0;
30
    int delay = 0;
31
    float gain = 1.0f;
32
+   unsigned long rate;
33
 
34
    if (config == NULL)
35
        return NULL;
36
@@ -647,8 +648,13 @@
37
        samples = create_dirac(filename, gain, delay, offset,
38
                length, &n_samples);
39
    } else {
40
+       rate = SampleRate;
41
        samples = read_samples(filename, gain, delay, offset,
42
-               length, channel, SampleRate, &n_samples);
43
+               length, channel, &rate, &n_samples);
44
+       if (rate != SampleRate) {
45
+           pw_log_warn("Convolver samplerate %lu doesn't match filter rate %lu. "
46
+                   "Consider forcing a filter rate.", rate, SampleRate);
47
+       }
48
    }
49
    if (samples == NULL)
50
        return NULL;
51
@@ -664,7 +670,7 @@
52
    if (impl == NULL)
53
        goto error;
54
 
55
-   impl->rate = *SampleRate;
56
+   impl->rate = SampleRate;
57
 
58
    impl->conv = convolver_new(blocksize, tailsize, samples, n_samples);
59
    if (impl->conv == NULL)
60
@@ -750,7 +756,7 @@
61
 }
62
 
63
 static void *delay_instantiate(const struct fc_descriptor * Descriptor,
64
-       unsigned long *SampleRate, int index, const char *config)
65
+       unsigned long SampleRate, int index, const char *config)
66
 {
67
    struct delay_impl *impl;
68
    struct spa_json it2;
69
@@ -782,7 +788,7 @@
70
    if (impl == NULL)
71
        return NULL;
72
 
73
-   impl->rate = *SampleRate;
74
+   impl->rate = SampleRate;
75
    impl->buffer_samples = max_delay * impl->rate;
76
    pw_log_info("%lu %d", impl->rate, impl->buffer_samples);
77
 
78
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
14
 
1
@@ -47,10 +47,10 @@
2
 };
3
 
4
 static void *ladspa_instantiate(const struct fc_descriptor *desc,
5
-                        unsigned long *SampleRate, int index, const char *config)
6
+                        unsigned long SampleRate, int index, const char *config)
7
 {
8
    struct descriptor *d = (struct descriptor *)desc;
9
-   return d->d->instantiate(d->d, *SampleRate);
10
+   return d->d->instantiate(d->d, SampleRate);
11
 }
12
 
13
 static const LADSPA_Descriptor *find_desc(LADSPA_Descriptor_Function desc_func, const char *name)
14
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
28
 
1
@@ -298,7 +298,7 @@
2
 }
3
 
4
 static void *lv2_instantiate(const struct fc_descriptor *desc,
5
-                        unsigned long *SampleRate, int index, const char *config)
6
+                        unsigned long SampleRate, int index, const char *config)
7
 {
8
    struct descriptor *d = (struct descriptor*)desc;
9
    struct plugin *p = d->p;
10
@@ -308,7 +308,7 @@
11
    static const int32_t min_block_length = 1;
12
    static const int32_t max_block_length = 8192;
13
    static const int32_t seq_size = 32768;
14
-   float fsample_rate = *SampleRate;
15
+   float fsample_rate = SampleRate;
16
 
17
    i = calloc(1, sizeof(*i));
18
    if (i == NULL)
19
@@ -350,7 +350,7 @@
20
         i->options_feature.data = i->options;
21
         i->featuresn_features++ = &i->options_feature;
22
 
23
-   i->instance = lilv_plugin_instantiate(p->p, *SampleRate, i->features);
24
+   i->instance = lilv_plugin_instantiate(p->p, SampleRate, i->features);
25
    if (i->instance == NULL) {
26
        free(i);
27
        return NULL;
28
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
10
 
1
@@ -72,7 +72,7 @@
2
    struct fc_port *ports;
3
 
4
    void *(*instantiate) (const struct fc_descriptor *desc,
5
-           unsigned long *SampleRate, int index, const char *config);
6
+           unsigned long SampleRate, int index, const char *config);
7
 
8
    void (*cleanup) (void *instance);
9
 
10
pipewire-0.3.58.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.59.tar.gz/src/modules/module-loopback.c Changed
69
 
1
@@ -179,6 +179,12 @@
2
 static void capture_process(void *d)
3
 {
4
    struct impl *impl = d;
5
+   pw_stream_trigger_process(impl->playback);
6
+}
7
+
8
+static void playback_process(void *d)
9
+{
10
+   struct impl *impl = d;
11
    struct pw_buffer *in, *out;
12
    uint32_t i;
13
 
14
@@ -225,8 +231,6 @@
15
        pw_stream_queue_buffer(impl->capture, in);
16
    if (out != NULL)
17
        pw_stream_queue_buffer(impl->playback, out);
18
-
19
-   pw_stream_trigger_process(impl->playback);
20
 }
21
 
22
 static void param_latency_changed(struct impl *impl, const struct spa_pod *param,
23
@@ -305,6 +309,7 @@
24
 static const struct pw_stream_events out_stream_events = {
25
    PW_VERSION_STREAM_EVENTS,
26
    .destroy = playback_destroy,
27
+   .process = playback_process,
28
    .state_changed = stream_state_changed,
29
    .param_changed = playback_param_changed,
30
 };
31
@@ -399,12 +404,20 @@
32
 
33
 static void impl_destroy(struct impl *impl)
34
 {
35
+   /* disconnect both streams before destroying any of them */
36
+   if (impl->capture)
37
+       pw_stream_disconnect(impl->capture);
38
+   if (impl->playback)
39
+       pw_stream_disconnect(impl->playback);
40
+
41
    if (impl->capture)
42
        pw_stream_destroy(impl->capture);
43
    if (impl->playback)
44
        pw_stream_destroy(impl->playback);
45
+
46
    if (impl->core && impl->do_disconnect)
47
        pw_core_disconnect(impl->core);
48
+
49
    pw_properties_free(impl->capture_props);
50
    pw_properties_free(impl->playback_props);
51
    free(impl);
52
@@ -518,6 +531,8 @@
53
        pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "loopback-%u-%u", pid, id);
54
    if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL)
55
        pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
56
+   if (pw_properties_get(props, "resample.prefill") == NULL)
57
+       pw_properties_set(props, "resample.prefill", "true");
58
 
59
    if ((str = pw_properties_get(props, "capture.props")) != NULL)
60
        pw_properties_update_string(impl->capture_props, str, strlen(str));
61
@@ -533,6 +548,7 @@
62
    copy_props(impl, props, PW_KEY_NODE_LATENCY);
63
    copy_props(impl, props, PW_KEY_NODE_VIRTUAL);
64
    copy_props(impl, props, PW_KEY_MEDIA_NAME);
65
+   copy_props(impl, props, "resample.prefill");
66
 
67
    if ((str = pw_properties_get(props, PW_KEY_NODE_NAME)) == NULL) {
68
        pw_properties_setf(props, PW_KEY_NODE_NAME,
69
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
43
 
1
@@ -221,7 +221,10 @@
2
    struct cmsghdr *cmsg = NULL;
3
    struct msghdr msg = { 0 };
4
    struct iovec iov1;
5
-   char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int));
6
+   union {
7
+       char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int));
8
+       struct cmsghdr align;
9
+   } cmsgbuf;
10
    int n_fds = 0;
11
    size_t avail;
12
 
13
@@ -231,7 +234,7 @@
14
    iov0.iov_len = avail;
15
    msg.msg_iov = iov;
16
    msg.msg_iovlen = 1;
17
-   msg.msg_control = cmsgbuf;
18
+   msg.msg_control = &cmsgbuf;
19
    msg.msg_controllen = sizeof(cmsgbuf);
20
    msg.msg_flags = MSG_CMSG_CLOEXEC | MSG_DONTWAIT;
21
 
22
@@ -755,7 +758,10 @@
23
    struct msghdr msg = { 0 };
24
    struct iovec iov1;
25
    struct cmsghdr *cmsg;
26
-   char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int));
27
+   union {
28
+       char cmsgbufCMSG_SPACE(MAX_FDS_MSG * sizeof(int));
29
+       struct cmsghdr align;
30
+   } cmsgbuf;
31
    int res = 0, *fds;
32
    uint32_t fds_len, to_close, n_fds, outfds, i;
33
    struct buffer *buf;
34
@@ -786,7 +792,7 @@
35
        msg.msg_iovlen = 1;
36
 
37
        if (outfds > 0) {
38
-           msg.msg_control = cmsgbuf;
39
+           msg.msg_control = &cmsgbuf;
40
            msg.msg_controllen = CMSG_SPACE(fds_len);
41
            cmsg = CMSG_FIRSTHDR(&msg);
42
            cmsg->cmsg_level = SOL_SOCKET;
43
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
24
 
1
@@ -31,13 +31,19 @@
2
                        void (*done_callback) (void *data, int res),
3
                        void *data);
4
 
5
-static inline void *get_first_pod_from_data(void *data, size_t maxsize, off_t offset)
6
+static inline void *get_first_pod_from_data(void *data, uint32_t maxsize, uint64_t offset)
7
 {
8
    void *pod;
9
-   if (offset + sizeof(struct spa_pod) > maxsize)
10
+   if (maxsize <= offset)
11
        return NULL;
12
+
13
+   /* spa_pod_parser_advance() rounds up, so round down here to compensate */
14
+   maxsize = SPA_ROUND_DOWN_N(maxsize - offset, 8);
15
+   if (maxsize < sizeof(struct spa_pod))
16
+       return NULL;
17
+
18
    pod = SPA_PTROFF(data, offset, void);
19
-   if (offset + SPA_POD_SIZE(pod) > maxsize)
20
+   if (SPA_POD_BODY_SIZE(pod) > maxsize - sizeof(struct spa_pod))
21
        return NULL;
22
    return pod;
23
 }
24
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
10
 
1
@@ -45,7 +45,7 @@
2
    unsigned int started:1;
3
 };
4
 
5
-#define FOOTER_BUILDER_INIT(builder) (struct footer_builder) { builder }
6
+#define FOOTER_BUILDER_INIT(builder) ((struct footer_builder) { (builder) })
7
 
8
 static void start_footer_entry(struct footer_builder *fb, uint32_t opcode)
9
 {
10
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
47
 
1
@@ -219,13 +219,13 @@
2
        spa_pod_parser_get(prs,                         \
3
                   SPA_POD_Int(&(n_params)), NULL) < 0)         \
4
        return -EINVAL;                             \
5
-   params = NULL;                                  \
6
-   if (n_params > 0) {                             \
7
+   (params) = NULL;                                    \
8
+   if ((n_params) > 0) {                               \
9
        uint32_t i;                             \
10
-       if (n_params > MAX_PARAM_INFO)                      \
11
+       if ((n_params) > MAX_PARAM_INFO)                        \
12
            return -ENOSPC;                         \
13
-       params = alloca(n_params * sizeof(struct spa_param_info));      \
14
-       for (i = 0; i < n_params; i++) {                    \
15
+       (params) = alloca((n_params) * sizeof(struct spa_param_info));      \
16
+       for (i = 0; i < (n_params); i++) {                  \
17
            if (spa_pod_parser_get(prs,                 \
18
                       SPA_POD_Id(&(params)i.id),           \
19
                       SPA_POD_Int(&(params)i.flags), NULL) < 0)    \
20
@@ -240,18 +240,18 @@
21
 do {                                               \
22
    if (spa_pod_parser_push_struct(prs, f) < 0 ||                       \
23
        spa_pod_parser_get(prs,                             \
24
-           SPA_POD_Int(&n_permissions), NULL) < 0)                 \
25
+           SPA_POD_Int(&(n_permissions)), NULL) < 0)                   \
26
        return -EINVAL;                                 \
27
-   permissions = NULL;                                 \
28
-   if (n_permissions > 0) {                                \
29
+   (permissions) = NULL;                                   \
30
+   if ((n_permissions) > 0) {                              \
31
        uint32_t i;                                 \
32
-       if (n_permissions > MAX_PERMISSIONS)                        \
33
+       if ((n_permissions) > MAX_PERMISSIONS)                      \
34
            return -ENOSPC;                             \
35
-       permissions = alloca(n_permissions * sizeof(struct pw_permission));     \
36
-       for (i = 0; i < n_permissions; i++) {                       \
37
+       (permissions) = alloca((n_permissions) * sizeof(struct pw_permission));     \
38
+       for (i = 0; i < (n_permissions); i++) {                     \
39
            if (spa_pod_parser_get(prs,                     \
40
-                   SPA_POD_Int(&permissionsi.id),          \
41
-                   SPA_POD_Int(&permissionsi.permissions), NULL) < 0)  \
42
+                   SPA_POD_Int(&(permissions)i.id),            \
43
+                   SPA_POD_Int(&(permissions)i.permissions), NULL) < 0)    \
44
                return -EINVAL;                         \
45
        }                                       \
46
    }                                           \
47
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
10
 
1
@@ -415,7 +415,7 @@
2
              (iter) <= SPA_PTROFF((body), (_size)-(body)->value.size, __typeof__(*iter));       \
3
              (iter) = SPA_PTROFF((iter), (body)->value.size, __typeof__(*iter)))
4
 
5
-#define SPA0_POD_PROP_N_VALUES(b,size)     ((size - sizeof(struct spa_pod_prop_body0)) / (b)->value.size)
6
+#define SPA0_POD_PROP_N_VALUES(b,size)     (((size) - sizeof(struct spa_pod_prop_body0)) / (b)->value.size)
7
 
8
 static int remap_from_v2(uint32_t type, void *body, uint32_t size, struct pw_impl_client *client,
9
        struct spa_pod_builder *builder)
10
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
22
 
1
@@ -35,13 +35,13 @@
2
 
3
 #define MAX_PARAMS 32
4
 
5
-#define manager_emit_sync(m) spa_hook_list_call(&m->hooks, struct pw_manager_events, sync, 0)
6
-#define manager_emit_added(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, added, 0, o)
7
-#define manager_emit_updated(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, updated, 0, o)
8
-#define manager_emit_removed(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, removed, 0, o)
9
-#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)
10
-#define manager_emit_disconnect(m) spa_hook_list_call(&m->hooks, struct pw_manager_events, disconnect, 0)
11
-#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)
12
+#define manager_emit_sync(m) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, sync, 0)
13
+#define manager_emit_added(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, added, 0, o)
14
+#define manager_emit_updated(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, updated, 0, o)
15
+#define manager_emit_removed(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, removed, 0, o)
16
+#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)
17
+#define manager_emit_disconnect(m) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, disconnect, 0)
18
+#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)
19
 
20
 struct object;
21
 
22
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
129
 
1
@@ -89,7 +89,7 @@
2
 #define MAX_FORMATS    32
3
 /* The max amount of data we send in one block when capturing. In PulseAudio this
4
  * size is derived from the mempool PA_MEMPOOL_SLOT_SIZE */
5
-#define MAX_FRAGSIZE   (64*1024)
6
+#define MAX_BLOCK  (64*1024)
7
 
8
 #define TEMPORARY_MOVE_TIMEOUT (SPA_NSEC_PER_SEC)
9
 
10
@@ -455,7 +455,7 @@
11
 static uint64_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *attr,
12
        uint32_t rate, struct spa_fraction *lat)
13
 {
14
-   uint32_t frame_size, max_prebuf, minreq, latency, max_latency;
15
+   uint32_t frame_size, max_prebuf, minreq, latency, max_latency, maxlength;
16
    struct defs *defs = &s->impl->defs;
17
 
18
    if ((frame_size = s->frame_size) == 0)
19
@@ -463,24 +463,26 @@
20
    if (frame_size == 0)
21
        frame_size = 4;
22
 
23
-   pw_log_info("%s maxlength:%u tlength:%u minreq:%u prebuf:%u",
24
+   maxlength = SPA_ROUND_DOWN(MAXLENGTH, frame_size);
25
+
26
+   pw_log_info("%s maxlength:%u tlength:%u minreq:%u prebuf:%u max:%u",
27
            s->client->name, attr->maxlength, attr->tlength,
28
-           attr->minreq, attr->prebuf);
29
+           attr->minreq, attr->prebuf, maxlength);
30
 
31
    minreq = frac_to_bytes_round_up(s->min_req, &s->ss);
32
    max_latency = defs->quantum_limit * frame_size;
33
 
34
-   if (attr->maxlength == (uint32_t) -1 || attr->maxlength > MAXLENGTH)
35
-       attr->maxlength = MAXLENGTH;
36
-   attr->maxlength = SPA_ROUND_UP(attr->maxlength, frame_size);
37
+   if (attr->maxlength == (uint32_t) -1 || attr->maxlength > maxlength)
38
+       attr->maxlength = maxlength;
39
+   else
40
+       attr->maxlength = SPA_ROUND_DOWN(attr->maxlength, frame_size);
41
 
42
    minreq = SPA_MIN(minreq, attr->maxlength);
43
 
44
    if (attr->tlength == (uint32_t) -1)
45
        attr->tlength = frac_to_bytes_round_up(s->default_tlength, &s->ss);
46
-   attr->tlength = SPA_MIN(attr->tlength, attr->maxlength);
47
+   attr->tlength = SPA_CLAMP(attr->tlength, minreq, attr->maxlength);
48
    attr->tlength = SPA_ROUND_UP(attr->tlength, frame_size);
49
-   attr->tlength = SPA_MAX(attr->tlength, minreq);
50
 
51
    if (attr->minreq == (uint32_t) -1) {
52
        uint32_t process = frac_to_bytes_round_up(s->default_req, &s->ss);
53
@@ -655,39 +657,46 @@
54
 static uint64_t fix_record_buffer_attr(struct stream *s, struct buffer_attr *attr,
55
        uint32_t rate, struct spa_fraction *lat)
56
 {
57
-   uint32_t frame_size, minfrag, latency;
58
+   uint32_t frame_size, minfrag, latency, maxlength;
59
 
60
    if ((frame_size = s->frame_size) == 0)
61
        frame_size = sample_spec_frame_size(&s->ss);
62
    if (frame_size == 0)
63
        frame_size = 4;
64
 
65
+   maxlength = SPA_ROUND_DOWN(MAXLENGTH, frame_size);
66
+
67
    pw_log_info("%s maxlength:%u fragsize:%u framesize:%u",
68
            s->client->name, attr->maxlength, attr->fragsize,
69
            frame_size);
70
 
71
-   if (attr->maxlength == (uint32_t) -1 || attr->maxlength > MAXLENGTH)
72
-       attr->maxlength = MAXLENGTH;
73
-   attr->maxlength -= attr->maxlength % frame_size;
74
+   if (attr->maxlength == (uint32_t) -1 || attr->maxlength > maxlength)
75
+       attr->maxlength = maxlength;
76
+   else
77
+       attr->maxlength = SPA_ROUND_DOWN(attr->maxlength, frame_size);
78
    attr->maxlength = SPA_MAX(attr->maxlength, frame_size);
79
 
80
    minfrag = frac_to_bytes_round_up(s->min_frag, &s->ss);
81
 
82
    if (attr->fragsize == (uint32_t) -1 || attr->fragsize == 0)
83
        attr->fragsize = frac_to_bytes_round_up(s->default_frag, &s->ss);
84
-   attr->fragsize = SPA_MIN(attr->fragsize, attr->maxlength);
85
+   attr->fragsize = SPA_CLAMP(attr->fragsize, minfrag, attr->maxlength);
86
    attr->fragsize = SPA_ROUND_UP(attr->fragsize, frame_size);
87
-   attr->fragsize = SPA_MAX(attr->fragsize, minfrag);
88
 
89
    attr->tlength = attr->minreq = attr->prebuf = 0;
90
 
91
-   /* make sure can queue at least to fragsize without overruns */
92
-   if (attr->maxlength < attr->fragsize * 4)
93
+   /* make sure we can queue at least to fragsize without overruns */
94
+   if (attr->maxlength < attr->fragsize * 4) {
95
        attr->maxlength = attr->fragsize * 4;
96
+       if (attr->maxlength > maxlength) {
97
+           attr->maxlength = maxlength;
98
+           attr->fragsize = SPA_ROUND_DOWN(maxlength / 4, frame_size);
99
+       }
100
+   }
101
 
102
-   latency = attr->fragsize / frame_size;
103
+   latency = attr->fragsize;
104
 
105
-   lat->num = latency;
106
+   lat->num = latency / frame_size;
107
    lat->denom = rate;
108
    clamp_latency(s, lat);
109
 
110
@@ -1341,7 +1350,8 @@
111
            pw_log_trace("avail:%d index:%u", avail, index);
112
 
113
            while ((uint32_t)avail >= stream->attr.fragsize) {
114
-               towrite = SPA_MIN(avail, MAX_FRAGSIZE);
115
+               towrite = SPA_MIN(avail, MAX_BLOCK);
116
+               towrite = SPA_MIN(towrite, stream->attr.fragsize);
117
                towrite = SPA_ROUND_DOWN(towrite, stream->frame_size);
118
 
119
                msg = message_alloc(impl, stream->channel, towrite);
120
@@ -1421,7 +1431,7 @@
121
                    spa_ringbuffer_read_data(&stream->ring,
122
                        stream->buffer, MAXLENGTH,
123
                        index % MAXLENGTH,
124
-                       p, avail);
125
+                       p, SPA_MIN((uint32_t)avail, size));
126
                    index += avail;
127
                }
128
                pd.playing_for = size;
129
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
10
 
1
@@ -195,7 +195,7 @@
2
 
3
    strcat(pid_file, "/pid");
4
 
5
-   if ((f = fopen(pid_file, "w")) == NULL) {
6
+   if ((f = fopen(pid_file, "we")) == NULL) {
7
        res = -errno;
8
        pw_log_error("failed to open pid file: %m");
9
        return res;
10
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
10
 
1
@@ -113,7 +113,7 @@
2
    const char *domain;
3
 };
4
 
5
-#define TUNNEL_INFO(...) (struct tunnel_info){ __VA_ARGS__ }
6
+#define TUNNEL_INFO(...) ((struct tunnel_info){ __VA_ARGS__ })
7
 
8
 struct tunnel {
9
    struct spa_list link;
10
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
26
 
1
@@ -421,6 +421,7 @@
2
 
3
    switch (impl->codec) {
4
    case CODEC_PCM:
5
+   case CODEC_ALAC:
6
        len = write_codec_pcm(dst, impl->buffer, n_frames);
7
        break;
8
    default:
9
@@ -463,6 +464,7 @@
10
 
11
    switch (impl->codec) {
12
    case CODEC_PCM:
13
+   case CODEC_ALAC:
14
        len = write_codec_pcm(dst, impl->buffer, n_frames);
15
        break;
16
    default:
17
@@ -1756,6 +1758,8 @@
18
        str = "PCM";
19
    if (spa_streq(str, "PCM"))
20
        impl->codec = CODEC_PCM;
21
+   else if (spa_streq(str, "ALAC"))
22
+       impl->codec = CODEC_ALAC;
23
    else {
24
        pw_log_error( "can't handle codec type %s", str);
25
        res = -EINVAL;
26
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
12
 
1
@@ -314,8 +314,8 @@
2
            return -EPROTO;
3
 
4
        *value++ = '\0';
5
-       while (*value == ' ')
6
-           value++;
7
+
8
+       value = pw_strip(value, " ");
9
 
10
        pw_properties_set(client->headers, key, value);
11
    }
12
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
9
 
1
@@ -25,6 +25,7 @@
2
 
3
 #ifndef MODULE_SESSION_MANAGER_ENDPOINT_LINK_H
4
 #define MODULE_SESSION_MANAGER_ENDPOINT_LINK_H
5
+#include <stdint.h>
6
 
7
 #ifdef __cplusplus
8
 extern "C" {
9
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
9
 
1
@@ -25,6 +25,7 @@
2
 
3
 #ifndef MODULE_SESSION_MANAGER_SESSION_H
4
 #define MODULE_SESSION_MANAGER_SESSION_H
5
+#include <stdint.h>
6
 
7
 #ifdef __cplusplus
8
 extern "C" {
9
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
10
 
1
@@ -109,7 +109,7 @@
2
    const char *domain;
3
 };
4
 
5
-#define TUNNEL_INFO(...) (struct tunnel_info){ __VA_ARGS__ }
6
+#define TUNNEL_INFO(...) ((struct tunnel_info){ __VA_ARGS__ })
7
 
8
 struct tunnel {
9
    struct spa_list link;
10
pipewire-0.3.58.tar.gz/src/pipewire/array.h -> pipewire-0.3.59.tar.gz/src/pipewire/array.h Changed
32
 
1
@@ -52,7 +52,7 @@
2
    size_t extend;      /**< number of bytes to extend with */
3
 };
4
 
5
-#define PW_ARRAY_INIT(extend) (struct pw_array) { NULL, 0, 0, extend }
6
+#define PW_ARRAY_INIT(extend) ((struct pw_array) { NULL, 0, 0, (extend) })
7
 
8
 #define pw_array_get_len_s(a,s)            ((a)->size / (s))
9
 #define pw_array_get_unchecked_s(a,idx,s,t)    SPA_PTROFF((a)->data,(idx)*(s),t)
10
@@ -67,17 +67,17 @@
11
 
12
 #define pw_array_first(a)  ((a)->data)
13
 #define pw_array_end(a)        SPA_PTROFF((a)->data, (a)->size, void)
14
-#define pw_array_check(a,p)    (SPA_PTROFF(p,sizeof(*p),void) <= pw_array_end(a))
15
+#define pw_array_check(a,p)    (SPA_PTROFF(p,sizeof(*(p)),void) <= pw_array_end(a))
16
 
17
 #define pw_array_for_each(pos, array)                  \
18
-   for (pos = (__typeof__(pos)) pw_array_first(array);     \
19
+   for ((pos) = (__typeof__(pos)) pw_array_first(array);       \
20
         pw_array_check(array, pos);                \
21
         (pos)++)
22
 
23
 #define pw_array_consume(pos, array)                   \
24
-   for (pos = (__typeof__(pos)) pw_array_first(array);     \
25
+   for ((pos) = (__typeof__(pos)) pw_array_first(array);       \
26
         pw_array_check(array, pos);                \
27
-        pos = (__typeof__(pos)) pw_array_first(array))
28
+        (pos) = (__typeof__(pos)) pw_array_first(array))
29
 
30
 #define pw_array_remove(a,p)                       \
31
 ({                                 \
32
pipewire-0.3.58.tar.gz/src/pipewire/context.c -> pipewire-0.3.59.tar.gz/src/pipewire/context.c Changed
19
 
1
@@ -1205,7 +1205,7 @@
2
                if (settings->clock_rate_update_mode == CLOCK_RATE_UPDATE_MODE_HARD)
3
                    suspend_driver(context, n);
4
            } else {
5
-               if (n->info.state >= PW_NODE_STATE_IDLE)
6
+               if (n->info.state >= PW_NODE_STATE_SUSPENDED)
7
                    suspend_driver(context, n);
8
            }
9
            /* we're setting the pending rate. This will become the new
10
@@ -1263,7 +1263,7 @@
11
            n->current_pending = false;
12
        }
13
 
14
-       pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'",
15
+       pw_log_debug("%p: driver %p running:%d passive:%d quantum:%u '%s'",
16
                context, n, running, n->passive, quantum, n->name);
17
 
18
        /* first change the node states of the followers to the new target */
19
pipewire-0.3.58.tar.gz/src/pipewire/filter.c -> pipewire-0.3.59.tar.gz/src/pipewire/filter.c Changed
10
 
1
@@ -1179,7 +1179,7 @@
2
    struct pw_filter *filter;
3
    int count;
4
 };
5
-#define MATCH_INIT(f) (struct match){ .filter = f }
6
+#define MATCH_INIT(f) ((struct match){ .filter = (f) })
7
 
8
 static int execute_match(void *data, const char *location, const char *action,
9
        const char *val, size_t len)
10
pipewire-0.3.58.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.59.tar.gz/src/pipewire/impl-node.c Changed
76
 
1
@@ -188,12 +188,12 @@
2
    pw_loop_invoke(this->data_loop, do_node_remove, 1, NULL, 0, true, this);
3
 }
4
 
5
-static int pause_node(struct pw_impl_node *this)
6
+static int idle_node(struct pw_impl_node *this)
7
 {
8
    struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
9
    int res = 0;
10
 
11
-   pw_log_debug("%p: pause node state:%s pending:%s pause-on-idle:%d", this,
12
+   pw_log_debug("%p: idle node state:%s pending:%s pause-on-idle:%d", this,
13
            pw_node_state_as_string(this->info.state),
14
            pw_node_state_as_string(impl->pending_state),
15
            impl->pause_on_idle);
16
@@ -201,6 +201,9 @@
17
    if (impl->pending_state <= PW_NODE_STATE_IDLE)
18
        return 0;
19
 
20
+   if (!impl->pause_on_idle)
21
+       return 0;
22
+
23
    node_deactivate(this);
24
 
25
    res = spa_node_send_command(this->node,
26
@@ -247,7 +250,8 @@
27
    if (impl->pending_state >= PW_NODE_STATE_RUNNING)
28
        return 0;
29
 
30
-   pw_log_debug("%p: start node", this);
31
+   pw_log_debug("%p: start node driving:%d driver:%d added:%d", this,
32
+           this->driving, this->driver, this->added);
33
 
34
    if (!(this->driving && this->driver)) {
35
        impl->pending_play = true;
36
@@ -357,6 +361,9 @@
37
 
38
    switch (state) {
39
    case PW_NODE_STATE_RUNNING:
40
+       pw_log_debug("%p: start node driving:%d driver:%d added:%d", node,
41
+               node->driving, node->driver, node->added);
42
+
43
        if (node->driving && node->driver) {
44
            res = spa_node_send_command(node->node,
45
                &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Start));
46
@@ -438,6 +445,9 @@
47
        p->state = PW_IMPL_PORT_STATE_CONFIGURE;
48
    }
49
 
50
+   pw_log_debug("%p: suspend node driving:%d driver:%d added:%d", this,
51
+           this->driving, this->driver, this->added);
52
+
53
    res = spa_node_send_command(this->node,
54
                    &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend));
55
    if (res == -ENOTSUP)
56
@@ -2185,8 +2195,7 @@
57
        break;
58
 
59
    case PW_NODE_STATE_IDLE:
60
-       if (impl->pause_on_idle)
61
-           res = pause_node(node);
62
+       res = idle_node(node);
63
        break;
64
 
65
    case PW_NODE_STATE_RUNNING:
66
@@ -2215,8 +2224,7 @@
67
                state < PW_NODE_STATE_RUNNING &&
68
                impl->pending_play) {
69
                impl->pending_play = false;
70
-               spa_node_send_command(node->node,
71
-                   &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Pause));
72
+               idle_node(node);
73
            }
74
            pw_work_queue_cancel(impl->work, node, impl->pending_id);
75
            node->info.state = impl->pending_state;
76
pipewire-0.3.58.tar.gz/src/pipewire/log.h -> pipewire-0.3.59.tar.gz/src/pipewire/log.h Changed
19
 
1
@@ -116,7 +116,7 @@
2
  */
3
 #define PW_LOG_TOPIC_STATIC(var, topic) \
4
   static struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \
5
-  static struct spa_log_topic *var = &(var##__LINE__)
6
+  static struct spa_log_topic *(var) = &(var##__LINE__)
7
 
8
 /**
9
  * Declare a static log topic named \a var.
10
@@ -131,7 +131,7 @@
11
  */
12
 #define PW_LOG_TOPIC(var, topic) \
13
   struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \
14
-  struct spa_log_topic *var = &(var##__LINE__)
15
+  struct spa_log_topic *(var) = &(var##__LINE__)
16
 
17
 #define PW_LOG_TOPIC_INIT(var) \
18
    spa_log_topic_init(pw_log_get(), var);
19
pipewire-0.3.58.tar.gz/src/pipewire/map.h -> pipewire-0.3.59.tar.gz/src/pipewire/map.h Changed
10
 
1
@@ -85,7 +85,7 @@
2
 };
3
 
4
 /** \param extend the amount of bytes to grow the map with when needed */
5
-#define PW_MAP_INIT(extend) (struct pw_map) { PW_ARRAY_INIT(extend), SPA_ID_INVALID }
6
+#define PW_MAP_INIT(extend) ((struct pw_map) { PW_ARRAY_INIT(extend), SPA_ID_INVALID })
7
 
8
 /**
9
  * Get the number of currently allocated elements in the map.
10
pipewire-0.3.58.tar.gz/src/pipewire/permission.h -> pipewire-0.3.59.tar.gz/src/pipewire/permission.h Changed
10
 
1
@@ -66,7 +66,7 @@
2
    uint32_t permissions;   /**< bitmask of above permissions */
3
 };
4
 
5
-#define PW_PERMISSION_INIT(id,p) (struct pw_permission){ (id), (p) }
6
+#define PW_PERMISSION_INIT(id,p) ((struct pw_permission){ (id), (p) })
7
 
8
 #define PW_PERMISSION_FORMAT "%c%c%c%c"
9
 #define PW_PERMISSION_ARGS(permission)     \
10
pipewire-0.3.58.tar.gz/src/pipewire/private.h -> pipewire-0.3.59.tar.gz/src/pipewire/private.h Changed
19
 
1
@@ -177,7 +177,7 @@
2
    return NULL;
3
 }
4
 
5
-#define pw_protocol_emit_destroy(p) spa_hook_list_call(&p->listener_list, struct pw_protocol_events, destroy, 0)
6
+#define pw_protocol_emit_destroy(p) spa_hook_list_call(&(p)->listener_list, struct pw_protocol_events, destroy, 0)
7
 
8
 struct pw_protocol {
9
    struct spa_list link;                   /**< link in context protocol_list */
10
@@ -805,7 +805,7 @@
11
 #define pw_impl_port_emit_param_changed(p,i)       pw_impl_port_emit(p, param_changed, 1, i)
12
 #define pw_impl_port_emit_latency_changed(p)       pw_impl_port_emit(p, latency_changed, 2)
13
 
14
-#define PW_IMPL_PORT_IS_CONTROL(port)  SPA_FLAG_MASK(port->flags, \
15
+#define PW_IMPL_PORT_IS_CONTROL(port)  SPA_FLAG_MASK((port)->flags, \
16
                        PW_IMPL_PORT_FLAG_BUFFERS|PW_IMPL_PORT_FLAG_CONTROL,\
17
                        PW_IMPL_PORT_FLAG_CONTROL)
18
 struct pw_impl_port {
19
pipewire-0.3.58.tar.gz/src/pipewire/stream.c -> pipewire-0.3.59.tar.gz/src/pipewire/stream.c Changed
128
 
1
@@ -400,6 +400,28 @@
2
    return NULL;
3
 }
4
 
5
+static inline uint32_t update_requested(struct stream *impl)
6
+{
7
+   uint32_t index, id, res = 0;
8
+   struct buffer *buffer;
9
+   struct spa_io_rate_match *r = impl->rate_match;
10
+
11
+   if (spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index) < 1)
12
+       return 0;
13
+
14
+   id = impl->dequeued.idsindex & MASK_BUFFERS;
15
+   buffer = &impl->buffersid;
16
+   if (r) {
17
+       buffer->this.requested = r->size;
18
+       res = r->size > 0 ? 1 : 0;
19
+   } else {
20
+       buffer->this.requested = impl->quantum;
21
+       res = 1;
22
+   }
23
+   pw_log_trace_fp("%p: update buffer:%u size:%"PRIu64, impl, id, buffer->this.requested);
24
+   return res;
25
+}
26
+
27
 static int
28
 do_call_process(struct spa_loop *loop,
29
                  bool async, uint32_t seq, const void *data, size_t size, void *user_data)
30
@@ -411,9 +433,11 @@
31
    return 0;
32
 }
33
 
34
-static void call_process(struct stream *impl)
35
+static inline void call_process(struct stream *impl)
36
 {
37
    pw_log_trace_fp("%p: call process rt:%u", impl, impl->process_rt);
38
+   if (impl->direction == SPA_DIRECTION_OUTPUT && update_requested(impl) <= 0)
39
+       return;
40
    if (impl->process_rt)
41
        spa_callbacks_call(&impl->rt_callbacks, struct pw_stream_events, process, 0);
42
    else
43
@@ -563,28 +587,6 @@
44
    return 0;
45
 }
46
 
47
-static inline uint32_t update_requested(struct stream *impl)
48
-{
49
-   uint32_t index, id, res = 0;
50
-   struct buffer *buffer;
51
-   struct spa_io_rate_match *r = impl->rate_match;
52
-
53
-   if (spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index) < 1)
54
-       return 0;
55
-
56
-   id = impl->dequeued.idsindex & MASK_BUFFERS;
57
-   buffer = &impl->buffersid;
58
-   if (r) {
59
-       buffer->this.requested = r->size;
60
-       res = r->size > 0 ? 1 : 0;
61
-   } else {
62
-       buffer->this.requested = impl->quantum;
63
-       res = 1;
64
-   }
65
-   pw_log_trace_fp("%p: update buffer:%u size:%"PRIu64, impl, id, buffer->this.requested);
66
-   return res;
67
-}
68
-
69
 static int impl_send_command(void *object, const struct spa_command *command)
70
 {
71
    struct stream *impl = object;
72
@@ -612,10 +614,8 @@
73
 
74
            if (impl->direction == SPA_DIRECTION_INPUT)
75
                impl->io->status = SPA_STATUS_NEED_DATA;
76
-           else if (!impl->process_rt && !impl->driving) {
77
-               if (update_requested(impl) > 0)
78
-                   call_process(impl);
79
-           }
80
+           else if (!impl->process_rt && !impl->driving)
81
+               call_process(impl);
82
 
83
            stream_set_state(stream, PW_STREAM_STATE_STREAMING, NULL);
84
        }
85
@@ -1081,8 +1081,7 @@
86
        /* we're not draining, not a driver check if we need to get
87
         * more buffers */
88
        if (ask_more) {
89
-           if (update_requested(impl) > 0)
90
-               call_process(impl);
91
+           call_process(impl);
92
            /* realtime, we can try again now if there is something.
93
             * non-realtime, we will have to try in the next round */
94
            if (impl->process_rt &&
95
@@ -1403,7 +1402,7 @@
96
    struct pw_stream *stream;
97
    int count;
98
 };
99
-#define MATCH_INIT(s) (struct match){ .stream = s }
100
+#define MATCH_INIT(s) ((struct match){ .stream = (s) })
101
 
102
 static int execute_match(void *data, const char *location, const char *action,
103
        const char *val, size_t len)
104
@@ -2352,7 +2351,7 @@
105
    int res;
106
    if (impl->direction == SPA_DIRECTION_OUTPUT) {
107
        if (impl->process_rt)
108
-           spa_callbacks_call(&impl->rt_callbacks, struct pw_stream_events, process, 0);
109
+           call_process(impl);
110
        res = impl->node_methods.process(impl);
111
    } else {
112
        res = SPA_STATUS_NEED_DATA;
113
@@ -2386,11 +2385,9 @@
114
    if (!impl->driving && !impl->trigger) {
115
        res = trigger_request_process(impl);
116
    } else {
117
-       if (impl->direction == SPA_DIRECTION_OUTPUT &&
118
-           !impl->process_rt) {
119
-           pw_loop_invoke(impl->context->main_loop,
120
-               do_call_process, 1, NULL, 0, false, impl);
121
-       }
122
+       if (!impl->process_rt)
123
+           call_process(impl);
124
+
125
        res = pw_loop_invoke(impl->context->data_loop,
126
            do_trigger_process, 1, NULL, 0, false, impl);
127
    }
128
pipewire-0.3.58.tar.gz/src/pipewire/thread-loop.c -> pipewire-0.3.59.tar.gz/src/pipewire/thread-loop.c Changed
10
 
1
@@ -91,7 +91,7 @@
2
 
3
 #define CHECK(expression,label)                        \
4
 do {                                   \
5
-   if ((errno = expression) != 0) {                \
6
+   if ((errno = (expression)) != 0) {              \
7
        res = -errno;                       \
8
        pw_log_error(#expression ": %s", strerror(errno));  \
9
        goto label;                     \
10
pipewire-0.3.58.tar.gz/src/pipewire/thread.c -> pipewire-0.3.59.tar.gz/src/pipewire/thread.c Changed
10
 
1
@@ -37,7 +37,7 @@
2
 
3
 #define CHECK(expression,label)                        \
4
 do {                                   \
5
-   if ((errno = expression) != 0) {                \
6
+   if ((errno = (expression)) != 0) {              \
7
        res = -errno;                       \
8
        pw_log_error(#expression ": %s", strerror(errno));  \
9
        goto label;                     \
10
pipewire-0.3.58.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.59.tar.gz/src/tools/pw-cli.c Changed
11
 
1
@@ -2374,8 +2374,8 @@
2
            fprintf(stderr, "Error: \"%s\"\n", error);
3
            free(error);
4
        }
5
+       data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0);
6
        while (!data.quit && data.current) {
7
-           data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0);
8
            pw_main_loop_run(data.loop);
9
            if (!monitor)
10
                break;
11
pipewire-0.3.58.tar.gz/src/tools/pw-dot.c -> pipewire-0.3.59.tar.gz/src/tools/pw-dot.c Changed
10
 
1
@@ -514,7 +514,7 @@
2
        fputs(d->dot_str, stdout);
3
    } else {
4
        /* open the file */
5
-       fp = fopen(path, "w");
6
+       fp = fopen(path, "we");
7
        if (fp == NULL) {
8
            printf("open error: could not open %s for writing\n", path);
9
            return -1;
10
pipewire-0.3.58.tar.gz/src/tools/pw-profiler.c -> pipewire-0.3.59.tar.gz/src/tools/pw-profiler.c Changed
73
 
1
@@ -262,7 +262,7 @@
2
 
3
    printf("\ndumping scripts for %d followers\n", d->n_followers);
4
 
5
-   out = fopen("Timing1.plot", "w");
6
+   out = fopen("Timing1.plot", "we");
7
    if (out == NULL) {
8
        pw_log_error("Can't open Timing1.plot: %m");
9
    } else {
10
@@ -282,7 +282,7 @@
11
        fclose(out);
12
    }
13
 
14
-   out = fopen("Timing2.plot", "w");
15
+   out = fopen("Timing2.plot", "we");
16
    if (out == NULL) {
17
        pw_log_error("Can't open Timing2.plot: %m");
18
    } else {
19
@@ -298,7 +298,7 @@
20
        fclose(out);
21
    }
22
 
23
-   out = fopen("Timing3.plot", "w");
24
+   out = fopen("Timing3.plot", "we");
25
    if (out == NULL) {
26
        pw_log_error("Can't open Timing3.plot: %m");
27
    } else {
28
@@ -328,7 +328,7 @@
29
        fclose(out);
30
    }
31
 
32
-   out = fopen("Timing4.plot", "w");
33
+   out = fopen("Timing4.plot", "we");
34
    if (out == NULL) {
35
        pw_log_error("Can't open Timing4.plot: %m");
36
    } else {
37
@@ -355,7 +355,7 @@
38
        fclose(out);
39
    }
40
 
41
-   out = fopen("Timing5.plot", "w");
42
+   out = fopen("Timing5.plot", "we");
43
    if (out == NULL) {
44
        pw_log_error("Can't open Timing5.plot: %m");
45
    } else {
46
@@ -381,7 +381,7 @@
47
            "unset output\n");
48
        fclose(out);
49
    }
50
-   out = fopen("Timings.html", "w");
51
+   out = fopen("Timings.html", "we");
52
    if (out == NULL) {
53
        pw_log_error("Can't open Timings.html: %m");
54
    } else {
55
@@ -409,7 +409,7 @@
56
        fclose(out);
57
    }
58
 
59
-   out = fopen("generate_timings.sh", "w");
60
+   out = fopen("generate_timings.sh", "we");
61
    if (out == NULL) {
62
        pw_log_error("Can't open generate_timings.sh: %m");
63
    } else {
64
@@ -624,7 +624,7 @@
65
 
66
    data.filename = opt_output;
67
 
68
-   data.output = fopen(data.filename, "w");
69
+   data.output = fopen(data.filename, "we");
70
    if (data.output == NULL) {
71
        fprintf(stderr, "Can't open file %s: %m\n", data.filename);
72
        return -1;
73
pipewire-0.3.58.tar.gz/test/pwtest.c -> pipewire-0.3.59.tar.gz/test/pwtest.c Changed
19
 
1
@@ -835,7 +835,7 @@
2
 #ifdef __linux__
3
    {
4
        FILE *f;
5
-       f = fopen("/proc/sys/fs/pipe-max-size", "r");
6
+       f = fopen("/proc/sys/fs/pipe-max-size", "re");
7
        if (f) {
8
            if (fscanf(f, "%d", &r) == 1)
9
                pipe_max_size = SPA_MIN(r, pipe_max_size);
10
@@ -1244,7 +1244,7 @@
11
    /* Marker file to avoid removing a random directory during cleanup */
12
    r = spa_scnprintf(path, sizeof(path), "%s/pwtest.dir", dir);
13
    spa_assert_se((size_t)r == strlen(dir) + 11);
14
-   fp = fopen(path, "w");
15
+   fp = fopen(path, "we");
16
    spa_assert_se(fp);
17
    fprintf(fp, "pwtest\n");
18
    fclose(fp);
19
pipewire-0.3.58.tar.gz/test/test-config.c -> pipewire-0.3.59.tar.gz/test/test-config.c Changed
10
 
1
@@ -35,7 +35,7 @@
2
    char *basename;
3
 
4
    pwtest_mkstemp(path);
5
-   fp = fopen(path, "w");
6
+   fp = fopen(path, "we");
7
    fputs("data = x", fp);
8
    fclose(fp);
9
 
10
pipewire-0.3.58.tar.gz/test/test-logger.c -> pipewire-0.3.59.tar.gz/test/test-logger.c Changed
46
 
1
@@ -63,7 +63,7 @@
2
    /* Print a line expected to be truncated */
3
    spa_log_error(iface, "MARK: %1100s", "foo");
4
 
5
-   fp = fopen(fname, "r");
6
+   fp = fopen(fname, "re");
7
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
8
        if (strstr(buffer, "MARK:")) {
9
            const char *suffix = ".. (truncated)\n";
10
@@ -110,7 +110,7 @@
11
     * tty so expect none despite colors being enabled */
12
    spa_log_error(iface, "MARK\n");
13
 
14
-   fp = fopen(fname, "r");
15
+   fp = fopen(fname, "re");
16
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
17
        if (strstr(buffer, "MARK")) {
18
            mark_line_found = true;
19
@@ -157,7 +157,7 @@
20
    if (level < SPA_LOG_LEVEL_TRACE)
21
        pw_log(level + 1, "ABOVE");
22
 
23
-   fp = fopen(fname, "r");
24
+   fp = fopen(fname, "re");
25
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
26
        if (strstr(buffer, "CURRENT"))
27
            current_level_found = true;
28
@@ -427,7 +427,7 @@
29
 
30
    spa_logt_info(iface, &topic, "MARK\n");
31
 
32
-   fp = fopen(fname, "r");
33
+   fp = fopen(fname, "re");
34
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
35
        if (strstr(buffer, "MARK")) {
36
            mark_line_found = true;
37
@@ -602,7 +602,7 @@
38
    /* Now check that the line is in the chained file logger too */
39
    spa_memzero(buffer, sizeof(buffer));
40
    mark_line_found = false;
41
-   fp = fopen(fname, "r");
42
+   fp = fopen(fname, "re");
43
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
44
        if (strstr(buffer, token)) {
45
            mark_line_found = true;
46
pipewire-0.3.58.tar.gz/test/test-properties.c -> pipewire-0.3.59.tar.gz/test/test-properties.c Changed
10
 
1
@@ -484,7 +484,7 @@
2
    dict = SPA_DICT_INIT(items, 2);
3
 
4
    pwtest_mkstemp(tmpfile);
5
-   fp = fopen(tmpfile, "w");
6
+   fp = fopen(tmpfile, "we");
7
    pwtest_ptr_notnull(fp);
8
    r = pw_properties_serialize_dict(fp, &dict, 0);
9
    pwtest_int_eq(r, 1);
10
pipewire-0.3.58.tar.gz/test/test-spa-pod.c -> pipewire-0.3.59.tar.gz/test/test-spa-pod.c Changed
64
 
1
@@ -1639,6 +1639,54 @@
2
    return PWTEST_PASS;
3
 }
4
 
5
+static int handle_overflow(void *data, uint32_t size)
6
+{
7
+   uint32_t *d = data;
8
+   (*d)++;
9
+   return -ENOSPC;
10
+}
11
+
12
+static struct spa_pod_builder_callbacks overflow_cb = {
13
+   SPA_VERSION_POD_BUILDER_CALLBACKS,
14
+   .overflow = handle_overflow
15
+};
16
+
17
+PWTEST(pod_overflow2)
18
+{
19
+   uint8_t buffer1024;
20
+   struct spa_pod_builder b = { 0 };
21
+   struct spa_pod_builder_state state;
22
+   struct spa_pod_frame f2;
23
+   uint32_t idx, overflow_count = 0;
24
+   struct spa_pod *pod;
25
+
26
+   spa_pod_builder_init(&b, buffer, sizeof(buffer));
27
+   spa_pod_builder_set_callbacks(&b, &overflow_cb, &overflow_count);
28
+
29
+   spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo);
30
+   spa_pod_builder_add(&b,
31
+           SPA_PROP_INFO_id,    SPA_POD_Id(32567359),
32
+           SPA_PROP_INFO_type,  SPA_POD_CHOICE_ENUM_Int(1, 0),
33
+           SPA_PROP_INFO_description,  SPA_POD_String("DV Timings"),
34
+           0);
35
+
36
+   spa_pod_builder_get_state(&b, &state),
37
+
38
+   spa_pod_builder_prop(&b, SPA_PROP_INFO_labels, 0);
39
+   spa_pod_builder_push_struct(&b, &f1);
40
+
41
+   for (idx = 0; idx < 512; idx++) {
42
+       spa_pod_builder_int(&b, idx);
43
+       spa_pod_builder_string(&b, "foo");
44
+   }
45
+   spa_assert_se(b.state.offset > sizeof(buffer));
46
+   pod = spa_pod_builder_pop(&b, &f1);
47
+   spa_assert_se(pod == NULL);
48
+   spa_assert_se(overflow_count == 1);
49
+
50
+   return PWTEST_PASS;
51
+}
52
+
53
 PWTEST_SUITE(spa_pod)
54
 {
55
    pwtest_add(pod_abi_sizes, PWTEST_NOARG);
56
@@ -1652,6 +1700,7 @@
57
    pwtest_add(pod_parser2, PWTEST_NOARG);
58
    pwtest_add(pod_static, PWTEST_NOARG);
59
    pwtest_add(pod_overflow, PWTEST_NOARG);
60
+   pwtest_add(pod_overflow2, PWTEST_NOARG);
61
 
62
    return PWTEST_PASS;
63
 }
64