Changes of Revision 33

pipewire-aptx.changes Changed
x
 
1
@@ -1,4 +1,9 @@
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
@@ -7,7 +7,7 @@
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
@@ -1,3 +1,111 @@
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
@@ -49,9 +157,6 @@
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
@@ -1,7 +1,7 @@
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
@@ -21,37 +21,37 @@
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,7 +59,7 @@
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
@@ -70,28 +70,28 @@
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
@@ -106,9 +106,9 @@
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
@@ -150,15 +150,18 @@
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
@@ -171,5 +171,7 @@
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
@@ -1,5 +1,5 @@
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
@@ -22,6 +22,7 @@
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
@@ -919,118 +920,199 @@
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
@@ -13,7 +13,7 @@
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
@@ -14,7 +14,7 @@
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
@@ -18,7 +18,7 @@
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
@@ -14,7 +14,7 @@
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
@@ -13,7 +13,7 @@
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
@@ -13,7 +13,7 @@
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
@@ -14,7 +14,7 @@
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
@@ -15,7 +15,7 @@
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
@@ -13,7 +13,7 @@
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
@@ -14,7 +14,7 @@
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
@@ -14,7 +14,7 @@
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
@@ -13,7 +13,7 @@
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
@@ -13,7 +13,7 @@
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
@@ -13,7 +13,7 @@
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
@@ -86,12 +86,12 @@
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
@@ -171,6 +171,7 @@
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
@@ -248,6 +249,8 @@
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
@@ -718,12 +721,20 @@
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
@@ -900,12 +911,6 @@
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
@@ -928,7 +933,7 @@
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
@@ -981,10 +986,7 @@
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
@@ -992,7 +994,7 @@
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
@@ -1019,7 +1021,14 @@
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
@@ -1035,10 +1044,13 @@
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
@@ -1049,6 +1061,7 @@
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
@@ -1056,13 +1069,11 @@
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
@@ -1076,6 +1087,7 @@
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
@@ -1084,8 +1096,10 @@
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
@@ -1098,13 +1112,15 @@
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
@@ -1118,7 +1134,9 @@
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
@@ -1,25 +1,25 @@
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
@@ -32,36 +32,44 @@
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
@@ -76,14 +84,15 @@
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
@@ -106,7 +115,7 @@
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
@@ -139,21 +148,23 @@
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
@@ -161,23 +172,26 @@
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
@@ -193,7 +207,7 @@
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
@@ -202,7 +216,7 @@
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
@@ -19,8 +19,8 @@
2
 "Project-Id-Version: pipewire\n"
3
 "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
4
 "issues\n"
