We truncated the diff of some files because they were too big.
If you want to see the full diff for every file, click here.
Changes of Revision 33
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Wed Aug 30 13:49:39 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.79
6
+
7
+-------------------------------------------------------------------
8
Wed Aug 9 15:43:07 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.77
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.77
6
+Version: 0.3.79
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.77.tar.gz/NEWS -> pipewire-0.3.79.tar.gz/NEWS
Changed
123
1
2
+# PipeWire 0.3.79 (2023-08-29)
3
+
4
+This is a quick bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+ - Fix a regression in suspend that could cause silence.
9
+ - Fix a regression in JACK port registration that could cause all kinds of
10
+ JACK problems. (#3485)
11
+ - Fix a typo in the neon sample conversion functions that could cause
12
+ distortion.
13
+ - Add BAP broadcast source and sink support.
14
+ - pw-top now has a batch mode to dump the output to stdout.
15
+ - Many more bugfixes and improvements.
16
+
17
+
18
+## PipeWire
19
+ - Fix a regression in shutdown where a node might not first suspend
20
+ properly. This cause loss of sound in some cases. (#3378)
21
+ - Failure to compile a regular expression in the config file will now
22
+ be reported and ! can be used to negate the match. (#3460)
23
+ - Fix a regression where some nodes might not set running in some
24
+ cases.
25
+ - Nodes are now suspended before the format is cleared, which might
26
+ fix some crashes.
27
+
28
+## Tools
29
+ - pw-top now has a batch mode to dump the output to stdout.
30
+
31
+## SPA
32
+ - The queued samples in audioconvert are now correctly reported in the
33
+ delay. (#3454)
34
+ - Make it easier to add a custom profile in ACP.
35
+ - Fix a typo in the neon sample conversion functions that could cause
36
+ distortion. (#3463)
37
+ - device.profile.pro=true is added for pro audio nodes.
38
+ - An xrun counter was added to spa_io_clock to detect and track skipped
39
+ data because of xruns.
40
+
41
+## Pulse-server
42
+ - Add alsa-sink and alsa-source modules. (#3456)
43
+
44
+## Bluetooth
45
+ - Fix a regression where only the BAP off profile is shown.
46
+ - Add BAP broadcast source and sink support.
47
+
48
+## JACK
49
+ - Also emit a latency notify when the buffer size changes.
50
+ - Fix a regression in JACK port registration. (#3485)
51
+ - jack_port_tie() is now supported.
52
+
53
+## ALSA
54
+ - Improve property handling, support lists and ranges in addition to
55
+ fixed values. (#3451)
56
+
57
+Older versions:
58
+
59
+
60
+# PipeWire 0.3.78 (2023-08-22)
61
+
62
+This is a small bugfix release that is API and ABI compatible with previous
63
+0.3.x releases.
64
+
65
+## Highlights
66
+ - An old regression was fixed with where some nodes would not run.
67
+ - A regression was fixed where removed events would not be shown in some
68
+ cases. This would result in duplicate entries in audio clients.
69
+ - Fix an off-by-one in the vban audio receiver. Tweak the rate adaption
70
+ a little.
71
+ - ACP will now set a UCM verb before probing the pro-audio devices.
72
+ - More bugfixes and improvements.
73
+
74
+
75
+## PipeWire
76
+ - An old regression was fixed with where some nodes would not run. (#3405)
77
+ - Suspend was improved a little to avoid races when the session manager would
78
+ suspend right when a driver was starting.
79
+
80
+## Modules
81
+ - module-rtp-sap does not use the deprecated inet_aton anymore.
82
+ - Fix an off-by-one in the vban audio receiver. Tweak the rate adaption
83
+ a little. (#3380)
84
+
85
+## SPA
86
+ - ACP will now set a UCM verb before probing the pro-audio devices. (#3407)
87
+ - The mandatory flag will be set now on the video modifiers.
88
+ - EVL was updated to Xenomai4 r46 and xbuf creation was improved.
89
+ - An option was added to force colors in the log even when logging to !tty.
90
+ - The return type of spa_pod_builder_control() was fixed.
91
+ - inotify errors are handled better now. (#3439)
92
+
93
+## pulse-server
94
+ - A regression was fixed where removed events would not be shown in some
95
+ cases. (#3414)
96
+
97
+## Bluetooth
98
+ - Improve compatibility with more devices, avoid reusing the same transport
99
+ for different media-sink instances to avoid encoder resets.
100
+ - Improve enumeration of codec profiles for BAP and A2DP.
101
+
102
+## JACK
103
+ - Ensure we can't iterate ports from a deactivated client. Also make sure
104
+ the JACK clients with the node.always-process=false always show their
105
+ ports. (#3416)
106
+
107
+## GStreamer
108
+ - A potential crash was fixed in the device provider when stopping.
109
+
110
# PipeWire 0.3.77 (2023-08-04)
111
112
This is a quick bugfix release that is API and ABI compatible with previous
113
114
## bluetooth
115
- Use some more autoptr cleanups, fix some leaks.
116
117
-Older versions:
118
-
119
-
120
# PipeWire 0.3.76 (2023-07-28)
121
122
This is a quick bugfix release that is API and ABI compatible with previous
123
pipewire-0.3.77.tar.gz/doc/dma-buf.dox -> pipewire-0.3.79.tar.gz/doc/dma-buf.dox
Changed
141
1
2
/** \page page_dma_buf DMA-BUF Sharing
3
4
PipeWire supports sharing Direct Memory Access buffers (DMA-BUFs) between
5
-clients via the `SPA_DATA_DmaBuf` data type. However properly negotiating
6
+clients via the \ref SPA_DATA_DmaBuf data type. However properly negotiating
7
DMA-BUF support on both the producer and the consumer side require following
8
a specific procedure. This page describes said procedure by using events and
9
methods from the filter or stream API.
10
11
12
## pw_stream_connect
13
14
-The stream parameters should contain two `SPA_PARAM_EnumFormat` objects for
15
+The stream parameters should contain two \ref SPA_PARAM_EnumFormat objects for
16
each format: one for DMA-BUFs, one for shared memory buffers as a fallback.
17
18
Query the list of all supported modifiers from your graphics API of choice.
19
-Add a `SPA_FORMAT_VIDEO_modifier` property to the first stream parameter with
20
+Add a \ref SPA_FORMAT_VIDEO_modifier property to the first stream parameter with
21
the flags `SPA_POD_PROP_FLAG_MANDATORY | SPA_POD_PROP_FLAG_DONT_FIXATE`. The
22
-value of the property should be set to a `SPA_CHOICE_Enum` containing one
23
+value of the property should be set to a \ref SPA_CHOICE_Enum containing one
24
`long` choice per supported modifier, plus `DRM_FORMAT_MOD_INVALID` if the
25
graphics API supports modifier-less buffers.
26
27
Note: When a producer is only supporting modifier-less buffers it can omit
28
-the `SPA_POD_PROP_FLAG_DONT_FIXATE` (see param_changed hook, For producers).
29
+the \ref SPA_POD_PROP_FLAG_DONT_FIXATE (see param_changed hook, For producers).
30
31
-The second stream parameter should not contain any `SPA_FORMAT_VIDEO_modifier`
32
+The second stream parameter should not contain any \ref SPA_FORMAT_VIDEO_modifier
33
property.
34
35
-To prioritise DMA-BUFs place those `SPA_PARAM_EnumFormat` containing modifiers
36
+To prioritise DMA-BUFs place those \ref SPA_PARAM_EnumFormat containing modifiers
37
first, when emitting them to PipeWire.
38
39
## param_changed Hook
40
41
-When the `param_changed` hook is called for a `SPA_PARAM_Format` the client
42
+When the `param_changed` hook is called for a \ref SPA_PARAM_Format the client
43
has to parse the `spa_pod` directly. Use
44
`spa_pod_find_prop(param, NULL, SPA_FORMAT_VIDEO_modifier)` to check
45
whether modifiers were negotiated. If they were negotiated, set the
46
-`SPA_PARAM_BUFFERS_dataType` property to `1 << SPA_DATA_DmaBuf`. If they were
47
+\ref SPA_PARAM_BUFFERS_dataType property to `1 << SPA_DATA_DmaBuf`. If they were
48
not negotiated, fall back to shared memory by setting the
49
-`SPA_PARAM_BUFFERS_dataType` property to `1 << SPA_DATA_MemFd`,
50
+\ref SPA_PARAM_BUFFERS_dataType property to `1 << SPA_DATA_MemFd`,
51
`1 << SPA_DATA_MemPtr`, or both.
52
53
-While consumers only have to parse the resulting `SPA_PARAM_Format` for any
54
+While consumers only have to parse the resulting \ref SPA_PARAM_Format for any
55
format related information, it's up to the producer to fixate onto a single
56
format modifier pair. The producer is also responsible to check if all clients
57
announce sufficient capabilities or fallback to shared memory buffers when
58
59
60
### For Consumers
61
62
-Use `spa_format_video_raw_parse` to get the format and modifier.
63
+Use \ref spa_format_video_raw_parse to get the format and modifier.
64
65
### For Producers
66
67
68
- modifier-less:
69
In this case only the modifier `DRM_FORMAT_MOD_INVALID` was announced with
70
the format.
71
- It is sufficient to check if the `SPA_PARAM_Format` contains the modifier
72
+ It is sufficient to check if the \ref SPA_PARAM_Format contains the modifier
73
property as described above. If that is the case, use DMA-BUFs for screen-sharing,
74
else fall back to SHM, if possible.
75
- modifier-aware:
76
In this case a list with all supported modifiers will be returned in the format.
77
(using `DRM_FORMAT_MOD_INVALID` as the token for the modifier-less API).
78
On the `param_changed` event check if the modifier key is present and has the flag
79
- `SPA_POD_PROP_FLAG_DONT_FIXATE` attached to it. In this case, extract all modifiers
80
+ \ref SPA_POD_PROP_FLAG_DONT_FIXATE attached to it. In this case, extract all modifiers
81
from the list and do a test allocation with your allocator to choose the preferred
82
- modifier. Fixate on that `EnumFormat` by announcing a `SPA_PARAM_EnumFormat` with
83
- only one modifier in the `SPA_CHOICE_Enum` and without the
84
- `SPA_POD_PROP_FLAG_DONT_FIXATE` flag, followed by the previous announced
85
- `EnumFormat`. This will retrigger the `param_changed` event with an
86
- `SPA_PARAM_Format` as described below.
87
- If the `SPA_PARAM_Format` contains a modifier key, without the flag
88
- `SPA_POD_PROP_FLAG_DONT_FIXATE`, it should only contain one value in the
89
- `SPA_CHOICE_Enum`. In this case announce the `SPA_PARAM_Buffers` accordingly
90
+ modifier. Fixate on that \ref EnumFormat by announcing a \ref SPA_PARAM_EnumFormat with
91
+ only one modifier in the \ref SPA_CHOICE_Enum and without the
92
+ \ref SPA_POD_PROP_FLAG_DONT_FIXATE flag, followed by the previous announced
93
+ \ref EnumFormat. This will retrigger the `param_changed` event with an
94
+ \ref SPA_PARAM_Format as described below.
95
+ If the \ref SPA_PARAM_Format contains a modifier key, without the flag
96
+ \ref SPA_POD_PROP_FLAG_DONT_FIXATE, it should only contain one value in the
97
+ \ref SPA_CHOICE_Enum. In this case announce the \ref SPA_PARAM_Buffers accordingly
98
to the selected format and modifier. It is important to query the plane count
99
of the used format modifier pair and set `SPA_PARAM_BUFFERS_blocks` accordingly.
100
101
Note: When test allocating a buffer, collect all possible modifiers, while omitting
102
-`DRM_FORMAT_MOD_INVALID` from the `SPA_FORMAT_VIDEO_modifier` property and
103
+`DRM_FORMAT_MOD_INVALID` from the \ref SPA_FORMAT_VIDEO_modifier property and
104
pass them all to the graphics API. If the allocation fails and the list of
105
possible modifiers contains `DRM_FORMAT_MOD_INVALID`, fall back to allocating
106
without an explicit modifier if the graphics API allows it.
107
108
109
This is relevant for consumers.
110
111
-Check the type of the dequeued buffer. If its `SPA_DATA_MemFd` or
112
-`SPA_DATA_MemPtr` use the fallback SHM import mechanism.
113
-If it's `SPA_DATA_DmaBuf`
114
+Check the type of the dequeued buffer. If its \ref SPA_DATA_MemFd or
115
+\ref SPA_DATA_MemPtr use the fallback SHM import mechanism.
116
+If it's \ref SPA_DATA_DmaBuf
117
get the DMA-BUF FDs (the plane count is encoded in the `n_datas` variable of the
118
`spa_buffer` struct) and import them with the graphics API.
119
120
121
# SPA param video format helpers
122
123
SPA offers helper functions to parse and build a spa_pod object to/from the spa_video_info_*
124
-struct. The flags `SPA_VIDEO_FLAG_MODIFIER` and `SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED`
125
+struct. The flags \ref SPA_VIDEO_FLAG_MODIFIER and \ref SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED
126
are used to indicate modifier usage with the format. `SPA_VIDEO_FLAG_MODIFIER` declares the
127
parsed/provided spa_video_info_* struct contains valid modifier information. For legacy
128
reasons `spa_format_video_*_build` will announce any modifier != 0 even when this flag is
129
unused. `SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED` is exclusive to the parse helpers and
130
declares that the parsed spa_pod contains modifier information which needs to be fixated as
131
-described aboath. The list of available modifiers has to be parsed manually from the spa_pod
132
+described above. The list of available modifiers has to be parsed manually from the spa_pod
133
object.
134
135
+- \ref spa_video_info_raw, \ref spa_format_video_raw_parse, \ref spa_format_video_raw_build
136
+- \ref spa_video_info_dsp, \ref spa_format_video_dsp_parse, \ref spa_format_video_dsp_build
137
+
138
# v4l2
139
140
Another use case for streaming via DMA-BUFs are exporting a camera feed from v4l2
141
pipewire-0.3.77.tar.gz/doc/pipewire-daemon.dox -> pipewire-0.3.79.tar.gz/doc/pipewire-daemon.dox
Changed
9
1
2
- `PIPEWIRE_LOG_SYSTEMD=false`: Disable logging to the systemd journal.
3
- `PIPEWIRE_LOG=<filename>`: Redirect the log to the given filename.
4
- `PIPEWIRE_LOG_LINE=false`: Don't log filename, function, and source code line.
5
+- `PIPEWIRE_LOG_COLOR=true/false/force`: Enable/disable color logging, and optionally force
6
+ colors even when logging to a file.
7
8
*/
9
pipewire-0.3.77.tar.gz/meson.build -> pipewire-0.3.79.tar.gz/meson.build
Changed
8
1
2
project('pipewire', 'c' ,
3
- version : '0.3.77',
4
+ version : '0.3.79',
5
license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ,
6
meson_version : '>= 0.61.1',
7
default_options : 'warning_level=3',
8
pipewire-0.3.77.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.79.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
201
1
2
#include <spa/utils/atomic.h>
3
#include <spa/utils/result.h>
4
#include <spa/utils/string.h>
5
+#include <spa/utils/json.h>
6
7
#include <pipewire/pipewire.h>
8
9
10
.query_chmaps = snd_pcm_pipewire_query_chmaps,
11
};
12
13
-static int pipewire_set_hw_constraint(snd_pcm_pipewire_t *pw)
14
+#define MAX_VALS 64
15
+struct param_info {
16
+ const char *prop;
17
+ int key;
18
+#define TYPE_LIST 0
19
+#define TYPE_MIN_MAX 1
20
+ int type;
21
+ unsigned int valsMAX_VALS;
22
+ unsigned int n_vals;
23
+ int (*collect) (const char *str, int len, unsigned int *val);
24
+
25
+};
26
+
27
+static int collect_access(const char *str, int len, unsigned int *val)
28
+{
29
+ char key64;
30
+
31
+ if (spa_json_parse_stringn(str, len, key, sizeof(key)) <= 0)
32
+ return -EINVAL;
33
+
34
+ if (strcasecmp(key, "MMAP_INTERLEAVED") == 0)
35
+ *val = SND_PCM_ACCESS_MMAP_INTERLEAVED;
36
+ else if (strcasecmp(key, "MMAP_NONINTERLEAVED") == 0)
37
+ *val = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
38
+ else if (strcasecmp(key, "RW_INTERLEAVED") == 0)
39
+ *val = SND_PCM_ACCESS_RW_INTERLEAVED;
40
+ else if (strcasecmp(key, "RW_NONINTERLEAVED") == 0)
41
+ *val = SND_PCM_ACCESS_RW_NONINTERLEAVED;
42
+ else
43
+ return -EINVAL;
44
+ return 0;
45
+}
46
+
47
+static int collect_format(const char *str, int len, unsigned int *val)
48
+{
49
+ char key64;
50
+ snd_pcm_format_t fmt;
51
+
52
+ if (spa_json_parse_stringn(str, len, key, sizeof(key)) < 0)
53
+ return -EINVAL;
54
+
55
+ fmt = snd_pcm_format_value(key);
56
+ if (fmt != SND_PCM_FORMAT_UNKNOWN)
57
+ *val = fmt;
58
+ else
59
+ return -EINVAL;
60
+ return 0;
61
+}
62
+
63
+static int collect_int(const char *str, int len, unsigned int *val)
64
{
65
- unsigned int access_list = {
66
- SND_PCM_ACCESS_MMAP_INTERLEAVED,
67
- SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
68
- SND_PCM_ACCESS_RW_INTERLEAVED,
69
- SND_PCM_ACCESS_RW_NONINTERLEAVED
70
- };
71
- unsigned int format_list = {
72
+ int v;
73
+ if (spa_json_parse_int(str, len, &v) > 0)
74
+ *val = v;
75
+ else
76
+ return -EINVAL;
77
+ return 0;
78
+}
79
+
80
+struct param_info infos = {
81
+ { "alsa.access", SND_PCM_IOPLUG_HW_ACCESS, TYPE_LIST,
82
+ { SND_PCM_ACCESS_MMAP_INTERLEAVED,
83
+ SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
84
+ SND_PCM_ACCESS_RW_INTERLEAVED,
85
+ SND_PCM_ACCESS_RW_NONINTERLEAVED }, 4, collect_access },
86
+ { "alsa.format", SND_PCM_IOPLUG_HW_FORMAT, TYPE_LIST,
87
+ {
88
#if __BYTE_ORDER == __LITTLE_ENDIAN
89
- SND_PCM_FORMAT_FLOAT_LE,
90
- SND_PCM_FORMAT_S32_LE,
91
- SND_PCM_FORMAT_S24_LE,
92
- SND_PCM_FORMAT_S24_3LE,
93
- SND_PCM_FORMAT_S24_3BE,
94
- SND_PCM_FORMAT_S16_LE,
95
+ SND_PCM_FORMAT_FLOAT_LE,
96
+ SND_PCM_FORMAT_S32_LE,
97
+ SND_PCM_FORMAT_S24_LE,
98
+ SND_PCM_FORMAT_S24_3LE,
99
+ SND_PCM_FORMAT_S24_3BE,
100
+ SND_PCM_FORMAT_S16_LE,
101
#elif __BYTE_ORDER == __BIG_ENDIAN
102
- SND_PCM_FORMAT_FLOAT_BE,
103
- SND_PCM_FORMAT_S32_BE,
104
- SND_PCM_FORMAT_S24_BE,
105
- SND_PCM_FORMAT_S24_3LE,
106
- SND_PCM_FORMAT_S24_3BE,
107
- SND_PCM_FORMAT_S16_BE,
108
+ SND_PCM_FORMAT_FLOAT_BE,
109
+ SND_PCM_FORMAT_S32_BE,
110
+ SND_PCM_FORMAT_S24_BE,
111
+ SND_PCM_FORMAT_S24_3LE,
112
+ SND_PCM_FORMAT_S24_3BE,
113
+ SND_PCM_FORMAT_S16_BE,
114
#endif
115
- SND_PCM_FORMAT_U8,
116
- };
117
- int val;
118
- int min_rate;
119
- int max_rate;
120
- int min_channels;
121
- int max_channels;
122
- int min_period_bytes;
123
- int max_period_bytes;
124
- int min_buffer_bytes;
125
- int max_buffer_bytes;
126
- const char *str;
127
- snd_pcm_format_t format;
128
- int err;
129
+ SND_PCM_FORMAT_U8 }, 7, collect_format },
130
+ { "alsa.rate", SND_PCM_IOPLUG_HW_RATE, TYPE_MIN_MAX,
131
+ { 1, MAX_RATE }, 2, collect_int },
132
+ { "alsa.channels", SND_PCM_IOPLUG_HW_CHANNELS, TYPE_MIN_MAX,
133
+ { 1, MAX_CHANNELS }, 2, collect_int },
134
+ { "alsa.buffer-bytes", SND_PCM_IOPLUG_HW_BUFFER_BYTES, TYPE_MIN_MAX,
135
+ { MIN_BUFFER_BYTES, MAX_BUFFER_BYTES }, 2, collect_int },
136
+ { "alsa.period-bytes", SND_PCM_IOPLUG_HW_PERIOD_BYTES, TYPE_MIN_MAX,
137
+ { MIN_PERIOD_BYTES, MAX_PERIOD_BYTES }, 2, collect_int },
138
+ { "alsa.periods", SND_PCM_IOPLUG_HW_PERIODS, TYPE_MIN_MAX,
139
+ { MIN_BUFFERS, 1024 }, 2, collect_int },
140
+};
141
142
- val = pw_properties_get_uint32(pw->props, "alsa.rate", 0);
143
- if (val > 0) {
144
- min_rate = max_rate = SPA_CLAMP(val, 1, MAX_RATE);
145
- } else {
146
- min_rate = 1;
147
- max_rate = MAX_RATE;
148
- }
149
- val = pw_properties_get_uint32(pw->props, "alsa.channels", 0);
150
- if (val > 0) {
151
- min_channels = max_channels = SPA_CLAMP(val, 1, MAX_CHANNELS);
152
- } else {
153
- min_channels = 1;
154
- max_channels = MAX_CHANNELS;
155
+static struct param_info *param_info_by_key(int key)
156
+{
157
+ SPA_FOR_EACH_ELEMENT_VAR(infos, p) {
158
+ if (p->key == key)
159
+ return p;
160
}
161
- val = pw_properties_get_uint32(pw->props, "alsa.period-bytes", 0);
162
- if (val > 0) {
163
- min_period_bytes = max_period_bytes = SPA_CLAMP(val,
164
- MIN_PERIOD_BYTES, MAX_PERIOD_BYTES);
165
- } else {
166
- min_period_bytes = MIN_PERIOD_BYTES;
167
- max_period_bytes = MAX_PERIOD_BYTES;
168
+ return NULL;
169
+}
170
+
171
+static int parse_value(const char *str, struct param_info *info)
172
+{
173
+ struct spa_json it2;
174
+ unsigned int v;
175
+ const char *val;
176
+ int len;
177
+
178
+ spa_json_init(&it0, str, strlen(str));
179
+ if ((len = spa_json_next(&it0, &val)) <= 0)
180
+ return -EINVAL;
181
+
182
+ if (spa_json_is_array(val, len)) {
183
+ info->type = TYPE_LIST;
184
+ info->n_vals = 0;
185
+ spa_json_enter(&it0, &it1);
186
+ while ((len = spa_json_next(&it1, &val)) > 0 && info->n_vals < MAX_VALS) {
187
+ if (info->collect(val, len, &v) < 0)
188
+ continue;
189
+ info->valsinfo->n_vals++ = v;
190
+ }
191
}
192
- val = pw_properties_get_uint32(pw->props, "alsa.buffer-bytes", 0);
193
- if (val > 0) {
194
- min_buffer_bytes = max_buffer_bytes = SPA_CLAMP(val,
195
- MIN_BUFFER_BYTES, MAX_BUFFER_BYTES);
196
- } else {
197
- min_buffer_bytes = MIN_BUFFER_BYTES;
198
- max_buffer_bytes = MAX_BUFFER_BYTES;
199
+ else if (spa_json_is_object(val, len)) {
200
+ char key64;
201
pipewire-0.3.77.tar.gz/pipewire-jack/jack/intclient.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/intclient.h
Changed
10
1
2
*
3
* You should have received a copy of the GNU Lesser General Public License
4
* along with this program; if not, write to the Free Software
5
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
*
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/jack.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/jack.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/jslist.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/jslist.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/metadata.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/metadata.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software Foundation,
5
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
*/
8
9
/**
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/midiport.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/midiport.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/net.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/net.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/ringbuffer.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/ringbuffer.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/session.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/session.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
*/
8
9
#ifndef __jack_session_h__
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/thread.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/thread.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/transport.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/transport.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/types.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/types.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/uuid.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/uuid.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/weakjack.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/weakjack.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/jack/weakmacros.h -> pipewire-0.3.79.tar.gz/pipewire-jack/jack/weakmacros.h
Changed
10
1
2
3
You should have received a copy of the GNU Lesser General Public License
4
along with this program; if not, write to the Free Software
5
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
7
8
*/
9
10
pipewire-0.3.77.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.79.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
201
1
2
#define NOTIFY_TYPE_REGISTRATION ((1<<4))
3
#define NOTIFY_TYPE_PORTREGISTRATION ((2<<4)|NOTIFY_ACTIVE_FLAG)
4
#define NOTIFY_TYPE_CONNECT ((3<<4)|NOTIFY_ACTIVE_FLAG)
5
-#define NOTIFY_TYPE_GRAPH ((4<<4)|NOTIFY_ACTIVE_FLAG)
6
-#define NOTIFY_TYPE_BUFFER_FRAMES ((5<<4)|NOTIFY_ACTIVE_FLAG)
7
-#define NOTIFY_TYPE_SAMPLE_RATE ((6<<4)|NOTIFY_ACTIVE_FLAG)
8
-#define NOTIFY_TYPE_FREEWHEEL ((7<<4)|NOTIFY_ACTIVE_FLAG)
9
-#define NOTIFY_TYPE_SHUTDOWN ((8<<4)|NOTIFY_ACTIVE_FLAG)
10
-#define NOTIFY_TYPE_LATENCY ((9<<4)|NOTIFY_ACTIVE_FLAG)
11
+#define NOTIFY_TYPE_BUFFER_FRAMES ((4<<4)|NOTIFY_ACTIVE_FLAG)
12
+#define NOTIFY_TYPE_SAMPLE_RATE ((5<<4)|NOTIFY_ACTIVE_FLAG)
13
+#define NOTIFY_TYPE_FREEWHEEL ((6<<4)|NOTIFY_ACTIVE_FLAG)
14
+#define NOTIFY_TYPE_SHUTDOWN ((7<<4)|NOTIFY_ACTIVE_FLAG)
15
+#define NOTIFY_TYPE_LATENCY ((8<<4)|NOTIFY_ACTIVE_FLAG)
16
+#define NOTIFY_TYPE_TOTAL_LATENCY ((9<<4)|NOTIFY_ACTIVE_FLAG)
17
int type;
18
struct object *object;
19
int arg1;
20
21
struct spa_hook proxy_listener;
22
struct spa_hook object_listener;
23
int registered;
24
+ unsigned int visible;
25
unsigned int removing:1;
26
unsigned int removed:1;
27
};
28
29
struct spa_list mix;
30
struct mix *global_mix;
31
32
+ struct port *tied;
33
+
34
unsigned int empty_out:1;
35
unsigned int zeroed:1;
36
37
38
return false;
39
}
40
41
+static inline bool client_port_visible(struct client *c, struct object *o)
42
+{
43
+ if (o->port.port != NULL && o->port.port->client == c)
44
+ return true;
45
+ return o->visible;
46
+}
47
+
48
static struct object *find_port_by_name(struct client *c, const char *name)
49
{
50
struct object *o;
51
52
spa_list_for_each(o, &c->context.objects, link) {
53
- if (o->type != INTERFACE_Port || o->removed)
54
+ if (o->type != INTERFACE_Port || o->removed ||
55
+ (!client_port_visible(c, o)))
56
continue;
57
if (spa_streq(o->port.name, name) ||
58
spa_streq(o->port.alias1, name) ||
59
60
return name;
61
}
62
63
-static void recompute_latencies(struct client *c)
64
-{
65
- do_callback(c, latency_callback, c->active, JackCaptureLatency, c->latency_arg);
66
- do_callback(c, latency_callback, c->active, JackPlaybackLatency, c->latency_arg);
67
-}
68
-
69
#define freeze_callbacks(c) \
70
({ \
71
(c)->frozen_callbacks++; \
72
73
int32_t avail;
74
uint32_t index;
75
struct notify *notify;
76
- bool do_graph = false;
77
+ bool do_graph = false, do_recompute_capture = false, do_recompute_playback = false;
78
79
if (c->frozen_callbacks != 0 || !c->pending_callbacks)
80
return;
81
82
c->connect_arg);
83
84
do_graph = true;
85
- break;
86
- case NOTIFY_TYPE_GRAPH:
87
- pw_log_debug("%p: graph", c);
88
- do_graph = true;
89
+ do_recompute_capture = do_recompute_playback = true;
90
break;
91
case NOTIFY_TYPE_BUFFER_FRAMES:
92
pw_log_debug("%p: buffer frames %d", c, notify->arg1);
93
94
do_callback_expr(c, c->buffer_frames = notify->arg1,
95
bufsize_callback, c->active,
96
notify->arg1, c->bufsize_arg);
97
- recompute_latencies(c);
98
+ do_recompute_capture = do_recompute_playback = true;
99
}
100
break;
101
case NOTIFY_TYPE_SAMPLE_RATE:
102
103
break;
104
case NOTIFY_TYPE_LATENCY:
105
pw_log_debug("%p: latency %d", c, notify->arg1);
106
- do_callback(c, latency_callback, c->active, notify->arg1, c->latency_arg);
107
+ if (notify->arg1 == JackCaptureLatency)
108
+ do_recompute_capture = true;
109
+ else if (notify->arg1 == JackPlaybackLatency)
110
+ do_recompute_playback = true;
111
+ break;
112
+ case NOTIFY_TYPE_TOTAL_LATENCY:
113
+ pw_log_debug("%p: total latency", c);
114
+ do_recompute_capture = do_recompute_playback = true;
115
break;
116
default:
117
break;
118
119
index += sizeof(struct notify);
120
spa_ringbuffer_read_update(&c->notify_ring, index);
121
}
122
- if (do_graph) {
123
- recompute_latencies(c);
124
+ if (do_recompute_capture)
125
+ do_callback(c, latency_callback, c->active, JackCaptureLatency, c->latency_arg);
126
+ if (do_recompute_playback)
127
+ do_callback(c, latency_callback, c->active, JackPlaybackLatency, c->latency_arg);
128
+ if (do_graph)
129
do_callback(c, graph_callback, c->active, c->graph_arg);
130
- }
131
+
132
thaw_callbacks(c);
133
pw_log_debug("%p: leave", c);
134
}
135
136
uint32_t index;
137
struct notify *notify;
138
bool emit = false;
139
+ int res = 0;
140
141
switch (type) {
142
case NOTIFY_TYPE_REGISTRATION:
143
144
break;
145
case NOTIFY_TYPE_PORTREGISTRATION:
146
emit = c->portregistration_callback != NULL && o != NULL;
147
+ o->visible = arg1;
148
break;
149
case NOTIFY_TYPE_CONNECT:
150
emit = c->connect_callback != NULL && o != NULL;
151
break;
152
- case NOTIFY_TYPE_GRAPH:
153
- emit = c->graph_callback != NULL || c->latency_callback != NULL;
154
- break;
155
case NOTIFY_TYPE_BUFFER_FRAMES:
156
emit = c->bufsize_callback != NULL;
157
break;
158
159
emit = c->info_shutdown_callback != NULL || c->shutdown_callback != NULL;
160
break;
161
case NOTIFY_TYPE_LATENCY:
162
+ case NOTIFY_TYPE_TOTAL_LATENCY:
163
emit = c->latency_callback != NULL;
164
break;
165
default:
166
167
if (!emit || ((type & NOTIFY_ACTIVE_FLAG) && !c->active)) {
168
switch (type) {
169
case NOTIFY_TYPE_BUFFER_FRAMES:
170
- if (!emit)
171
+ if (!emit) {
172
c->buffer_frames = arg1;
173
+ queue_notify(c, NOTIFY_TYPE_TOTAL_LATENCY, NULL, 0, NULL);
174
+ }
175
break;
176
case NOTIFY_TYPE_SAMPLE_RATE:
177
if (!emit)
178
179
o->removing = false;
180
free_object(c, o);
181
}
182
- return 0;
183
+ return res;
184
}
185
186
+ pthread_mutex_lock(&c->context.lock);
187
filled = spa_ringbuffer_get_write_index(&c->notify_ring, &index);
188
if (filled < 0 || filled + sizeof(struct notify) > NOTIFY_BUFFER_SIZE) {
189
pw_log_warn("%p: notify queue full %d", c, type);
190
- return -ENOSPC;
191
+ res = -ENOSPC;
192
+ goto done;
193
}
194
195
notify = SPA_PTROFF(c->notify_buffer, index & NOTIFY_BUFFER_MASK, struct notify);
196
197
spa_ringbuffer_write_update(&c->notify_ring, index);
198
c->pending_callbacks = true;
199
check_callbacks(c);
200
- return 0;
201
pipewire-0.3.77.tar.gz/po/ka.po -> pipewire-0.3.79.tar.gz/po/ka.po
Changed
201
1
2
-# Georgian translation for pipewire.
3
-# Copyright (C) 2022 pipewire'S authors
4
+# Georgian translation of pipewire
5
+# Copyright (C) 2023 pipewire's authors
6
# This file is distributed under the same license as the pipewire package.
7
-# Temuri Doghonadze <temuri.doghonadze@gmail.com>, 2022.
8
+# Temuri Doghonadze <temuri.doghonadze@gmail.com>, 2023.
9
#
10
msgid ""
11
msgstr ""
12
"Project-Id-Version: pipewire\n"
13
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
14
"issues/new\n"
15
-"POT-Creation-Date: 2022-06-30 12:50+0200\n"
16
-"PO-Revision-Date: 2022-11-20 11:50+0100\n"
17
+"POT-Creation-Date: 2023-08-07 22:01+0200\n"
18
+"PO-Revision-Date: 2023-08-07 22:06+0200\n"
19
"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n"
20
-"Language-Team: \n"
21
+"Language-Team: Georgian <(nothing)>\n"
22
"Language: ka\n"
23
"MIME-Version: 1.0\n"
24
"Content-Type: text/plain; charset=UTF-8\n"
25
"Content-Transfer-Encoding: 8bit\n"
26
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
27
-"X-Generator: Poedit 3.2\n"
28
+"X-Generator: Poedit 3.3.2\n"
29
30
-#: src/daemon/pipewire.c:46
31
+#: src/daemon/pipewire.c:26
32
#, c-format
33
msgid ""
34
"%s options\n"
35
36
" --version ვერსიის ჩვენება\n"
37
" -c, --config ჩატვირთვის კონფიგურაცია (ნაგულისხმები %s)\n"
38
39
-#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180
40
-#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
41
+#: src/daemon/pipewire.desktop.in:4
42
+msgid "PipeWire Media System"
43
+msgstr "PipeWire Media System"
44
+
45
+#: src/daemon/pipewire.desktop.in:5
46
+msgid "Start the PipeWire Media System"
47
+msgstr "PipeWire Media System-ის გაშვება"
48
+
49
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:141
50
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:141
51
#, c-format
52
-msgid "Tunnel to %s/%s"
53
-msgstr "გვირაბი %s/%s -მდე"
54
+msgid "Tunnel to %s%s%s"
55
+msgstr "გვირაბი %s%s%s-მდე"
56
57
-#: src/modules/module-fallback-sink.c:51
58
+#: src/modules/module-fallback-sink.c:31
59
msgid "Dummy Output"
60
msgstr "ნულოვანი გამოყვანა"
61
62
-#: src/modules/module-pulse-tunnel.c:662
63
+#: src/modules/module-pulse-tunnel.c:847
64
#, c-format
65
msgid "Tunnel for %s@%s"
66
msgstr "გვირაბი %s@%s-სთვის"
67
68
-#: src/modules/module-zeroconf-discover.c:332
69
+#: src/modules/module-zeroconf-discover.c:311
70
msgid "Unknown device"
71
msgstr "უცნობი მოწყობილობა"
72
73
-#: src/modules/module-zeroconf-discover.c:344
74
+#: src/modules/module-zeroconf-discover.c:323
75
#, c-format
76
msgid "%s on %s@%s"
77
msgstr "%s %s@%s -ზე"
78
79
-#: src/modules/module-zeroconf-discover.c:348
80
+#: src/modules/module-zeroconf-discover.c:327
81
#, c-format
82
msgid "%s on %s"
83
msgstr "%s %s-ზე"
84
85
-#: src/tools/pw-cat.c:784
86
+#: src/tools/pw-cat.c:979
87
#, c-format
88
msgid ""
89
"%s options <file>|-\n"
90
91
" -v, --verbose დამატებითი შეტყობინებების გამოტანა\n"
92
"\n"
93
94
-#: src/tools/pw-cat.c:791
95
+#: src/tools/pw-cat.c:986
96
#, c-format
97
msgid ""
98
" -R, --remote Remote daemon name\n"
99
" --media-type Set media type (default %s)\n"
100
" --media-category Set media category (default %s)\n"
101
" --media-role Set media role (default %s)\n"
102
-" --target Set node target (default %s)\n"
103
+" --target Set node target serial or name "
104
+"(default %s)\n"
105
" 0 means don't link\n"
106
" --latency Set node latency (default %s)\n"
107
" Xunit (unit = s, ms, us, ns)\n"
108
109
"ფაილი\n"
110
" -P --properties კვანძის თვისებების დაყენება\n"
111
112
-#: src/tools/pw-cat.c:809
113
+#: src/tools/pw-cat.c:1004
114
#, c-format
115
msgid ""
116
" --rate Sample rate (req. for rec) (default "
117
118
" -q --quality Resampler ხარისხი (0 - 15) "
119
"(ნაგულისხმები %d)\n"
120
121
-#: src/tools/pw-cat.c:826
122
+#: src/tools/pw-cat.c:1021
123
msgid ""
124
" -p, --playback Playback mode\n"
125
" -r, --record Recording mode\n"
126
" -m, --midi Midi mode\n"
127
" -d, --dsd DSD mode\n"
128
+" -o, --encoded Encoded mode\n"
129
"\n"
130
msgstr ""
131
-" -p, --playback დაკვრის რეჟიმი\n"
132
-" -r, -- record ჩაწერის რეჟიმი\n"
133
-" -m, --midi Midi რეჟიმი\n"
134
-" -d, --dsd DSD რეჟიმი\n"
135
+" -p, --playback დაკვრის რეჟიმი\n"
136
+" -r, --record ჩაწერის რეჟიმი\n"
137
+" -m, --midi Midi რეჟიმი\n"
138
+" -d, --dsd DSD რეჟიმი\n"
139
+" -o, --encoded დაშიფრული რეჟიმი\n"
140
"\n"
141
142
-#: src/tools/pw-cli.c:2250
143
+#: src/tools/pw-cli.c:2220
144
#, c-format
145
msgid ""
146
"%s options command\n"
147
148
" --version Show version\n"
149
" -d, --daemon Start as daemon (Default false)\n"
150
" -r, --remote Remote daemon name\n"
151
+" -m, --monitor Monitor activity\n"
152
"\n"
153
msgstr ""
154
"%s პარამეტრები ბრძანება\n"
155
-" -h, --help ამ დახმარების ჩვენება\n"
156
-" --version ვერსიის ჩვენება\n"
157
-" -d, --daemon დაწყება როგორც დემონი (ნაგულისხმები "
158
-"false)\n"
159
-" -r, --remote დაშორებული დემონის სახელი\n"
160
+" -h, --help ამ დახმარების ჩვენება\n"
161
+" --version ვერსიის ჩვენება\n"
162
+" -d, --daemon დემონის სახით გაშვება (ნაგულისხმევად "
163
+"გამორთულია)\n"
164
+" -r, --remote დაშორებული დემონის სახელი\n"
165
+" -m, --monitor აქტივობის მონიტორინგი\n"
166
+"\n"
167
168
-#: spa/plugins/alsa/acp/acp.c:321
169
+#: spa/plugins/alsa/acp/acp.c:325
170
msgid "Pro Audio"
171
msgstr "Pro Audio"
172
173
-#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
174
-#: spa/plugins/bluez5/bluez5-device.c:1236
175
+#: spa/plugins/alsa/acp/acp.c:449 spa/plugins/alsa/acp/alsa-mixer.c:4648
176
+#: spa/plugins/bluez5/bluez5-device.c:1586
177
msgid "Off"
178
-msgstr "გამორთული"
179
+msgstr "გამორთულია"
180
181
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
182
msgid "Input"
183
184
185
#: spa/plugins/alsa/acp/alsa-mixer.c:2655
186
msgid "Docking Station Line In"
187
-msgstr "Docking Station Line In"
188
+msgstr "Docking Station-ის Line In პორტი"
189
190
#: spa/plugins/alsa/acp/alsa-mixer.c:2656
191
#: spa/plugins/alsa/acp/alsa-mixer.c:2747
192
193
194
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
195
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
196
-#: spa/plugins/bluez5/bluez5-device.c:1454
197
+#: spa/plugins/bluez5/bluez5-device.c:1831
198
msgid "Microphone"
199
msgstr "მიკროფონი"
200
201
pipewire-0.3.77.tar.gz/po/sv.po -> pipewire-0.3.79.tar.gz/po/sv.po
Changed
201
1
2
"Project-Id-Version: pipewire\n"
3
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
4
"issues\n"
5
-"POT-Creation-Date: 2023-02-26 15:27+0000\n"
6
-"PO-Revision-Date: 2023-02-26 17:32+0100\n"
7
+"POT-Creation-Date: 2023-08-07 15:27+0000\n"
8
+"PO-Revision-Date: 2023-05-12 18:46+0200\n"
9
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
10
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
11
"Language: sv\n"
12
13
msgid "Start the PipeWire Media System"
14
msgstr "Starta mediasystemet PipeWire"
15
16
-#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:159
17
-#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:159
18
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:141
19
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:141
20
#, c-format
21
-msgid "Tunnel to %s/%s"
22
-msgstr "Tunnel till %s/%s"
23
+msgid "Tunnel to %s%s%s"
24
+msgstr "Tunnel till %s%s%s"
25
26
#: src/modules/module-fallback-sink.c:31
27
msgid "Dummy Output"
28
msgstr "Attrapputgång"
29
30
-#: src/modules/module-pulse-tunnel.c:675
31
+#: src/modules/module-pulse-tunnel.c:847
32
#, c-format
33
msgid "Tunnel for %s@%s"
34
msgstr "Tunnel för %s@%s"
35
36
-#: src/modules/module-zeroconf-discover.c:315
37
+#: src/modules/module-zeroconf-discover.c:311
38
msgid "Unknown device"
39
msgstr "Okänd enhet"
40
41
-#: src/modules/module-zeroconf-discover.c:327
42
+#: src/modules/module-zeroconf-discover.c:323
43
#, c-format
44
msgid "%s on %s@%s"
45
msgstr "%s på %s@%s"
46
47
-#: src/modules/module-zeroconf-discover.c:331
48
+#: src/modules/module-zeroconf-discover.c:327
49
#, c-format
50
msgid "%s on %s"
51
msgstr "%s på %s"
52
53
-#: src/tools/pw-cat.c:974
54
+#: src/tools/pw-cat.c:979
55
#, c-format
56
msgid ""
57
"%s options <file>|-\n"
58
59
" -v, --verbose Aktivera utförliga operationer\n"
60
"\n"
61
62
-#: src/tools/pw-cat.c:981
63
+#: src/tools/pw-cat.c:986
64
#, c-format
65
msgid ""
66
" -R, --remote Remote daemon name\n"
67
68
" -P --properties Sätt nodegenskaper\n"
69
"\n"
70
71
-#: src/tools/pw-cat.c:999
72
+#: src/tools/pw-cat.c:1004
73
#, c-format
74
msgid ""
75
" --rate Sample rate (req. for rec) (default "
76
77
"%d)\n"
78
"\n"
79
80
-#: src/tools/pw-cat.c:1016
81
+#: src/tools/pw-cat.c:1021
82
msgid ""
83
" -p, --playback Playback mode\n"
84
" -r, --record Recording mode\n"
85
86
" -o, --encoded Kodat läge\n"
87
"\n"
88
89
-#: src/tools/pw-cli.c:2216
90
+#: src/tools/pw-cli.c:2220
91
#, c-format
92
msgid ""
93
"%s options command\n"
94
95
" -m, --monitor Övervaka aktivitet\n"
96
"\n"
97
98
-#: spa/plugins/alsa/acp/acp.c:303
99
+#: spa/plugins/alsa/acp/acp.c:325
100
msgid "Pro Audio"
101
msgstr "Professionellt ljud"
102
103
-#: spa/plugins/alsa/acp/acp.c:427 spa/plugins/alsa/acp/alsa-mixer.c:4648
104
-#: spa/plugins/bluez5/bluez5-device.c:1283
105
+#: spa/plugins/alsa/acp/acp.c:449 spa/plugins/alsa/acp/alsa-mixer.c:4648
106
+#: spa/plugins/bluez5/bluez5-device.c:1586
107
msgid "Off"
108
msgstr "Av"
109
110
111
112
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
113
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
114
-#: spa/plugins/bluez5/bluez5-device.c:1519
115
+#: spa/plugins/bluez5/bluez5-device.c:1831
116
msgid "Microphone"
117
msgstr "Mikrofon"
118
119
120
msgstr "Ingen basökning"
121
122
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
123
-#: spa/plugins/bluez5/bluez5-device.c:1525
124
+#: spa/plugins/bluez5/bluez5-device.c:1837
125
msgid "Speaker"
126
msgstr "Högtalare"
127
128
129
130
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
131
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
132
-#: spa/plugins/bluez5/bluez5-device.c:1507
133
+#: spa/plugins/bluez5/bluez5-device.c:1819
134
msgid "Headset"
135
msgstr "Headset"
136
137
138
msgid "Mono Chat + 7.1 Surround"
139
msgstr "Mono Chatt + 7.1 Surround"
140
141
-#: spa/plugins/alsa/acp/alsa-mixer.c:4754
142
+#: spa/plugins/alsa/acp/alsa-mixer.c:4748
143
#, c-format
144
msgid "%s Output"
145
msgstr "%s-utgång"
146
147
-#: spa/plugins/alsa/acp/alsa-mixer.c:4761
148
+#: spa/plugins/alsa/acp/alsa-mixer.c:4756
149
#, c-format
150
msgid "%s Input"
151
msgstr "%s-ingång"
152
153
msgid "Modem"
154
msgstr "Modem"
155
156
-#: spa/plugins/bluez5/bluez5-device.c:1294
157
+#: spa/plugins/bluez5/bluez5-device.c:1597
158
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
159
msgstr "Audio gateway (A2DP-källa & HSP/HFP AG)"
160
161
-#: spa/plugins/bluez5/bluez5-device.c:1319
162
+#: spa/plugins/bluez5/bluez5-device.c:1622
163
#, c-format
164
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
165
msgstr "High fidelity-uppspelning (A2DP-utgång, kodek %s)"
166
167
-#: spa/plugins/bluez5/bluez5-device.c:1322
168
+#: spa/plugins/bluez5/bluez5-device.c:1625
169
#, c-format
170
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
171
msgstr "High fidelity duplex (A2DP-källa/utgång, kodek %s)"
172
173
-#: spa/plugins/bluez5/bluez5-device.c:1330
174
+#: spa/plugins/bluez5/bluez5-device.c:1633
175
msgid "High Fidelity Playback (A2DP Sink)"
176
msgstr "High fidelity-uppspelning (A2DP-utgång)"
177
178
-#: spa/plugins/bluez5/bluez5-device.c:1332
179
+#: spa/plugins/bluez5/bluez5-device.c:1635
180
msgid "High Fidelity Duplex (A2DP Source/Sink)"
181
msgstr "High fidelity duplex (A2DP-källa/utgång)"
182
183
-#: spa/plugins/bluez5/bluez5-device.c:1374
184
+#: spa/plugins/bluez5/bluez5-device.c:1677
185
#, c-format
186
msgid "High Fidelity Playback (BAP Sink, codec %s)"
187
msgstr "High fidelity-uppspelning (BAP-utgång, kodek %s)"
188
189
-#: spa/plugins/bluez5/bluez5-device.c:1378
190
+#: spa/plugins/bluez5/bluez5-device.c:1681
191
#, c-format
192
msgid "High Fidelity Input (BAP Source, codec %s)"
193
msgstr "High fidelity-ingång (BAP-källa, kodek %s)"
194
195
-#: spa/plugins/bluez5/bluez5-device.c:1382
196
+#: spa/plugins/bluez5/bluez5-device.c:1685
197
#, c-format
198
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
199
msgstr "High fidelity duplex (BAP-källa/utgång, kodek %s)"
200
201
pipewire-0.3.77.tar.gz/spa/include/spa/node/io.h -> pipewire-0.3.79.tar.gz/spa/include/spa/node/io.h
Changed
21
1
2
* is unique per clock and can be used to check if nodes
3
* share the same clock. */
4
uint64_t nsec; /**< time in nanoseconds against monotonic clock */
5
- struct spa_fraction rate; /**< rate for position/duration/delay */
6
+ struct spa_fraction rate; /**< rate for position/duration/delay/xrun */
7
uint64_t position; /**< current position */
8
uint64_t duration; /**< duration of current cycle */
9
int64_t delay; /**< delay between position and hardware,
10
11
uint64_t target_duration; /**< target duration of next cycle */
12
uint32_t target_seq; /**< seq counter. must be equal at start and
13
* end of read and lower bit must be 0 */
14
-
15
- uint32_t padding3;
16
+ uint32_t padding;
17
+ uint64_t xrun; /**< estimated accumulated xrun duration */
18
};
19
20
/* the size of the video in this cycle */
21
pipewire-0.3.77.tar.gz/spa/include/spa/param/video/dsp-utils.h -> pipewire-0.3.79.tar.gz/spa/include/spa/param/video/dsp-utils.h
Changed
16
1
2
if (info->format != SPA_VIDEO_FORMAT_UNKNOWN)
3
spa_pod_builder_add(builder,
4
SPA_FORMAT_VIDEO_format, SPA_POD_Id(info->format), 0);
5
- if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER)
6
- spa_pod_builder_add(builder,
7
- SPA_FORMAT_VIDEO_modifier, SPA_POD_Long(info->modifier), 0);
8
+ if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER) {
9
+ spa_pod_builder_prop(builder,
10
+ SPA_FORMAT_VIDEO_modifier, SPA_POD_PROP_FLAG_MANDATORY);
11
+ spa_pod_builder_long(builder, info->modifier);
12
+ }
13
return (struct spa_pod*)spa_pod_builder_pop(builder, &f);
14
}
15
16
pipewire-0.3.77.tar.gz/spa/include/spa/param/video/raw-utils.h -> pipewire-0.3.79.tar.gz/spa/include/spa/param/video/raw-utils.h
Changed
16
1
2
if (info->framerate.denom != 0)
3
spa_pod_builder_add(builder,
4
SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate), 0);
5
- if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER)
6
- spa_pod_builder_add(builder,
7
- SPA_FORMAT_VIDEO_modifier, SPA_POD_Long(info->modifier), 0);
8
+ if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER) {
9
+ spa_pod_builder_prop(builder,
10
+ SPA_FORMAT_VIDEO_modifier, SPA_POD_PROP_FLAG_MANDATORY);
11
+ spa_pod_builder_long(builder, info->modifier);
12
+ }
13
if (info->max_framerate.denom != 0)
14
spa_pod_builder_add(builder,
15
SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(info->max_framerate), 0);
16
pipewire-0.3.77.tar.gz/spa/include/spa/pod/builder.h -> pipewire-0.3.79.tar.gz/spa/include/spa/pod/builder.h
Changed
10
1
2
return res;
3
}
4
5
-static inline uint32_t
6
+static inline int
7
spa_pod_builder_control(struct spa_pod_builder *builder, uint32_t offset, uint32_t type)
8
{
9
const struct { uint32_t offset; uint32_t type; } p = { offset, type };
10
pipewire-0.3.77.tar.gz/spa/include/spa/support/log.h -> pipewire-0.3.79.tar.gz/spa/include/spa/support/log.h
Changed
11
1
2
3
/** keys can be given when initializing the logger handle */
4
#define SPA_KEY_LOG_LEVEL "log.level" /**< the default log level */
5
-#define SPA_KEY_LOG_COLORS "log.colors" /**< enable colors in the logger */
6
+#define SPA_KEY_LOG_COLORS "log.colors" /**< enable colors in the logger, set to "force" to enable
7
+ * colors even when not logging to a terminal */
8
#define SPA_KEY_LOG_FILE "log.file" /**< log to the specified file instead of
9
* stderr. */
10
#define SPA_KEY_LOG_TIMESTAMP "log.timestamp" /**< log timestamps */
11
pipewire-0.3.77.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.79.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
53
1
2
}
3
}
4
5
+static const char *find_best_verb(pa_card *impl)
6
+{
7
+ const char *res = NULL;
8
+ unsigned prio = 0;
9
+ pa_alsa_ucm_verb *verb;
10
+ PA_LLIST_FOREACH(verb, impl->ucm.verbs) {
11
+ if (verb->priority >= prio)
12
+ res = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME);
13
+ }
14
+ return res;
15
+}
16
+
17
static int add_pro_profile(pa_card *impl, uint32_t index)
18
{
19
snd_ctl_t *ctl_hndl;
20
21
pa_sample_spec ss;
22
snd_pcm_uframes_t try_period_size, try_buffer_size;
23
24
+ if (impl->use_ucm) {
25
+ const char *verb = find_best_verb(impl);
26
+ if (verb == NULL)
27
+ return -ENOTSUP;
28
+ if ((err = snd_use_case_set(impl->ucm.ucm_mgr, "_verb", verb)) < 0) {
29
+ pa_log_error("error setting verb: %s", snd_strerror(err));
30
+ return err;
31
+ }
32
+ }
33
+
34
ss.format = PA_SAMPLE_S32LE;
35
ss.rate = impl->rate;
36
ss.channels = impl->pro_channels;
37
38
0, NULL, NULL, false))) {
39
pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm);
40
pa_proplist_setf(m->output_proplist, "clock.name", "api.alsa.%u", index);
41
+ pa_proplist_setf(m->output_proplist, "device.profile.pro", "true");
42
pa_alsa_close(&m->output_pcm);
43
m->supported = true;
44
pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX);
45
46
0, NULL, NULL, false))) {
47
pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm);
48
pa_proplist_setf(m->input_proplist, "clock.name", "api.alsa.%u", index);
49
+ pa_proplist_setf(m->input_proplist, "device.profile.pro", "true");
50
pa_alsa_close(&m->input_pcm);
51
m->supported = true;
52
pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX);
53
pipewire-0.3.77.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.79.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
102
1
2
{
3
uint32_t i;
4
int err;
5
+ const char *str;
6
7
snd_config_update_free_global();
8
9
+ if ((str = spa_dict_lookup(info, "device.profile.pro")) != NULL)
10
+ state->is_pro = spa_atob(str);
11
+
12
state->multi_rate = true;
13
state->htimestamp = false;
14
for (i = 0; info && i < info->n_items; i++) {
15
16
17
dir = 0;
18
period_size = state->default_period_size;
19
- is_batch = snd_pcm_hw_params_is_batch(params) &&
20
- !state->disable_batch;
21
+ is_batch = snd_pcm_hw_params_is_batch(params) && !state->disable_batch;
22
23
/* no period size specified. If we are batch or not using timers,
24
* use the graph duration as the period */
25
if (period_size == 0 && (is_batch || state->disable_tsched))
26
- period_size = state->position ? state->position->clock.duration : DEFAULT_PERIOD;
27
-
28
- if (is_batch) {
29
- if (period_size == 0)
30
- period_size = DEFAULT_PERIOD;
31
- /* batch devices get their hw pointers updated every period. Make
32
- * the period smaller and add one period of headroom. Limit the
33
- * period size to our default so that we don't create too much
34
- * headroom. */
35
- if (!state->disable_tsched)
36
+ period_size = state->position ? state->position->clock.target_duration : DEFAULT_PERIOD;
37
+ if (period_size == 0)
38
+ period_size = DEFAULT_PERIOD;
39
+
40
+ if (!state->disable_tsched) {
41
+ if (is_batch) {
42
+ /* batch devices get their hw pointers updated every period. Make
43
+ * the period smaller and add one period of headroom. Limit the
44
+ * period size to our default so that we don't create too much
45
+ * headroom. */
46
period_size = SPA_MIN(period_size, DEFAULT_PERIOD) / 2;
47
- spa_log_info(state->log, "%s: batch mode, period_size:%ld",
48
- state->props.device, period_size);
49
- } else {
50
- if (period_size == 0)
51
- period_size = DEFAULT_PERIOD;
52
- /* disable ALSA wakeups, if we use a timer */
53
- if (!state->disable_tsched && snd_pcm_hw_params_can_disable_period_wakeup(params))
54
- CHECK(snd_pcm_hw_params_set_period_wakeup(hndl, params, 0), "set_period_wakeup");
55
+ } else {
56
+ /* disable ALSA wakeups */
57
+ if (snd_pcm_hw_params_can_disable_period_wakeup(params))
58
+ CHECK(snd_pcm_hw_params_set_period_wakeup(hndl, params, 0), "set_period_wakeup");
59
+ }
60
}
61
62
CHECK(snd_pcm_hw_params_set_period_size_near(hndl, params, &period_size, &dir), "set_period_size_near");
63
64
65
spa_log_info(state->log, "%s (%s): format:%s access:%s-%s rate:%d channels:%d "
66
"buffer frames %lu, period frames %lu, periods %u, frame_size %zd "
67
- "headroom %u start-delay:%u tsched:%u",
68
+ "headroom %u start-delay:%u batch:%u tsched:%u",
69
state->props.device,
70
state->stream == SND_PCM_STREAM_CAPTURE ? "capture" : "playback",
71
snd_pcm_format_name(state->format),
72
73
planar ? "planar" : "interleaved",
74
state->rate, state->channels, state->buffer_frames, state->period_frames,
75
periods, state->frame_size, state->headroom, state->start_delay,
76
- !state->disable_tsched);
77
+ is_batch, !state->disable_tsched);
78
79
/* write the parameters to device */
80
CHECK(snd_pcm_hw_params(hndl, params), "set_hw_params");
81
82
83
delay = SPA_TIMEVAL_TO_USEC(&diff);
84
missing = delay * state->rate / SPA_USEC_PER_SEC;
85
+ if (missing == 0)
86
+ missing = state->threshold;
87
88
spa_log_trace(state->log, "%p: xrun of %"PRIu64" usec %"PRIu64,
89
state, delay, missing);
90
91
+ if (state->clock)
92
+ state->clock->xrun += missing;
93
+ state->sample_count += missing;
94
+
95
spa_node_call_xrun(&state->callbacks,
96
SPA_TIMEVAL_TO_USEC(&trigger), delay, NULL);
97
-
98
- state->sample_count += missing ? missing : state->threshold;
99
break;
100
}
101
case SND_PCM_STATE_SUSPENDED:
102
pipewire-0.3.77.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.79.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
9
1
2
unsigned int is_hdmi:1;
3
unsigned int multi_rate:1;
4
unsigned int htimestamp:1;
5
+ unsigned int is_pro:1;
6
7
uint64_t iec958_codecs;
8
9
pipewire-0.3.79.tar.gz/spa/plugins/alsa/mixer/profile-sets/9999-custom.conf
Added
24
1
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
+; Put your custom profiles here.
18
+
19
+; An example for defining multiple-sink profiles
20
+#Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo
21
+#description = Foobar
22
+#output-mappings = analog-stereo iec958-stereo
23
+#input-mappings = analog-stereo
24
pipewire-0.3.77.tar.gz/spa/plugins/alsa/mixer/profile-sets/default.conf -> pipewire-0.3.79.tar.gz/spa/plugins/alsa/mixer/profile-sets/default.conf
Changed
11
1
2
priority = 1
3
direction = input
4
5
-; An example for defining multiple-sink profiles
6
-#Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo
7
-#description = Foobar
8
-#output-mappings = analog-stereo iec958-stereo
9
-#input-mappings = analog-stereo
10
+.include 9999-custom.conf
11
pipewire-0.3.77.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.79.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
10
1
2
spa_log_trace_fp(this->log, "%p: next match %u", this, match_size);
3
4
if (this->io_rate_match) {
5
- this->io_rate_match->delay = delay;
6
+ this->io_rate_match->delay = delay + in_queued;
7
this->io_rate_match->size = match_size;
8
}
9
return match_size;
10
pipewire-0.3.77.tar.gz/spa/plugins/audioconvert/fmt-ops-neon.c -> pipewire-0.3.79.tar.gz/spa/plugins/audioconvert/fmt-ops-neon.c
Changed
10
1
2
" beq 4f\n"
3
"3:"
4
" ld1 { v0.s }0, %s0, #4\n"
5
- " ld1 { v2.s }0, %s1, #4\n"
6
+ " ld1 { v1.s }0, %s1, #4\n"
7
" subs %remainder, %remainder, #1\n"
8
" sqadd v0.4s, v0.4s, v2.4s\n"
9
" sqadd v1.4s, v1.4s, v2.4s\n"
10
pipewire-0.3.77.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.79.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
201
1
2
* stopped/started rapidly, postpone release until the transport has remained
3
* unused for a time.
4
*
5
- * Avoiding unnecessary release+reacquire also makes sense for other transports,
6
- * so we use the release timeout for all of them.
7
+ * Avoiding unnecessary release+reacquire also makes sense for ISO.
8
*/
9
#define TRANSPORT_RELEASE_TIMEOUT_MSEC 1000
10
11
#define TRANSPORT_VOLUME_TIMEOUT_MSEC 200
12
13
+#define SPA_BT_TRANSPORT_IS_A2DP(transport) ((transport)->profile & (SPA_BT_PROFILE_A2DP_SOURCE | SPA_BT_PROFILE_A2DP_SINK))
14
+
15
static int spa_bt_transport_stop_volume_timer(struct spa_bt_transport *transport);
16
static int spa_bt_transport_start_volume_timer(struct spa_bt_transport *transport);
17
static int spa_bt_transport_stop_release_timer(struct spa_bt_transport *transport);
18
19
20
if (direction == SPA_BT_MEDIA_SOURCE)
21
endpoint = codec->bap ? BAP_SOURCE_ENDPOINT : A2DP_SOURCE_ENDPOINT;
22
- else
23
+ else if (direction == SPA_BT_MEDIA_SINK)
24
endpoint = codec->bap ? BAP_SINK_ENDPOINT : A2DP_SINK_ENDPOINT;
25
+ else if (direction == SPA_BT_MEDIA_SOURCE_BROADCAST)
26
+ endpoint = BAP_BROADCAST_SOURCE_ENDPOINT;
27
+ else if (direction == SPA_BT_MEDIA_SINK_BROADCAST)
28
+ endpoint = BAP_BROADCAST_SINK_ENDPOINT;
29
30
*object_path = spa_aprintf("%s/%s", endpoint,
31
codec->endpoint_name ? codec->endpoint_name : codec->name);
32
33
} else if (spa_strstartswith(endpoint, BAP_SINK_ENDPOINT "/")) {
34
ep_name = endpoint + strlen(BAP_SINK_ENDPOINT "/");
35
*sink = true;
36
+ } else if (spa_strstartswith(endpoint, BAP_BROADCAST_SOURCE_ENDPOINT "/")) {
37
+ ep_name = endpoint + strlen(BAP_BROADCAST_SOURCE_ENDPOINT "/");
38
+ *sink = false;
39
+ } else if (spa_strstartswith(endpoint, BAP_BROADCAST_SINK_ENDPOINT "/")) {
40
+ ep_name = endpoint + strlen(BAP_BROADCAST_SINK_ENDPOINT "/");
41
+ *sink = true;
42
} else {
43
*sink = true;
44
return NULL;
45
46
return SPA_BT_PROFILE_BAP_SOURCE;
47
else if (spa_strstartswith(endpoint, BAP_SOURCE_ENDPOINT "/"))
48
return SPA_BT_PROFILE_BAP_SINK;
49
+ else if (spa_strstartswith(endpoint, BAP_BROADCAST_SINK_ENDPOINT "/"))
50
+ return SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
51
+ else if (spa_strstartswith(endpoint, BAP_BROADCAST_SOURCE_ENDPOINT "/"))
52
+ return SPA_BT_PROFILE_BAP_BROADCAST_SINK;
53
else
54
return SPA_BT_PROFILE_NULL;
55
}
56
57
{
58
switch (direction) {
59
case SPA_BT_MEDIA_SOURCE:
60
+ case SPA_BT_MEDIA_SOURCE_BROADCAST:
61
return codec->encode;
62
case SPA_BT_MEDIA_SINK:
63
+ case SPA_BT_MEDIA_SINK_BROADCAST:
64
return codec->decode;
65
default:
66
spa_assert_not_reached();
67
68
return codec->bap ? SPA_BT_PROFILE_BAP_SOURCE : SPA_BT_PROFILE_A2DP_SOURCE;
69
case SPA_BT_MEDIA_SINK:
70
return codec->bap ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_A2DP_SINK;
71
+ case SPA_BT_MEDIA_SOURCE_BROADCAST:
72
+ return SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
73
+ case SPA_BT_MEDIA_SINK_BROADCAST:
74
+ return SPA_BT_PROFILE_BAP_BROADCAST_SINK;
75
default:
76
spa_assert_not_reached();
77
}
78
79
adapter->profiles |= SPA_BT_PROFILE_BAP_SINK;
80
spa_log_debug(monitor->log, "adapter %p: add UUID=%s", adapter, SPA_BT_UUID_BAP_SOURCE);
81
adapter->profiles |= SPA_BT_PROFILE_BAP_SOURCE;
82
+ spa_log_debug(monitor->log, "adapter %p: add UUID=%s", adapter, SPA_BT_UUID_BAP_BROADCAST_SOURCE);
83
+ adapter->profiles |= SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
84
+ spa_log_debug(monitor->log, "adapter %p: add UUID=%s", adapter, SPA_BT_UUID_BAP_BROADCAST_SINK);
85
+ adapter->profiles |= SPA_BT_PROFILE_BAP_BROADCAST_SINK;
86
}
87
dbus_message_iter_next(&iter);
88
}
89
90
spa_log_info(monitor->log, "Adapter %s: LE Audio supported",
91
adapter->path);
92
}
93
+
94
+ if (spa_streq(uuid, SPA_BT_UUID_BAP_BROADCAST_SOURCE) ||
95
+ spa_streq(uuid, SPA_BT_UUID_BAP_BROADCAST_SINK)) {
96
+ adapter->le_audio_bcast_supported = true;
97
+ spa_log_info(monitor->log, "Adapter %s: LE Broadcast Audio supported",
98
+ adapter->path);
99
+ }
100
+
101
dbus_message_iter_next(&iter);
102
}
103
}
104
105
if (profiles & SPA_BT_PROFILE_BAP_SOURCE)
106
mask |= SPA_BT_PROFILE_BAP_SINK;
107
108
+ if (profiles & SPA_BT_PROFILE_BAP_BROADCAST_SINK)
109
+ mask |= SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
110
+ if (profiles & SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)
111
+ mask |= SPA_BT_PROFILE_BAP_BROADCAST_SINK;
112
+
113
if (profiles & SPA_BT_PROFILE_HSP_AG)
114
mask |= SPA_BT_PROFILE_HSP_HS;
115
if (profiles & SPA_BT_PROFILE_HSP_HS)
116
117
device_try_connect_profile(device, SPA_BT_UUID_BAP_SINK);
118
if (reconnect & SPA_BT_PROFILE_BAP_SOURCE)
119
device_try_connect_profile(device, SPA_BT_UUID_BAP_SOURCE);
120
+ if (reconnect & SPA_BT_PROFILE_BAP_BROADCAST_SINK)
121
+ device_try_connect_profile(device, SPA_BT_UUID_BAP_BROADCAST_SINK);
122
+ if (reconnect & SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)
123
+ device_try_connect_profile(device, SPA_BT_UUID_BAP_BROADCAST_SOURCE);
124
125
return reconnect;
126
}
127
128
return false;
129
}
130
131
- if (codec->bap)
132
- codec_profile = sink ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_BAP_SOURCE;
133
- else
134
- codec_profile = sink ? SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
135
-
136
spa_list_for_each(ep, &device->remote_endpoint_list, device_link) {
137
- const enum spa_bt_profile profile = spa_bt_profile_from_uuid(ep->uuid);
138
+ enum spa_bt_profile profile = spa_bt_profile_from_uuid(ep->uuid);
139
+ if (codec->bap) {
140
+ if ((profile == SPA_BT_PROFILE_BAP_BROADCAST_SINK) || (profile == SPA_BT_PROFILE_BAP_BROADCAST_SOURCE))
141
+ codec_profile = sink ? SPA_BT_PROFILE_BAP_BROADCAST_SINK : SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
142
+ else
143
+ codec_profile = sink ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_BAP_SOURCE;
144
+ } else
145
+ codec_profile = sink ? SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
146
147
if (profile != codec_profile)
148
continue;
149
150
* can only know that the currently configured codec is supported.
151
*/
152
spa_list_for_each(t, &device->transport_list, device_link) {
153
+ if (codec->bap) {
154
+ if((t->profile == SPA_BT_PROFILE_BAP_BROADCAST_SINK) || (t->profile == SPA_BT_PROFILE_BAP_BROADCAST_SOURCE))
155
+ codec_profile = sink ? SPA_BT_PROFILE_BAP_BROADCAST_SINK : SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
156
+ else
157
+ codec_profile = sink ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_BAP_SOURCE;
158
+ } else
159
+ codec_profile = sink ? SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
160
+
161
if (t->profile != codec_profile)
162
continue;
163
164
165
return NULL;
166
}
167
168
+static struct spa_bt_device* create_bcast_device(struct spa_bt_monitor *monitor,
169
+ const char *object_path)
170
+{
171
+ struct spa_bt_device *d;
172
+ d = device_create(monitor, object_path);
173
+ if (d == NULL) {
174
+ spa_log_warn(monitor->log, "can't create Bluetooth device %s: %m",
175
+ object_path);
176
+ return NULL;
177
+ }
178
+
179
+ d->adapter = adapter_find(monitor, object_path);
180
+ if (d->adapter == NULL) {
181
+ spa_log_warn(monitor->log, "unknown adapter %s", d->adapter_path);
182
+ }
183
+ d->adapter_path = d->adapter->path;
184
+ d->alias = strdup("bcast_device");
185
+ d->name = strdup("bcast_device");
186
+ d->address = strdup("00:00:00:00:00:00");
187
+
188
+ spa_bt_device_check_profiles(d, false);
189
+ d->reconnect_state = BT_DEVICE_RECONNECT_INIT;
190
+
191
+ if (!device_props_ready(d))
192
+ {
193
+ return NULL;
194
+ }
195
+
196
+ device_update_hw_volume_profiles(d);
197
+
198
+ spa_bt_device_add_profile(d, SPA_BT_PROFILE_NULL);
199
+
200
+ return d;
201
pipewire-0.3.77.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.79.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
156
1
2
emit_device_set_node(this, DEVICE_ID_SINK_SET);
3
}
4
5
+ if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_BAP_BROADCAST_SINK)) {
6
+ t = find_transport(this, SPA_BT_PROFILE_BAP_BROADCAST_SINK, this->props.codec);
7
+ if (t) {
8
+ this->props.codec = t->media_codec->id;
9
+ emit_node(this, t, DEVICE_ID_SINK, SPA_NAME_API_BLUEZ5_MEDIA_SINK, false);
10
+ }
11
+
12
+ if (this->device_set.leader && this->device_set.sinks > 0)
13
+ emit_device_set_node(this, DEVICE_ID_SINK_SET);
14
+ }
15
+
16
+ if (this->bt_dev->connected_profiles & (SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)) {
17
+ t = find_transport(this, SPA_BT_PROFILE_BAP_BROADCAST_SOURCE, this->props.codec);
18
+ if (t) {
19
+ this->props.codec = t->media_codec->id;
20
+ emit_dynamic_node(&this->dyn_media_source, this, t,
21
+ DEVICE_ID_SOURCE, SPA_NAME_API_BLUEZ5_MEDIA_SOURCE, false);
22
+ }
23
+ }
24
+
25
if (get_supported_media_codec(this, this->props.codec, NULL) == NULL)
26
this->props.codec = 0;
27
break;
28
29
if (profile == DEVICE_PROFILE_OFF || profile == DEVICE_PROFILE_AG)
30
return profile;
31
32
- if (profile == DEVICE_PROFILE_A2DP) {
33
- if (codec == 0 || (this->bt_dev->connected_profiles & SPA_BT_PROFILE_MEDIA_SOURCE))
34
- return profile;
35
-
36
- return codec + DEVICE_PROFILE_LAST;
37
- }
38
-
39
- if (profile == DEVICE_PROFILE_BAP) {
40
- if (codec == 0)
41
- return profile;
42
-
43
+ if ((profile == DEVICE_PROFILE_A2DP) || (profile == DEVICE_PROFILE_BAP))
44
return codec + DEVICE_PROFILE_LAST;
45
- }
46
47
if (profile == DEVICE_PROFILE_HSP_HFP) {
48
if (codec == 0 || (this->bt_dev->connected_profiles & SPA_BT_PROFILE_HFP_AG))
49
50
if (!(profile & SPA_BT_PROFILE_A2DP_SINK)) {
51
return NULL;
52
}
53
+
54
+ /* A2DP will only enlist codec profiles */
55
+ if (!codec)
56
+ return NULL;
57
+
58
name = spa_bt_profile_name(profile);
59
n_sink++;
60
if (codec) {
61
62
return NULL;
63
}
64
name_and_codec = spa_aprintf("%s-%s", name, media_codec->name);
65
- name = name_and_codec;
66
+
67
+ /*
68
+ * Give base name to highest priority profile, so that best codec can be
69
+ * selected at command line with out knowing which codecs are actually
70
+ * supported
71
+ */
72
+ if (idx != 0)
73
+ name = name_and_codec;
74
+
75
if (profile == SPA_BT_PROFILE_A2DP_SINK && !media_codec->duplex_codec) {
76
desc_and_codec = spa_aprintf(_("High Fidelity Playback (A2DP Sink, codec %s)"),
77
media_codec->description);
78
79
case DEVICE_PROFILE_BAP:
80
{
81
uint32_t profile = device->connected_profiles &
82
- (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE);
83
+ (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE
84
+ | SPA_BT_PROFILE_BAP_BROADCAST_SOURCE
85
+ | SPA_BT_PROFILE_BAP_BROADCAST_SINK);
86
size_t idx;
87
const struct media_codec *media_codec;
88
89
+ /* BAP will only enlist codec profiles */
90
+ if (codec == 0)
91
+ return NULL;
92
+
93
if (profile == 0)
94
return NULL;
95
96
- if (profile & (SPA_BT_PROFILE_BAP_SINK))
97
+ if ((profile & (SPA_BT_PROFILE_BAP_SINK)) ||
98
+ (profile & (SPA_BT_PROFILE_BAP_BROADCAST_SINK)))
99
n_sink++;
100
- if (profile & (SPA_BT_PROFILE_BAP_SOURCE))
101
+ if ((profile & (SPA_BT_PROFILE_BAP_SOURCE)) ||
102
+ (profile & (SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)))
103
n_source++;
104
105
name = spa_bt_profile_name(profile);
106
107
- /* If we can't codec switch, emit codecless profile */
108
- if (current && !can_bap_codec_switch(this)) {
109
- codec = 0;
110
- index = get_index_from_profile(this, profile_index, codec);
111
- } else if ((codec != 0) != can_bap_codec_switch(this)) {
112
- errno = -EINVAL;
113
- return NULL;
114
- }
115
-
116
if (codec) {
117
media_codec = get_supported_media_codec(this, codec, &idx);
118
if (media_codec == NULL) {
119
120
return NULL;
121
}
122
name_and_codec = spa_aprintf("%s-%s", name, media_codec->name);
123
- name = name_and_codec;
124
+
125
+ /*
126
+ * Give base name to highest priority profile, so that best codec can be
127
+ * selected at command line with out knowing which codecs are actually
128
+ * supported
129
+ */
130
+ if (idx != 0)
131
+ name = name_and_codec;
132
+
133
switch (profile) {
134
case SPA_BT_PROFILE_BAP_SINK:
135
+ case SPA_BT_PROFILE_BAP_BROADCAST_SINK:
136
desc_and_codec = spa_aprintf(_("High Fidelity Playback (BAP Sink, codec %s)"),
137
media_codec->description);
138
break;
139
case SPA_BT_PROFILE_BAP_SOURCE:
140
+ case SPA_BT_PROFILE_BAP_BROADCAST_SOURCE:
141
desc_and_codec = spa_aprintf(_("High Fidelity Input (BAP Source, codec %s)"),
142
media_codec->description);
143
break;
144
145
} else {
146
switch (profile) {
147
case SPA_BT_PROFILE_BAP_SINK:
148
+ case SPA_BT_PROFILE_BAP_BROADCAST_SINK:
149
desc = _("High Fidelity Playback (BAP Sink)");
150
break;
151
case SPA_BT_PROFILE_BAP_SOURCE:
152
+ case SPA_BT_PROFILE_BAP_BROADCAST_SOURCE:
153
desc = _("High Fidelity Input (BAP Source)");
154
break;
155
default:
156
pipewire-0.3.77.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.79.tar.gz/spa/plugins/bluez5/defs.h
Changed
89
1
2
#define SPA_BT_UUID_PACS "00001850-0000-1000-8000-00805f9b34fb"
3
#define SPA_BT_UUID_BAP_SINK "00002bc9-0000-1000-8000-00805f9b34fb"
4
#define SPA_BT_UUID_BAP_SOURCE "00002bcb-0000-1000-8000-00805f9b34fb"
5
+#define SPA_BT_UUID_BAP_BROADCAST_SOURCE "00001852-0000-1000-8000-00805f9b34fb"
6
+#define SPA_BT_UUID_BAP_BROADCAST_SINK "00001851-0000-1000-8000-00805f9b34fb"
7
8
#define PROFILE_HSP_AG "/Profile/HSPAG"
9
#define PROFILE_HSP_HS "/Profile/HSPHS"
10
11
#define BAP_OBJECT_MANAGER_PATH "/MediaEndpointLE"
12
#define BAP_SINK_ENDPOINT BAP_OBJECT_MANAGER_PATH "/BAPSink"
13
#define BAP_SOURCE_ENDPOINT BAP_OBJECT_MANAGER_PATH "/BAPSource"
14
+#define BAP_BROADCAST_SOURCE_ENDPOINT BAP_OBJECT_MANAGER_PATH "/BAPBroadcastSource"
15
+#define BAP_BROADCAST_SINK_ENDPOINT BAP_OBJECT_MANAGER_PATH "/BAPBroadcastSink"
16
17
#define SPA_BT_UNKNOWN_DELAY 0
18
19
20
enum spa_bt_media_direction {
21
SPA_BT_MEDIA_SOURCE,
22
SPA_BT_MEDIA_SINK,
23
+ SPA_BT_MEDIA_SOURCE_BROADCAST,
24
+ SPA_BT_MEDIA_SINK_BROADCAST,
25
};
26
27
enum spa_bt_profile {
28
29
SPA_BT_PROFILE_HSP_AG = (1 << 5),
30
SPA_BT_PROFILE_HFP_HF = (1 << 6),
31
SPA_BT_PROFILE_HFP_AG = (1 << 7),
32
+ SPA_BT_PROFILE_BAP_BROADCAST_SOURCE = (1 << 8),
33
+ SPA_BT_PROFILE_BAP_BROADCAST_SINK = (1 << 9),
34
35
SPA_BT_PROFILE_A2DP_DUPLEX = (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_A2DP_SOURCE),
36
SPA_BT_PROFILE_BAP_DUPLEX = (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE),
37
38
SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY = (SPA_BT_PROFILE_HSP_AG | SPA_BT_PROFILE_HFP_AG),
39
SPA_BT_PROFILE_HEADSET_AUDIO = (SPA_BT_PROFILE_HEADSET_HEAD_UNIT | SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY),
40
41
- SPA_BT_PROFILE_MEDIA_SINK = (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_BAP_SINK),
42
- SPA_BT_PROFILE_MEDIA_SOURCE = (SPA_BT_PROFILE_A2DP_SOURCE | SPA_BT_PROFILE_BAP_SOURCE),
43
+ SPA_BT_PROFILE_MEDIA_SINK = (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_BAP_SINK |
44
+ SPA_BT_PROFILE_BAP_BROADCAST_SINK),
45
+ SPA_BT_PROFILE_MEDIA_SOURCE = (SPA_BT_PROFILE_A2DP_SOURCE | SPA_BT_PROFILE_BAP_SOURCE |
46
+ SPA_BT_PROFILE_BAP_BROADCAST_SOURCE),
47
};
48
49
static inline enum spa_bt_profile spa_bt_profile_from_uuid(const char *uuid)
50
51
return SPA_BT_PROFILE_BAP_SINK;
52
else if (strcasecmp(uuid, SPA_BT_UUID_BAP_SOURCE) == 0)
53
return SPA_BT_PROFILE_BAP_SOURCE;
54
+ else if (strcasecmp(uuid, SPA_BT_UUID_BAP_BROADCAST_SOURCE) == 0)
55
+ return SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
56
+ else if (strcasecmp(uuid, SPA_BT_UUID_BAP_BROADCAST_SINK) == 0)
57
+ return SPA_BT_PROFILE_BAP_BROADCAST_SINK;
58
else
59
return 0;
60
}
61
62
case SPA_BT_PROFILE_HEADSET_AUDIO:
63
return "headset-audio";
64
case SPA_BT_PROFILE_BAP_SOURCE:
65
+ case SPA_BT_PROFILE_BAP_BROADCAST_SOURCE:
66
return "bap-source";
67
case SPA_BT_PROFILE_BAP_SINK:
68
+ case SPA_BT_PROFILE_BAP_BROADCAST_SINK:
69
return "bap-sink";
70
case SPA_BT_PROFILE_BAP_DUPLEX:
71
return "bap-duplex";
72
73
unsigned int le_audio_supported:1;
74
unsigned int has_adapter1_interface:1;
75
unsigned int has_media1_interface:1;
76
+ unsigned int le_audio_bcast_supported:1;
77
};
78
79
enum spa_bt_form_factor {
80
81
unsigned int latency_us;
82
uint8_t bap_cig;
83
uint8_t bap_cis;
84
+ uint8_t bap_big;
85
+ uint8_t bap_bis;
86
uint32_t bap_interval;
87
88
struct spa_bt_iso_io *iso_io;
89
pipewire-0.3.77.tar.gz/spa/plugins/bluez5/iso-io.c -> pipewire-0.3.79.tar.gz/spa/plugins/bluez5/iso-io.c
Changed
17
1
2
int block_size = 0;
3
struct spa_audio_info format = { 0 };
4
int res;
5
- bool sink = (t->profile & SPA_BT_PROFILE_BAP_SINK) != 0;
6
+ bool sink;
7
+ if((t->profile == SPA_BT_PROFILE_BAP_SINK) ||
8
+ (t->profile == SPA_BT_PROFILE_BAP_BROADCAST_SINK)) {
9
+ sink = true;
10
+ } else {
11
+ sink = false;
12
+ }
13
+
14
15
if (!t->media_codec->bap) {
16
res = -EINVAL;
17
pipewire-0.3.77.tar.gz/spa/plugins/support/evl-system.c -> pipewire-0.3.79.tar.gz/spa/plugins/support/evl-system.c
Changed
63
1
2
#include <spa/support/log.h>
3
#include <spa/support/system.h>
4
#include <spa/support/plugin.h>
5
+#include <spa/utils/names.h>
6
#include <spa/utils/type.h>
7
#include <spa/utils/result.h>
8
#include <spa/utils/string.h>
9
10
e->fd = fd;
11
e->events = events;
12
e->data = data;
13
- return evl_add_pollfd(pfd, fd, e->events);
14
+ return evl_add_pollfd(pfd, fd, e->events, evl_nil);
15
}
16
17
static int impl_pollfd_mod(void *object, int pfd, int fd, uint32_t events, void *data)
18
19
20
e->events = events;
21
e->data = data;
22
- return evl_mod_pollfd(pfd, fd, e->events);
23
+ return evl_mod_pollfd(pfd, fd, e->events, evl_nil);
24
}
25
26
static int impl_pollfd_del(void *object, int pfd, int fd)
27
28
}
29
static int impl_timerfd_read(void *object, int fd, uint64_t *expirations)
30
{
31
- uint32_t ticks;
32
- if (oob_read(fd, &ticks, sizeof(ticks)) != sizeof(ticks))
33
+ if (oob_read(fd, expirations, sizeof(uint64_t)) != sizeof(uint64_t))
34
return -errno;
35
- *expirations = ticks;
36
return 0;
37
}
38
39
40
static int impl_eventfd_create(void *object, int flags)
41
{
42
struct impl *impl = object;
43
- int res;
44
+ int res, fl;
45
+
46
+ fl = EVL_CLONE_PRIVATE;
47
+ if (flags & SPA_FD_NONBLOCK)
48
+ fl |= EVL_CLONE_NONBLOCK;
49
50
- res = evl_new_xbuf(1024, 1024, "xbuf-%d-%p-%d", impl->pid, impl, impl->n_xbuf);
51
+ res = evl_create_xbuf(1024, 1024, fl, "xbuf-%d-%p-%d", impl->pid, impl, impl->n_xbuf);
52
if (res < 0)
53
return res;
54
55
impl->n_xbuf++;
56
57
- if (flags & SPA_FD_NONBLOCK)
58
- fcntl(res, F_SETFL, fcntl(res, F_GETFL) | O_NONBLOCK);
59
-
60
return res;
61
}
62
63
pipewire-0.3.77.tar.gz/spa/plugins/support/logger.c -> pipewire-0.3.79.tar.gz/spa/plugins/support/logger.c
Changed
37
1
2
struct spa_loop *loop = NULL;
3
const char *str, *dest = "";
4
bool linebuf = false;
5
+ bool force_colors = false;
6
7
spa_return_val_if_fail(factory != NULL, -EINVAL);
8
spa_return_val_if_fail(handle != NULL, -EINVAL);
9
10
this->timestamp = spa_atob(str);
11
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_LINE)) != NULL)
12
this->line = spa_atob(str);
13
- if ((str = spa_dict_lookup(info, SPA_KEY_LOG_COLORS)) != NULL)
14
- this->colors = spa_atob(str);
15
+ if ((str = spa_dict_lookup(info, SPA_KEY_LOG_COLORS)) != NULL) {
16
+ if (spa_streq(str, "force")) {
17
+ this->colors = true;
18
+ force_colors = true;
19
+ } else {
20
+ this->colors = spa_atob(str);
21
+ }
22
+ }
23
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_LEVEL)) != NULL)
24
this->log.level = atoi(str);
25
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_FILE)) != NULL) {
26
27
if (linebuf)
28
setlinebuf(this->file);
29
30
- if (!isatty(fileno(this->file)))
31
+ if (!isatty(fileno(this->file)) && !force_colors) {
32
this->colors = false;
33
+ }
34
35
spa_ringbuffer_init(&this->trace_rb);
36
37
pipewire-0.3.77.tar.gz/spa/plugins/support/meson.build -> pipewire-0.3.79.tar.gz/spa/plugins/support/meson.build
Changed
13
1
2
spa_support_dep = declare_dependency(link_with: spa_support_lib)
3
4
if get_option('evl').allowed()
5
- evl_inc = include_directories('/usr/evl/include')
6
+ evl_inc = include_directories('/usr/include')
7
evl_lib = cc.find_library('evl',
8
- dirs: '/usr/evl/lib/',
9
+ dirs: '/usr/lib/',
10
required: get_option('evl'))
11
12
spa_evl_sources = 'evl-system.c', 'evl-plugin.c'
13
pipewire-0.3.77.tar.gz/spa/plugins/v4l2/v4l2-udev.c -> pipewire-0.3.79.tar.gz/spa/plugins/v4l2/v4l2-udev.c
Changed
54
1
2
}
3
}
4
5
+static int stop_inotify(struct device *dev)
6
+{
7
+ struct impl *impl = dev->impl;
8
+ if (dev->notify.fd == -1)
9
+ return 0;
10
+ spa_log_info(impl->log, "stop inotify for /dev/video%u", dev->id);
11
+ spa_loop_remove_source(impl->main_loop, &dev->notify);
12
+ close(dev->notify.fd);
13
+ dev->notify.fd = -1;
14
+ return 0;
15
+}
16
+
17
+
18
static void impl_on_notify_events(struct spa_source *source)
19
{
20
struct device *dev = source->data;
21
22
struct inotify_event e; /* for appropriate alignment */
23
} buf;
24
25
- while (true) {
26
+ if (source->rmask & (SPA_IO_ERR | SPA_IO_HUP)) {
27
+ spa_log_warn(impl->log, "notify error on /dev/video%u", dev->id);
28
+ stop_inotify(dev);
29
+ return;
30
+ }
31
+ while (source->rmask & SPA_IO_IN) {
32
ssize_t len;
33
const struct inotify_event *event;
34
void *p, *e;
35
36
return 0;
37
}
38
39
-static int stop_inotify(struct device *dev)
40
-{
41
- struct impl *impl = dev->impl;
42
- if (dev->notify.fd == -1)
43
- return 0;
44
- spa_log_info(impl->log, "stop inotify for /dev/video%u", dev->id);
45
- spa_loop_remove_source(impl->main_loop, &dev->notify);
46
- close(dev->notify.fd);
47
- dev->notify.fd = -1;
48
- return 0;
49
-}
50
-
51
static void impl_on_fd_events(struct spa_source *source)
52
{
53
struct impl *impl = source->data;
54
pipewire-0.3.77.tar.gz/src/daemon/client-rt.conf.in -> pipewire-0.3.79.tar.gz/src/daemon/client-rt.conf.in
Changed
41
1
2
#dither.noise = 0
3
}
4
5
+stream.rules =
6
+ { matches =
7
+ {
8
+ # all keys must match the value. ! negates. ~ starts regex.
9
+ #application.name = "pw-cat"
10
+ #node.name = "~Google Chrome$"
11
+ }
12
+
13
+ actions = {
14
+ update-props = {
15
+ #node.latency = 512/48000
16
+ }
17
+ }
18
+ }
19
+
20
+
21
alsa.properties = {
22
- #alsa.format = 0
23
- #alsa.rate = 0
24
- #alsa.channels = 0
25
- #alsa.period-bytes = 0
26
- #alsa.buffer-bytes = 0
27
- #alsa.volume-method = cubic # linear, cubic
28
+ # ALSA params take a single value, an array of values
29
+ # or a range { min=.. max=... }
30
+ #alsa.access = MMAP_INTERLEAVED MMAP_NONINTERLEAVED RW_INTERLEAVED RW_NONINTERLEAVED
31
+ #alsa.format = FLOAT S32 S24 S24_3 S16 U8
32
+ #alsa.rate = { min=1 max=384000 } # or 44100 48000 ..
33
+ #alsa.channels = { min=1 max=64 } # or 2 4 6 ..
34
+ #alsa.period-bytes = { min=128 max=2097152 } # or 128 256 1024 ..
35
+ #alsa.buffer-bytes = { min=256 max=4194304 } # or 256 512 4096 ..
36
+
37
+ #alsa.volume-method = cubic # linear, cubic
38
}
39
40
# client specific properties
41
pipewire-0.3.77.tar.gz/src/daemon/jack.conf.in -> pipewire-0.3.79.tar.gz/src/daemon/jack.conf.in
Changed
10
1
2
jack.rules =
3
{ matches =
4
{
5
- # all keys must match the value. ~ starts regex.
6
+ # all keys must match the value. ! negates. ~ starts regex.
7
#client.name = "Carla"
8
#application.process.binary = "jack_simple_client"
9
#application.name = "~jack_simple_client.*"
10
pipewire-0.3.77.tar.gz/src/daemon/pipewire-pulse.conf.in -> pipewire-0.3.79.tar.gz/src/daemon/pipewire-pulse.conf.in
Changed
10
1
2
{
3
matches =
4
{
5
- # all keys must match the value. ~ starts regex.
6
+ # all keys must match the value. ! negates. ~ starts regex.
7
#client.name = "Firefox"
8
#application.process.binary = "teams"
9
#application.name = "~speech-dispatcher.*"
10
pipewire-0.3.77.tar.gz/src/gst/gstpipewiredeviceprovider.c -> pipewire-0.3.79.tar.gz/src/gst/gstpipewiredeviceprovider.c
Changed
20
1
2
{
3
GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider);
4
5
- pw_thread_loop_lock (self->core->loop);
6
+ /* core might be NULL if we failed to connect in _start. */
7
+ if (self->core != NULL) {
8
+ pw_thread_loop_lock (self->core->loop);
9
+ }
10
GST_DEBUG_OBJECT (self, "stopping provider");
11
12
g_clear_pointer ((struct pw_proxy**)&self->registry, pw_proxy_destroy);
13
- pw_thread_loop_unlock (self->core->loop);
14
+ if (self->core != NULL) {
15
+ pw_thread_loop_unlock (self->core->loop);
16
+ }
17
g_clear_pointer (&self->core, gst_pipewire_core_release);
18
}
19
20
pipewire-0.3.77.tar.gz/src/modules/meson.build -> pipewire-0.3.79.tar.gz/src/modules/meson.build
Changed
10
1
2
'module-protocol-pulse/stream.c',
3
'module-protocol-pulse/utils.c',
4
'module-protocol-pulse/volume.c',
5
+ 'module-protocol-pulse/modules/module-alsa-sink.c',
6
+ 'module-protocol-pulse/modules/module-alsa-source.c',
7
'module-protocol-pulse/modules/module-always-sink.c',
8
'module-protocol-pulse/modules/module-combine-sink.c',
9
'module-protocol-pulse/modules/module-echo-cancel.c',
10
pipewire-0.3.77.tar.gz/src/modules/module-combine-stream.c -> pipewire-0.3.79.tar.gz/src/modules/module-combine-stream.c
Changed
10
1
2
* # any of the items in matches needs to match, if one does,
3
* # actions are emited.
4
* {
5
- * # all keys must match the value. ~ in value starts regex.
6
+ * # all keys must match the value. ! negates. ~ starts regex.
7
* #node.name = "~alsa_input.*"
8
* media.class = "Audio/Sink"
9
* }
10
pipewire-0.3.77.tar.gz/src/modules/module-profiler.c -> pipewire-0.3.79.tar.gz/src/modules/module-profiler.c
Changed
13
1
2
struct spa_source *flush_event;
3
unsigned int listening:1;
4
5
+#ifdef max_align_t
6
alignas(max_align_t)
7
+#else
8
+ alignas(64)
9
+#endif
10
uint8_t flushFLUSH_BUFFER + sizeof(struct spa_pod_struct);
11
};
12
13
pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/manager.c -> pipewire-0.3.79.tar.gz/src/modules/module-protocol-pulse/manager.c
Changed
14
1
2
3
o->this.removing = true;
4
5
- if (!o->this.creating)
6
+ if (!o->this.creating) {
7
+ o->this.change_mask = ~0;
8
manager_emit_removed(m, &o->this);
9
-
10
+ }
11
object_destroy(o);
12
}
13
14
pipewire-0.3.79.tar.gz/src/modules/module-protocol-pulse/modules/module-alsa-sink.c
Added
201
1
2
+/* PipeWire */
3
+/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans <wim.taymans@gmail.com> */
4
+/* SPDX-License-Identifier: MIT */
5
+
6
+#include <pipewire/pipewire.h>
7
+
8
+#include "../manager.h"
9
+#include "../module.h"
10
+
11
+#define NAME "alsa-sink"
12
+
13
+#define DEFAULT_DEVICE "default"
14
+
15
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
16
+#define PW_LOG_TOPIC_DEFAULT mod_topic
17
+
18
+struct module_alsa_sink_data {
19
+ struct pw_core *core;
20
+ struct spa_hook core_listener;
21
+
22
+ struct pw_proxy *proxy;
23
+ struct spa_hook proxy_listener;
24
+};
25
+
26
+static void module_alsa_sink_proxy_removed(void *data)
27
+{
28
+ struct module *module = data;
29
+ struct module_alsa_sink_data *d = module->user_data;
30
+ pw_proxy_destroy(d->proxy);
31
+}
32
+
33
+static void module_alsa_sink_proxy_destroy(void *data)
34
+{
35
+ struct module *module = data;
36
+ struct module_alsa_sink_data *d = module->user_data;
37
+
38
+ pw_log_info("proxy %p destroy", d->proxy);
39
+
40
+ spa_hook_remove(&d->proxy_listener);
41
+ d->proxy = NULL;
42
+
43
+ module_schedule_unload(module);
44
+}
45
+
46
+static void module_alsa_sink_proxy_bound_props(void *data, uint32_t global_id, const struct spa_dict *props)
47
+{
48
+ struct module *module = data;
49
+ struct module_alsa_sink_data *d = module->user_data;
50
+
51
+ pw_log_info("proxy %p bound", d->proxy);
52
+
53
+ module_emit_loaded(module, 0);
54
+}
55
+
56
+static void module_alsa_sink_proxy_error(void *data, int seq, int res, const char *message)
57
+{
58
+ struct module *module = data;
59
+ struct module_alsa_sink_data *d = module->user_data;
60
+
61
+ pw_log_info("proxy %p error %d", d->proxy, res);
62
+
63
+ pw_proxy_destroy(d->proxy);
64
+}
65
+
66
+static const struct pw_proxy_events proxy_events = {
67
+ PW_VERSION_PROXY_EVENTS,
68
+ .removed = module_alsa_sink_proxy_removed,
69
+ .bound_props = module_alsa_sink_proxy_bound_props,
70
+ .error = module_alsa_sink_proxy_error,
71
+ .destroy = module_alsa_sink_proxy_destroy,
72
+};
73
+
74
+static void module_alsa_sink_core_error(void *data, uint32_t id, int seq, int res, const char *message)
75
+{
76
+ struct module *module = data;
77
+
78
+ pw_log_warn("error id:%u seq:%d res:%d (%s): %s",
79
+ id, seq, res, spa_strerror(res), message);
80
+
81
+ if (id == PW_ID_CORE && res == -EPIPE)
82
+ module_schedule_unload(module);
83
+}
84
+
85
+static const struct pw_core_events core_events = {
86
+ PW_VERSION_CORE_EVENTS,
87
+ .error = module_alsa_sink_core_error,
88
+};
89
+
90
+static int module_alsa_sink_load(struct module *module)
91
+{
92
+ struct module_alsa_sink_data *d = module->user_data;
93
+
94
+ d->core = pw_context_connect(module->impl->context, NULL, 0);
95
+ if (d->core == NULL)
96
+ return -errno;
97
+
98
+ pw_core_add_listener(d->core, &d->core_listener, &core_events, module);
99
+
100
+ pw_properties_setf(module->props, "pulse.module.id", "%u", module->index);
101
+
102
+ d->proxy = pw_core_create_object(d->core,
103
+ "adapter", PW_TYPE_INTERFACE_Node, PW_VERSION_NODE,
104
+ module->props ? &module->props->dict : NULL, 0);
105
+ if (d->proxy == NULL)
106
+ return -errno;
107
+
108
+ pw_proxy_add_listener(d->proxy, &d->proxy_listener, &proxy_events, module);
109
+
110
+ return SPA_RESULT_RETURN_ASYNC(0);
111
+}
112
+
113
+static int module_alsa_sink_unload(struct module *module)
114
+{
115
+ struct module_alsa_sink_data *d = module->user_data;
116
+
117
+ if (d->proxy != NULL) {
118
+ spa_hook_remove(&d->proxy_listener);
119
+ pw_proxy_destroy(d->proxy);
120
+ d->proxy = NULL;
121
+ }
122
+
123
+ if (d->core != NULL) {
124
+ spa_hook_remove(&d->core_listener);
125
+ pw_core_disconnect(d->core);
126
+ d->core = NULL;
127
+ }
128
+
129
+ return 0;
130
+}
131
+
132
+static const struct spa_dict_item module_alsa_sink_info = {
133
+ { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
134
+ { PW_KEY_MODULE_DESCRIPTION, "An ALSA sink" },
135
+ { PW_KEY_MODULE_USAGE,
136
+ "name=<name of the sink, to be prefixed> "
137
+ "sink_name=<name for the sink> "
138
+ "sink_properties=<properties for the sink> "
139
+ "namereg_fail=<when false attempt to synthesise new sink_name if it is already taken> "
140
+ "device=<ALSA device> "
141
+ "device_id=<ALSA card index> "
142
+ "format=<sample format> "
143
+ "rate=<sample rate> "
144
+ "alternate_rate=<alternate sample rate> "
145
+ "channels=<number of channels> "
146
+ "channel_map=<channel map> "
147
+ "fragments=<number of fragments> "
148
+ "fragment_size=<fragment size> "
149
+ "mmap=<enable memory mapping?> "
150
+ "tsched=<enable system timer based scheduling mode?> "
151
+ "tsched_buffer_size=<buffer size when using timer based scheduling> "
152
+ "tsched_buffer_watermark=<lower fill watermark> "
153
+ "ignore_dB=<ignore dB information from the device?> "
154
+ "control=<name of mixer control, or name and index separated by a comma> "
155
+ "rewind_safeguard=<number of bytes that cannot be rewound> "
156
+ "deferred_volume=<Synchronize software and hardware volume changes to avoid momentary jumps?> "
157
+ "deferred_volume_safety_margin=<usec adjustment depending on volume direction> "
158
+ "deferred_volume_extra_delay=<usec adjustment to HW volume changes> "
159
+ "fixed_latency_range=<disable latency range changes on underrun?>" },
160
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
161
+};
162
+
163
+static int module_alsa_sink_prepare(struct module * const module)
164
+{
165
+ struct pw_properties * const props = module->props;
166
+ const char *str, *dev_id;
167
+ struct spa_audio_info_raw info = { 0 };
168
+
169
+ PW_LOG_TOPIC_INIT(mod_topic);
170
+
171
+ dev_id = pw_properties_get(props, "device_id");
172
+ if (dev_id == NULL)
173
+ dev_id = pw_properties_get(props, "device");
174
+ if (dev_id == NULL)
175
+ dev_id = DEFAULT_DEVICE;
176
+
177
+ pw_properties_set(props, "api.alsa.path", dev_id);
178
+
179
+ if ((str = pw_properties_get(props, "sink_name")) != NULL) {
180
+ pw_properties_set(props, PW_KEY_NODE_NAME, str);
181
+ pw_properties_set(props, "sink_name", NULL);
182
+ }
183
+ else if ((str = pw_properties_get(props, "name")) != NULL) {
184
+ pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_output.%s", str);
185
+ pw_properties_set(props, "name", NULL);
186
+ }
187
+ else {
188
+ pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_output.%s", dev_id);
189
+ }
190
+
191
+ if ((str = pw_properties_get(props, "sink_properties")) != NULL) {
192
+ module_args_add_props(props, str);
193
+ pw_properties_set(props, "sink_properties", NULL);
194
+ }
195
+
196
+ if ((str = pw_properties_get(props, "fragments")) != NULL) {
197
+ pw_properties_set(props, "api.alsa.period-num", str);
198
+ pw_properties_set(props, "fragments", NULL);
199
+ }
200
+ if ((str = pw_properties_get(props, "fragment_size")) != NULL) {
201
pipewire-0.3.79.tar.gz/src/modules/module-protocol-pulse/modules/module-alsa-source.c
Added
201
1
2
+/* PipeWire */
3
+/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans <wim.taymans@gmail.com> */
4
+/* SPDX-License-Identifier: MIT */
5
+
6
+#include <pipewire/pipewire.h>
7
+
8
+#include "../manager.h"
9
+#include "../module.h"
10
+
11
+#define NAME "alsa-source"
12
+
13
+#define DEFAULT_DEVICE "default"
14
+
15
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
16
+#define PW_LOG_TOPIC_DEFAULT mod_topic
17
+
18
+struct module_alsa_source_data {
19
+ struct pw_core *core;
20
+ struct spa_hook core_listener;
21
+
22
+ struct pw_proxy *proxy;
23
+ struct spa_hook proxy_listener;
24
+};
25
+
26
+static void module_alsa_source_proxy_removed(void *data)
27
+{
28
+ struct module *module = data;
29
+ struct module_alsa_source_data *d = module->user_data;
30
+ pw_proxy_destroy(d->proxy);
31
+}
32
+
33
+static void module_alsa_source_proxy_destroy(void *data)
34
+{
35
+ struct module *module = data;
36
+ struct module_alsa_source_data *d = module->user_data;
37
+
38
+ pw_log_info("proxy %p destroy", d->proxy);
39
+
40
+ spa_hook_remove(&d->proxy_listener);
41
+ d->proxy = NULL;
42
+
43
+ module_schedule_unload(module);
44
+}
45
+
46
+static void module_alsa_source_proxy_bound_props(void *data, uint32_t global_id, const struct spa_dict *props)
47
+{
48
+ struct module *module = data;
49
+ struct module_alsa_source_data *d = module->user_data;
50
+
51
+ pw_log_info("proxy %p bound", d->proxy);
52
+
53
+ module_emit_loaded(module, 0);
54
+}
55
+
56
+static void module_alsa_source_proxy_error(void *data, int seq, int res, const char *message)
57
+{
58
+ struct module *module = data;
59
+ struct module_alsa_source_data *d = module->user_data;
60
+
61
+ pw_log_info("proxy %p error %d", d->proxy, res);
62
+
63
+ pw_proxy_destroy(d->proxy);
64
+}
65
+
66
+static const struct pw_proxy_events proxy_events = {
67
+ PW_VERSION_PROXY_EVENTS,
68
+ .removed = module_alsa_source_proxy_removed,
69
+ .bound_props = module_alsa_source_proxy_bound_props,
70
+ .error = module_alsa_source_proxy_error,
71
+ .destroy = module_alsa_source_proxy_destroy,
72
+};
73
+
74
+static void module_alsa_source_core_error(void *data, uint32_t id, int seq, int res, const char *message)
75
+{
76
+ struct module *module = data;
77
+
78
+ pw_log_warn("error id:%u seq:%d res:%d (%s): %s",
79
+ id, seq, res, spa_strerror(res), message);
80
+
81
+ if (id == PW_ID_CORE && res == -EPIPE)
82
+ module_schedule_unload(module);
83
+}
84
+
85
+static const struct pw_core_events core_events = {
86
+ PW_VERSION_CORE_EVENTS,
87
+ .error = module_alsa_source_core_error,
88
+};
89
+
90
+static int module_alsa_source_load(struct module *module)
91
+{
92
+ struct module_alsa_source_data *d = module->user_data;
93
+
94
+ d->core = pw_context_connect(module->impl->context, NULL, 0);
95
+ if (d->core == NULL)
96
+ return -errno;
97
+
98
+ pw_core_add_listener(d->core, &d->core_listener, &core_events, module);
99
+
100
+ pw_properties_setf(module->props, "pulse.module.id", "%u", module->index);
101
+
102
+ d->proxy = pw_core_create_object(d->core,
103
+ "adapter", PW_TYPE_INTERFACE_Node, PW_VERSION_NODE,
104
+ module->props ? &module->props->dict : NULL, 0);
105
+ if (d->proxy == NULL)
106
+ return -errno;
107
+
108
+ pw_proxy_add_listener(d->proxy, &d->proxy_listener, &proxy_events, module);
109
+
110
+ return SPA_RESULT_RETURN_ASYNC(0);
111
+}
112
+
113
+static int module_alsa_source_unload(struct module *module)
114
+{
115
+ struct module_alsa_source_data *d = module->user_data;
116
+
117
+ if (d->proxy != NULL) {
118
+ spa_hook_remove(&d->proxy_listener);
119
+ pw_proxy_destroy(d->proxy);
120
+ d->proxy = NULL;
121
+ }
122
+
123
+ if (d->core != NULL) {
124
+ spa_hook_remove(&d->core_listener);
125
+ pw_core_disconnect(d->core);
126
+ d->core = NULL;
127
+ }
128
+
129
+ return 0;
130
+}
131
+
132
+static const struct spa_dict_item module_alsa_source_info = {
133
+ { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
134
+ { PW_KEY_MODULE_DESCRIPTION, "An ALSA source" },
135
+ { PW_KEY_MODULE_USAGE,
136
+ "name=<name of the source, to be prefixed> "
137
+ "source_name=<name for the source> "
138
+ "source_properties=<properties for the source> "
139
+ "namereg_fail=<when false attempt to synthesise new source_name if it is already taken> "
140
+ "device=<ALSA device> "
141
+ "device_id=<ALSA card index> "
142
+ "format=<sample format> "
143
+ "rate=<sample rate> "
144
+ "alternate_rate=<alternate sample rate> "
145
+ "channels=<number of channels> "
146
+ "channel_map=<channel map> "
147
+ "fragments=<number of fragments> "
148
+ "fragment_size=<fragment size> "
149
+ "mmap=<enable memory mapping?> "
150
+ "tsched=<enable system timer based scheduling mode?> "
151
+ "tsched_buffer_size=<buffer size when using timer based scheduling> "
152
+ "tsched_buffer_watermark=<lower fill watermark> "
153
+ "ignore_dB=<ignore dB information from the device?> "
154
+ "control=<name of mixer control, or name and index separated by a comma> "
155
+ "rewind_safeguard=<number of bytes that cannot be rewound> "
156
+ "deferred_volume=<Synchronize software and hardware volume changes to avoid momentary jumps?> "
157
+ "deferred_volume_safety_margin=<usec adjustment depending on volume direction> "
158
+ "deferred_volume_extra_delay=<usec adjustment to HW volume changes> "
159
+ "fixed_latency_range=<disable latency range changes on underrun?>" },
160
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
161
+};
162
+
163
+static int module_alsa_source_prepare(struct module * const module)
164
+{
165
+ struct pw_properties * const props = module->props;
166
+ const char *str, *dev_id;
167
+ struct spa_audio_info_raw info = { 0 };
168
+
169
+ PW_LOG_TOPIC_INIT(mod_topic);
170
+
171
+ dev_id = pw_properties_get(props, "device_id");
172
+ if (dev_id == NULL)
173
+ dev_id = pw_properties_get(props, "device");
174
+ if (dev_id == NULL)
175
+ dev_id = DEFAULT_DEVICE;
176
+
177
+ pw_properties_set(props, "api.alsa.path", dev_id);
178
+
179
+ if ((str = pw_properties_get(props, "source_name")) != NULL) {
180
+ pw_properties_set(props, PW_KEY_NODE_NAME, str);
181
+ pw_properties_set(props, "source_name", NULL);
182
+ }
183
+ else if ((str = pw_properties_get(props, "name")) != NULL) {
184
+ pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_output.%s", str);
185
+ pw_properties_set(props, "name", NULL);
186
+ }
187
+ else {
188
+ pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_output.%s", dev_id);
189
+ }
190
+
191
+ if ((str = pw_properties_get(props, "source_properties")) != NULL) {
192
+ module_args_add_props(props, str);
193
+ pw_properties_set(props, "source_properties", NULL);
194
+ }
195
+
196
+ if ((str = pw_properties_get(props, "fragments")) != NULL) {
197
+ pw_properties_set(props, "api.alsa.period-num", str);
198
+ pw_properties_set(props, "fragments", NULL);
199
+ }
200
+ if ((str = pw_properties_get(props, "fragment_size")) != NULL) {
201
pipewire-0.3.77.tar.gz/src/modules/module-rtp-sap.c -> pipewire-0.3.79.tar.gz/src/modules/module-rtp-sap.c
Changed
44
1
2
* { matches =
3
* # any of the items in matches needs to match, if one does,
4
* # actions are emited.
5
- * { # all keys must match the value. ~ in value starts regex.
6
+ * { # all keys must match the value. ! negates. ~ starts regex.
7
* #rtp.origin = "wim 3883629975 0 IN IP4 0.0.0.0"
8
* #rtp.payload = "127"
9
* #rtp.fmt = "L16/48000/2"
10
11
* }
12
* }
13
* { matches =
14
- * { # all keys must match the value. ~ in value starts regex.
15
+ * { # all keys must match the value. ! negates. ~ starts regex.
16
* #rtp.origin = "wim 3883629975 0 IN IP4 0.0.0.0"
17
* #rtp.payload = "127"
18
* #rtp.fmt = "L16/48000/2"
19
20
uint32_t port;
21
const char *str;
22
int res = 0;
23
+ char addr64;
24
25
PW_LOG_TOPIC_INIT(mod_topic);
26
27
28
res = ioctl(fd, SIOCGIFADDR, &req);
29
if (res < 0)
30
pw_log_warn("SIOCGIFADDR %s failed: %m", impl->ifname);
31
- str = inet_ntoa(((struct sockaddr_in *)&req.ifr_addr)->sin_addr);
32
+ str = inet_ntop(req.ifr_addr.sa_family,
33
+ &((struct sockaddr_in *)&req.ifr_addr)->sin_addr,
34
+ addr, sizeof(addr));
35
+ if (str == NULL) {
36
+ pw_log_warn("can't parse interface ip: %m");
37
+ str = DEFAULT_SOURCE_IP;
38
+ } else {
39
+ pw_log_info("interface %s IP: %s", impl->ifname, str);
40
+ }
41
close(fd);
42
}
43
}
44
pipewire-0.3.77.tar.gz/src/modules/module-vban/audio.c -> pipewire-0.3.79.tar.gz/src/modules/module-vban/audio.c
Changed
28
1
2
3
hlen = VBAN_HEADER_SIZE;
4
plen = len - hlen;
5
- samples = SPA_MIN(hdr->format_nbs, plen / stride);
6
+ samples = SPA_MIN(hdr->format_nbs+1, plen / stride);
7
8
n_frames = hdr->n_frames;
9
if (impl->have_sync && impl->n_frames != n_frames) {
10
11
filled = impl->target_buffer;
12
13
spa_dll_init(&impl->dll);
14
- spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MIN, 128, impl->rate);
15
+ spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MAX, 128, impl->rate);
16
memset(impl->buffer, 0, BUFFER_SIZE);
17
impl->have_sync = true;
18
} else if (expected_write != write) {
19
20
BUFFER_SIZE / stride);
21
impl->have_sync = false;
22
} else {
23
- pw_log_debug("got samples:%u", samples);
24
+ pw_log_trace("got samples:%u", samples);
25
spa_ringbuffer_write_data(&impl->ring,
26
impl->buffer,
27
BUFFER_SIZE,
28
pipewire-0.3.77.tar.gz/src/modules/module-vban/stream.c -> pipewire-0.3.79.tar.gz/src/modules/module-vban/stream.c
Changed
10
1
2
pw_properties_setf(props, "vban.channels", "%u", impl->info.info.raw.channels);
3
4
spa_dll_init(&impl->dll);
5
- spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MIN, 128, impl->rate);
6
+ spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MAX, 128, impl->rate);
7
impl->corr = 1.0;
8
9
impl->stream = pw_stream_new(core, "vban-session", props);
10
pipewire-0.3.77.tar.gz/src/pipewire/conf.c -> pipewire-0.3.79.tar.gz/src/pipewire/conf.c
Changed
70
1
2
/*
3
* {
4
* # all keys must match the value. ~ in value starts regex.
5
+ * # ! as the first char of the value negates the match
6
* <key> = <value>
7
* ...
8
* }
9
10
char key256, val1024;
11
const char *str, *value;
12
int match = 0, fail = 0;
13
- int len;
14
+ int len, skip = 0;
15
16
while (spa_json_get_string(&it0, key, sizeof(key)) > 0) {
17
bool success = false;
18
19
continue;
20
value = val;
21
len = strlen(val);
22
+ if (len > 0 && value0 == '!') {
23
+ success = !success;
24
+ skip++;
25
+ }
26
}
27
if (str != NULL) {
28
- if (value0 == '~') {
29
+ if (valueskip == '~') {
30
regex_t preg;
31
- if (regcomp(&preg, value+1, REG_EXTENDED | REG_NOSUB) == 0) {
32
+ int res;
33
+ skip++;
34
+ if ((res = regcomp(&preg, value+skip, REG_EXTENDED | REG_NOSUB)) != 0) {
35
+ char errbuf1024;
36
+ regerror(res, &preg, errbuf, sizeof(errbuf));
37
+ pw_log_warn("invalid regex %s: %s", value+skip, errbuf);
38
+ } else {
39
if (regexec(&preg, str, 0, NULL, 0) == 0)
40
- success = true;
41
+ success = !success;
42
regfree(&preg);
43
}
44
- } else if (strncmp(str, value, len) == 0 &&
45
- strlen(str) == (size_t)len) {
46
- success = true;
47
+ } else if (strncmp(str, value+skip, len-skip) == 0 &&
48
+ strlen(str) == (size_t)(len-skip)) {
49
+ success = !success;
50
}
51
}
52
if (success) {
53
54
pw_log_debug("'%s' match '%s' < > '%.*s'", key, str, len, value);
55
}
56
else {
57
+ pw_log_debug("'%s' fail '%s' < > '%.*s'", key, str, len, value);
58
fail++;
59
break;
60
}
61
62
* # any of the items in matches needs to match, if one does,
63
* # actions are emited.
64
* {
65
- * # all keys must match the value. ~ in value starts regex.
66
+ * # all keys must match the value. ! negates. ~ starts regex.
67
* <key> = <value>
68
* ...
69
* }
70
pipewire-0.3.77.tar.gz/src/pipewire/context.c -> pipewire-0.3.79.tar.gz/src/pipewire/context.c
Changed
114
1
2
return pw_impl_node_set_state(node, state);
3
}
4
5
-/* From a node (that is runnable) follow all prepared links and groups to
6
- * active nodes up to the driver and make them recursively runnable as well.
7
- *
8
- * We stop at driver nodes so that other paths linked to the driver will stay
9
- * unrunnable when no other runnable path exists.
10
+/* From a node (that is runnable) follow all prepared links in the given direction
11
+ * and groups to active nodes and make them recursively runnable as well.
12
*/
13
-static inline int run_nodes(struct pw_context *context, struct pw_impl_node *node, struct spa_list *nodes)
14
+static inline int run_nodes(struct pw_context *context, struct pw_impl_node *node,
15
+ struct spa_list *nodes, enum pw_direction direction)
16
{
17
struct pw_impl_node *t;
18
struct pw_impl_port *p;
19
struct pw_impl_link *l;
20
21
- pw_log_debug("node %p: '%s'", node, node->name);
22
+ pw_log_debug("node %p: '%s' direction:%s", node, node->name,
23
+ pw_direction_as_string(direction));
24
25
- spa_list_for_each(p, &node->input_ports, link) {
26
- spa_list_for_each(l, &p->links, input_link) {
27
- t = l->output->node;
28
+ SPA_FLAG_SET(node->checked, 1u<<direction);
29
30
- if (!t->active || !l->prepared || t->runnable)
31
- continue;
32
+ if (direction == PW_DIRECTION_INPUT) {
33
+ spa_list_for_each(p, &node->input_ports, link) {
34
+ spa_list_for_each(l, &p->links, input_link) {
35
+ t = l->output->node;
36
37
- pw_log_debug(" peer %p: '%s'", t, t->name);
38
- t->runnable = true;
39
- if (!t->driving)
40
- run_nodes(context, t, nodes);
41
+ if (!t->active || !l->prepared || (!t->driving && t->runnable))
42
+ continue;
43
+
44
+ pw_log_debug(" peer %p: '%s'", t, t->name);
45
+ t->runnable = true;
46
+ run_nodes(context, t, nodes, direction);
47
+ }
48
}
49
- }
50
- spa_list_for_each(p, &node->output_ports, link) {
51
- spa_list_for_each(l, &p->links, output_link) {
52
- t = l->input->node;
53
+ } else {
54
+ spa_list_for_each(p, &node->output_ports, link) {
55
+ spa_list_for_each(l, &p->links, output_link) {
56
+ t = l->input->node;
57
58
- if (!t->active || !l->prepared || t->runnable)
59
- continue;
60
+ if (!t->active || !l->prepared || (!t->driving && t->runnable))
61
+ continue;
62
63
- pw_log_debug(" peer %p: '%s'", t, t->name);
64
- t->runnable = true;
65
- if (!t->driving)
66
- run_nodes(context, t, nodes);
67
+ pw_log_debug(" peer %p: '%s'", t, t->name);
68
+ t->runnable = true;
69
+ run_nodes(context, t, nodes, direction);
70
+ }
71
}
72
}
73
/* now go through all the nodes that have the same link group and
74
75
* them. */
76
if (node->link_group != NULL) {
77
spa_list_for_each(t, nodes, sort_link) {
78
- if (t->exported || !t->active || t->runnable)
79
+ if (t->exported || !t->active ||
80
+ SPA_FLAG_IS_SET(t->checked, 1u<<direction))
81
continue;
82
if (!spa_streq(t->link_group, node->link_group))
83
continue;
84
85
pw_log_debug(" group %p: '%s'", t, t->name);
86
t->runnable = true;
87
if (!t->driving)
88
- run_nodes(context, t, nodes);
89
+ run_nodes(context, t, nodes, direction);
90
}
91
}
92
return 0;
93
94
pw_log_debug(" next node %p: '%s' runnable:%u", n, n->name, n->runnable);
95
}
96
spa_list_for_each(n, collect, sort_link)
97
- if (!n->driving && n->runnable)
98
- run_nodes(context, n, collect);
99
+ if (!n->driving && n->runnable) {
100
+ run_nodes(context, n, collect, PW_DIRECTION_OUTPUT);
101
+ run_nodes(context, n, collect, PW_DIRECTION_INPUT);
102
+ }
103
104
return 0;
105
}
106
107
/* clean up the flags first */
108
spa_list_for_each(n, &context->node_list, link) {
109
n->visited = false;
110
+ n->checked = 0;
111
n->runnable = n->always_process && n->active;
112
}
113
114
pipewire-0.3.77.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.79.tar.gz/src/pipewire/impl-node.c
Changed
51
1
2
3
node_deactivate(this);
4
5
+ pw_log_debug("%p: suspend node driving:%d driver:%d added:%d", this,
6
+ this->driving, this->driver, this->added);
7
+
8
+ res = spa_node_send_command(this->node,
9
+ &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend));
10
+ if (res == -ENOTSUP)
11
+ res = spa_node_send_command(this->node,
12
+ &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Pause));
13
+ if (res < 0 && res != -EIO)
14
+ pw_log_warn("%p: suspend node error %s", this, spa_strerror(res));
15
+
16
spa_list_for_each(p, &this->input_ports, link) {
17
if ((res = pw_impl_port_set_param(p, SPA_PARAM_Format, 0, NULL)) < 0)
18
pw_log_warn("%p: error unset format input: %s",
19
20
p->state = PW_IMPL_PORT_STATE_CONFIGURE;
21
}
22
23
- pw_log_debug("%p: suspend node driving:%d driver:%d added:%d", this,
24
- this->driving, this->driver, this->added);
25
-
26
- res = spa_node_send_command(this->node,
27
- &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend));
28
- if (res == -ENOTSUP)
29
- res = spa_node_send_command(this->node,
30
- &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Pause));
31
- if (res < 0 && res != -EIO)
32
- pw_log_warn("%p: suspend node error %s", this, spa_strerror(res));
33
-
34
node_update_state(this, PW_NODE_STATE_SUSPENDED, 0, NULL);
35
36
return res;
37
38
* help drivers that don't support this yet */
39
if (SPA_UNLIKELY(node->rt.position->clock.duration != node->rt.position->clock.target_duration ||
40
node->rt.position->clock.rate.denom != node->rt.position->clock.target_rate.denom)) {
41
- pw_log_warn("driver %s did not update duration/rate", node->name);
42
+ pw_log_warn("driver %s did not update duration/rate (%"PRIu64"/%"PRIu64" %u/%u)",
43
+ node->name,
44
+ node->rt.position->clock.duration,
45
+ node->rt.position->clock.target_duration,
46
+ node->rt.position->clock.rate.denom,
47
+ node->rt.position->clock.target_rate.denom);
48
node->rt.position->clock.duration = node->rt.position->clock.target_duration;
49
node->rt.position->clock.rate = node->rt.position->clock.target_rate;
50
}
51
pipewire-0.3.77.tar.gz/src/pipewire/pipewire.c -> pipewire-0.3.79.tar.gz/src/pipewire/pipewire.c
Changed
15
1
2
char *patterns = NULL;
3
4
n_items = 0;
5
- if (!support->no_color)
6
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_COLORS, "true");
7
+ if (!support->no_color) {
8
+ if ((str = getenv("PIPEWIRE_LOG_COLOR")) == NULL)
9
+ str = "true";
10
+ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_COLORS, str);
11
+ }
12
itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_TIMESTAMP, "true");
13
if ((str = getenv("PIPEWIRE_LOG_LINE")) == NULL || spa_atob(str))
14
itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_LINE, "true");
15
pipewire-0.3.77.tar.gz/src/pipewire/private.h -> pipewire-0.3.79.tar.gz/src/pipewire/private.h
Changed
9
1
2
unsigned int trigger:1; /**< has the TRIGGER property and needs an extra
3
* trigger to start processing. */
4
unsigned int can_suspend:1;
5
+ unsigned int checked; /**< for sorting */
6
7
uint32_t port_user_data_size; /**< extra size for port user data */
8
9
pipewire-0.3.77.tar.gz/src/pipewire/stream.h -> pipewire-0.3.79.tar.gz/src/pipewire/stream.h
Changed
44
1
2
* value, and pw_time.ticks, were captured at pw_time.now and can be extrapolated
3
* to the current time like this:
4
*
5
+ *\code{.c}
6
* struct timespec ts;
7
* clock_gettime(CLOCK_MONOTONIC, &ts);
8
* int64_t diff = SPA_TIMESPEC_TO_NSEC(&ts) - pw_time.now;
9
* int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC);
10
+ *\endcode
11
*
12
* pw_time.delay contains the total delay that a signal will travel through the
13
* graph. This includes the delay caused by filters in the graph as well as delays
14
15
* in milliseconds for the first sample in the newly queued buffer to be played
16
* by the hardware can be calculated as:
17
*
18
+ *\code{.unparsed}
19
* (pw_time.buffered * 1000 / stream.samplerate) +
20
* (pw_time.queued * 1000 / app.rate) +
21
* ((pw_time.delay - elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom)
22
+ *\endcode
23
*
24
* The current extrapolated time (in ms) in the source or sink can be calculated as:
25
*
26
+ *\code{.unparsed}
27
* (pw_time.ticks + elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom
28
+ *\endcode
29
*
30
+ * Below is an overview of the different timing values:
31
*
32
+ *\code{.unparsed}
33
* stream time domain graph time domain
34
* /-----------------------\/-----------------------------\
35
*
36
37
* latency latency
38
* \--------/\-------------/\-----------------------------/
39
* queued buffered delay
40
+ *\endcode
41
*/
42
struct pw_time {
43
int64_t now; /**< the monotonic time in nanoseconds. This is the time
44
pipewire-0.3.77.tar.gz/src/tools/pw-mon.c -> pipewire-0.3.79.tar.gz/src/tools/pw-mon.c
Changed
10
1
2
3
setlinebuf(stdout);
4
5
- if (isatty(STDERR_FILENO) && getenv("NO_COLOR") == NULL)
6
+ if (isatty(STDOUT_FILENO) && getenv("NO_COLOR") == NULL)
7
colors = true;
8
9
while ((c = getopt_long(argc, argv, "hVr:NC", long_options, NULL)) != -1) {
10
pipewire-0.3.77.tar.gz/src/tools/pw-top.c -> pipewire-0.3.79.tar.gz/src/tools/pw-top.c
Changed
201
1
2
unsigned pending_refresh:1;
3
4
WINDOW *win;
5
+
6
+ unsigned int batch_mode:1;
7
+ int iterations;
8
};
9
10
struct point {
11
12
struct driver info;
13
};
14
15
+static SPA_PRINTF_FUNC(4, 5) void print_mode_dependent(struct data *d, int y, int x, const char *fmt, ...)
16
+{
17
+ va_list argp;
18
+ if (!d->batch_mode)
19
+ mvwprintw(d->win, y, x, "%s", "");
20
+
21
+ va_start(argp, fmt);
22
+ if (d->batch_mode) {
23
+ vprintf(fmt, argp);
24
+ printf("\n");
25
+ } else
26
+ vw_printw(d->win, fmt, argp);
27
+ va_end(argp);
28
+}
29
+
30
+
31
static int process_info(struct data *d, const struct spa_pod *pod, struct driver *info)
32
{
33
return spa_pod_parse_struct(pod,
34
35
.destroy = on_node_destroy,
36
};
37
38
-static void do_refresh(struct data *d);
39
+static void do_refresh(struct data *d, bool force_refresh);
40
41
static void node_info(void *data, const struct pw_node_info *info)
42
{
43
44
45
if (n->state != info->state) {
46
n->state = info->state;
47
- do_refresh(n->data);
48
+ do_refresh(n->data, !n->data->batch_mode);
49
}
50
}
51
52
53
break;
54
}
55
done:
56
- do_refresh(n->data);
57
+ do_refresh(n->data, !n->data->batch_mode);
58
}
59
60
static const struct pw_node_events node_events = {
61
62
}
63
spa_list_append(&d->node_list, &n->link);
64
d->n_nodes++;
65
- d->pending_refresh = true;
66
+ if (!d->batch_mode)
67
+ d->pending_refresh = true;
68
69
return n;
70
}
71
72
pw_proxy_destroy(n->proxy);
73
spa_list_remove(&n->link);
74
d->n_nodes--;
75
- d->pending_refresh = true;
76
+ if (!d->batch_mode)
77
+ d->pending_refresh = true;
78
free(n);
79
}
80
81
82
else
83
busy = -1;
84
85
- mvwprintw(d->win, y, 0, "%s %4.1u %6.1u %6.1u %s %s %s %s %3.1u %16.16s %s%s",
86
+ print_mode_dependent(d, y, 0, "%s %4.1u %6.1u %6.1u %s %s %s %s %3.1u %16.16s %s%s",
87
state_as_string(n->state),
88
n->id,
89
frac.num, frac.denom,
90
91
spa_zero(n->info);
92
}
93
94
-static void do_refresh(struct data *d)
95
+#define HEADER "S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME "
96
+
97
+static void do_refresh(struct data *d, bool force_refresh)
98
{
99
struct node *n, *t, *f;
100
int y = 1;
101
102
- wclear(d->win);
103
- wattron(d->win, A_REVERSE);
104
- wprintw(d->win, "%-*.*s", COLS, COLS, "S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME ");
105
- wattroff(d->win, A_REVERSE);
106
- wprintw(d->win, "\n");
107
+ if (!d->pending_refresh && !force_refresh)
108
+ return;
109
+
110
+ if (!d->batch_mode) {
111
+ wclear(d->win);
112
+ wattron(d->win, A_REVERSE);
113
+ wprintw(d->win, "%-*.*s", COLS, COLS, HEADER);
114
+ wattroff(d->win, A_REVERSE);
115
+ wprintw(d->win, "\n");
116
+ } else
117
+ printf(HEADER "\n");
118
119
spa_list_for_each_safe(n, t, &d->node_list, link) {
120
if (n->driver != n)
121
continue;
122
123
print_node(d, &n->info, n, y++);
124
- if(y > LINES)
125
+ if(!d->batch_mode && y > LINES)
126
break;
127
128
spa_list_for_each(f, &d->node_list, link) {
129
130
}
131
}
132
133
- // Clear from last line to the end of the window to hide text wrapping from the last node
134
- wmove(d->win, y, 0);
135
- wclrtobot(d->win);
136
+ if (!d->batch_mode) {
137
+ // Clear from last line to the end of the window to hide text wrapping from the last node
138
+ wmove(d->win, y, 0);
139
+ wclrtobot(d->win);
140
+
141
+ wrefresh(d->win);
142
+ }
143
144
- wrefresh(d->win);
145
d->pending_refresh = false;
146
+
147
+ if (d->iterations > 0)
148
+ d->iterations--;
149
+
150
+ if (d->iterations == 0)
151
+ pw_main_loop_quit(d->loop);
152
}
153
154
static void do_timeout(void *data, uint64_t expirations)
155
{
156
struct data *d = data;
157
d->generation++;
158
- do_refresh(d);
159
+ do_refresh(d, true);
160
}
161
162
static void profiler_profile(void *data, const struct spa_pod *pod)
163
164
if (res < 0)
165
continue;
166
}
167
- if (d->pending_refresh)
168
- do_refresh(d);
169
+
170
+ do_refresh(d, false);
171
}
172
173
static const struct pw_profiler_events profiler_events = {
174
175
d->profiler = proxy;
176
pw_proxy_add_object_listener(proxy, &d->profiler_listener, &profiler_events, d);
177
}
178
- if (d->pending_refresh)
179
- do_refresh(d);
180
+
181
+ do_refresh(d, false);
182
return;
183
184
error_proxy:
185
186
struct node *n;
187
if ((n = find_node(d, id)) != NULL)
188
remove_node(d, n);
189
- if (d->pending_refresh)
190
- do_refresh(d);
191
+
192
+ do_refresh(d, false);
193
}
194
195
static const struct pw_registry_events registry_events = {
196
197
pw_log_error("no Profiler Interface found, please load one in the server");
198
pw_main_loop_quit(d->loop);
199
} else {
200
- do_refresh(d);
201