We truncated the diff of some files because they were too big.
If you want to see the full diff for every file, click here.
Changes of Revision 38
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Fri Nov 3 13:41:27 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.84
6
+
7
+-------------------------------------------------------------------
8
Mon Oct 23 15:00:54 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.83
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.83
6
+Version: 0.3.84
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.83.tar.gz/NEWS -> pipewire-0.3.84.tar.gz/NEWS
Changed
76
1
2
+# PipeWire 0.3.84 (2023-11-02)
3
+
4
+This is the fourth 1.0 release candidate that is API and ABI compatible
5
+with previous 0.3.x releases.
6
+
7
+## Highlights
8
+ - Fix a regression with openal because the queued buffers in the stream
9
+ were not reported correctly.
10
+ - Fix a bug in port busy counters that could cause random silent links.
11
+ - Fix a regression in echo-cancel because it was not reporting its
12
+ streams as ASYNC.
13
+ - Fix a JACK regression where not all ports were enumerated in all cases.
14
+ - Many more fixes and improvements.
15
+
16
+
17
+## PipeWire
18
+ - pw_stream now reports the queued buffers more accurately. This fixes
19
+ a regression when using openal. (#3592)
20
+ - The port busy counters were not updated correctly in some cases. This
21
+ could lead to negotiation errors and silent links. (#3547)
22
+ - Ignore latency maximum when forcing rate/quantum. (#3613)
23
+ - Nodes can now be added to multiple groups and link-groups. (#3612)
24
+
25
+## Modules
26
+ - The filter-chain now also handles notify port dependencies
27
+ correctly. (#3596)
28
+ - Filter-chain has support for new linear, clamp, recip, exp, log, mult,
29
+ sine builtin plugins.
30
+ - The echo-cancel module now correctly reports its playback and capture
31
+ streams as ASYNC to avoid running out of buffers. (#3593)
32
+ - It is now possible to specify an array of remote names to connect to
33
+ with the native protocol.
34
+ - module-rtp-sap and module-rtp-sink now try to bind to the specified
35
+ interface.
36
+
37
+## SPA
38
+ - The alsa plugin now removes the runtime properties such as period-num,
39
+ period-size and max-latency when suspended. (#3613)
40
+
41
+## Bluetooth
42
+ - BAP Locations/Context is now set on endpoints as required by new bluez.
43
+ - Improve selection of BAP leader.
44
+
45
+## JACK
46
+ - Add a jack_set_sample_rate() extension function.
47
+ - Make sure we get the info of all nodes/ports before completing the
48
+ jack_client_open() operation so that we can enumerate the ports
49
+ correctly in all cases. (#3618)
50
+
51
+## GStreamer
52
+ - Fix types of metadata in pipewiresink.
53
+ - Also copy metadata in buffers in all cases.
54
+ - Fix size allocation in bufferpool for compressed formats.
55
+ - Don't stop streaming thread when unlinked. (#3620)
56
+
57
+## ALSA
58
+ - The ALSA plugin now handles NULL values from mmap_areas. (#3600)
59
+
60
+Older versions:
61
+
62
+
63
# PipeWire 0.3.83 (2023-10-19)
64
65
This is the third 1.0 release candidate that is API and ABI compatible
66
67
(#3585)
68
- Potentially fix silent export in ardour in some cases. (#3514)
69
70
-Older versions:
71
-
72
-
73
# PipeWire 0.3.82 (2023-10-13)
74
75
This is the second 1.0 release candidate that is API and ABI compatible
76
pipewire-0.3.83.tar.gz/meson.build -> pipewire-0.3.84.tar.gz/meson.build
Changed
8
1
2
project('pipewire', 'c' ,
3
- version : '0.3.83',
4
+ version : '0.3.84',
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.83.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.84.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
38
1
2
xfer = nframes;
3
if (xfer > 0) {
4
const snd_pcm_channel_area_t *areas = snd_pcm_ioplug_mmap_areas(io);
5
- const snd_pcm_uframes_t offset = hw_ptr % io->buffer_size;
6
-
7
- if (io->stream == SND_PCM_STREAM_PLAYBACK)
8
- snd_pcm_areas_copy_wrap(pwareas, 0, nframes,
9
- areas, offset,
10
- io->buffer_size,
11
- io->channels, xfer,
12
- io->format);
13
- else
14
- snd_pcm_areas_copy_wrap(areas, offset,
15
- io->buffer_size,
16
- pwareas, 0, nframes,
17
- io->channels, xfer,
18
- io->format);
19
-
20
+ if (areas != NULL) {
21
+ const snd_pcm_uframes_t offset = hw_ptr % io->buffer_size;
22
+ if (io->stream == SND_PCM_STREAM_PLAYBACK)
23
+ snd_pcm_areas_copy_wrap(pwareas, 0, nframes,
24
+ areas, offset,
25
+ io->buffer_size,
26
+ io->channels, xfer,
27
+ io->format);
28
+ else
29
+ snd_pcm_areas_copy_wrap(areas, offset,
30
+ io->buffer_size,
31
+ pwareas, 0, nframes,
32
+ io->channels, xfer,
33
+ io->format);
34
+ }
35
hw_ptr += xfer;
36
if (hw_ptr >= pw->boundary)
37
hw_ptr -= pw->boundary;
38
pipewire-0.3.83.tar.gz/pipewire-jack/src/pipewire-jack-extensions.h -> pipewire-0.3.84.tar.gz/pipewire-jack/src/pipewire-jack-extensions.h
Changed
10
1
2
3
int jack_get_video_image_size(jack_client_t *client, jack_image_size_t *size);
4
5
+int jack_set_sample_rate (jack_client_t *client, jack_nframes_t nframes);
6
+
7
#ifdef __cplusplus
8
}
9
#endif
10
pipewire-0.3.83.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.84.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
201
1
2
int rt_max;
3
unsigned int fix_midi_events:1;
4
unsigned int global_buffer_size:1;
5
+ unsigned int global_sample_rate:1;
6
unsigned int passive_links:1;
7
unsigned int graph_callback_pending:1;
8
unsigned int pending_callbacks:1;
9
10
static void prepare_output(struct port *p, uint32_t frames)
11
{
12
struct mix *mix;
13
+ struct spa_io_buffers *io;
14
15
if (SPA_UNLIKELY(p->empty_out || p->tied))
16
process_empty(p, frames);
17
18
+ if (p->global_mix == NULL || (io = p->global_mix->io) == NULL)
19
+ return;
20
+
21
spa_list_for_each(mix, &p->mix, port_link) {
22
if (SPA_LIKELY(mix->io != NULL))
23
- *mix->io = p->io;
24
+ *mix->io = *io;
25
}
26
}
27
28
29
struct client *c = (struct client *) data;
30
struct object *o, *ot, *op;
31
const char *str;
32
- bool do_emit = true;
33
+ bool do_emit = true, do_sync = false;
34
uint32_t serial;
35
36
if (props == NULL)
37
38
&o->proxy_listener, &proxy_events, o);
39
pw_proxy_add_object_listener(o->proxy,
40
&o->object_listener, &node_events, o);
41
+ do_sync = true;
42
}
43
}
44
pthread_mutex_lock(&c->context.lock);
45
46
47
pw_port_subscribe_params((struct pw_port*)o->proxy,
48
ids, 1);
49
+ do_sync = true;
50
}
51
pthread_mutex_lock(&c->context.lock);
52
spa_list_append(&c->context.objects, &o->link);
53
54
pw_metadata_add_listener(proxy,
55
&c->metadata->listener,
56
&metadata_events, c);
57
+ do_sync = true;
58
} else if (spa_streq(str, "settings")) {
59
proxy = pw_registry_bind(c->registry,
60
id, type, PW_VERSION_METADATA, sizeof(struct metadata));
61
62
pw_proxy_add_listener(proxy,
63
&c->settings->proxy_listener,
64
&settings_proxy_events, c);
65
+ do_sync = true;
66
}
67
goto exit;
68
}
69
70
}
71
72
exit:
73
+ if (do_sync)
74
+ c->pending_sync = pw_proxy_sync((struct pw_proxy*)c->core,
75
+ c->pending_sync);
76
return;
77
exit_free:
78
free_object(c, o);
79
80
client->default_as_system = pw_properties_get_bool(client->props, "jack.default-as-system", false);
81
client->fix_midi_events = pw_properties_get_bool(client->props, "jack.fix-midi-events", true);
82
client->global_buffer_size = pw_properties_get_bool(client->props, "jack.global-buffer-size", false);
83
+ client->global_sample_rate = pw_properties_get_bool(client->props, "jack.global-sample-rate", false);
84
client->max_ports = pw_properties_get_uint32(client->props, "jack.max-client-ports", MAX_CLIENT_PORTS);
85
client->fill_aliases = pw_properties_get_bool(client->props, "jack.fill-aliases", false);
86
client->writable_input = pw_properties_get_bool(client->props, "jack.writable-input", true);
87
88
if (status)
89
*status = 0;
90
91
+ client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync);
92
+
93
while (true) {
94
pw_thread_loop_wait(client->context.loop);
95
96
if (client->last_res < 0)
97
goto init_failed;
98
99
- if (client->has_transport)
100
+ if (client->pending_sync == client->last_sync)
101
break;
102
}
103
104
105
}
106
107
SPA_EXPORT
108
+int jack_set_sample_rate (jack_client_t *client, jack_nframes_t nframes)
109
+{
110
+ struct client *c = (struct client *) client;
111
+
112
+ return_val_if_fail(c != NULL, -EINVAL);
113
+
114
+ pw_log_info("%p: sample-size %u", client, nframes);
115
+
116
+ pw_thread_loop_lock(c->context.loop);
117
+ if (c->global_sample_rate && c->settings && c->settings->proxy) {
118
+ char val256;
119
+ snprintf(val, sizeof(val), "%u", nframes);
120
+ pw_metadata_set_property(c->settings->proxy, 0,
121
+ "clock.force-rate", "", val);
122
+ } else {
123
+ pw_properties_setf(c->props, PW_KEY_NODE_FORCE_RATE, "%u", nframes);
124
+
125
+ c->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
126
+ c->info.props = &c->props->dict;
127
+
128
+ pw_client_node_update(c->node,
129
+ PW_CLIENT_NODE_UPDATE_INFO,
130
+ 0, NULL, &c->info);
131
+ c->info.change_mask = 0;
132
+ }
133
+ pw_thread_loop_unlock(c->context.loop);
134
+
135
+ return 0;
136
+}
137
+
138
+SPA_EXPORT
139
jack_nframes_t jack_get_sample_rate (jack_client_t *client)
140
{
141
struct client *c = (struct client *) client;
142
143
return &mix->buffersio->buffer_id;
144
}
145
146
+static inline void *get_buffer_data(struct buffer *b, jack_nframes_t frames)
147
+{
148
+ struct spa_data *d;
149
+ uint32_t offset, size;
150
+
151
+ d = &b->datas0;
152
+ offset = SPA_MIN(d->chunk->offset, d->maxsize);
153
+ size = SPA_MIN(d->chunk->size, d->maxsize - offset);
154
+ if (size / sizeof(float) < frames)
155
+ return NULL;
156
+ return SPA_PTROFF(d->data, offset, void);
157
+}
158
+
159
static void *get_buffer_input_float(struct port *p, jack_nframes_t frames)
160
{
161
struct mix *mix;
162
163
bool ptr_aligned = true;
164
165
spa_list_for_each(mix, &p->mix, port_link) {
166
- struct spa_data *d;
167
- uint32_t offset, size;
168
+ if (mix->id == SPA_ID_INVALID)
169
+ continue;
170
171
pw_log_trace_fp("%p: port %s mix %d.%d get buffer %d",
172
p->client, p->object->port.name, p->port_id, mix->id, frames);
173
174
if ((b = get_mix_buffer(mix, frames)) == NULL)
175
continue;
176
177
- d = &b->datas0;
178
- offset = SPA_MIN(d->chunk->offset, d->maxsize);
179
- size = SPA_MIN(d->chunk->size, d->maxsize - offset);
180
- if (size / sizeof(float) < frames)
181
+ if ((np = get_buffer_data(b, frames)) == NULL)
182
continue;
183
184
- np = SPA_PTROFF(d->data, offset, float);
185
if (!SPA_IS_ALIGNED(np, 16))
186
ptr_aligned = false;
187
188
189
struct buffer *b;
190
void *pod;
191
192
+ if (mix->id == SPA_ID_INVALID)
193
+ continue;
194
+
195
pw_log_trace_fp("%p: port %p mix %d.%d get buffer %d",
196
p->client, p, p->port_id, mix->id, frames);
197
198
199
if ((p = o->port.port) == NULL) {
200
struct mix *mix;
201
pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
13
1
2
itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", nperiods);
3
snprintf(headroom, sizeof(headroom), "%u", this->headroom);
4
itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", headroom);
5
+ } else {
6
+ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, NULL);
7
+ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", NULL);
8
+ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", NULL);
9
+ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", NULL);
10
}
11
this->info.props = &SPA_DICT_INIT(items, n_items);
12
13
pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
13
1
2
itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", nperiods);
3
snprintf(headroom, sizeof(headroom), "%u", this->headroom);
4
itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", headroom);
5
+ } else {
6
+ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, NULL);
7
+ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", NULL);
8
+ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", NULL);
9
+ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", NULL);
10
}
11
this->info.props = &SPA_DICT_INIT(items, n_items);
12
13
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bap-codec-caps.h -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bap-codec-caps.h
Changed
88
1
2
#define LC3_CONFIG_DURATION_7_5 0x00
3
#define LC3_CONFIG_DURATION_10 0x01
4
5
-#define LC3_CONFIG_CHNL_NOT_ALLOWED 0x00000000
6
-#define LC3_CONFIG_CHNL_FL 0x00000001 /* front left */
7
-#define LC3_CONFIG_CHNL_FR 0x00000002 /* front right */
8
-#define LC3_CONFIG_CHNL_FC 0x00000004 /* front center */
9
-#define LC3_CONFIG_CHNL_LFE 0x00000008 /* LFE */
10
-#define LC3_CONFIG_CHNL_BL 0x00000010 /* back left */
11
-#define LC3_CONFIG_CHNL_BR 0x00000020 /* back right */
12
-#define LC3_CONFIG_CHNL_FLC 0x00000040 /* front left center */
13
-#define LC3_CONFIG_CHNL_FRC 0x00000080 /* front right center */
14
-#define LC3_CONFIG_CHNL_BC 0x00000100 /* back center */
15
-#define LC3_CONFIG_CHNL_LFE2 0x00000200 /* LFE 2 */
16
-#define LC3_CONFIG_CHNL_SL 0x00000400 /* side left */
17
-#define LC3_CONFIG_CHNL_SR 0x00000800 /* side right */
18
-#define LC3_CONFIG_CHNL_TFL 0x00001000 /* top front left */
19
-#define LC3_CONFIG_CHNL_TFR 0x00002000 /* top front right */
20
-#define LC3_CONFIG_CHNL_TFC 0x00004000 /* top front center */
21
-#define LC3_CONFIG_CHNL_TC 0x00008000 /* top center */
22
-#define LC3_CONFIG_CHNL_TBL 0x00010000 /* top back left */
23
-#define LC3_CONFIG_CHNL_TBR 0x00020000 /* top back right */
24
-#define LC3_CONFIG_CHNL_TSL 0x00040000 /* top side left */
25
-#define LC3_CONFIG_CHNL_TSR 0x00080000 /* top side right */
26
-#define LC3_CONFIG_CHNL_TBC 0x00100000 /* top back center */
27
-#define LC3_CONFIG_CHNL_BFC 0x00200000 /* bottom front center */
28
-#define LC3_CONFIG_CHNL_BFL 0x00400000 /* bottom front left */
29
-#define LC3_CONFIG_CHNL_BFR 0x00800000 /* bottom front right */
30
-#define LC3_CONFIG_CHNL_FLW 0x01000000 /* front left wide */
31
-#define LC3_CONFIG_CHNL_FRW 0x02000000 /* front right wide */
32
-#define LC3_CONFIG_CHNL_LS 0x04000000 /* left surround */
33
-#define LC3_CONFIG_CHNL_RS 0x08000000 /* right surround */
34
-
35
#define LC3_MAX_CHANNELS 28
36
37
+#define BAP_CHANNEL_NOT_ALLOWED 0x00000000
38
+#define BAP_CHANNEL_FL 0x00000001 /* front left */
39
+#define BAP_CHANNEL_FR 0x00000002 /* front right */
40
+#define BAP_CHANNEL_FC 0x00000004 /* front center */
41
+#define BAP_CHANNEL_LFE 0x00000008 /* LFE */
42
+#define BAP_CHANNEL_BL 0x00000010 /* back left */
43
+#define BAP_CHANNEL_BR 0x00000020 /* back right */
44
+#define BAP_CHANNEL_FLC 0x00000040 /* front left center */
45
+#define BAP_CHANNEL_FRC 0x00000080 /* front right center */
46
+#define BAP_CHANNEL_BC 0x00000100 /* back center */
47
+#define BAP_CHANNEL_LFE2 0x00000200 /* LFE 2 */
48
+#define BAP_CHANNEL_SL 0x00000400 /* side left */
49
+#define BAP_CHANNEL_SR 0x00000800 /* side right */
50
+#define BAP_CHANNEL_TFL 0x00001000 /* top front left */
51
+#define BAP_CHANNEL_TFR 0x00002000 /* top front right */
52
+#define BAP_CHANNEL_TFC 0x00004000 /* top front center */
53
+#define BAP_CHANNEL_TC 0x00008000 /* top center */
54
+#define BAP_CHANNEL_TBL 0x00010000 /* top back left */
55
+#define BAP_CHANNEL_TBR 0x00020000 /* top back right */
56
+#define BAP_CHANNEL_TSL 0x00040000 /* top side left */
57
+#define BAP_CHANNEL_TSR 0x00080000 /* top side right */
58
+#define BAP_CHANNEL_TBC 0x00100000 /* top back center */
59
+#define BAP_CHANNEL_BFC 0x00200000 /* bottom front center */
60
+#define BAP_CHANNEL_BFL 0x00400000 /* bottom front left */
61
+#define BAP_CHANNEL_BFR 0x00800000 /* bottom front right */
62
+#define BAP_CHANNEL_FLW 0x01000000 /* front left wide */
63
+#define BAP_CHANNEL_FRW 0x02000000 /* front right wide */
64
+#define BAP_CHANNEL_LS 0x04000000 /* left surround */
65
+#define BAP_CHANNEL_RS 0x08000000 /* right surround */
66
+
67
+#define BAP_CHANNEL_ALL 0x0fffffff /* mask of all */
68
+
69
+#define BAP_CONTEXT_PROHIBITED 0x0000 /* Prohibited */
70
+#define BAP_CONTEXT_UNSPECIFIED 0x0001 /* Unspecified */
71
+#define BAP_CONTEXT_CONVERSATIONAL 0x0002 /* Telephony, video calls, ... */
72
+#define BAP_CONTEXT_MEDIA 0x0004 /* Music, radio, podcast, movie soundtrack, TV */
73
+#define BAP_CONTEXT_GAME 0x0008 /* Gaming media, game effects, music, in-game voice chat */
74
+#define BAP_CONTEXT_INSTRUCTIONAL 0x0010 /* Instructional audio, navigation, announcements, user guidance */
75
+#define BAP_CONTEXT_VOICE 0x0020 /* Man-machine communication, voice recognition, virtual assistants */
76
+#define BAP_CONTEXT_LIVE 0x0040 /* Live audio, perceived both via direct acoustic path and via BAP */
77
+#define BAP_CONTEXT_SOUND_EFFECTS 0x0080 /* Keyboard and touch feedback, menu, UI, other system sounds */
78
+#define BAP_CONTEXT_NOTIFICATIONS 0x0100 /* Attention-seeking, message arrival, reminders */
79
+#define BAP_CONTEXT_RINGTONE 0x0200 /* Incoming call alert audio */
80
+#define BAP_CONTEXT_ALERTS 0x0400 /* Alarms and timers, critical battery, alarm clock, toaster */
81
+#define BAP_CONTEXT_EMERGENCY 0x0800 /* Fire alarm, other urgent alerts */
82
+
83
+#define BAP_CONTEXT_ALL 0x0fff
84
+
85
#define BT_ISO_QOS_CIG_UNSET 0xff
86
#define BT_ISO_QOS_CIS_UNSET 0xff
87
88
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c
Changed
64
1
2
uint32_t bit;
3
enum spa_audio_channel channel;
4
} channel_bits = {
5
- { LC3_CONFIG_CHNL_FL, SPA_AUDIO_CHANNEL_FL },
6
- { LC3_CONFIG_CHNL_FR, SPA_AUDIO_CHANNEL_FR },
7
- { LC3_CONFIG_CHNL_FC, SPA_AUDIO_CHANNEL_FC },
8
- { LC3_CONFIG_CHNL_LFE, SPA_AUDIO_CHANNEL_LFE },
9
- { LC3_CONFIG_CHNL_BL, SPA_AUDIO_CHANNEL_RL },
10
- { LC3_CONFIG_CHNL_BR, SPA_AUDIO_CHANNEL_RR },
11
- { LC3_CONFIG_CHNL_FLC, SPA_AUDIO_CHANNEL_FLC },
12
- { LC3_CONFIG_CHNL_FRC, SPA_AUDIO_CHANNEL_FRC },
13
- { LC3_CONFIG_CHNL_BC, SPA_AUDIO_CHANNEL_BC },
14
- { LC3_CONFIG_CHNL_LFE2, SPA_AUDIO_CHANNEL_LFE2 },
15
- { LC3_CONFIG_CHNL_SL, SPA_AUDIO_CHANNEL_SL },
16
- { LC3_CONFIG_CHNL_SR, SPA_AUDIO_CHANNEL_SR },
17
- { LC3_CONFIG_CHNL_TFL, SPA_AUDIO_CHANNEL_TFL },
18
- { LC3_CONFIG_CHNL_TFR, SPA_AUDIO_CHANNEL_TFR },
19
- { LC3_CONFIG_CHNL_TFC, SPA_AUDIO_CHANNEL_TFC },
20
- { LC3_CONFIG_CHNL_TC, SPA_AUDIO_CHANNEL_TC },
21
- { LC3_CONFIG_CHNL_TBL, SPA_AUDIO_CHANNEL_TRL },
22
- { LC3_CONFIG_CHNL_TBR, SPA_AUDIO_CHANNEL_TRR },
23
- { LC3_CONFIG_CHNL_TSL, SPA_AUDIO_CHANNEL_TSL },
24
- { LC3_CONFIG_CHNL_TSR, SPA_AUDIO_CHANNEL_TSR },
25
- { LC3_CONFIG_CHNL_TBC, SPA_AUDIO_CHANNEL_TRC },
26
- { LC3_CONFIG_CHNL_BFC, SPA_AUDIO_CHANNEL_BC },
27
- { LC3_CONFIG_CHNL_BFL, SPA_AUDIO_CHANNEL_BLC },
28
- { LC3_CONFIG_CHNL_BFR, SPA_AUDIO_CHANNEL_BRC },
29
- { LC3_CONFIG_CHNL_FLW, SPA_AUDIO_CHANNEL_FLW },
30
- { LC3_CONFIG_CHNL_FRW, SPA_AUDIO_CHANNEL_FRW },
31
- { LC3_CONFIG_CHNL_LS, SPA_AUDIO_CHANNEL_SL }, /* is it the right mapping? */
32
- { LC3_CONFIG_CHNL_RS, SPA_AUDIO_CHANNEL_SR }, /* is it the right mapping? */
33
+ { BAP_CHANNEL_FL, SPA_AUDIO_CHANNEL_FL },
34
+ { BAP_CHANNEL_FR, SPA_AUDIO_CHANNEL_FR },
35
+ { BAP_CHANNEL_FC, SPA_AUDIO_CHANNEL_FC },
36
+ { BAP_CHANNEL_LFE, SPA_AUDIO_CHANNEL_LFE },
37
+ { BAP_CHANNEL_BL, SPA_AUDIO_CHANNEL_RL },
38
+ { BAP_CHANNEL_BR, SPA_AUDIO_CHANNEL_RR },
39
+ { BAP_CHANNEL_FLC, SPA_AUDIO_CHANNEL_FLC },
40
+ { BAP_CHANNEL_FRC, SPA_AUDIO_CHANNEL_FRC },
41
+ { BAP_CHANNEL_BC, SPA_AUDIO_CHANNEL_BC },
42
+ { BAP_CHANNEL_LFE2, SPA_AUDIO_CHANNEL_LFE2 },
43
+ { BAP_CHANNEL_SL, SPA_AUDIO_CHANNEL_SL },
44
+ { BAP_CHANNEL_SR, SPA_AUDIO_CHANNEL_SR },
45
+ { BAP_CHANNEL_TFL, SPA_AUDIO_CHANNEL_TFL },
46
+ { BAP_CHANNEL_TFR, SPA_AUDIO_CHANNEL_TFR },
47
+ { BAP_CHANNEL_TFC, SPA_AUDIO_CHANNEL_TFC },
48
+ { BAP_CHANNEL_TC, SPA_AUDIO_CHANNEL_TC },
49
+ { BAP_CHANNEL_TBL, SPA_AUDIO_CHANNEL_TRL },
50
+ { BAP_CHANNEL_TBR, SPA_AUDIO_CHANNEL_TRR },
51
+ { BAP_CHANNEL_TSL, SPA_AUDIO_CHANNEL_TSL },
52
+ { BAP_CHANNEL_TSR, SPA_AUDIO_CHANNEL_TSR },
53
+ { BAP_CHANNEL_TBC, SPA_AUDIO_CHANNEL_TRC },
54
+ { BAP_CHANNEL_BFC, SPA_AUDIO_CHANNEL_BC },
55
+ { BAP_CHANNEL_BFL, SPA_AUDIO_CHANNEL_BLC },
56
+ { BAP_CHANNEL_BFR, SPA_AUDIO_CHANNEL_BRC },
57
+ { BAP_CHANNEL_FLW, SPA_AUDIO_CHANNEL_FLW },
58
+ { BAP_CHANNEL_FRW, SPA_AUDIO_CHANNEL_FRW },
59
+ { BAP_CHANNEL_LS, SPA_AUDIO_CHANNEL_SL }, /* is it the right mapping? */
60
+ { BAP_CHANNEL_RS, SPA_AUDIO_CHANNEL_SR }, /* is it the right mapping? */
61
};
62
63
static int write_ltv(uint8_t *dest, uint8_t type, void* value, size_t len)
64
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
103
1
2
#include "dbus-helpers.h"
3
#include "player.h"
4
#include "iso-io.h"
5
+#include "bap-codec-caps.h"
6
#include "defs.h"
7
8
static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5");
9
10
11
static bool device_set_update_leader(struct spa_bt_set_membership *set)
12
{
13
- struct spa_bt_set_membership *s, *leader;
14
- int min_rank = INT_MAX;
15
- int leader_rank = INT_MAX;
16
-
17
- leader = NULL;
18
+ struct spa_bt_set_membership *s, *leader = NULL;
19
20
+ /* Make minimum rank device the leader, so that device set nodes always
21
+ * appear under a specific device.
22
+ */
23
spa_bt_for_each_set_member(s, set) {
24
if (!(s->device->connected_profiles & SPA_BT_PROFILE_BAP_DUPLEX))
25
continue;
26
- min_rank = SPA_MIN(min_rank, s->rank);
27
- if (s->leader) {
28
- leader_rank = s->rank;
29
+
30
+ if (leader == NULL || s->rank < leader->rank ||
31
+ (s->rank == leader->rank && s->leader))
32
leader = s;
33
- }
34
}
35
36
- if (min_rank >= leader_rank && leader)
37
+ if (leader == NULL || (leader && leader->leader))
38
return false;
39
40
- spa_bt_for_each_set_member(s, set) {
41
- if (leader == NULL && s->rank == min_rank &&
42
- (s->device->connected_profiles & SPA_BT_PROFILE_BAP_DUPLEX)) {
43
- s->leader = true;
44
- leader = s;
45
- } else {
46
- s->leader = false;
47
- }
48
- }
49
+ spa_bt_for_each_set_member(s, set)
50
+ s->leader = false;
51
52
- if (leader) {
53
- struct spa_bt_monitor *monitor = leader->device->monitor;
54
+ leader->leader = true;
55
56
- spa_log_debug(monitor->log, "device set %s: leader is %s",
57
- leader->path, leader->device->path);
58
- }
59
+ spa_log_debug(leader->device->monitor->log,
60
+ "device set %p %s: leader is %s",
61
+ set, leader->path, leader->device->path);
62
63
return true;
64
}
65
66
{
67
const char *interface_name = BLUEZ_MEDIA_ENDPOINT_INTERFACE;
68
DBusMessageIter object, array, entry, dict;
69
- dbus_bool_t delay_reporting;
70
71
dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &object);
72
dbus_message_iter_append_basic(&object, DBUS_TYPE_OBJECT_PATH, &endpoint);
73
74
append_basic_variant_dict_entry(&dict, "UUID", DBUS_TYPE_STRING, "s", &uuid);
75
append_basic_variant_dict_entry(&dict, "Codec", DBUS_TYPE_BYTE, "y", &codec_id);
76
append_basic_array_variant_dict_entry(&dict, "Capabilities", "ay", "y", DBUS_TYPE_BYTE, caps, caps_size);
77
+
78
if (spa_bt_profile_from_uuid(uuid) & SPA_BT_PROFILE_A2DP_SOURCE) {
79
- delay_reporting = TRUE;
80
+ dbus_bool_t delay_reporting = TRUE;
81
+
82
append_basic_variant_dict_entry(&dict, "DelayReporting", DBUS_TYPE_BOOLEAN, "b", &delay_reporting);
83
}
84
+ if (spa_bt_profile_from_uuid(uuid) & (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE)) {
85
+ dbus_uint32_t locations;
86
+ dbus_uint16_t supported_context, context;
87
+
88
+ locations = BAP_CHANNEL_ALL;
89
+ if (spa_bt_profile_from_uuid(uuid) & SPA_BT_PROFILE_BAP_SINK) {
90
+ supported_context = context = BAP_CONTEXT_ALL;
91
+ } else {
92
+ supported_context = context = (BAP_CONTEXT_UNSPECIFIED | BAP_CONTEXT_CONVERSATIONAL |
93
+ BAP_CONTEXT_MEDIA | BAP_CONTEXT_GAME);
94
+ }
95
+
96
+ append_basic_variant_dict_entry(&dict, "Locations", DBUS_TYPE_UINT32, "u", &locations);
97
+ append_basic_variant_dict_entry(&dict, "Context", DBUS_TYPE_UINT16, "q", &context);
98
+ append_basic_variant_dict_entry(&dict, "SupportedContext", DBUS_TYPE_UINT16, "q", &supported_context);
99
+ }
100
101
dbus_message_iter_close_container(&entry, &dict);
102
dbus_message_iter_close_container(&array, &entry);
103
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
40
1
2
char transport32, str_id32, object_path512;
3
bool is_dyn_node = SPA_FLAG_IS_SET(id, DYNAMIC_NODE_ID_FLAG);
4
5
- spa_log_debug(this->log, "node, transport:%p id:%08x factory:%s", t, id, factory_name);
6
+ spa_log_debug(this->log, "%p: node, transport:%p id:%08x factory:%s", this, t, id, factory_name);
7
8
snprintf(transport, sizeof(transport), "pointer:%p", t);
9
items0 = SPA_DICT_ITEM_INIT(SPA_KEY_API_BLUEZ5_TRANSPORT, transport);
10
11
static void emit_dynamic_node(struct dynamic_node *this, struct impl *impl,
12
struct spa_bt_transport *t, uint32_t id, const char *factory_name, bool a2dp_duplex)
13
{
14
- spa_log_debug(impl->log, "dynamic node, transport: %p->%p id: %08x->%08x",
15
- this->transport, t, this->id, id);
16
+ spa_log_debug(impl->log, "%p: dynamic node, transport: %p->%p id: %08x->%08x",
17
+ this, this->transport, t, this->id, id);
18
19
if (this->transport) {
20
/* Session manager don't really handles transport ptr changing. */
21
22
continue;
23
}
24
25
+ spa_log_debug(this->log, "%p: %s belongs to set %s leader:%d", this,
26
+ device->path, set->path, set->leader);
27
+
28
dset->path = strdup(set->path);
29
dset->leader = set->leader;
30
break;
31
32
33
static void emit_remove_nodes(struct impl *this)
34
{
35
- spa_log_debug(this->log, "remove nodes");
36
+ spa_log_debug(this->log, "%p: remove nodes", this);
37
38
remove_dynamic_node (&this->dyn_media_source);
39
remove_dynamic_node (&this->dyn_media_sink);
40
pipewire-0.3.83.tar.gz/spa/plugins/videotestsrc/videotestsrc.c -> pipewire-0.3.84.tar.gz/spa/plugins/videotestsrc/videotestsrc.c
Changed
36
1
2
struct spa_param_info params2;
3
struct props props;
4
5
+ struct spa_io_clock *clock;
6
+ struct spa_io_position *position;
7
+
8
struct spa_hook_list hooks;
9
struct spa_callbacks callbacks;
10
11
12
13
static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
14
{
15
- return -ENOTSUP;
16
+ struct impl *this = object;
17
+
18
+ spa_return_val_if_fail(this != NULL, -EINVAL);
19
+
20
+ switch (id) {
21
+ case SPA_IO_Clock:
22
+ if (size > 0 && size < sizeof(struct spa_io_clock))
23
+ return -EINVAL;
24
+ this->clock = data;
25
+ break;
26
+ case SPA_IO_Position:
27
+ this->position = data;
28
+ break;
29
+ default:
30
+ return -ENOENT;
31
+ }
32
+ return 0;
33
}
34
35
static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
36
pipewire-0.3.83.tar.gz/src/daemon/minimal.conf.in -> pipewire-0.3.84.tar.gz/src/daemon/minimal.conf.in
Changed
10
1
2
# Creates an object from a PipeWire factory with the given parameters.
3
# If nofail is given, errors are ignored (and no object is created).
4
#
5
- #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
6
+ #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } }
7
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = nofail }
8
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
9
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
10
pipewire-0.3.83.tar.gz/src/daemon/pipewire-vulkan.conf.in -> pipewire-0.3.84.tar.gz/src/daemon/pipewire-vulkan.conf.in
Changed
15
1
2
# If condition is given, the object is created only when the context properties
3
# all match the match rules.
4
#
5
- #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
6
+ #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } }
7
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = nofail }
8
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
9
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
10
- #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } }
11
+ #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } }
12
{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = vulkan-compute-source object.export = true } }
13
{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.filter node.name = vulkan-compute-filter object.export = true } }
14
15
pipewire-0.3.83.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.84.tar.gz/src/daemon/pipewire.conf.in
Changed
19
1
2
condition = { module.x11.bell = true }
3
}
4
{ name = libpipewire-module-jackdbus-detect
5
- args {
6
+ args = {
7
#jack.library = libjack.so.0
8
#jack.server = null
9
#jack.client-name = PipeWire
10
11
# If condition is given, the object is created only when the context properties
12
# all match the match rules.
13
#
14
- #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
15
+ #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } }
16
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = nofail }
17
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
18
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
19
pipewire-0.3.83.tar.gz/src/examples/bluez-session.c -> pipewire-0.3.84.tar.gz/src/examples/bluez-session.c
Changed
38
1
2
struct spa_hook listener;
3
4
struct spa_list device_list;
5
+ struct pw_properties *props;
6
};
7
8
static struct node *find_node(struct object *obj, uint32_t id)
9
10
spa_list_remove(&obj->link);
11
spa_hook_remove(&obj->listener);
12
pw_proxy_destroy(obj->proxy);
13
- free(obj->handle);
14
+ pw_unload_spa_handle(obj->handle);
15
free(obj);
16
}
17
18
19
int res;
20
void *iface;
21
22
- handle = pw_context_load_spa_handle(impl->context, SPA_NAME_API_BLUEZ5_ENUM_DBUS, NULL);
23
+ handle = pw_context_load_spa_handle(impl->context, SPA_NAME_API_BLUEZ5_ENUM_DBUS, &impl->props->dict);
24
if (handle == NULL) {
25
res = -errno;
26
goto out;
27
28
return -1;
29
}
30
31
+ if ((impl.props = pw_properties_new(NULL, NULL)) == NULL) {
32
+ return -1;
33
+ }
34
+
35
pw_core_add_listener(impl.core,
36
&impl.core_listener,
37
&core_events, &impl);
38
pipewire-0.3.83.tar.gz/src/gst/gstpipewirepool.c -> pipewire-0.3.84.tar.gz/src/gst/gstpipewirepool.c
Changed
13
1
2
p->add_metavideo = has_video && gst_buffer_pool_config_has_option (config,
3
GST_BUFFER_POOL_OPTION_VIDEO_META);
4
5
- gst_buffer_pool_config_set_params (config, caps, p->video_info.size, min_buffers, max_buffers);
6
+ if (p->video_info.size != 0)
7
+ size = p->video_info.size;
8
+
9
+ gst_buffer_pool_config_set_params (config, caps, size, min_buffers, max_buffers);
10
11
return GST_BUFFER_POOL_CLASS (gst_pipewire_pool_parent_class)->set_config (pool, config);
12
}
13
pipewire-0.3.83.tar.gz/src/gst/gstpipewiresink.c -> pipewire-0.3.84.tar.gz/src/gst/gstpipewiresink.c
Changed
49
1
2
3
port_params1 = spa_pod_builder_add_object (&b,
4
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
5
- SPA_PARAM_META_type, SPA_POD_Int(SPA_META_Header),
6
+ SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
7
SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_header)));
8
9
port_params2 = spa_pod_builder_add_object (&b,
10
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
11
- SPA_PARAM_META_type, SPA_POD_Int(SPA_META_VideoCrop),
12
+ SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoCrop),
13
SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_region)));
14
15
pw_thread_loop_lock (sink->core->loop);
16
17
goto start_error;
18
19
if (state == PW_STREAM_STATE_UNCONNECTED) {
20
- enum pw_stream_flags flags = 0;
21
+ enum pw_stream_flags flags;
22
uint32_t target_id;
23
24
+ flags = PW_STREAM_FLAG_ASYNC;
25
if (pwsink->mode != GST_PIPEWIRE_SINK_MODE_PROVIDE)
26
flags |= PW_STREAM_FLAG_AUTOCONNECT;
27
else
28
29
config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pwsink->pool));
30
gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers);
31
32
- size = (size == 0) ? gst_buffer_get_size (buffer) : size;
33
+ if (size == 0) {
34
+ gsize maxsize;
35
+ gst_buffer_get_sizes (buffer, NULL, &maxsize);
36
+ size = maxsize;
37
+ }
38
39
gst_buffer_pool_config_set_params (config, caps, size, min_buffers, max_buffers);
40
gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pwsink->pool), config);
41
42
gst_buffer_extract (buffer, 0, info.data, info.maxsize);
43
gst_buffer_unmap (b, &info);
44
gst_buffer_resize (b, 0, gst_buffer_get_size (buffer));
45
+ gst_buffer_copy_into(b, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
46
buffer = b;
47
unref_buffer = TRUE;
48
49
pipewire-0.3.83.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.84.tar.gz/src/gst/gstpipewiresrc.c
Changed
21
1
2
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s, target-object %s",
3
pwsrc->path, pwsrc->target_object);
4
pwsrc->negotiated = FALSE;
5
- enum pw_stream_flags flags = PW_STREAM_FLAG_DONT_RECONNECT;
6
+ enum pw_stream_flags flags;
7
+ flags = PW_STREAM_FLAG_DONT_RECONNECT |
8
+ PW_STREAM_FLAG_ASYNC;
9
if (pwsrc->autoconnect)
10
flags |= PW_STREAM_FLAG_AUTOCONNECT;
11
pw_stream_connect (pwsrc->stream,
12
13
if (state == PW_STREAM_STATE_ERROR)
14
goto streaming_error;
15
16
- if (state != PW_STREAM_STATE_STREAMING)
17
+ if (state == PW_STREAM_STATE_UNCONNECTED)
18
goto streaming_stopped;
19
20
if ((caps = pwsrc->caps) != NULL) {
21
pipewire-0.3.83.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.84.tar.gz/src/modules/module-echo-cancel.c
Changed
21
1
2
PW_DIRECTION_OUTPUT,
3
PW_ID_ANY,
4
PW_STREAM_FLAG_MAP_BUFFERS |
5
- PW_STREAM_FLAG_RT_PROCESS,
6
+ PW_STREAM_FLAG_RT_PROCESS |
7
+ PW_STREAM_FLAG_ASYNC,
8
params, n_params)) < 0) {
9
spa_pod_dynamic_builder_clean(&b);
10
return res;
11
12
PW_ID_ANY,
13
PW_STREAM_FLAG_AUTOCONNECT |
14
PW_STREAM_FLAG_MAP_BUFFERS |
15
- PW_STREAM_FLAG_RT_PROCESS,
16
+ PW_STREAM_FLAG_RT_PROCESS |
17
+ PW_STREAM_FLAG_ASYNC,
18
params, n_params)) < 0) {
19
spa_pod_dynamic_builder_clean(&b);
20
return res;
21
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain.c
Changed
106
1
2
* - `bq_notch` a notch filter.
3
* - `bq_allpass` an allpass filter.
4
* - `bq_raw` a raw biquad filter. You need a config section to specify coefficients
5
- * per sample rate. The coefficients of the sample rate closest to the
6
- * graph rate are selected:
7
+ * per sample rate. The coefficients of the sample rate closest to the
8
+ * graph rate are selected:
9
*
10
*\code{.unparsed}
11
* filter.graph = {
12
13
*
14
* It has an input port "In" and an output port "Out".
15
*
16
+ * ### Clamp
17
+ *
18
+ * The clamp plugin can be used to clamp samples between min and max values.
19
+ *
20
+ * It has an input port "In" and an output port "Out". It also has a "Control"
21
+ * and "Notify" port for the control values.
22
+ *
23
+ * The final result is clamped to the "Min" and "Max" control values.
24
+ *
25
+ * ### Linear
26
+ *
27
+ * The linear plugin can be used to apply a linear transformation on samples
28
+ * or control values.
29
+ *
30
+ * It has an input port "In" and an output port "Out". It also has a "Control"
31
+ * and "Notify" port for the control values.
32
+ *
33
+ * The control value "Mult" and "Add" are used to configure the linear transform. Each
34
+ * sample or control value will be calculated as: new = old * Mult + Add.
35
+ *
36
+ * ### Reciprocal
37
+ *
38
+ * The recip plugin can be used to calculate the reciprocal (1/x) of samples
39
+ * or control values.
40
+ *
41
+ * It has an input port "In" and an output port "Out". It also has a "Control"
42
+ * and "Notify" port for the control values.
43
+ *
44
+ * ### Exp
45
+ *
46
+ * The exp plugin can be used to calculate the exponential (base^x) of samples
47
+ * or control values.
48
+ *
49
+ * It has an input port "In" and an output port "Out". It also has a "Control"
50
+ * and "Notify" port for the control values.
51
+ *
52
+ * The control value "Base" is used to calculate base ^ x for each sample.
53
+ *
54
+ * ### Log
55
+ *
56
+ * The log plugin can be used to calculate the logarithm of samples
57
+ * or control values.
58
+ *
59
+ * It has an input port "In" and an output port "Out". It also has a "Control"
60
+ * and "Notify" port for the control values.
61
+ *
62
+ * The control value "Base", "M1" and "M2" are used to calculate
63
+ * out = M2 * log2f(fabsf(in * M1)) / log2f(Base) for each sample.
64
+ *
65
+ * ### Multiply
66
+ *
67
+ * The mult plugin can be used to multiply samples together.
68
+ *
69
+ * It has 8 input ports named "In 1" to "In 8" and an output port "Out".
70
+ *
71
+ * All input ports samples are multiplied together into the output. Unused input ports
72
+ * will be ignored and not cause overhead.
73
+ *
74
+ * ### Sine
75
+ *
76
+ * The sine plugin generates a sine wave.
77
+ *
78
+ * It has an output port "Out" and also a control output port "notify".
79
+ *
80
+ * "Freq", "Ampl", "Offset" and "Phase" can be used to control the sine wave
81
+ * frequence, amplitude, offset and phase.
82
+ *
83
* ## SOFA filter
84
*
85
* There is an optional builtin SOFA filter available.
86
87
* - \ref PW_KEY_NODE_LINK_GROUP
88
* - \ref PW_KEY_NODE_VIRTUAL
89
* - \ref PW_KEY_NODE_NAME: See notes below. If not specified, defaults to
90
- * 'filter-chain-<pid>-<module-id>'.
91
+ * 'filter-chain-<pid>-<module-id>'.
92
*
93
* Stream only properties:
94
*
95
96
spa_list_for_each(link, &node->output_porti.link_list, output_link)
97
link->input->node->n_deps--;
98
}
99
+ for (i = 0; i < desc->n_notify; i++) {
100
+ spa_list_for_each(link, &node->notify_porti.link_list, output_link)
101
+ link->input->node->n_deps--;
102
+ }
103
104
/* collect all control ports on the graph */
105
for (i = 0; i < desc->n_control; i++) {
106
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
201
1
2
float gain;
3
float b0, b1, b2;
4
float a0, a1, a2;
5
+ float accum;
6
};
7
8
static void *builtin_instantiate(const struct fc_descriptor * Descriptor,
9
10
.cleanup = builtin_cleanup,
11
};
12
13
+/* clamp */
14
+static void clamp_run(void * Instance, unsigned long SampleCount)
15
+{
16
+ struct builtin *impl = Instance;
17
+ float min = impl->port40, max = impl->port50;
18
+ float *in = impl->port1, *out = impl->port0;
19
+ float *ctrl = impl->port3, *notify = impl->port2;
20
+
21
+ if (in != NULL && out != NULL) {
22
+ unsigned long n;
23
+ for (n = 0; n < SampleCount; n++)
24
+ outn = SPA_CLAMPF(inn, min, max);
25
+ }
26
+ if (ctrl != NULL && notify != NULL)
27
+ notify0 = SPA_CLAMPF(ctrl0, min, max);
28
+}
29
+
30
+static struct fc_port clamp_ports = {
31
+ { .index = 0,
32
+ .name = "Out",
33
+ .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
34
+ },
35
+ { .index = 1,
36
+ .name = "In",
37
+ .flags = FC_PORT_INPUT | FC_PORT_AUDIO,
38
+ },
39
+ { .index = 2,
40
+ .name = "Notify",
41
+ .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL,
42
+ },
43
+ { .index = 3,
44
+ .name = "Control",
45
+ .flags = FC_PORT_INPUT | FC_PORT_CONTROL,
46
+ },
47
+ { .index = 4,
48
+ .name = "Min",
49
+ .flags = FC_PORT_INPUT | FC_PORT_CONTROL,
50
+ .def = 0.0f, .min = -100.0f, .max = 100.0f
51
+ },
52
+ { .index = 5,
53
+ .name = "Max",
54
+ .flags = FC_PORT_INPUT | FC_PORT_CONTROL,
55
+ .def = 1.0f, .min = -100.0f, .max = 100.0f
56
+ },
57
+};
58
+
59
+static const struct fc_descriptor clamp_desc = {
60
+ .name = "clamp",
61
+ .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA,
62
+
63
+ .n_ports = SPA_N_ELEMENTS(clamp_ports),
64
+ .ports = clamp_ports,
65
+
66
+ .instantiate = builtin_instantiate,
67
+ .connect_port = builtin_connect_port,
68
+ .run = clamp_run,
69
+ .cleanup = builtin_cleanup,
70
+};
71
+
72
+/* linear */
73
+static void linear_run(void * Instance, unsigned long SampleCount)
74
+{
75
+ struct builtin *impl = Instance;
76
+ float mult = impl->port40, add = impl->port50;
77
+ float *in = impl->port1, *out = impl->port0;
78
+ float *ctrl = impl->port3, *notify = impl->port2;
79
+
80
+ if (in != NULL && out != NULL)
81
+ dsp_ops_linear(dsp_ops, out, in, mult, add, SampleCount);
82
+
83
+ if (ctrl != NULL && notify != NULL)
84
+ notify0 = ctrl0 * mult + add;
85
+}
86
+
87
+static struct fc_port linear_ports = {
88
+ { .index = 0,
89
+ .name = "Out",
90
+ .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
91
+ },
92
+ { .index = 1,
93
+ .name = "In",
94
+ .flags = FC_PORT_INPUT | FC_PORT_AUDIO,
95
+ },
96
+ { .index = 2,
97
+ .name = "Notify",
98
+ .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL,
99
+ },
100
+ { .index = 3,
101
+ .name = "Control",
102
+ .flags = FC_PORT_INPUT | FC_PORT_CONTROL,
103
+ },
104
+ { .index = 4,
105
+ .name = "Mult",
106
+ .flags = FC_PORT_INPUT | FC_PORT_CONTROL,
107
+ .def = 1.0f, .min = -10.0f, .max = 10.0f
108
+ },
109
+ { .index = 5,
110
+ .name = "Add",
111
+ .flags = FC_PORT_INPUT | FC_PORT_CONTROL,
112
+ .def = 0.0f, .min = -10.0f, .max = 10.0f
113
+ },
114
+};
115
+
116
+static const struct fc_descriptor linear_desc = {
117
+ .name = "linear",
118
+ .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA,
119
+
120
+ .n_ports = SPA_N_ELEMENTS(linear_ports),
121
+ .ports = linear_ports,
122
+
123
+ .instantiate = builtin_instantiate,
124
+ .connect_port = builtin_connect_port,
125
+ .run = linear_run,
126
+ .cleanup = builtin_cleanup,
127
+};
128
+
129
+
130
+/* reciprocal */
131
+static void recip_run(void * Instance, unsigned long SampleCount)
132
+{
133
+ struct builtin *impl = Instance;
134
+ float *in = impl->port1, *out = impl->port0;
135
+ float *ctrl = impl->port3, *notify = impl->port2;
136
+
137
+ if (in != NULL && out != NULL) {
138
+ unsigned long n;
139
+ for (n = 0; n < SampleCount; n++) {
140
+ if (in0 == 0.0f)
141
+ outn = 0.0f;
142
+ else
143
+ outn = 1.0f / inn;
144
+ }
145
+ }
146
+ if (ctrl != NULL && notify != NULL) {
147
+ if (ctrl0 == 0.0f)
148
+ notify0 = 0.0f;
149
+ else
150
+ notify0 = 1.0f / ctrl0;
151
+ }
152
+}
153
+
154
+static struct fc_port recip_ports = {
155
+ { .index = 0,
156
+ .name = "Out",
157
+ .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
158
+ },
159
+ { .index = 1,
160
+ .name = "In",
161
+ .flags = FC_PORT_INPUT | FC_PORT_AUDIO,
162
+ },
163
+ { .index = 2,
164
+ .name = "Notify",
165
+ .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL,
166
+ },
167
+ { .index = 3,
168
+ .name = "Control",
169
+ .flags = FC_PORT_INPUT | FC_PORT_CONTROL,
170
+ },
171
+};
172
+
173
+static const struct fc_descriptor recip_desc = {
174
+ .name = "recip",
175
+ .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA,
176
+
177
+ .n_ports = SPA_N_ELEMENTS(recip_ports),
178
+ .ports = recip_ports,
179
+
180
+ .instantiate = builtin_instantiate,
181
+ .connect_port = builtin_connect_port,
182
+ .run = recip_run,
183
+ .cleanup = builtin_cleanup,
184
+};
185
+
186
+/* exp */
187
+static void exp_run(void * Instance, unsigned long SampleCount)
188
+{
189
+ struct builtin *impl = Instance;
190
+ float base = impl->port40;
191
+ float *in = impl->port1, *out = impl->port0;
192
+ float *ctrl = impl->port3, *notify = impl->port2;
193
+
194
+ if (in != NULL && out != NULL) {
195
+ unsigned long n;
196
+ for (n = 0; n < SampleCount; n++)
197
+ outn = powf(base, inn);
198
+ }
199
+ if (ctrl != NULL && notify != NULL)
200
+ notify0 = powf(base, ctrl0);
201
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c
Changed
110
1
2
uint32_t i;
3
const float *s = src;
4
float *d = dst;
5
- for (i = 0; i < n_samples; i++)
6
- di = si * gain;
7
+ if (gain == 0.0f)
8
+ dsp_clear_c(ops, dst, n_samples);
9
+ else if (gain == 1.0f)
10
+ dsp_copy_c(ops, dst, src, n_samples);
11
+ else {
12
+ for (i = 0; i < n_samples; i++)
13
+ di = si * gain;
14
+ }
15
}
16
17
static inline void dsp_gain_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst,
18
19
uint32_t i;
20
const float *s = src;
21
float *d = dst;
22
- for (i = 0; i < n_samples; i++)
23
- di += si * gain;
24
+
25
+ if (gain == 0.0f)
26
+ return;
27
+ else if (gain == 1.0f)
28
+ dsp_add_c(ops, dst, src, n_samples);
29
+ else {
30
+ for (i = 0; i < n_samples; i++)
31
+ di += si * gain;
32
+ }
33
}
34
35
36
37
if (n_src == 0) {
38
dsp_clear_c(ops, dst, n_samples);
39
} else {
40
- if (gain0 == 1.0f)
41
- dsp_copy_c(ops, dst, src0, n_samples);
42
- else
43
- dsp_gain_c(ops, dst, src0, gain0, n_samples);
44
-
45
- for (i = 1; i < n_src; i++) {
46
- if (gaini == 1.0f)
47
- dsp_add_c(ops, dst, srci, n_samples);
48
- else
49
- dsp_gain_add_c(ops, dst, srci, gaini, n_samples);
50
- }
51
+ dsp_gain_c(ops, dst, src0, gain0, n_samples);
52
+ for (i = 1; i < n_src; i++)
53
+ dsp_gain_add_c(ops, dst, srci, gaini, n_samples);
54
+ }
55
+}
56
+
57
+static inline void dsp_mult1_c(struct dsp_ops *ops, void * SPA_RESTRICT dst,
58
+ const void * SPA_RESTRICT src, uint32_t n_samples)
59
+{
60
+ uint32_t i;
61
+ const float *s = src;
62
+ float *d = dst;
63
+ for (i = 0; i < n_samples; i++)
64
+ di *= si;
65
+}
66
+
67
+void dsp_mult_c(struct dsp_ops *ops,
68
+ void * SPA_RESTRICT dst,
69
+ const void * SPA_RESTRICT src,
70
+ uint32_t n_src, uint32_t n_samples)
71
+{
72
+ uint32_t i;
73
+ if (n_src == 0) {
74
+ dsp_clear_c(ops, dst, n_samples);
75
+ } else {
76
+ dsp_copy_c(ops, dst, src0, n_samples);
77
+ for (i = 1; i < n_src; i++)
78
+ dsp_mult1_c(ops, dst, srci, n_samples);
79
}
80
}
81
82
83
dsti = ai + bi;
84
}
85
86
+void dsp_linear_c(struct dsp_ops *ops, float * dst,
87
+ const float * SPA_RESTRICT src, const float mult,
88
+ const float add, uint32_t n_samples)
89
+{
90
+ uint32_t i;
91
+ if (add == 0.0f) {
92
+ dsp_gain_c(ops, dst, src, mult, n_samples);
93
+ } else {
94
+ if (mult == 0.0f) {
95
+ for (i = 0; i < n_samples; i++)
96
+ dsti = add;
97
+ } else if (mult == 1.0f) {
98
+ for (i = 0; i < n_samples; i++)
99
+ dsti = srci + add;
100
+ } else {
101
+ for (i = 0; i < n_samples; i++)
102
+ dsti = mult * srci + add;
103
+ }
104
+ }
105
+}
106
+
107
void *dsp_fft_new_c(struct dsp_ops *ops, int32_t size, bool real)
108
{
109
return pffft_new_setup(size, real ? PFFFT_REAL : PFFFT_COMPLEX);
110
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/dsp-ops.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/dsp-ops.c
Changed
28
1
2
.funcs.mix_gain = dsp_mix_gain_sse,
3
.funcs.biquad_run = dsp_biquad_run_c,
4
.funcs.sum = dsp_sum_avx,
5
+ .funcs.linear = dsp_linear_c,
6
+ .funcs.mult = dsp_mult_c,
7
.funcs.fft_new = dsp_fft_new_c,
8
.funcs.fft_free = dsp_fft_free_c,
9
.funcs.fft_run = dsp_fft_run_c,
10
11
.funcs.mix_gain = dsp_mix_gain_sse,
12
.funcs.biquad_run = dsp_biquad_run_c,
13
.funcs.sum = dsp_sum_sse,
14
+ .funcs.linear = dsp_linear_c,
15
+ .funcs.mult = dsp_mult_c,
16
.funcs.fft_new = dsp_fft_new_c,
17
.funcs.fft_free = dsp_fft_free_c,
18
.funcs.fft_run = dsp_fft_run_c,
19
20
.funcs.mix_gain = dsp_mix_gain_c,
21
.funcs.biquad_run = dsp_biquad_run_c,
22
.funcs.sum = dsp_sum_c,
23
+ .funcs.linear = dsp_linear_c,
24
+ .funcs.mult = dsp_mult_c,
25
.funcs.fft_new = dsp_fft_new_c,
26
.funcs.fft_free = dsp_fft_free_c,
27
.funcs.fft_run = dsp_fft_run_c,
28
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/dsp-ops.h -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/dsp-ops.h
Changed
45
1
2
float * dst, const float * src,
3
const float * SPA_RESTRICT a, const float * SPA_RESTRICT b,
4
uint32_t len, const float scale);
5
+ void (*linear) (struct dsp_ops *ops,
6
+ float * dst, const float * SPA_RESTRICT src,
7
+ const float mult, const float add, uint32_t n_samples);
8
+ void (*mult) (struct dsp_ops *ops,
9
+ void * SPA_RESTRICT dst,
10
+ const void * SPA_RESTRICT src, uint32_t n_src, uint32_t n_samples);
11
};
12
13
struct dsp_ops {
14
15
#define dsp_ops_mix_gain(ops,...) (ops)->funcs.mix_gain(ops, __VA_ARGS__)
16
#define dsp_ops_biquad_run(ops,...) (ops)->funcs.biquad_run(ops, __VA_ARGS__)
17
#define dsp_ops_sum(ops,...) (ops)->funcs.sum(ops, __VA_ARGS__)
18
+#define dsp_ops_linear(ops,...) (ops)->funcs.linear(ops, __VA_ARGS__)
19
+#define dsp_ops_mult(ops,...) (ops)->funcs.mult(ops, __VA_ARGS__)
20
21
#define dsp_ops_fft_new(ops,...) (ops)->funcs.fft_new(ops, __VA_ARGS__)
22
#define dsp_ops_fft_free(ops,...) (ops)->funcs.fft_free(ops, __VA_ARGS__)
23
24
#define MAKE_SUM_FUNC(arch) \
25
void dsp_sum_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \
26
const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples)
27
+#define MAKE_LINEAR_FUNC(arch) \
28
+void dsp_linear_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \
29
+ const float * SPA_RESTRICT src, const float mult, const float add, uint32_t n_samples)
30
+#define MAKE_MULT_FUNC(arch) \
31
+void dsp_mult_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \
32
+ const void * SPA_RESTRICT src, uint32_t n_src, uint32_t n_samples)
33
34
#define MAKE_FFT_NEW_FUNC(arch) \
35
void *dsp_fft_new_##arch(struct dsp_ops *ops, int32_t size, bool real)
36
37
MAKE_MIX_GAIN_FUNC(c);
38
MAKE_BIQUAD_RUN_FUNC(c);
39
MAKE_SUM_FUNC(c);
40
+MAKE_LINEAR_FUNC(c);
41
+MAKE_MULT_FUNC(c);
42
43
MAKE_FFT_NEW_FUNC(c);
44
MAKE_FFT_FREE_FUNC(c);
45
pipewire-0.3.83.tar.gz/src/modules/module-protocol-native/local-socket.c -> pipewire-0.3.84.tar.gz/src/modules/module-protocol-native/local-socket.c
Changed
87
1
2
#include <stdio.h>
3
#include <string.h>
4
#include <errno.h>
5
+#include <limits.h>
6
#include <unistd.h>
7
#include <sys/socket.h>
8
#include <sys/un.h>
9
10
#endif
11
12
#include <pipewire/pipewire.h>
13
+#include <spa/utils/json.h>
14
15
#define DEFAULT_SYSTEM_RUNTIME_DIR "/run/pipewire"
16
17
18
return res;
19
}
20
21
-int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client,
22
- const struct spa_dict *props,
23
- void (*done_callback) (void *data, int res),
24
- void *data)
25
+static int try_connect_name(struct pw_protocol_client *client,
26
+ const char *name,
27
+ void (*done_callback) (void *data, int res),
28
+ void *data)
29
{
30
- const char *runtime_dir, *name;
31
+ const char *runtime_dir;
32
int res;
33
34
- name = get_remote(props);
35
- if (name == NULL)
36
- return -EINVAL;
37
-
38
if (name0 == '/') {
39
- res = try_connect(client, NULL, name, done_callback, data);
40
+ return try_connect(client, NULL, name, done_callback, data);
41
} else {
42
runtime_dir = get_runtime_dir();
43
if (runtime_dir != NULL) {
44
res = try_connect(client, runtime_dir, name, done_callback, data);
45
if (res >= 0)
46
- goto exit;
47
+ return res;
48
}
49
runtime_dir = get_system_dir();
50
if (runtime_dir != NULL)
51
- res = try_connect(client, runtime_dir, name, done_callback, data);
52
+ return try_connect(client, runtime_dir, name, done_callback, data);
53
+ }
54
+
55
+ return -EINVAL;
56
+}
57
+
58
+int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client,
59
+ const struct spa_dict *props,
60
+ void (*done_callback) (void *data, int res),
61
+ void *data)
62
+{
63
+ const char *name;
64
+ struct spa_json it2;
65
+ char pathPATH_MAX;
66
+ int res = -EINVAL;
67
+
68
+ name = get_remote(props);
69
+ if (name == NULL)
70
+ return -EINVAL;
71
+
72
+ spa_json_init(&it0, name, strlen(name));
73
+
74
+ if (spa_json_enter_array(&it0, &it1) < 0)
75
+ return try_connect_name(client, name, done_callback, data);
76
+
77
+ while (spa_json_get_string(&it1, path, sizeof(path)) > 0) {
78
+ res = try_connect_name(client, path, done_callback, data);
79
+ if (res < 0)
80
+ continue;
81
+ break;
82
}
83
-exit:
84
+
85
return res;
86
}
87
pipewire-0.3.83.tar.gz/src/modules/module-rtp-sap.c -> pipewire-0.3.84.tar.gz/src/modules/module-rtp-sap.c
Changed
22
1
2
if ((str = pw_properties_get(props, "rtp.session")) != NULL)
3
fprintf(f, "\"sess.name\" = \"%s\", ", str);
4
5
+ /* Use an interface if explicitly specified, else use the SAP interface if that was specified */
6
+ if ((str = pw_properties_get(props, "local.ifname")) != NULL || (str = impl->ifname) != NULL) {
7
+ fprintf(f, "\"local.ifname\" = \"%s\", ", str);
8
+ }
9
+
10
if ((media = pw_properties_get(props, "sess.media")) == NULL)
11
media = "audio";
12
13
14
15
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_info));
16
17
- pw_log_info("Successfully loaded module-rtp-sink");
18
+ pw_log_info("Successfully loaded module-rtp-sap");
19
20
return 0;
21
out:
22
pipewire-0.3.83.tar.gz/src/modules/module-rtp-sink.c -> pipewire-0.3.84.tar.gz/src/modules/module-rtp-sink.c
Changed
34
1
2
3
static int make_socket(struct sockaddr_storage *src, socklen_t src_len,
4
struct sockaddr_storage *dst, socklen_t dst_len,
5
- bool loop, int ttl, int dscp)
6
+ bool loop, int ttl, int dscp, char *ifname)
7
{
8
int af, fd, val, res;
9
10
11
pw_log_error("bind() failed: %m");
12
goto error;
13
}
14
+#ifdef SO_BINDTODEVICE
15
+ if (ifname && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) {
16
+ res = -errno;
17
+ pw_log_error("setsockopt(SO_BINDTODEVICE) failed: %m");
18
+ goto error;
19
+ }
20
+#endif
21
if (connect(fd, (struct sockaddr*)dst, dst_len) < 0) {
22
res = -errno;
23
pw_log_error("connect() failed: %m");
24
25
26
if ((res = make_socket(&impl->src_addr, impl->src_len,
27
&impl->dst_addr, impl->dst_len,
28
- impl->mcast_loop, impl->ttl, impl->dscp)) < 0) {
29
+ impl->mcast_loop, impl->ttl, impl->dscp,
30
+ impl->ifname)) < 0) {
31
pw_log_error("can't make socket: %s", spa_strerror(res));
32
goto out;
33
}
34
pipewire-0.3.83.tar.gz/src/pipewire/context.c -> pipewire-0.3.84.tar.gz/src/pipewire/context.c
Changed
69
1
2
spa_list_for_each(l, &p->links, input_link) {
3
t = l->output->node;
4
5
- if (!t->active || !l->prepared || (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction)))
6
+ if (!t->active || !l->prepared ||
7
+ (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction)))
8
continue;
9
10
pw_log_debug(" peer %p: '%s'", t, t->name);
11
12
spa_list_for_each(l, &p->links, output_link) {
13
t = l->input->node;
14
15
- if (!t->active || !l->prepared || (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction)))
16
+ if (!t->active || !l->prepared ||
17
+ (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction)))
18
continue;
19
20
pw_log_debug(" peer %p: '%s'", t, t->name);
21
22
* don't get included here. They were added to the same driver but
23
* need to otherwise stay idle unless some non-passive link activates
24
* them. */
25
- if (node->link_group != NULL) {
26
+ if (node->link_groups != NULL) {
27
spa_list_for_each(t, nodes, sort_link) {
28
if (t->exported || !t->active ||
29
SPA_FLAG_IS_SET(t->checked, 1u<<direction))
30
continue;
31
- if (!spa_streq(t->link_group, node->link_group))
32
+ if (pw_strv_find_common(t->link_groups, node->link_groups) < 0)
33
continue;
34
35
pw_log_debug(" group %p: '%s'", t, t->name);
36
37
}
38
/* now go through all the nodes that have the same group and
39
* that are not yet visited */
40
- if (n->group != NULL || n->link_group != NULL) {
41
+ if (n->groups != NULL || n->link_groups != NULL) {
42
spa_list_for_each(t, &context->node_list, link) {
43
if (t->exported || !t->active || t->visited)
44
continue;
45
- if ((t->group == NULL || !spa_streq(t->group, n->group)) &&
46
- (t->link_group == NULL || !spa_streq(t->link_group, n->link_group)))
47
+ if (pw_strv_find_common(t->groups, n->groups) < 0 &&
48
+ pw_strv_find_common(t->link_groups, n->link_groups) < 0)
49
continue;
50
- pw_log_debug("%p: %s join group:%s link-group:%s",
51
- t, t->name, n->group, n->link_group);
52
+ pw_log_debug("%p: %s join group of %s",
53
+ t, t->name, n->name);
54
t->visited = true;
55
spa_list_append(&queue, &t->sort_link);
56
}
57
58
node_max_quantum = node_max_quantum * current_rate / node_rate_quantum;
59
}
60
61
- /* calculate desired quantum */
62
- if (max_latency.denom != 0) {
63
+ /* calculate desired quantum. Don't limit to the max_latency when we are
64
+ * going to force a quantum or rate and reconfigure the nodes. */
65
+ if (max_latency.denom != 0 && !force_quantum && !force_rate) {
66
uint32_t tmp = (max_latency.num * current_rate / max_latency.denom);
67
if (tmp < node_max_quantum)
68
node_max_quantum = tmp;
69
pipewire-0.3.83.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.84.tar.gz/src/pipewire/impl-link.c
Changed
201
1
2
link->info.change_mask = 0;
3
}
4
5
+static inline void input_set_busy_id(struct pw_impl_link *link, uint32_t id)
6
+{
7
+ struct impl *impl = SPA_CONTAINER_OF(link, struct impl, this);
8
+ if (impl->input_busy_id != SPA_ID_INVALID)
9
+ link->input->busy_count--;
10
+ if (id != SPA_ID_INVALID)
11
+ link->input->busy_count++;
12
+ impl->input_busy_id = id;
13
+ if (link->input->busy_count < 0)
14
+ pw_log_error("%s: invalid busy count:%d", link->name, link->input->busy_count);
15
+}
16
+
17
+static inline void output_set_busy_id(struct pw_impl_link *link, uint32_t id)
18
+{
19
+ struct impl *impl = SPA_CONTAINER_OF(link, struct impl, this);
20
+ if (impl->output_busy_id != SPA_ID_INVALID)
21
+ link->output->busy_count--;
22
+ if (id != SPA_ID_INVALID)
23
+ link->output->busy_count++;
24
+ impl->output_busy_id = id;
25
+ if (link->output->busy_count < 0)
26
+ pw_log_error("%s: invalid busy count:%d", link->name, link->output->busy_count);
27
+}
28
+
29
static void link_update_state(struct pw_impl_link *link, enum pw_link_state state, int res, char *error)
30
{
31
struct impl *impl = SPA_CONTAINER_OF(link, struct impl, this);
32
33
} else if (state == PW_LINK_STATE_INIT) {
34
link->prepared = false;
35
link->preparing = false;
36
- if (impl->output_busy_id != SPA_ID_INVALID) {
37
- impl->output_busy_id = SPA_ID_INVALID;
38
- link->output->busy_count--;
39
- }
40
+
41
+ output_set_busy_id(link, SPA_ID_INVALID);
42
pw_work_queue_cancel(impl->work, &link->output_link, SPA_ID_INVALID);
43
- if (impl->input_busy_id != SPA_ID_INVALID) {
44
- impl->input_busy_id = SPA_ID_INVALID;
45
- link->input->busy_count--;
46
- }
47
+
48
+ input_set_busy_id(link, SPA_ID_INVALID);
49
pw_work_queue_cancel(impl->work, &link->input_link, SPA_ID_INVALID);
50
}
51
}
52
53
else
54
port = this->output;
55
56
- if (id == impl->input_busy_id) {
57
- impl->input_busy_id = SPA_ID_INVALID;
58
- port->busy_count--;
59
- } else if (id == impl->output_busy_id) {
60
- impl->output_busy_id = SPA_ID_INVALID;
61
- port->busy_count--;
62
- } else if (id != SPA_ID_INVALID)
63
- return;
64
+ if (id != SPA_ID_INVALID) {
65
+ if (id == impl->input_busy_id) {
66
+ input_set_busy_id(this, SPA_ID_INVALID);
67
+ } else if (id == impl->output_busy_id) {
68
+ output_set_busy_id(this, SPA_ID_INVALID);
69
+ } else {
70
+ return;
71
+ }
72
+ }
73
74
pw_log_debug("%p: obj:%p port %p complete state:%d: %s", this, obj, port,
75
port->state, spa_strerror(res));
76
77
mix = &this->rt.out_mix;
78
}
79
80
- if (id == impl->input_busy_id) {
81
- impl->input_busy_id = SPA_ID_INVALID;
82
- port->busy_count--;
83
- } else if (id == impl->output_busy_id) {
84
- impl->output_busy_id = SPA_ID_INVALID;
85
- port->busy_count--;
86
- } else if (id != SPA_ID_INVALID)
87
- return;
88
+ if (id != SPA_ID_INVALID) {
89
+ if (id == impl->input_busy_id) {
90
+ input_set_busy_id(this, SPA_ID_INVALID);
91
+ } else if (id == impl->output_busy_id) {
92
+ output_set_busy_id(this, SPA_ID_INVALID);
93
+ } else {
94
+ return;
95
+ }
96
+ }
97
98
pw_log_debug("%p: obj:%p port %p complete state:%d: %s", this, obj, port,
99
port->state, spa_strerror(res));
100
101
struct pw_impl_port *input, *output;
102
uint8_t buffer4096;
103
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
104
- uint32_t index;
105
+ uint32_t index, busy_id;
106
uint32_t in_state, out_state;
107
108
if (this->info.state >= PW_LINK_STATE_NEGOTIATING)
109
110
goto error;
111
}
112
if (SPA_RESULT_IS_ASYNC(res)) {
113
- output->busy_count++;
114
res = spa_node_sync(output->node->node, res);
115
- impl->output_busy_id = pw_work_queue_add(impl->work, &this->output_link, res,
116
+ busy_id = pw_work_queue_add(impl->work, &this->output_link, res,
117
complete_ready, this);
118
+ output_set_busy_id(this, busy_id);
119
} else {
120
complete_ready(&this->output_link, this, res, SPA_ID_INVALID);
121
}
122
123
goto error;
124
}
125
if (SPA_RESULT_IS_ASYNC(res2)) {
126
- input->busy_count++;
127
res2 = spa_node_sync(input->node->node, res2);
128
- impl->input_busy_id = pw_work_queue_add(impl->work, &this->input_link, res2,
129
+ busy_id = pw_work_queue_add(impl->work, &this->input_link, res2,
130
complete_ready, this);
131
+ input_set_busy_id(this, busy_id);
132
if (res == 0)
133
res = res2;
134
} else {
135
136
{
137
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
138
int res;
139
- uint32_t in_flags, out_flags;
140
+ uint32_t in_flags, out_flags, busy_id;
141
char *error = NULL;
142
struct pw_impl_port *input, *output;
143
144
145
goto error_clear;
146
}
147
if (SPA_RESULT_IS_ASYNC(res)) {
148
- output->busy_count++;
149
res = spa_node_sync(output->node->node, res);
150
- impl->output_busy_id = pw_work_queue_add(impl->work, &this->output_link, res,
151
+ busy_id = pw_work_queue_add(impl->work, &this->output_link, res,
152
complete_paused, this);
153
+ output_set_busy_id(this, busy_id);
154
if (flags & SPA_NODE_BUFFERS_FLAG_ALLOC)
155
return 0;
156
} else {
157
158
}
159
160
if (SPA_RESULT_IS_ASYNC(res)) {
161
- input->busy_count++;
162
res = spa_node_sync(input->node->node, res);
163
- impl->input_busy_id = pw_work_queue_add(impl->work, &this->input_link, res,
164
+ busy_id = pw_work_queue_add(impl->work, &this->input_link, res,
165
complete_paused, this);
166
+ input_set_busy_id(this, busy_id);
167
} else {
168
complete_paused(&this->input_link, this, res, SPA_ID_INVALID);
169
}
170
171
}
172
173
if (output->busy_count > 0) {
174
- pw_log_debug("%p: output port %p was busy", this, output);
175
+ pw_log_debug("%p: output port %p was busy %d", this, output, output->busy_count);
176
res = spa_node_sync(output->node->node, 0);
177
pw_work_queue_add(impl->work, &this->output_link, res, complete_sync, this);
178
goto exit;
179
}
180
else if (input->busy_count > 0) {
181
- pw_log_debug("%p: input port %p was busy", this, input);
182
+ pw_log_debug("%p: input port %p was busy %d", this, input, input->busy_count);
183
res = spa_node_sync(input->node->node, 0);
184
pw_work_queue_add(impl->work, &this->input_link, res, complete_sync, this);
185
goto exit;
186
187
188
pw_log_debug("%p: remove input port %p", this, port);
189
190
- if (impl->input_busy_id != SPA_ID_INVALID) {
191
- impl->input_busy_id = SPA_ID_INVALID;
192
- port->busy_count--;
193
- }
194
+ input_set_busy_id(this, SPA_ID_INVALID);
195
+
196
spa_hook_remove(&impl->input_port_listener);
197
spa_hook_remove(&impl->input_node_listener);
198
spa_hook_remove(&impl->input_global_listener);
199
200
201
pipewire-0.3.83.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.84.tar.gz/src/pipewire/impl-node.c
Changed
75
1
2
#include <errno.h>
3
#include <time.h>
4
#include <malloc.h>
5
+#include <limits.h>
6
7
#include <spa/support/system.h>
8
#include <spa/pod/parser.h>
9
10
11
unsigned int cache_params:1;
12
unsigned int pending_play:1;
13
+
14
+ char *group;
15
+ char *link_group;
16
};
17
18
#define pw_node_resource(r,m,v,...) pw_resource_call(r,struct pw_node_events,m,v,__VA_ARGS__)
19
20
static void
21
clear_info(struct pw_impl_node *this)
22
{
23
- free(this->group);
24
- free(this->link_group);
25
+ pw_free_strv(this->groups);
26
+ pw_free_strv(this->link_groups);
27
free(this->name);
28
free((char*)this->info.error);
29
}
30
31
32
/* group defines what nodes are scheduled together */
33
str = pw_properties_get(node->properties, PW_KEY_NODE_GROUP);
34
- if (!spa_streq(str, node->group)) {
35
- pw_log_info("%p: group '%s'->'%s'", node, node->group, str);
36
- free(node->group);
37
- node->group = str ? strdup(str) : NULL;
38
- node->freewheel = spa_streq(node->group, "pipewire.freewheel");
39
+ if (!spa_streq(str, impl->group)) {
40
+ pw_log_info("%p: group '%s'->'%s'", node, impl->group, str);
41
+ free(impl->group);
42
+ impl->group = str ? strdup(str) : NULL;
43
+ pw_free_strv(node->groups);
44
+ node->groups = impl->group ?
45
+ pw_strv_parse(impl->group, strlen(impl->group), INT_MAX, NULL) : NULL;
46
+ node->freewheel = pw_strv_find(node->groups, "pipewire.freewheel") >= 0;
47
recalc_reason = "group changed";
48
}
49
50
/* link group defines what nodes are logically linked together */
51
str = pw_properties_get(node->properties, PW_KEY_NODE_LINK_GROUP);
52
- if (!spa_streq(str, node->link_group)) {
53
- pw_log_info("%p: link group '%s'->'%s'", node, node->link_group, str);
54
- free(node->link_group);
55
- node->link_group = str ? strdup(str) : NULL;
56
+ if (!spa_streq(str, impl->link_group)) {
57
+ pw_log_info("%p: link group '%s'->'%s'", node, impl->link_group, str);
58
+ free(impl->link_group);
59
+ impl->link_group = str ? strdup(str) : NULL;
60
+ pw_free_strv(node->link_groups);
61
+ node->link_groups = impl->link_group ?
62
+ pw_strv_parse(impl->link_group, strlen(impl->link_group), INT_MAX, NULL) : NULL;
63
recalc_reason = "link group changed";
64
}
65
66
67
clear_info(node);
68
69
spa_system_close(node->data_system, node->source.fd);
70
+ free(impl->group);
71
+ free(impl->link_group);
72
free(impl);
73
74
#ifdef HAVE_MALLOC_TRIM
75
pipewire-0.3.83.tar.gz/src/pipewire/keys.h -> pipewire-0.3.84.tar.gz/src/pipewire/keys.h
Changed
32
1
2
/* remote keys */
3
#define PW_KEY_REMOTE_NAME "remote.name" /**< The name of the remote to connect to,
4
* default pipewire-0, overwritten by
5
- * env(PIPEWIRE_REMOTE) */
6
+ * env(PIPEWIRE_REMOTE). May also be
7
+ * a SPA-JSON array of sockets, to be tried
8
+ * in order. */
9
#define PW_KEY_REMOTE_INTENTION "remote.intention" /**< The intention of the remote connection,
10
* "generic", "screencast" */
11
12
13
#define PW_KEY_NODE_SESSION "node.session" /**< the session id this node is part of */
14
#define PW_KEY_NODE_GROUP "node.group" /**< the group id this node is part of. Nodes
15
* in the same group are always scheduled
16
- * with the same driver. */
17
+ * with the same driver. Can be an array of
18
+ * group names. */
19
#define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */
20
#define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected
21
* to a compatible node */
22
23
* on output/input/all ports when the value is
24
* "out"/"in"/"true" respectively */
25
#define PW_KEY_NODE_LINK_GROUP "node.link-group" /**< the node is internally linked to
26
- * nodes with the same link-group */
27
+ * nodes with the same link-group. Can be an
28
+ * array of group names. */
29
#define PW_KEY_NODE_NETWORK "node.network" /**< the node is on a network */
30
#define PW_KEY_NODE_TRIGGER "node.trigger" /**< the node is not scheduled automatically
31
* based on the dependencies in the graph
32
pipewire-0.3.83.tar.gz/src/pipewire/private.h -> pipewire-0.3.84.tar.gz/src/pipewire/private.h
Changed
12
1
2
char *name; /** for debug */
3
4
uint32_t priority_driver; /** priority for being driver */
5
- char *group; /** group to schedule this node in */
6
- char *link_group; /** group this node is linked to */
7
+ char **groups; /** groups to schedule this node in */
8
+ char **link_groups; /** groups this node is linked to */
9
uint64_t spa_flags;
10
11
unsigned int registered:1;
12
pipewire-0.3.83.tar.gz/src/pipewire/stream.c -> pipewire-0.3.84.tar.gz/src/pipewire/stream.c
Changed
37
1
2
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
3
uintptr_t seq1, seq2;
4
uint32_t buffered, quantum, index;
5
+ int32_t avail_buffers;
6
7
do {
8
seq1 = SPA_SEQ_READ(impl->seq);
9
10
time->delay += (impl->latency.min_rate + impl->latency.max_rate) / 2;
11
time->delay += ((impl->latency.min_ns + impl->latency.max_ns) / 2) * time->rate.denom / SPA_NSEC_PER_SEC;
12
13
+ avail_buffers = spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index);
14
+ avail_buffers = SPA_CLAMP(avail_buffers, 0, (int32_t)impl->n_buffers);
15
+
16
if (size >= offsetof(struct pw_time, queued_buffers))
17
time->buffered = buffered;
18
if (size >= offsetof(struct pw_time, avail_buffers))
19
- time->queued_buffers = spa_ringbuffer_get_read_index(&impl->queued.ring, &index);
20
+ time->queued_buffers = impl->n_buffers - avail_buffers;
21
if (size >= sizeof(struct pw_time))
22
- time->avail_buffers = spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index);
23
+ time->avail_buffers = avail_buffers;
24
25
pw_log_trace_fp("%p: %"PRIi64" %"PRIi64" %"PRIu64" %d/%d %"PRIu64" %"
26
- PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, stream,
27
+ PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %d/%d", stream,
28
time->now, time->delay, time->ticks,
29
time->rate.num, time->rate.denom, time->queued,
30
impl->dequeued.outcount, impl->dequeued.incount,
31
- impl->queued.outcount, impl->queued.incount);
32
+ impl->queued.outcount, impl->queued.incount,
33
+ avail_buffers, impl->n_buffers);
34
return 0;
35
}
36
37
pipewire-0.3.83.tar.gz/src/pipewire/utils.c -> pipewire-0.3.84.tar.gz/src/pipewire/utils.c
Changed
110
1
2
#include <string.h>
3
#include <time.h>
4
5
+#include <spa/utils/json.h>
6
+
7
#include <pipewire/array.h>
8
#include <pipewire/log.h>
9
#include <pipewire/utils.h>
10
11
}
12
pw_array_add_ptr(&arr, NULL);
13
14
- *n_tokens = n;
15
+ if (n_tokens != NULL)
16
+ *n_tokens = n;
17
18
return arr.data;
19
}
20
21
return n;
22
}
23
24
+/** Parse an array of strings
25
+ * \param val a string to parse
26
+ * \param len the length of \a val
27
+ * \param max_tokens the max number of tokens to split
28
+ * \paramout n_tokens the number of tokens, may be NULL
29
+ * \return a NULL terminated array of strings that should be
30
+ * freed with \ref pw_free_strv.
31
+ *
32
+ * \a val is parsed using relaxed json syntax.
33
+ *
34
+ * \since 0.3.84
35
+ */
36
+SPA_EXPORT
37
+char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens)
38
+{
39
+ struct pw_array arr;
40
+ struct spa_json it2;
41
+ char v256;
42
+ int n = 0;
43
+
44
+ if (val == NULL)
45
+ return NULL;
46
+
47
+ pw_array_init(&arr, 16);
48
+
49
+ spa_json_init(&it0, val, len);
50
+ if (spa_json_enter_array(&it0, &it1) <= 0)
51
+ spa_json_init(&it1, val, len);
52
+
53
+ while (spa_json_get_string(&it1, v, sizeof(v)) > 0 && n + 1 < max_tokens) {
54
+ pw_array_add_ptr(&arr, strdup(v));
55
+ n++;
56
+ }
57
+ pw_array_add_ptr(&arr, NULL);
58
+
59
+ if (n_tokens != NULL)
60
+ *n_tokens = n;
61
+
62
+ return arr.data;
63
+}
64
+
65
+/** Find a string in a NULL terminated array of strings.
66
+ * \param a a strv to check
67
+ * \param b the string to find
68
+ * \return the index in \a a where \a b is found or < 0 if not.
69
+ *
70
+ * \since 0.3.84
71
+ */
72
+SPA_EXPORT
73
+int pw_strv_find(char **a, char *b)
74
+{
75
+ int i;
76
+ if (a == NULL || b == NULL)
77
+ return -EINVAL;
78
+ for (i = 0; ai; i++) {
79
+ if (spa_streq(ai, b))
80
+ return i;
81
+ }
82
+ return -ENOENT;
83
+}
84
+
85
+/** Check if two NULL terminated arrays of strings have a common string.
86
+ * \param a a strv to check
87
+ * \param b another strv to check
88
+ * \return the index in \a a of the first common string or < 0 if not.
89
+ *
90
+ * \since 0.3.84
91
+ */
92
+SPA_EXPORT
93
+int pw_strv_find_common(char **a, char **b)
94
+{
95
+ int i;
96
+
97
+ if (a == NULL || b == NULL)
98
+ return -EINVAL;
99
+
100
+ for (i = 0; ai; i++) {
101
+ if (pw_strv_find(b, ai) >= 0)
102
+ return i;
103
+ }
104
+ return -ENOENT;
105
+}
106
+
107
/** Free a NULL terminated array of strings
108
* \param str a NULL terminated array of string
109
*
110
pipewire-0.3.83.tar.gz/src/pipewire/utils.h -> pipewire-0.3.84.tar.gz/src/pipewire/utils.h
Changed
14
1
2
int
3
pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens);
4
5
+char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens);
6
+
7
+int pw_strv_find(char **a, char *b);
8
+
9
+int pw_strv_find_common(char **a, char **b);
10
+
11
void
12
pw_free_strv(char **str);
13
14
pipewire-0.3.83.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.84.tar.gz/src/tools/pw-dump.c
Changed
11
1
2
3
data.core = pw_context_connect(data.context,
4
pw_properties_new(
5
- PW_KEY_REMOTE_NAME, opt_remote,
6
+ PW_KEY_REMOTE_NAME, opt_remote ? opt_remote :
7
+ ("" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE ""),
8
NULL),
9
0);
10
if (data.core == NULL) {
11
pipewire-0.3.83.tar.gz/src/tools/pw-mon.c -> pipewire-0.3.84.tar.gz/src/tools/pw-mon.c
Changed
11
1
2
3
data.core = pw_context_connect(data.context,
4
pw_properties_new(
5
- PW_KEY_REMOTE_NAME, opt_remote,
6
+ PW_KEY_REMOTE_NAME, opt_remote ? opt_remote :
7
+ ("" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE ""),
8
NULL),
9
0);
10
if (data.core == NULL) {
11
pipewire-0.3.83.tar.gz/src/tools/pw-top.c -> pipewire-0.3.84.tar.gz/src/tools/pw-top.c
Changed
11
1
2
3
data.core = pw_context_connect(data.context,
4
pw_properties_new(
5
- PW_KEY_REMOTE_NAME, opt_remote,
6
+ PW_KEY_REMOTE_NAME, opt_remote ? opt_remote :
7
+ ("" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE ""),
8
NULL),
9
0);
10
if (data.core == NULL) {
11