Changes of Revision 38

pipewire-aptx.changes Changed
x
 
1
@@ -1,4 +1,9 @@
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
@@ -7,7 +7,7 @@
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
@@ -1,3 +1,64 @@
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
@@ -52,9 +113,6 @@
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
@@ -1,5 +1,5 @@
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
@@ -309,21 +309,21 @@
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
@@ -23,6 +23,8 @@
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
@@ -426,6 +426,7 @@
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
@@ -1519,13 +1520,17 @@
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
@@ -3261,7 +3266,7 @@
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
@@ -3343,6 +3348,7 @@
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
@@ -3437,6 +3443,7 @@
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
@@ -3558,6 +3565,7 @@
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
@@ -3567,6 +3575,7 @@
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
@@ -3601,6 +3610,9 @@
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
@@ -3932,6 +3944,7 @@
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
@@ -3952,13 +3965,15 @@
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
@@ -4720,6 +4735,37 @@
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
@@ -5045,6 +5091,19 @@
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
@@ -5055,8 +5114,8 @@
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
@@ -5064,13 +5123,9 @@
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
@@ -5104,6 +5159,9 @@
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
@@ -5168,8 +5226,6 @@
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
@@ -55,6 +55,11 @@
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
@@ -55,6 +55,11 @@
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
@@ -51,38 +51,56 @@
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
@@ -53,34 +53,34 @@
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
@@ -38,6 +38,7 @@
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
@@ -2017,41 +2018,31 @@
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
@@ -4684,7 +4675,6 @@
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
@@ -4699,10 +4689,28 @@
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
@@ -634,7 +634,7 @@
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
@@ -838,8 +838,8 @@
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
@@ -955,6 +955,9 @@
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
@@ -1124,7 +1127,7 @@
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
@@ -89,6 +89,9 @@
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
@@ -196,7 +199,23 @@
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
@@ -144,7 +144,7 @@
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
@@ -88,11 +88,11 @@
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
@@ -178,7 +178,7 @@
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
@@ -214,7 +214,7 @@
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
@@ -71,6 +71,7 @@
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
@@ -266,7 +267,7 @@
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
@@ -302,7 +303,7 @@
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
@@ -362,6 +363,10 @@
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
@@ -228,7 +228,10 @@
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
@@ -267,12 +267,12 @@
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
@@ -576,9 +576,10 @@
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
@@ -676,7 +677,11 @@
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
@@ -702,6 +707,7 @@
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
@@ -892,7 +892,9 @@
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
@@ -1186,7 +1188,7 @@
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
@@ -1002,7 +1002,8 @@
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
@@ -1036,7 +1037,8 @@
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
@@ -203,8 +203,8 @@
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
@@ -320,6 +320,73 @@
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
@@ -391,7 +458,7 @@
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
@@ -2591,6 +2658,10 @@
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
@@ -41,6 +41,7 @@
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
@@ -1234,6 +1235,443 @@
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
@@ -33,8 +33,14 @@
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
@@ -43,8 +49,15 @@
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
@@ -64,17 +77,34 @@
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
@@ -113,6 +143,27 @@
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
@@ -27,6 +27,8 @@
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
@@ -41,6 +43,8 @@
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
@@ -54,6 +58,8 @@
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
@@ -37,6 +37,12 @@
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
@@ -58,6 +64,8 @@
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
@@ -79,6 +87,12 @@
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
@@ -102,6 +116,8 @@
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
@@ -9,6 +9,7 @@
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
@@ -20,6 +21,7 @@
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
@@ -119,31 +121,56 @@
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
@@ -757,6 +757,11 @@
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
@@ -1540,7 +1545,7 @@
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
@@ -253,7 +253,7 @@
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
@@ -267,6 +267,13 @@
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
@@ -517,7 +524,8 @@
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
@@ -807,7 +807,8 @@
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
@@ -820,7 +821,8 @@
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
@@ -834,12 +836,12 @@
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
@@ -931,15 +933,15 @@
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
@@ -1465,8 +1467,9 @@
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
@@ -140,6 +140,30 @@
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
@@ -194,15 +218,11 @@
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
@@ -218,14 +238,15 @@
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
@@ -258,14 +279,15 @@
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
@@ -309,7 +331,7 @@
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
@@ -430,10 +452,10 @@
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
@@ -449,10 +471,10 @@
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
@@ -524,7 +546,7 @@
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
@@ -597,10 +619,10 @@
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
@@ -620,10 +642,10 @@
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
@@ -726,13 +748,13 @@
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
@@ -762,10 +784,8 @@
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
@@ -792,10 +812,8 @@
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
@@ -9,6 +9,7 @@
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
@@ -42,6 +43,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
@@ -473,8 +477,8 @@
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
@@ -964,20 +968,26 @@
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
@@ -2098,6 +2108,8 @@
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
@@ -90,7 +90,9 @@
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
@@ -135,7 +137,8 @@
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
@@ -175,7 +178,8 @@
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
@@ -643,8 +643,8 @@
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
@@ -2340,6 +2340,7 @@
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
@@ -2358,19 +2359,23 @@
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
@@ -13,6 +13,8 @@
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
@@ -74,7 +76,8 @@
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
@@ -110,6 +113,89 @@
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
@@ -46,6 +46,12 @@
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
@@ -1608,7 +1608,8 @@
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
@@ -860,7 +860,8 @@
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
@@ -836,7 +836,8 @@
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