5
-"POT-Creation-Date: 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
@@ -51,36 +51,36 @@
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
@@ -95,7 +95,7 @@
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
@@ -127,7 +127,7 @@
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
@@ -162,7 +162,7 @@
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
@@ -178,7 +178,7 @@
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
@@ -197,12 +197,12 @@
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
@@ -229,7 +229,7 @@
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
@@ -295,7 +295,7 @@
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
@@ -410,7 +410,7 @@
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
@@ -524,12 +524,12 @@
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
@@ -628,104 +628,104 @@
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
@@ -117,7 +117,7 @@
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
@@ -129,8 +129,8 @@
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
@@ -49,9 +49,11 @@
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
@@ -68,9 +68,11 @@
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
@@ -441,7 +441,7 @@
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
@@ -284,7 +284,8 @@
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
@@ -281,6 +281,18 @@
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
@@ -293,6 +305,16 @@
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
@@ -365,6 +387,7 @@
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
@@ -395,6 +418,7 @@
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
@@ -499,9 +499,13 @@
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
@@ -1645,31 +1649,27 @@
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
@@ -1729,7 +1729,7 @@
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
@@ -1737,7 +1737,7 @@
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
@@ -1931,14 +1931,18 @@
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
@@ -199,6 +199,7 @@
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
@@ -0,0 +1,22 @@
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
@@ -573,8 +573,4 @@
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
@@ -2594,7 +2594,7 @@
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
@@ -294,7 +294,7 @@
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
@@ -193,13 +193,14 @@
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
@@ -406,8 +407,12 @@
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
@@ -435,6 +440,12 @@
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
@@ -471,6 +482,10 @@
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
@@ -484,8 +499,10 @@
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
@@ -500,6 +517,10 @@
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
@@ -963,6 +984,10 @@
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
@@ -1010,6 +1035,14 @@
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
@@ -1163,6 +1196,11 @@
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
@@ -1624,6 +1662,10 @@
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
@@ -2228,13 +2270,15 @@
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
@@ -2252,6 +2296,14 @@
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
@@ -2321,6 +2373,41 @@
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
@@ -1051,6 +1051,26 @@
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
@@ -1467,19 +1487,8 @@
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
@@ -1607,6 +1616,11 @@
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
@@ -1617,7 +1631,15 @@
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
@@ -1641,29 +1663,28 @@
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
@@ -1671,13 +1692,23 @@
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
@@ -1690,9 +1721,11 @@
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
@@ -125,6 +125,8 @@
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
@@ -149,6 +151,8 @@
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
@@ -163,6 +167,8 @@
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
@@ -175,6 +181,8 @@
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
@@ -182,8 +190,10 @@
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
@@ -206,6 +216,10 @@
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
@@ -307,8 +321,10 @@
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
@@ -349,6 +365,7 @@
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
@@ -630,6 +647,8 @@
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
@@ -315,7 +315,14 @@
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
@@ -18,6 +18,7 @@
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
@@ -133,7 +134,7 @@
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
@@ -147,7 +148,7 @@
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
@@ -248,10 +249,8 @@
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
@@ -259,17 +258,18 @@
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
@@ -295,6 +295,7 @@
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
@@ -333,8 +334,14 @@
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
@@ -363,8 +370,9 @@
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
@@ -24,9 +24,9 @@
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
@@ -393,6 +393,19 @@
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
@@ -402,7 +415,12 @@
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
@@ -469,18 +487,6 @@
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
@@ -94,13 +94,33 @@
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
@@ -95,7 +95,7 @@
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
@@ -116,7 +116,7 @@
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
@@ -665,11 +665,16 @@
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
@@ -356,6 +356,8 @@
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
@@ -93,7 +93,7 @@
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
@@ -104,7 +104,11 @@
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
@@ -641,9 +641,10 @@
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
@@ -0,0 +1,239 @@
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
@@ -0,0 +1,239 @@
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
@@ -75,7 +75,7 @@
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
@@ -91,7 +91,7 @@
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
@@ -1435,6 +1435,7 @@
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
@@ -1484,7 +1485,15 @@
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
@@ -103,7 +103,7 @@
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
@@ -132,7 +132,7 @@
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
@@ -145,7 +145,7 @@
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
@@ -393,7 +393,7 @@
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
@@ -586,6 +586,7 @@
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
@@ -598,7 +599,7 @@
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
@@ -615,18 +616,28 @@
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
@@ -634,6 +645,7 @@
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
@@ -1075,7 +1087,7 @@
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
@@ -787,44 +787,46 @@
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
@@ -834,7 +836,8 @@
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
@@ -842,7 +845,7 @@
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
@@ -944,8 +947,10 @@
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
@@ -1199,6 +1204,7 @@
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
@@ -445,6 +445,17 @@
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
@@ -461,17 +472,6 @@
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
@@ -1796,7 +1796,12 @@
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
@@ -598,8 +598,11 @@
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
@@ -676,6 +676,7 @@
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
@@ -226,10 +226,12 @@
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
@@ -255,15 +257,21 @@
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
@@ -275,6 +283,7 @@
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
@@ -757,7 +757,7 @@
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
@@ -82,6 +82,9 @@
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
@@ -89,6 +92,22 @@
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
@@ -144,7 +163,7 @@
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
@@ -152,7 +171,7 @@
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
@@ -259,7 +278,7 @@
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
@@ -296,7 +315,8 @@
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
@@ -307,7 +327,8 @@
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
@@ -462,7 +483,7 @@
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
@@ -484,23 +505,31 @@
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
@@ -517,19 +546,28 @@
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
@@ -568,8 +606,8 @@
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
@@ -608,8 +646,8 @@
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
@@ -623,8 +661,8 @@
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
@@ -662,7 +700,7 @@
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