Changes of Revision 36

pipewire-aptx.changes Changed
x
 
1
@@ -1,4 +1,9 @@
2
 -------------------------------------------------------------------
3
+Wed Oct 18 08:54:11 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.82
6
+
7
+-------------------------------------------------------------------
8
 Sun Oct  8 16:26:36 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
9
 
10
 - Update to version 0.3.81
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.81
6
+Version:        0.3.82
7
 Release:        0
8
 Summary:        PipeWire Bluetooth aptX codec plugin
9
 License:        MIT
10
pipewire-0.3.81.tar.gz/.gitlab/ci/check_missing_headers.sh -> pipewire-0.3.82.tar.gz/.gitlab/ci/check_missing_headers.sh Changed
10
 
1
@@ -5,7 +5,7 @@
2
 
3
 LIST=""
4
 
5
-for i in $(find spa/include -name '*.h' -a -not -path 'spa/include/spa/utils/cleanup.h' | sed s#spa/include/##);
6
+for i in $(find spa/include -name '*.h' | sed s#spa/include/##);
7
 do
8
     -f "$PREFIX/include/spa-0.2/$i"  || LIST="$i $LIST"
9
 done
10
pipewire-0.3.81.tar.gz/NEWS -> pipewire-0.3.82.tar.gz/NEWS Changed
80
 
1
@@ -1,3 +1,68 @@
2
+# PipeWire 0.3.82 (2023-10-13)
3
+
4
+This is the second 1.0 release candidate that is API and ABI compatible
5
+with previous 0.3.x releases.
6
+
7
+## Highlights
8
+  - Fix a regression in some devices when the Pro-Audio profile was selected.
9
+    Only enable the IRQ based scheduling and device linking in specific
10
+    safe cases. (#3556)
11
+  - Improve rate switching. In some cases the graph rate would not switch
12
+    correctly. (#2929)
13
+  - Fix regression in alsa wakeups that would cause silence in VMs.
14
+  - Fix a leak in the SBC codecs for SCO.
15
+  - More improvements to the RAOP module.
16
+  - Other small improvements and fixes.
17
+
18
+
19
+## PipeWire
20
+  - Improve client property checks.
21
+  - Allow non-power-of-2 quantums when forced.
22
+  - Improve rate switching. In some cases the graph rate would not switch
23
+    correctly. (#2929)
24
+  - The PIPEWIRE_QUANTUM env variable now forces the size and rate in the
25
+    graph for the duration of the application. The softer PIPEWIRE_LATENCY
26
+    and PIPEWIRE_RATE can still be used to merely suggest a maximum latency
27
+    and a rate.
28
+
29
+## modules
30
+  - Remove the RTSP FLUSH request in RAOP because it does not seem necessary.
31
+  - The RAOP module now uses the common RTP stream functions.
32
+  - Add sockets option to protocol-native to make pipewire listen on multiple
33
+    sockets.
34
+
35
+## SPA
36
+  - Clean up some of the log functions.
37
+  - Add an option in ALSA to disable linking devices together.
38
+  - Only link pcms together when 1 capture and 1 playback pcm. For more complex
39
+    devices we can't be sure which ones can be linked. (#3556)
40
+  - disable tsched only when using linked devices.
41
+  - Add some extra checks in ALSA to avoid segfaults. (#3554)
42
+  - Add Tag support to alsa-sink and alsa-source.
43
+  - Use dynamic pod builder when we can.
44
+  - Set priority.driver on midi-bridge to allow it as a fallback driver. (#3562)
45
+  - Fix regression in alsa wakeups. (#3565)
46
+  - The PTP clock can now be found from the interface in node-driver.
47
+
48
+## pulse-server
49
+  - Some small cleanups and internal improvements.
50
+  - Add some memory debugging messages.
51
+  - Add Tag messages to streams.
52
+
53
+## Bluetooth
54
+  - Fix a leak in the SBC codecs for SCO.
55
+
56
+## JACK
57
+  - Patch up midi events in the destination buffer instead of writing to the
58
+    source buffer. (#3580)
59
+  - Group all jack clients together to avoid transport issues. (#3562)
60
+
61
+## ALSA-plugins
62
+  - Add also.deny option to block alsa clients from opening the PCM.
63
+
64
+Older versions:
65
+
66
+
67
 # PipeWire 0.3.81 (2023-10-06)
68
 
69
 This is the first 1.0 release candidate that is API and ABI compatible
70
@@ -80,9 +145,6 @@
71
   - jack_property now always manages to actually change the metadata because
72
     it waits for a roundtrip before exiting.
73
 
74
-Older versions:
75
-
76
-
77
 # PipeWire 0.3.80 (2023-09-14)
78
 
79
 This is a bugfix release that is API and ABI compatible with previous
80
pipewire-0.3.81.tar.gz/README.md -> pipewire-0.3.82.tar.gz/README.md Changed
13
 
1
@@ -52,9 +52,8 @@
2
                   the samplerate.
3
 * `PIPEWIRE_RATE=<num/denom>`      to configure a rate for the graph.
4
 * `PIPEWIRE_QUANTUM=<num/denom>`   to configure latency as a fraction and a
5
-                  samplerate. This function will attempt to change
6
-                  the graph samplerate to `denom` and use the
7
-                  specified `num` as the buffer size.
8
+                   samplerate. This function will force the graph samplerate to
9
+                   `denom` and force the specified `num` as the buffer size.
10
 * `PIPEWIRE_NODE=<id>`             to request a link to the specified node. The
11
                     id can be a node.name or object.serial of the target node.
12
 
13
pipewire-0.3.81.tar.gz/meson.build -> pipewire-0.3.82.tar.gz/meson.build Changed
35
 
1
@@ -1,5 +1,5 @@
2
 project('pipewire', 'c' ,
3
-  version : '0.3.81',
4
+  version : '0.3.82',
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
@@ -232,6 +232,7 @@
9
   'sys/random.h', 'HAVE_SYS_RANDOM_H',
10
   'sys/vfs.h', 'HAVE_SYS_VFS_H',
11
   'pwd.h', 'HAVE_PWD_H',
12
+  'grp.h', 'HAVE_GRP_H',
13
 
14
 
15
 foreach h : check_headers
16
@@ -247,6 +248,10 @@
17
 summary({'libsystemd': systemd_dep.found()}, bool_yn: true)
18
 cdata.set('HAVE_SYSTEMD', systemd.found() and systemd_dep.found())
19
 
20
+selinux_dep = dependency('libselinux', required: get_option('selinux'))
21
+summary({'libselinux': selinux_dep.found()}, bool_yn: true)
22
+cdata.set('HAVE_SELINUX', selinux_dep.found())
23
+
24
 configinc = include_directories('.')
25
 includes_inc = include_directories('include')
26
 pipewire_inc = include_directories('src')
27
@@ -436,6 +441,7 @@
28
   'sigabbrev_np', '#include <string.h>', '-D_GNU_SOURCE', ,
29
   'XSetIOErrorExitHandler', '#include <X11/Xlib.h>', , x11_dep,
30
   'malloc_trim', '#include <malloc.h>', , ,
31
+  'malloc_info', '#include <malloc.h>', , ,
32
 
33
 
34
 foreach f : check_functions
35
pipewire-0.3.81.tar.gz/meson_options.txt -> pipewire-0.3.82.tar.gz/meson_options.txt Changed
12
 
1
@@ -42,6 +42,10 @@
2
        description: 'Install systemd user service file (ignored without systemd)',
3
        type: 'feature',
4
        value: 'enabled')
5
+option('selinux',
6
+       description: 'Enable SELinux integration',
7
+       type: 'feature',
8
+       value: 'auto')
9
 option('pipewire-alsa',
10
        description: 'Enable pipewire-alsa integration',
11
        type: 'feature',
12
pipewire-0.3.81.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.82.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c Changed
14
 
1
@@ -1238,6 +1238,12 @@
2
    if (str != NULL)
3
        pw_properties_update_string(pw->props, str, strlen(str));
4
 
5
+   if ((str = pw_properties_get(pw->props, "alsa.deny")) != NULL &&
6
+       spa_atob(str)) {
7
+       err = -EACCES;
8
+       goto error;
9
+   }
10
+
11
    str = getenv("PIPEWIRE_NODE");
12
    if (str != NULL && str0)
13
        pw_properties_set(pw->props, PW_KEY_TARGET_OBJECT, str);
14
pipewire-0.3.81.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.82.tar.gz/pipewire-jack/src/pipewire-jack.c Changed
95
 
1
@@ -1332,15 +1332,6 @@
2
    return b.state.offset;
3
 }
4
 
5
-static inline void fix_midi_event(uint8_t *data, size_t size)
6
-{
7
-   /* fixup NoteOn with vel 0 */
8
-   if (size > 2 && (data0 & 0xF0) == 0x90 && data2 == 0x00) {
9
-       data0 = 0x80 + (data0 & 0x0F);
10
-       data2 = 0x40;
11
-   }
12
-}
13
-
14
 static inline int event_sort(struct spa_pod_control *a, struct spa_pod_control *b)
15
 {
16
    if (a->offset < b->offset)
17
@@ -1373,6 +1364,29 @@
18
    }
19
 }
20
 
21
+static inline void fix_midi_event(uint8_t *data, size_t size)
22
+{
23
+   /* fixup NoteOn with vel 0 */
24
+   if (size > 2 && (data0 & 0xF0) == 0x90 && data2 == 0x00) {
25
+       data0 = 0x80 + (data0 & 0x0F);
26
+       data2 = 0x40;
27
+   }
28
+}
29
+
30
+static inline int midi_event_write(void *port_buffer,
31
+                      jack_nframes_t time,
32
+                      const jack_midi_data_t *data,
33
+                      size_t data_size, bool fix)
34
+{
35
+   jack_midi_data_t *retbuf = jack_midi_event_reserve (port_buffer, time, data_size);
36
+        if (SPA_UNLIKELY(retbuf == NULL))
37
+                return -ENOBUFS;
38
+   memcpy (retbuf, data, data_size);
39
+   if (fix)
40
+       fix_midi_event(retbuf, data_size);
41
+   return 0;
42
+}
43
+
44
 static void convert_to_midi(struct spa_pod_sequence **seq, uint32_t n_seq, void *midi, bool fix)
45
 {
46
    struct spa_pod_control *cn_seq;
47
@@ -1405,10 +1419,7 @@
48
            uint8_t *data = SPA_POD_BODY(&next->value);
49
            size_t size = SPA_POD_BODY_SIZE(&next->value);
50
 
51
-           if (fix)
52
-               fix_midi_event(data, size);
53
-
54
-           if ((res = jack_midi_event_write(midi, next->offset, data, size)) < 0)
55
+           if ((res = midi_event_write(midi, next->offset, data, size, fix)) < 0)
56
                pw_log_warn("midi %p: can't write event: %s", midi,
57
                        spa_strerror(res));
58
            break;
59
@@ -3804,10 +3815,10 @@
60
    if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) {
61
        struct spa_fraction q;
62
        if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) {
63
-           pw_properties_setf(client->props, PW_KEY_NODE_RATE,
64
+           pw_properties_setf(client->props, PW_KEY_NODE_FORCE_RATE,
65
                    "1/%u", q.denom);
66
-           pw_properties_setf(client->props, PW_KEY_NODE_LATENCY,
67
-                   "%u/%u", q.num, q.denom);
68
+           pw_properties_setf(client->props, PW_KEY_NODE_FORCE_QUANTUM,
69
+                   "%u", q.num);
70
        } else {
71
            pw_log_warn("invalid PIPEWIRE_QUANTUM: %s", str);
72
        }
73
@@ -3828,7 +3839,7 @@
74
    if (pw_properties_get(client->props, PW_KEY_NODE_NAME) == NULL)
75
        pw_properties_set(client->props, PW_KEY_NODE_NAME, client_name);
76
    if (pw_properties_get(client->props, PW_KEY_NODE_GROUP) == NULL)
77
-       pw_properties_setf(client->props, PW_KEY_NODE_GROUP, "jack-%d", getpid());
78
+       pw_properties_setf(client->props, PW_KEY_NODE_GROUP, "group.dsp.0");
79
    if (pw_properties_get(client->props, PW_KEY_NODE_DESCRIPTION) == NULL)
80
        pw_properties_set(client->props, PW_KEY_NODE_DESCRIPTION, client_name);
81
    if (pw_properties_get(client->props, PW_KEY_MEDIA_TYPE) == NULL)
82
@@ -6924,11 +6935,7 @@
83
                       const jack_midi_data_t *data,
84
                       size_t data_size)
85
 {
86
-   jack_midi_data_t *retbuf = jack_midi_event_reserve (port_buffer, time, data_size);
87
-        if (SPA_UNLIKELY(retbuf == NULL))
88
-                return -ENOBUFS;
89
-   memcpy (retbuf, data, data_size);
90
-   return 0;
91
+   return midi_event_write(port_buffer, time, data, data_size, false);
92
 }
93
 
94
 SPA_EXPORT
95
pipewire-0.3.81.tar.gz/spa/include/meson.build -> pipewire-0.3.82.tar.gz/spa/include/meson.build Changed
9
 
1
@@ -15,7 +15,4 @@
2
 spa_headers = 'spa'  # used by doxygen
3
 install_subdir('spa',
4
   install_dir : get_option('includedir') / spa_name,
5
-  exclude_files : 
6
-    'utils/cleanup.h',
7
-  ,
8
 )
9
pipewire-0.3.81.tar.gz/spa/include/spa/pod/dynamic.h -> pipewire-0.3.82.tar.gz/spa/include/spa/pod/dynamic.h Changed
40
 
1
@@ -10,6 +10,7 @@
2
 #endif
3
 
4
 #include <spa/pod/builder.h>
5
+#include <spa/utils/cleanup.h>
6
 
7
 struct spa_pod_dynamic_builder {
8
    struct spa_pod_builder b;
9
@@ -23,14 +24,15 @@
10
    struct spa_pod_dynamic_builder *d = (struct spa_pod_dynamic_builder*)data;
11
    int32_t old_size = d->b.size;
12
    int32_t new_size = SPA_ROUND_UP_N(size, d->extend);
13
-   void *old_data = d->b.data;
14
+   void *old_data = d->b.data, *new_data;
15
 
16
    if (old_data == d->data)
17
        d->b.data = NULL;
18
-   if ((d->b.data = realloc(d->b.data, new_size)) == NULL)
19
+   if ((new_data = realloc(d->b.data, new_size)) == NULL)
20
        return -errno;
21
-   if (old_data == d->data && d->b.data != old_data && old_size > 0)
22
-       memcpy(d->b.data, old_data, old_size);
23
+   if (old_data == d->data && new_data != old_data && old_size > 0)
24
+       memcpy(new_data, old_data, old_size);
25
+   d->b.data = new_data;
26
    d->b.size = new_size;
27
         return 0;
28
 }
29
@@ -54,6 +56,10 @@
30
        free(builder->b.data);
31
 }
32
 
33
+SPA_DEFINE_AUTO_CLEANUP(spa_pod_dynamic_builder, struct spa_pod_dynamic_builder, {
34
+   spa_pod_dynamic_builder_clean(thing);
35
+})
36
+
37
 #ifdef __cplusplus
38
 }  /* extern "C" */
39
 #endif
40
pipewire-0.3.81.tar.gz/spa/include/spa/support/log.h -> pipewire-0.3.82.tar.gz/spa/include/spa/support/log.h Changed
53
 
1
@@ -194,28 +194,29 @@
2
 #define SPA_LOG_TOPIC(v, t) \
3
    (struct spa_log_topic){ .version = (v), .topic = (t)}
4
 
5
-#define spa_log_topic_init(l, topic)               \
6
-do {                               \
7
-   struct spa_log *_l = l;                 \
8
-   if (SPA_LIKELY(_l)) {                   \
9
-       struct spa_interface *_if = &_l->iface;     \
10
-       spa_interface_call(_if, struct spa_log_methods, \
11
-               topic_init, 1, topic);      \
12
-   }                           \
13
-} while(0)
14
-
15
-/* Unused, left for backwards compat */
16
-#define spa_log_level_enabled(l,lev) ((l) && (l)->level >= (lev))
17
-
18
-#define spa_log_level_topic_enabled(l,topic,lev)       \
19
-({                             \
20
-   struct spa_log *_log = l;               \
21
-   enum spa_log_level _lev = _log ? _log->level : SPA_LOG_LEVEL_NONE;      \
22
-   struct spa_log_topic *_t = (struct spa_log_topic *)(topic); \
23
-   if (_t && _t->has_custom_level)                         \
24
-       _lev = _t->level;               \
25
-   _lev >= (lev);                      \
26
-})
27
+static inline void spa_log_topic_init(struct spa_log *log, struct spa_log_topic *topic)
28
+{
29
+   if (SPA_UNLIKELY(!log))
30
+       return;
31
+
32
+   spa_interface_call(&log->iface, struct spa_log_methods, topic_init, 1, topic);
33
+}
34
+
35
+static inline bool spa_log_level_topic_enabled(const struct spa_log *log,
36
+                          const struct spa_log_topic *topic,
37
+                          enum spa_log_level level)
38
+{
39
+   enum spa_log_level max_level;
40
+
41
+   if (topic && topic->has_custom_level)
42
+       max_level = topic->level;
43
+   else if (log)
44
+       max_level = log->level;
45
+   else
46
+       max_level = SPA_LOG_LEVEL_NONE;
47
+
48
+   return level <= max_level;
49
+}
50
 
51
 /* Transparently calls to version 0 log if v1 is not supported */
52
 #define spa_log_logt(l,lev,topic,...)                  \
53
pipewire-0.3.81.tar.gz/spa/include/spa/utils/cleanup.h -> pipewire-0.3.82.tar.gz/spa/include/spa/utils/cleanup.h Changed
116
 
1
@@ -5,10 +5,48 @@
2
 #ifndef SPA_UTILS_CLEANUP_H
3
 #define SPA_UTILS_CLEANUP_H
4
 
5
-#if !defined(__has_attribute) || !__has_attribute(__cleanup__)
6
-#error "attribute `cleanup` is required"
7
+#define spa_exchange(var, new_value) \
8
+__extension__ ({ \
9
+   __typeof__(var) *_ptr = &(var); \
10
+   __typeof__(var) _old_value = *_ptr; \
11
+   *_ptr = (new_value); \
12
+   _old_value; \
13
+})
14
+
15
+/* ========================================================================== */
16
+
17
+#if __GNUC__ >= 10 || defined(__clang__)
18
+#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL))
19
+#else
20
+#define spa_steal_ptr(ptr) spa_exchange((ptr), NULL)
21
 #endif
22
 
23
+#define spa_clear_ptr(ptr, destructor) \
24
+__extension__ ({ \
25
+   __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \
26
+   if (_old_value) \
27
+       destructor(_old_value); \
28
+   (void) 0; \
29
+})
30
+
31
+/* ========================================================================== */
32
+
33
+#include <unistd.h>
34
+
35
+#define spa_steal_fd(fd) spa_exchange((fd), -1)
36
+
37
+#define spa_clear_fd(fd) \
38
+__extension__ ({ \
39
+   int _old_value = spa_steal_fd(fd), _res = 0; \
40
+   if (_old_value >= 0) \
41
+       _res = close(_old_value); \
42
+   _res; \
43
+})
44
+
45
+/* ========================================================================== */
46
+
47
+#if defined(__has_attribute) && __has_attribute(__cleanup__)
48
+
49
 #define spa_cleanup(func) __attribute__((__cleanup__(func)))
50
 
51
 #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \
52
@@ -33,34 +71,10 @@
53
    spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \
54
    _spa_autoptr_cleanup_type_ ## name
55
 
56
-#define spa_exchange(var, new_value) \
57
-__extension__ ({ \
58
-   __typeof__(var) *_ptr = &(var); \
59
-   __typeof__(var) _old_value = *_ptr; \
60
-   *_ptr = (new_value); \
61
-   _old_value; \
62
-})
63
-
64
-#if __GNUC__ >= 10 || defined(__clang__)
65
-#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL))
66
-#else
67
-#define spa_steal_ptr(ptr) spa_exchange((ptr), NULL)
68
-#endif
69
-
70
-#define spa_steal_fd(fd) spa_exchange((fd), -1)
71
-
72
 /* ========================================================================== */
73
 
74
 #include <stdlib.h>
75
 
76
-#define spa_clear_ptr(ptr, destructor) \
77
-__extension__ ({ \
78
-   __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \
79
-   if (_old_value) \
80
-       destructor(_old_value); \
81
-   (void) 0; \
82
-})
83
-
84
 static inline void _spa_autofree_cleanup_func(void *p)
85
 {
86
    free(*(void **) p);
87
@@ -69,16 +83,6 @@
88
 
89
 /* ========================================================================== */
90
 
91
-#include <unistd.h>
92
-
93
-#define spa_clear_fd(fd) \
94
-__extension__ ({ \
95
-   int _old_value = spa_steal_fd(fd), _res = 0; \
96
-   if (_old_value >= 0) \
97
-       _res = close(_old_value); \
98
-   _res; \
99
-})
100
-
101
 static inline void _spa_autoclose_cleanup_func(int *fd)
102
 {
103
    spa_clear_fd(*fd);
104
@@ -101,4 +105,11 @@
105
    spa_clear_ptr(*thing, closedir);
106
 })
107
 
108
+#else
109
+
110
+#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...)
111
+#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...)
112
+
113
+#endif
114
+
115
 #endif /* SPA_UTILS_CLEANUP_H */
116
pipewire-0.3.81.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/acp/acp.c Changed
65
 
1
@@ -296,7 +296,7 @@
2
 static int add_pro_profile(pa_card *impl, uint32_t index)
3
 {
4
    snd_ctl_t *ctl_hndl;
5
-   int err, dev, count = 0;
6
+   int err, dev, count = 0, n_capture = 0, n_playback = 0;
7
    pa_alsa_profile *ap;
8
    pa_alsa_profile_set *ps = impl->profile_set;
9
    pa_alsa_mapping *m;
10
@@ -304,6 +304,7 @@
11
    snd_pcm_info_t *pcminfo;
12
    pa_sample_spec ss;
13
    snd_pcm_uframes_t try_period_size, try_buffer_size;
14
+   uint32_t idx;
15
 
16
    if (impl->use_ucm) {
17
        const char *verb = find_best_verb(impl);
18
@@ -388,11 +389,10 @@
19
                pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm);
20
                pa_proplist_setf(m->output_proplist, "clock.name", "api.alsa.%u", index);
21
                pa_proplist_setf(m->output_proplist, "device.profile.pro", "true");
22
-               pa_proplist_setf(m->output_proplist, "node.group", "pro-audio-%u", index);
23
-               pa_proplist_setf(m->output_proplist, "node.link-group", "pro-audio-%u", index);
24
                pa_alsa_close(&m->output_pcm);
25
                m->supported = true;
26
                pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX);
27
+               n_playback++;
28
            }
29
            pa_idxset_put(ap->output_mappings, m, NULL);
30
            free(name);
31
@@ -421,11 +421,10 @@
32
                pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm);
33
                pa_proplist_setf(m->input_proplist, "clock.name", "api.alsa.%u", index);
34
                pa_proplist_setf(m->input_proplist, "device.profile.pro", "true");
35
-               pa_proplist_setf(m->input_proplist, "node.group", "pro-audio-%u", index);
36
-               pa_proplist_setf(m->input_proplist, "node.link-group", "pro-audio-%u", index);
37
                pa_alsa_close(&m->input_pcm);
38
                m->supported = true;
39
                pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX);
40
+               n_capture++;
41
            }
42
            pa_idxset_put(ap->input_mappings, m, NULL);
43
            free(name);
44
@@ -433,6 +432,20 @@
45
    }
46
    snd_ctl_close(ctl_hndl);
47
 
48
+   if (n_capture == 1 && n_playback == 1) {
49
+       PA_IDXSET_FOREACH(m, ap->output_mappings, idx) {
50
+           pa_proplist_setf(m->output_proplist, "node.group", "pro-audio-%u", index);
51
+           pa_proplist_setf(m->output_proplist, "node.link-group", "pro-audio-%u", index);
52
+           pa_proplist_setf(m->output_proplist, "api.alsa.auto-link", "true");
53
+           pa_proplist_setf(m->output_proplist, "api.alsa.disable-tsched", "true");
54
+       }
55
+       PA_IDXSET_FOREACH(m, ap->input_mappings, idx) {
56
+           pa_proplist_setf(m->input_proplist, "node.group", "pro-audio-%u", index);
57
+           pa_proplist_setf(m->input_proplist, "node.link-group", "pro-audio-%u", index);
58
+           pa_proplist_setf(m->input_proplist, "api.alsa.auto-link", "true");
59
+           pa_proplist_setf(m->input_proplist, "api.alsa.disable-tsched", "true");
60
+       }
61
+   }
62
    return 0;
63
 }
64
 
65
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-acp-device.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-acp-device.c Changed
83
 
1
@@ -26,6 +26,7 @@
2
 #include <spa/param/param.h>
3
 #include <spa/pod/filter.h>
4
 #include <spa/pod/parser.h>
5
+#include <spa/pod/dynamic.h>
6
 #include <spa/debug/pod.h>
7
 #include <spa/debug/log.h>
8
 
9
@@ -484,7 +485,8 @@
10
 {
11
    struct impl *this = object;
12
    struct spa_pod *param;
13
-   struct spa_pod_builder b = { 0 };
14
+   spa_auto(spa_pod_dynamic_builder) b = { 0 };
15
+   struct spa_pod_builder_state state;
16
    uint8_t buffer4096;
17
    struct spa_result_device_params result;
18
    uint32_t count = 0;
19
@@ -496,6 +498,9 @@
20
    spa_return_val_if_fail(this != NULL, -EINVAL);
21
    spa_return_val_if_fail(num != 0, -EINVAL);
22
 
23
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
24
+   spa_pod_builder_get_state(&b.b, &state);
25
+
26
    card = this->card;
27
 
28
    result.id = id;
29
@@ -503,7 +508,7 @@
30
       next:
31
    result.index = result.next++;
32
 
33
-   spa_pod_builder_init(&b, buffer, sizeof(buffer));
34
+   spa_pod_builder_reset(&b.b, &state);
35
 
36
    switch (id) {
37
    case SPA_PARAM_EnumProfile:
38
@@ -511,7 +516,7 @@
39
            return 0;
40
 
41
        pr = card->profilesresult.index;
42
-       param = build_profile(&b, id, pr, false);
43
+       param = build_profile(&b.b, id, pr, false);
44
        break;
45
 
46
    case SPA_PARAM_Profile:
47
@@ -519,7 +524,7 @@
48
            return 0;
49
 
50
        pr = card->profilescard->active_profile_index;
51
-       param = build_profile(&b, id, pr, true);
52
+       param = build_profile(&b.b, id, pr, true);
53
        break;
54
 
55
    case SPA_PARAM_EnumRoute:
56
@@ -527,7 +532,7 @@
57
            return 0;
58
 
59
        p = card->portsresult.index;
60
-       param = build_route(&b, id, p, NULL, SPA_ID_INVALID);
61
+       param = build_route(&b.b, id, p, NULL, SPA_ID_INVALID);
62
        break;
63
 
64
    case SPA_PARAM_Route:
65
@@ -543,7 +548,7 @@
66
            result.index++;
67
        }
68
        result.next = result.index + 1;
69
-       param = build_route(&b, id, p, dev, card->active_profile_index);
70
+       param = build_route(&b.b, id, p, dev, card->active_profile_index);
71
        if (param == NULL)
72
            return -errno;
73
        break;
74
@@ -552,7 +557,7 @@
75
        return -ENOENT;
76
    }
77
 
78
-   if (spa_pod_filter(&b, &result.param, param, filter) < 0)
79
+   if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
80
        goto next;
81
 
82
    spa_device_emit_result(&this->hooks, seq, 0,
83
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c Changed
201
 
1
@@ -15,6 +15,7 @@
2
 #include <spa/utils/string.h>
3
 #include <spa/param/audio/format.h>
4
 #include <spa/pod/filter.h>
5
+#include <spa/pod/dynamic.h>
6
 #include <spa/debug/log.h>
7
 #include <spa/debug/pod.h>
8
 
9
@@ -100,7 +101,8 @@
10
 {
11
    struct state *this = object;
12
    struct spa_pod *param;
13
-   struct spa_pod_builder b = { 0 };
14
+   spa_auto(spa_pod_dynamic_builder) b = { 0 };
15
+   struct spa_pod_builder_state state;
16
    uint8_t buffer4096;
17
    struct spa_result_node_params result;
18
    uint32_t count = 0;
19
@@ -108,12 +110,15 @@
20
    spa_return_val_if_fail(this != NULL, -EINVAL);
21
    spa_return_val_if_fail(num != 0, -EINVAL);
22
 
23
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
24
+   spa_pod_builder_get_state(&b.b, &state);
25
+
26
    result.id = id;
27
    result.next = start;
28
-      next:
29
+next:
30
    result.index = result.next++;
31
 
32
-   spa_pod_builder_init(&b, buffer, sizeof(buffer));
33
+   spa_pod_builder_reset(&b.b, &state);
34
 
35
    switch (id) {
36
    case SPA_PARAM_PropInfo:
37
@@ -122,7 +127,7 @@
38
 
39
        switch (result.index) {
40
        case 0:
41
-           param = spa_pod_builder_add_object(&b,
42
+           param = spa_pod_builder_add_object(&b.b,
43
                SPA_TYPE_OBJECT_PropInfo, id,
44
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_device),
45
                SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH),
46
@@ -130,21 +135,21 @@
47
                SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device)));
48
            break;
49
        case 1:
50
-           param = spa_pod_builder_add_object(&b,
51
+           param = spa_pod_builder_add_object(&b.b,
52
                SPA_TYPE_OBJECT_PropInfo, id,
53
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_deviceName),
54
                SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"),
55
                SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)));
56
            break;
57
        case 2:
58
-           param = spa_pod_builder_add_object(&b,
59
+           param = spa_pod_builder_add_object(&b.b,
60
                SPA_TYPE_OBJECT_PropInfo, id,
61
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_cardName),
62
                SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"),
63
                SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)));
64
            break;
65
        case 3:
66
-           param = spa_pod_builder_add_object(&b,
67
+           param = spa_pod_builder_add_object(&b.b,
68
                SPA_TYPE_OBJECT_PropInfo, id,
69
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_latencyOffsetNsec),
70
                SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"),
71
@@ -153,7 +158,7 @@
72
        case 4:
73
            if (!this->is_iec958 && !this->is_hdmi)
74
                goto next;
75
-           param = spa_pod_builder_add_object(&b,
76
+           param = spa_pod_builder_add_object(&b.b,
77
                SPA_TYPE_OBJECT_PropInfo, id,
78
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_iec958Codecs),
79
                SPA_PROP_INFO_name, SPA_POD_String("iec958.codecs"),
80
@@ -163,7 +168,7 @@
81
                                 SPA_PROP_INFO_container, SPA_POD_Id(SPA_TYPE_Array));
82
            break;
83
        default:
84
-           param = spa_alsa_enum_propinfo(this, result.index - 5, &b);
85
+           param = spa_alsa_enum_propinfo(this, result.index - 5, &b.b);
86
            if (param == NULL)
87
                return 0;
88
        }
89
@@ -177,9 +182,9 @@
90
 
91
        switch (result.index) {
92
        case 0:
93
-           spa_pod_builder_push_object(&b, &f,
94
+           spa_pod_builder_push_object(&b.b, &f,
95
                                 SPA_TYPE_OBJECT_Props, id);
96
-           spa_pod_builder_add(&b,
97
+           spa_pod_builder_add(&b.b,
98
                SPA_PROP_device,       SPA_POD_Stringn(p->device, sizeof(p->device)),
99
                SPA_PROP_deviceName,   SPA_POD_Stringn(p->device_name, sizeof(p->device_name)),
100
                SPA_PROP_cardName,     SPA_POD_Stringn(p->card_name, sizeof(p->card_name)),
101
@@ -188,12 +193,12 @@
102
 
103
            if (this->is_iec958 || this->is_hdmi) {
104
                n_codecs = spa_alsa_get_iec958_codecs(this, codecs, SPA_N_ELEMENTS(codecs));
105
-               spa_pod_builder_prop(&b, SPA_PROP_iec958Codecs, 0);
106
-               spa_pod_builder_array(&b, sizeof(uint32_t), SPA_TYPE_Id,
107
+               spa_pod_builder_prop(&b.b, SPA_PROP_iec958Codecs, 0);
108
+               spa_pod_builder_array(&b.b, sizeof(uint32_t), SPA_TYPE_Id,
109
                        n_codecs, codecs);
110
            }
111
-           spa_alsa_add_prop_params(this, &b);
112
-           param = spa_pod_builder_pop(&b, &f);
113
+           spa_alsa_add_prop_params(this, &b.b);
114
+           param = spa_pod_builder_pop(&b.b, &f);
115
            break;
116
        default:
117
            return 0;
118
@@ -203,13 +208,13 @@
119
    case SPA_PARAM_IO:
120
        switch (result.index) {
121
        case 0:
122
-           param = spa_pod_builder_add_object(&b,
123
+           param = spa_pod_builder_add_object(&b.b,
124
                SPA_TYPE_OBJECT_ParamIO, id,
125
                SPA_PARAM_IO_id,   SPA_POD_Id(SPA_IO_Clock),
126
                SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock)));
127
            break;
128
        case 1:
129
-           param = spa_pod_builder_add_object(&b,
130
+           param = spa_pod_builder_add_object(&b.b,
131
                SPA_TYPE_OBJECT_ParamIO, id,
132
                SPA_PARAM_IO_id,   SPA_POD_Id(SPA_IO_Position),
133
                SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position)));
134
@@ -222,7 +227,7 @@
135
    case SPA_PARAM_ProcessLatency:
136
        switch (result.index) {
137
        case 0:
138
-           param = spa_process_latency_build(&b, id, &this->process_latency);
139
+           param = spa_process_latency_build(&b.b, id, &this->process_latency);
140
            break;
141
        default:
142
            return 0;
143
@@ -233,7 +238,7 @@
144
        return -ENOENT;
145
    }
146
 
147
-   if (spa_pod_filter(&b, &result.param, param, filter) < 0)
148
+   if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
149
        goto next;
150
 
151
    spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
152
@@ -469,7 +474,8 @@
153
 
154
    struct state *this = object;
155
    struct spa_pod *param;
156
-   struct spa_pod_builder b = { 0 };
157
+   spa_auto(spa_pod_dynamic_builder) b = { 0 };
158
+   struct spa_pod_builder_state state;
159
    uint8_t buffer1024;
160
    struct spa_result_node_params result;
161
    uint32_t count = 0;
162
@@ -479,12 +485,15 @@
163
 
164
    spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
165
 
166
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
167
+   spa_pod_builder_get_state(&b.b, &state);
168
+
169
    result.id = id;
170
    result.next = start;
171
       next:
172
    result.index = result.next++;
173
 
174
-   spa_pod_builder_init(&b, buffer, sizeof(buffer));
175
+   spa_pod_builder_reset(&b.b, &state);
176
 
177
    switch (id) {
178
    case SPA_PARAM_EnumFormat:
179
@@ -498,15 +507,15 @@
180
 
181
        switch (this->current_format.media_subtype) {
182
        case SPA_MEDIA_SUBTYPE_raw:
183
-           param = spa_format_audio_raw_build(&b, id,
184
+           param = spa_format_audio_raw_build(&b.b, id,
185
                    &this->current_format.info.raw);
186
            break;
187
        case SPA_MEDIA_SUBTYPE_iec958:
188
-           param = spa_format_audio_iec958_build(&b, id,
189
+           param = spa_format_audio_iec958_build(&b.b, id,
190
                    &this->current_format.info.iec958);
191
            break;
192
        case SPA_MEDIA_SUBTYPE_dsd:
193
-           param = spa_format_audio_dsd_build(&b, id,
194
+           param = spa_format_audio_dsd_build(&b.b, id,
195
                    &this->current_format.info.dsd);
196
            break;
197
        default:
198
@@ -520,7 +529,7 @@
199
        if (result.index > 0)
200
            return 0;
201
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm-source.c Changed
201
 
1
@@ -16,6 +16,7 @@
2
 #include <spa/monitor/device.h>
3
 #include <spa/param/audio/format.h>
4
 #include <spa/pod/filter.h>
5
+#include <spa/pod/dynamic.h>
6
 
7
 #include "alsa.h"
8
 
9
@@ -100,7 +101,8 @@
10
    struct state *this = object;
11
    struct spa_pod *param;
12
    uint8_t buffer4096;
13
-   struct spa_pod_builder b = { 0 };
14
+   spa_auto(spa_pod_dynamic_builder) b = { 0 };
15
+   struct spa_pod_builder_state state;
16
    struct props *p;
17
    struct spa_result_node_params result;
18
    uint32_t count = 0;
19
@@ -108,6 +110,9 @@
20
    spa_return_val_if_fail(this != NULL, -EINVAL);
21
    spa_return_val_if_fail(num != 0, -EINVAL);
22
 
23
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
24
+   spa_pod_builder_get_state(&b.b, &state);
25
+
26
    p = &this->props;
27
 
28
    result.id = id;
29
@@ -115,13 +120,13 @@
30
       next:
31
    result.index = result.next++;
32
 
33
-   spa_pod_builder_init(&b, buffer, sizeof(buffer));
34
+   spa_pod_builder_reset(&b.b, &state);
35
 
36
    switch (id) {
37
    case SPA_PARAM_PropInfo:
38
        switch (result.index) {
39
        case 0:
40
-           param = spa_pod_builder_add_object(&b,
41
+           param = spa_pod_builder_add_object(&b.b,
42
                SPA_TYPE_OBJECT_PropInfo, id,
43
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_device),
44
                SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH),
45
@@ -129,28 +134,28 @@
46
                SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device)));
47
            break;
48
        case 1:
49
-           param = spa_pod_builder_add_object(&b,
50
+           param = spa_pod_builder_add_object(&b.b,
51
                SPA_TYPE_OBJECT_PropInfo, id,
52
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_deviceName),
53
                SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"),
54
                SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)));
55
            break;
56
        case 2:
57
-           param = spa_pod_builder_add_object(&b,
58
+           param = spa_pod_builder_add_object(&b.b,
59
                SPA_TYPE_OBJECT_PropInfo, id,
60
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_cardName),
61
                SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"),
62
                SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)));
63
            break;
64
        case 3:
65
-           param = spa_pod_builder_add_object(&b,
66
+           param = spa_pod_builder_add_object(&b.b,
67
                SPA_TYPE_OBJECT_PropInfo, id,
68
                SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_latencyOffsetNsec),
69
                SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"),
70
                SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0LL, 0LL, 2 * SPA_NSEC_PER_SEC));
71
            break;
72
        default:
73
-           param = spa_alsa_enum_propinfo(this, result.index - 4, &b);
74
+           param = spa_alsa_enum_propinfo(this, result.index - 4, &b.b);
75
            if (param == NULL)
76
                return 0;
77
        }
78
@@ -162,16 +167,16 @@
79
 
80
        switch (result.index) {
81
        case 0:
82
-           spa_pod_builder_push_object(&b, &f,
83
+           spa_pod_builder_push_object(&b.b, &f,
84
                                 SPA_TYPE_OBJECT_Props, id);
85
-           spa_pod_builder_add(&b,
86
+           spa_pod_builder_add(&b.b,
87
                SPA_PROP_device,       SPA_POD_Stringn(p->device, sizeof(p->device)),
88
                SPA_PROP_deviceName,   SPA_POD_Stringn(p->device_name, sizeof(p->device_name)),
89
                SPA_PROP_cardName,     SPA_POD_Stringn(p->card_name, sizeof(p->card_name)),
90
                SPA_PROP_latencyOffsetNsec,   SPA_POD_Long(this->process_latency.ns),
91
                0);
92
-           spa_alsa_add_prop_params(this, &b);
93
-           param = spa_pod_builder_pop(&b, &f);
94
+           spa_alsa_add_prop_params(this, &b.b);
95
+           param = spa_pod_builder_pop(&b.b, &f);
96
            break;
97
        default:
98
            return 0;
99
@@ -181,13 +186,13 @@
100
    case SPA_PARAM_IO:
101
        switch (result.index) {
102
        case 0:
103
-           param = spa_pod_builder_add_object(&b,
104
+           param = spa_pod_builder_add_object(&b.b,
105
                SPA_TYPE_OBJECT_ParamIO, id,
106
                SPA_PARAM_IO_id,   SPA_POD_Id(SPA_IO_Clock),
107
                SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock)));
108
            break;
109
        case 1:
110
-           param = spa_pod_builder_add_object(&b,
111
+           param = spa_pod_builder_add_object(&b.b,
112
                SPA_TYPE_OBJECT_ParamIO, id,
113
                SPA_PARAM_IO_id,   SPA_POD_Id(SPA_IO_Position),
114
                SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position)));
115
@@ -200,7 +205,7 @@
116
    case SPA_PARAM_ProcessLatency:
117
        switch (result.index) {
118
        case 0:
119
-           param = spa_process_latency_build(&b, id, &this->process_latency);
120
+           param = spa_process_latency_build(&b.b, id, &this->process_latency);
121
            break;
122
        default:
123
            return 0;
124
@@ -211,7 +216,7 @@
125
        return -ENOENT;
126
    }
127
 
128
-   if (spa_pod_filter(&b, &result.param, param, filter) < 0)
129
+   if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
130
        goto next;
131
 
132
    spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
133
@@ -431,22 +436,25 @@
134
 {
135
    struct state *this = object;
136
    struct spa_pod *param;
137
-   struct spa_pod_builder b = { 0 };
138
+   spa_auto(spa_pod_dynamic_builder) b = { 0 };
139
+   struct spa_pod_builder_state state;
140
    uint8_t buffer1024;
141
    struct spa_result_node_params result;
142
    uint32_t count = 0;
143
 
144
    spa_return_val_if_fail(this != NULL, -EINVAL);
145
    spa_return_val_if_fail(num != 0, -EINVAL);
146
-
147
    spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
148
 
149
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
150
+   spa_pod_builder_get_state(&b.b, &state);
151
+
152
    result.id = id;
153
    result.next = start;
154
       next:
155
    result.index = result.next++;
156
 
157
-   spa_pod_builder_init(&b, buffer, sizeof(buffer));
158
+   spa_pod_builder_reset(&b.b, &state);
159
 
160
    switch (id) {
161
    case SPA_PARAM_EnumFormat:
162
@@ -458,7 +466,7 @@
163
        if (result.index > 0)
164
            return 0;
165
 
166
-       param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw);
167
+       param = spa_format_audio_raw_build(&b.b, id, &this->current_format.info.raw);
168
        break;
169
 
170
    case SPA_PARAM_Buffers:
171
@@ -467,7 +475,7 @@
172
        if (result.index > 0)
173
            return 0;
174
 
175
-       param = spa_pod_builder_add_object(&b,
176
+       param = spa_pod_builder_add_object(&b.b,
177
            SPA_TYPE_OBJECT_ParamBuffers, id,
178
            SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS),
179
            SPA_PARAM_BUFFERS_blocks,  SPA_POD_Int(this->blocks),
180
@@ -481,7 +489,7 @@
181
    case SPA_PARAM_Meta:
182
        switch (result.index) {
183
        case 0:
184
-           param = spa_pod_builder_add_object(&b,
185
+           param = spa_pod_builder_add_object(&b.b,
186
                SPA_TYPE_OBJECT_ParamMeta, id,
187
                SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
188
                SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
189
@@ -494,13 +502,13 @@
190
    case SPA_PARAM_IO:
191
        switch (result.index) {
192
        case 0:
193
-           param = spa_pod_builder_add_object(&b,
194
+           param = spa_pod_builder_add_object(&b.b,
195
                SPA_TYPE_OBJECT_ParamIO, id,
196
                SPA_PARAM_IO_id,   SPA_POD_Id(SPA_IO_Buffers),
197
                SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
198
            break;
199
        case 1:
200
-           param = spa_pod_builder_add_object(&b,
201
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm.c Changed
138
 
1
@@ -131,6 +131,8 @@
2
        state->multi_rate = spa_atob(s);
3
    } else if (spa_streq(k, "api.alsa.htimestamp")) {
4
        state->htimestamp = spa_atob(s);
5
+   } else if (spa_streq(k, "api.alsa.auto-link")) {
6
+       state->auto_link = spa_atob(s);
7
    } else if (spa_streq(k, "latency.internal.rate")) {
8
        state->process_latency.rate = atoi(s);
9
    } else if (spa_streq(k, "latency.internal.ns")) {
10
@@ -512,7 +514,6 @@
11
 
12
    state->multi_rate = true;
13
    state->htimestamp = false;
14
-   state->disable_tsched = state->is_pro;
15
    for (i = 0; info && i < info->n_items; i++) {
16
        const char *k = info->itemsi.key;
17
        const char *s = info->itemsi.value;
18
@@ -574,6 +575,9 @@
19
        spa_log_warn(state->log, "output close failed: %s", snd_strerror(err));
20
    fclose(state->log_file);
21
 
22
+   free(state->tag0);
23
+   free(state->tag1);
24
+
25
    return err;
26
 }
27
 
28
@@ -1991,7 +1995,7 @@
29
 
30
    CHECK(set_swparams(state), "swparams");
31
 
32
-   if ((err = snd_pcm_prepare(state->hndl)) < 0 && err != -EBUSY) {
33
+   if ((!state->linked) && (err = snd_pcm_prepare(state->hndl)) < 0 && err != -EBUSY) {
34
        spa_log_error(state->log, "%s: snd_pcm_prepare error: %s",
35
                state->name, snd_strerror(err));
36
        return err;
37
@@ -2398,10 +2402,13 @@
38
    if (SPA_UNLIKELY((res = check_position_config(state)) < 0))
39
        return res;
40
 
41
-   if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0))
42
+   if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0)) {
43
+       spa_log_error(state->log, "get_status error");
44
+       state->next_time += state->threshold * 1e9 / state->rate;
45
        return res;
46
+   }
47
 
48
-   if (SPA_UNLIKELY(!following && delay > target + state->max_error)) {
49
+   if (SPA_UNLIKELY(!following && state->alsa_started && delay > target + state->max_error)) {
50
        spa_log_trace(state->log, "%p: early wakeup %ld %lu %lu", state,
51
                avail, delay, target);
52
        if (delay > target * 3)
53
@@ -2412,7 +2419,7 @@
54
    if (SPA_UNLIKELY((res = update_time(state, current_time, delay, target, following)) < 0))
55
        return res;
56
 
57
-   if (following && !state->linked) {
58
+   if (following && state->alsa_started && !state->linked) {
59
        if (SPA_UNLIKELY(state->alsa_sync)) {
60
            enum spa_log_level lev;
61
 
62
@@ -2553,11 +2560,9 @@
63
 
64
 int spa_alsa_write(struct state *state)
65
 {
66
-   int res = 0;
67
    if (state->following && state->rt.driver == NULL) {
68
        uint64_t current_time = state->position->clock.nsec;
69
-       if ((res = alsa_write_sync(state, current_time)) < 0)
70
-           return res;
71
+       alsa_write_sync(state, current_time);
72
    }
73
    return alsa_write_frames(state);
74
 }
75
@@ -2656,8 +2661,11 @@
76
    if (SPA_UNLIKELY((res = check_position_config(state)) < 0))
77
        return res;
78
 
79
-   if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0))
80
+   if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0)) {
81
+       spa_log_error(state->log, "get_status error");
82
+       state->next_time += state->threshold * 1e9 / state->rate;
83
        return res;
84
+   }
85
 
86
    if (SPA_UNLIKELY(!following && avail < state->read_size)) {
87
        spa_log_trace(state->log, "%p: early wakeup %ld %ld %ld %d", state,
88
@@ -2671,7 +2679,7 @@
89
        return res;
90
 
91
    max_read = state->buffer_frames;
92
-   if (following) {
93
+   if (following && !state->linked) {
94
        if (state->alsa_sync) {
95
            enum spa_log_level lev;
96
 
97
@@ -2767,11 +2775,9 @@
98
 
99
 int spa_alsa_read(struct state *state)
100
 {
101
-   int res;
102
    if (state->following && state->rt.driver == NULL) {
103
        uint64_t current_time = state->position->clock.nsec;
104
-       if ((res = alsa_read_sync(state, current_time)) < 0)
105
-           return res;
106
+       alsa_read_sync(state, current_time);
107
    }
108
    return alsa_read_frames(state);
109
 }
110
@@ -3019,6 +3025,9 @@
111
    struct state *follower;
112
    int err;
113
 
114
+   if (!state->opened)
115
+       return -EIO;
116
+
117
    spa_alsa_pause(state);
118
 
119
    if (state->prepared)
120
@@ -3034,7 +3043,7 @@
121
    spa_list_for_each(follower, &state->followers, driver_link) {
122
        if (follower != state && !follower->matching) {
123
            spa_alsa_prepare(follower);
124
-           if (!follower->linked)
125
+           if (!follower->linked && state->auto_link)
126
                do_link(state, follower);
127
        }
128
    }
129
@@ -3051,6 +3060,8 @@
130
 
131
    if (state->started)
132
        return 0;
133
+   else if (!state->opened)
134
+       return -EIO;
135
 
136
    spa_alsa_prepare(state);
137
 
138
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm.h Changed
36
 
1
@@ -30,6 +30,7 @@
2
 #include <spa/param/param.h>
3
 #include <spa/param/latency-utils.h>
4
 #include <spa/param/audio/format-utils.h>
5
+#include <spa/param/tag-utils.h>
6
 
7
 #include "alsa.h"
8
 
9
@@ -165,7 +166,8 @@
10
 #define PORT_Format        3
11
 #define PORT_Buffers       4
12
 #define PORT_Latency       5
13
-#define N_PORT_PARAMS      6
14
+#define PORT_Tag       6
15
+#define N_PORT_PARAMS      7
16
    struct spa_param_info port_paramsN_PORT_PARAMS;
17
    enum spa_direction port_direction;
18
    struct spa_io_buffers *io;
19
@@ -214,6 +216,7 @@
20
    unsigned int htimestamp:1;
21
    unsigned int is_pro:1;
22
    unsigned int sources_added:1;
23
+   unsigned int auto_link:1;
24
    unsigned int linked:1;
25
 
26
    uint64_t iec958_codecs;
27
@@ -233,6 +236,8 @@
28
    struct spa_latency_info latency2;
29
    struct spa_process_latency_info process_latency;
30
 
31
+   struct spa_pod *tag2;
32
+
33
    /* Rate match via an ALSA ctl */
34
    snd_ctl_t *ctl;
35
    snd_ctl_elem_value_t *pitch_elem;
36
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c Changed
9
 
1
@@ -195,6 +195,7 @@
2
    { SPA_KEY_DEVICE_API, "alsa" },
3
    { SPA_KEY_MEDIA_CLASS, "Midi/Bridge" },
4
    { SPA_KEY_NODE_DRIVER, "true" },
5
+   { "priority.driver", "1" },
6
 };
7
 
8
 static void emit_node_info(struct seq_state *this, bool full)
9
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa.c Changed
20
 
1
@@ -9,6 +9,8 @@
2
 #include <spa/support/plugin.h>
3
 #include <spa/support/log.h>
4
 
5
+#include "alsa.h"
6
+
7
 extern const struct spa_handle_factory spa_alsa_source_factory;
8
 extern const struct spa_handle_factory spa_alsa_sink_factory;
9
 extern const struct spa_handle_factory spa_alsa_udev_factory;
10
@@ -20,8 +22,7 @@
11
 extern const struct spa_handle_factory spa_alsa_compress_offload_device_factory;
12
 #endif
13
 
14
-struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.alsa");
15
-struct spa_log_topic *alsa_log_topic = &log_topic;
16
+struct spa_log_topic alsa_log_topic = SPA_LOG_TOPIC(0, "spa.alsa");
17
 
18
 SPA_EXPORT
19
 int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
20
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa.h -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa.h Changed
17
 
1
@@ -8,12 +8,12 @@
2
 #include <spa/support/log.h>
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT alsa_log_topic
6
-extern struct spa_log_topic *alsa_log_topic;
7
+#define SPA_LOG_TOPIC_DEFAULT &alsa_log_topic
8
+extern struct spa_log_topic alsa_log_topic;
9
 
10
 static inline void alsa_log_topic_init(struct spa_log *log)
11
 {
12
-   spa_log_topic_init(log, alsa_log_topic);
13
+   spa_log_topic_init(log, &alsa_log_topic);
14
 }
15
 
16
 #endif /* SPA_ALSA_H */
17
pipewire-0.3.81.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/audioadapter.c Changed
118
 
1
@@ -26,8 +26,8 @@
2
 #include <spa/debug/log.h>
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT log_topic
6
-static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.audioadapter");
7
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
8
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.audioadapter");
9
 
10
 #define DEFAULT_ALIGN  16
11
 
12
@@ -153,7 +153,8 @@
13
 {
14
    struct impl *this = object;
15
    uint8_t buffer4096;
16
-   struct spa_pod_dynamic_builder b;
17
+   spa_auto(spa_pod_dynamic_builder) b = { 0 };
18
+   struct spa_pod_builder_state state;
19
    struct spa_result_node_params result;
20
    uint32_t count = 0;
21
    int res;
22
@@ -161,6 +162,9 @@
23
    spa_return_val_if_fail(this != NULL, -EINVAL);
24
    spa_return_val_if_fail(num != 0, -EINVAL);
25
 
26
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
27
+   spa_pod_builder_get_state(&b.b, &state);
28
+
29
    result.id = id;
30
    result.next = start;
31
 next:
32
@@ -168,7 +172,7 @@
33
 
34
    spa_log_debug(this->log, "%p: %d id:%u", this, seq, id);
35
 
36
-   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
37
+   spa_pod_builder_reset(&b.b, &state);
38
 
39
    switch (id) {
40
    case SPA_PARAM_EnumPortConfig:
41
@@ -215,16 +219,12 @@
42
    default:
43
        return -ENOENT;
44
    }
45
-
46
-   if (res == 1) {
47
-       spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
48
-       count++;
49
-   }
50
-   spa_pod_dynamic_builder_clean(&b);
51
-
52
    if (res != 1)
53
        return res;
54
 
55
+   spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
56
+   count++;
57
+
58
    if (count != num)
59
        goto next;
60
 
61
@@ -580,8 +580,9 @@
62
 static int recalc_tag(struct impl *this, struct spa_node *src, enum spa_direction direction,
63
        uint32_t port_id, struct spa_node *dst)
64
 {
65
-   struct spa_pod_builder b = { 0 };
66
-   uint8_t buffer1024;
67
+   spa_auto(spa_pod_dynamic_builder) b = { 0 };
68
+   struct spa_pod_builder_state state;
69
+   uint8_t buffer2048;
70
    struct spa_pod *param;
71
    uint32_t index = 0;
72
    struct spa_tag_info info;
73
@@ -592,26 +593,25 @@
74
    if (this->target == this->follower)
75
        return 0;
76
 
77
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 2048);
78
+   spa_pod_builder_get_state(&b.b, &state);
79
+
80
    while (true) {
81
-       void *state = NULL;
82
-       spa_pod_builder_init(&b, buffer, sizeof(buffer));
83
+       void *tag_state = NULL;
84
+       spa_pod_builder_reset(&b.b, &state);
85
        if ((res = spa_node_port_enum_params_sync(src,
86
                        direction, port_id, SPA_PARAM_Tag,
87
-                       &index, NULL, &param, &b)) != 1) {
88
+                       &index, NULL, &param, &b.b)) != 1) {
89
            param = NULL;
90
            break;
91
        }
92
-       if ((res = spa_tag_parse(param, &info, &state)) < 0)
93
+       if ((res = spa_tag_parse(param, &info, &tag_state)) < 0)
94
            return res;
95
        if (info.direction == direction)
96
            break;
97
    }
98
-   if ((res = spa_node_port_set_param(dst,
99
-                   SPA_DIRECTION_REVERSE(direction), 0,
100
-                   SPA_PARAM_Tag, 0, param)) < 0)
101
-       return res;
102
-
103
-   return 0;
104
+   return spa_node_port_set_param(dst, SPA_DIRECTION_REVERSE(direction), 0,
105
+                   SPA_PARAM_Tag, 0, param);
106
 }
107
 
108
 
109
@@ -1755,7 +1755,7 @@
110
    this = (struct impl *) handle;
111
 
112
    this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
113
-   spa_log_topic_init(this->log, log_topic);
114
+   spa_log_topic_init(this->log, &log_topic);
115
 
116
    this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
117
 
118
pipewire-0.3.81.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/audioconvert.c Changed
21
 
1
@@ -36,8 +36,8 @@
2
 #include "wavfile.h"
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT log_topic
6
-static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.audioconvert");
7
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
8
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.audioconvert");
9
 
10
 #define DEFAULT_RATE       48000
11
 #define DEFAULT_CHANNELS   2
12
@@ -3354,7 +3354,7 @@
13
    this = (struct impl *) handle;
14
 
15
    this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
16
-   spa_log_topic_init(this->log, log_topic);
17
+   spa_log_topic_init(this->log, &log_topic);
18
 
19
    this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
20
    if (this->cpu) {
21
pipewire-0.3.81.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.82.tar.gz/spa/plugins/audiomixer/audiomixer.c Changed
21
 
1
@@ -23,8 +23,8 @@
2
 #include "mix-ops.h"
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT log_topic
6
-static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.audiomixer");
7
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
8
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.audiomixer");
9
 
10
 #define DEFAULT_RATE       48000
11
 #define DEFAULT_CHANNELS   2
12
@@ -918,7 +918,7 @@
13
    this = (struct impl *) handle;
14
 
15
    this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
16
-   spa_log_topic_init(this->log, log_topic);
17
+   spa_log_topic_init(this->log, &log_topic);
18
 
19
    this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
20
    if (this->data_loop == NULL) {
21
pipewire-0.3.81.tar.gz/spa/plugins/audiomixer/mixer-dsp.c -> pipewire-0.3.82.tar.gz/spa/plugins/audiomixer/mixer-dsp.c Changed
21
 
1
@@ -23,8 +23,8 @@
2
 #include "mix-ops.h"
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT log_topic
6
-static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.mixer-dsp");
7
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
8
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.mixer-dsp");
9
 
10
 #define MAX_BUFFERS    64
11
 #define MAX_PORTS  512
12
@@ -855,7 +855,7 @@
13
    this = (struct impl *) handle;
14
 
15
    this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
16
-   spa_log_topic_init(this->log, log_topic);
17
+   spa_log_topic_init(this->log, &log_topic);
18
 
19
    this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
20
    if (this->data_loop == NULL) {
21
pipewire-0.3.81.tar.gz/spa/plugins/avb/avb.c -> pipewire-0.3.82.tar.gz/spa/plugins/avb/avb.c Changed
16
 
1
@@ -7,11 +7,12 @@
2
 #include <spa/support/plugin.h>
3
 #include <spa/support/log.h>
4
 
5
+#include "avb.h"
6
+
7
 extern const struct spa_handle_factory spa_avb_sink_factory;
8
 extern const struct spa_handle_factory spa_avb_source_factory;
9
 
10
-struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.avb");
11
-struct spa_log_topic *avb_log_topic = &log_topic;
12
+struct spa_log_topic avb_log_topic = SPA_LOG_TOPIC(0, "spa.avb");
13
 
14
 SPA_EXPORT
15
 int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
16
pipewire-0.3.81.tar.gz/spa/plugins/avb/avb.h -> pipewire-0.3.82.tar.gz/spa/plugins/avb/avb.h Changed
17
 
1
@@ -8,12 +8,12 @@
2
 #include <spa/support/log.h>
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT avb_log_topic
6
-extern struct spa_log_topic *avb_log_topic;
7
+#define SPA_LOG_TOPIC_DEFAULT &avb_log_topic
8
+extern struct spa_log_topic avb_log_topic;
9
 
10
 static inline void avb_log_topic_init(struct spa_log *log)
11
 {
12
-   spa_log_topic_init(log, avb_log_topic);
13
+   spa_log_topic_init(log, &avb_log_topic);
14
 }
15
 
16
 #endif /* SPA_AVB_H */
17
pipewire-0.3.81.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.82.tar.gz/spa/plugins/bluez5/sco-sink.c Changed
29
 
1
@@ -662,7 +662,9 @@
2
 
3
    /* Init mSBC if needed */
4
    if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) {
5
-       sbc_init_msbc(&this->msbc, 0);
6
+       res = sbc_init_msbc(&this->msbc, 0);
7
+       if (res < 0)
8
+           return res;
9
        /* Libsbc expects audio samples by default in host endianness, mSBC requires little endian */
10
        this->msbc.endian = SBC_LE;
11
 
12
@@ -705,6 +707,7 @@
13
 fail:
14
    free(this->buffer);
15
    this->buffer = NULL;
16
+   sbc_finish(&this->msbc);
17
    return res;
18
 }
19
 
20
@@ -819,6 +822,8 @@
21
        this->buffer = NULL;
22
        this->buffer_head = this->buffer_next = this->buffer;
23
    }
24
+
25
+   sbc_finish(&this->msbc);
26
 }
27
 
28
 static int do_stop(struct impl *this)
29
pipewire-0.3.81.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.82.tar.gz/spa/plugins/bluez5/sco-source.c Changed
30
 
1
@@ -687,7 +687,10 @@
2
 
3
    /* Init mSBC if needed */
4
    if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) {
5
-       sbc_init_msbc(&this->msbc, 0);
6
+       res = sbc_init_msbc(&this->msbc, 0);
7
+       if (res < 0)
8
+           return res;
9
+
10
        /* Libsbc expects audio samples by default in host endianness, mSBC requires little endian */
11
        this->msbc.endian = SBC_LE;
12
        this->msbc_seq_initialized = false;
13
@@ -708,6 +711,7 @@
14
    return 0;
15
 
16
 fail:
17
+   sbc_finish(&this->msbc);
18
    return res;
19
 }
20
 
21
@@ -798,6 +802,8 @@
22
    spa_loop_invoke(this->data_loop, do_remove_transport_source, 0, NULL, 0, true, this);
23
 
24
    spa_bt_decode_buffer_clear(&port->buffer);
25
+
26
+   sbc_finish(&this->msbc);
27
 }
28
 
29
 static int do_stop(struct impl *this)
30
pipewire-0.3.81.tar.gz/spa/plugins/libcamera/libcamera.c -> pipewire-0.3.82.tar.gz/spa/plugins/libcamera/libcamera.c Changed
11
 
1
@@ -9,8 +9,7 @@
2
 
3
 #include "libcamera.h"
4
 
5
-struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.libcamera");
6
-struct spa_log_topic *libcamera_log_topic = &log_topic;
7
+struct spa_log_topic libcamera_log_topic = SPA_LOG_TOPIC(0, "spa.libcamera");
8
 
9
 SPA_EXPORT
10
 int spa_handle_factory_enum(const struct spa_handle_factory **factory,
11
pipewire-0.3.81.tar.gz/spa/plugins/libcamera/libcamera.h -> pipewire-0.3.82.tar.gz/spa/plugins/libcamera/libcamera.h Changed
17
 
1
@@ -18,12 +18,12 @@
2
 extern const struct spa_handle_factory spa_libcamera_device_factory;
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT libcamera_log_topic
6
-extern struct spa_log_topic *libcamera_log_topic;
7
+#define SPA_LOG_TOPIC_DEFAULT &libcamera_log_topic
8
+extern struct spa_log_topic libcamera_log_topic;
9
 
10
 static inline void libcamera_log_topic_init(struct spa_log *log)
11
 {
12
-   spa_log_topic_init(log, libcamera_log_topic);
13
+   spa_log_topic_init(log, &libcamera_log_topic);
14
 }
15
 
16
 #ifdef __cplusplus
17
pipewire-0.3.81.tar.gz/spa/plugins/support/log-patterns.c -> pipewire-0.3.82.tar.gz/spa/plugins/support/log-patterns.c Changed
22
 
1
@@ -22,6 +22,7 @@
2
               struct spa_log_topic *t)
3
 {
4
    enum spa_log_level level = default_level;
5
+   bool has_custom_level = false;
6
    const char *topic = t->topic;
7
    struct support_log_pattern *pattern;
8
 
9
@@ -29,10 +30,11 @@
10
        if (fnmatch(pattern->pattern, topic, 0) != 0)
11
            continue;
12
        level = pattern->level;
13
-       t->has_custom_level = true;
14
+       has_custom_level = true;
15
    }
16
 
17
    t->level = level;
18
+   t->has_custom_level = has_custom_level;
19
 }
20
 
21
 int
22
pipewire-0.3.81.tar.gz/spa/plugins/support/node-driver.c -> pipewire-0.3.82.tar.gz/spa/plugins/support/node-driver.c Changed
77
 
1
@@ -8,6 +8,11 @@
2
 #include <string.h>
3
 #include <stdio.h>
4
 #include <fcntl.h>
5
+#if !defined(__FreeBSD__) && !defined(__MidnightBSD__)
6
+#include <linux/ethtool.h>
7
+#include <linux/sockios.h>
8
+#endif
9
+#include <net/if.h>
10
 
11
 #include <spa/support/plugin.h>
12
 #include <spa/support/log.h>
13
@@ -485,6 +490,33 @@
14
    return sizeof(struct impl);
15
 }
16
 
17
+int get_phc_index(struct spa_system *s, const char *name) {
18
+#ifdef ETHTOOL_GET_TS_INFO
19
+   struct ethtool_ts_info info = {0};
20
+   struct ifreq ifr = {0};
21
+   int fd, err;
22
+
23
+   info.cmd = ETHTOOL_GET_TS_INFO;
24
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
25
+   ifr.ifr_data = (char *) &info;
26
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
27
+
28
+   if (fd < 0) {
29
+       return -1;
30
+   }
31
+
32
+   err = spa_system_ioctl(s, fd, SIOCETHTOOL, &ifr);
33
+   close(fd);
34
+   if (err < 0) {
35
+       return err;
36
+   }
37
+
38
+   return info.phc_index;
39
+#else
40
+   return -1;
41
+#endif
42
+}
43
+
44
 static int
45
 impl_init(const struct spa_handle_factory *factory,
46
      struct spa_handle *handle,
47
@@ -553,9 +585,28 @@
48
                this->props.clock_id = DEFAULT_CLOCK_ID;
49
            }
50
        } else if (spa_streq(k, "clock.device")) {
51
+           if (this->clock_fd >= 0) {
52
+               close(this->clock_fd);
53
+           }
54
            this->clock_fd = open(s, O_RDWR);
55
+
56
+           if (this->clock_fd == -1) {
57
+               spa_log_warn(this->log, "failed to open clock device '%s'", s);
58
+           } else {
59
+               this->props.clock_id = FD_TO_CLOCKID(this->clock_fd);
60
+           }
61
+       } else if (spa_streq(k, "clock.interface") && this->clock_fd < 0) {
62
+           int phc_index = get_phc_index(this->data_system, s);
63
+           if (phc_index < 0) {
64
+               spa_log_warn(this->log, "failed to get phc device index for interface '%s'", s);
65
+           } else {
66
+               char dev19;
67
+               spa_scnprintf(dev, sizeof(dev), "/dev/ptp%d", phc_index);
68
+               this->clock_fd = open(dev, O_RDWR);
69
+           }
70
+
71
            if (this->clock_fd == -1) {
72
-               spa_log_info(this->log, "failed to open clock device '%s'", s);
73
+               spa_log_warn(this->log, "failed to open clock device '%s'", s);
74
            } else {
75
                this->props.clock_id = FD_TO_CLOCKID(this->clock_fd);
76
            }
77
pipewire-0.3.81.tar.gz/spa/plugins/v4l2/v4l2.c -> pipewire-0.3.82.tar.gz/spa/plugins/v4l2/v4l2.c Changed
17
 
1
@@ -7,12 +7,13 @@
2
 #include <spa/support/plugin.h>
3
 #include <spa/support/log.h>
4
 
5
+#include "v4l2.h"
6
+
7
 extern const struct spa_handle_factory spa_v4l2_source_factory;
8
 extern const struct spa_handle_factory spa_v4l2_udev_factory;
9
 extern const struct spa_handle_factory spa_v4l2_device_factory;
10
 
11
-struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.v4l2");
12
-struct spa_log_topic *v4l2_log_topic = &log_topic;
13
+struct spa_log_topic v4l2_log_topic = SPA_LOG_TOPIC(0, "spa.v4l2");
14
 
15
 SPA_EXPORT
16
 int spa_handle_factory_enum(const struct spa_handle_factory **factory,
17
pipewire-0.3.81.tar.gz/spa/plugins/v4l2/v4l2.h -> pipewire-0.3.82.tar.gz/spa/plugins/v4l2/v4l2.h Changed
22
 
1
@@ -4,15 +4,17 @@
2
 
3
 #include <errno.h>
4
 
5
+#include <linux/videodev2.h>
6
+
7
 #include <spa/support/log.h>
8
 
9
 #undef SPA_LOG_TOPIC_DEFAULT
10
-#define SPA_LOG_TOPIC_DEFAULT v4l2_log_topic
11
-extern struct spa_log_topic *v4l2_log_topic;
12
+#define SPA_LOG_TOPIC_DEFAULT &v4l2_log_topic
13
+extern struct spa_log_topic v4l2_log_topic;
14
 
15
 static inline void v4l2_log_topic_init(struct spa_log *log)
16
 {
17
-   spa_log_topic_init(log, v4l2_log_topic);
18
+   spa_log_topic_init(log, &v4l2_log_topic);
19
 }
20
 
21
 struct spa_v4l2_device {
22
pipewire-0.3.81.tar.gz/spa/plugins/videoconvert/videoadapter.c -> pipewire-0.3.82.tar.gz/spa/plugins/videoconvert/videoadapter.c Changed
21
 
1
@@ -25,8 +25,8 @@
2
 #include <spa/debug/log.h>
3
 
4
 #undef SPA_LOG_TOPIC_DEFAULT
5
-#define SPA_LOG_TOPIC_DEFAULT log_topic
6
-static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.videoadapter");
7
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
8
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.videoadapter");
9
 
10
 #define DEFAULT_ALIGN  16
11
 
12
@@ -1554,7 +1554,7 @@
13
    this = (struct impl *) handle;
14
 
15
    this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
16
-   spa_log_topic_init(this->log, log_topic);
17
+   spa_log_topic_init(this->log, &log_topic);
18
 
19
    this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
20
 
21
pipewire-0.3.81.tar.gz/src/daemon/client-rt.conf.in -> pipewire-0.3.82.tar.gz/src/daemon/client-rt.conf.in Changed
9
 
1
@@ -111,6 +111,7 @@
2
 
3
 
4
 alsa.properties = {
5
+    #alsa.deny = false
6
     # ALSA params take a single value, an array  of values
7
     # or a range { min=.. max=... }
8
     #alsa.access =  MMAP_INTERLEAVED MMAP_NONINTERLEAVED RW_INTERLEAVED RW_NONINTERLEAVED 
9
pipewire-0.3.81.tar.gz/src/daemon/pipewire-aes67.conf.in -> pipewire-0.3.82.tar.gz/src/daemon/pipewire-aes67.conf.in Changed
27
 
1
@@ -23,9 +23,11 @@
2
 }
3
 
4
 context.objects = 
5
-    # An example clock reading from /dev/ptp0. Another option is to sync the
6
-    # ptp clock to CLOCK_TAI and then set clock.id = tai.
7
-    # If both device and ID are given and available, device takes precedence
8
+    # An example clock reading from /dev/ptp0. You can also specify the network interface name,
9
+    # pipewire will query the interface for the current active PHC index. Another option is to
10
+    # sync the ptp clock to CLOCK_TAI and then set clock.id = tai, keep in mind that tai may
11
+    # also be synced by a NTP client.
12
+    # The precedence is: device, interface, id
13
     { factory = spa-node-factory
14
         args = {
15
             factory.name    = support.node.driver
16
@@ -34,8 +36,9 @@
17
             # This driver should only be used for network nodes marked with group
18
             priority.driver = 0
19
             clock.name      = "clock.system.ptp0"
20
+            #clock.id        = tai
21
             clock.device    = "/dev/ptp0"
22
-            clock.id        = tai
23
+            #clock.interface = "eth0"
24
             object.export   = true
25
         }
26
     }
27
pipewire-0.3.81.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.82.tar.gz/src/daemon/pipewire.conf.in Changed
15
 
1
@@ -102,7 +102,12 @@
2
     }
3
 
4
     # The native communication protocol.
5
-    { name = libpipewire-module-protocol-native }
6
+    { name = libpipewire-module-protocol-native
7
+        args = {
8
+            # List of server Unix sockets, and optionally permissions
9
+            #sockets =  { name = "pipewire-0" }, { name = "pipewire-manager-0" } 
10
+        }
11
+    }
12
 
13
     # The profile module. Allows application to access profiler
14
     # and performance data. It provides an interface that is used
15
pipewire-0.3.81.tar.gz/src/modules/flatpak-utils.h -> pipewire-0.3.82.tar.gz/src/modules/flatpak-utils.h Changed
31
 
1
@@ -76,20 +76,20 @@
2
    spa_autoclose int root_fd = openat(AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
3
    if (root_fd < 0) {
4
        res = -errno;
5
+       pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res));
6
+
7
        if (res == -EACCES) {
8
-           struct statfs buf;
9
-           /* Access to the root dir isn't allowed. This can happen if the root is on a fuse
10
-            * filesystem, such as in a toolbox container. We will never have a fuse rootfs
11
-            * in the flatpak case, so in that case its safe to ignore this and
12
-            * continue to detect other types of apps. */
13
-           if (statfs(root_path, &buf) == 0 &&
14
-               buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */
15
-               return 0;
16
+           /* If we can't access the root filesystem, consider not sandboxed.
17
+            * This should not happen but for now it is a workaround for selinux
18
+            * where we can't access the gnome-shell root when it connects for
19
+            * screen sharing.
20
+            */
21
+           return 0;
22
        }
23
+
24
        /* Not able to open the root dir shouldn't happen. Probably the app died and
25
         * we're failing due to /proc/$pid not existing. In that case fail instead
26
         * of treating this as privileged. */
27
-       pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res));
28
        return res;
29
    }
30
 
31
pipewire-0.3.81.tar.gz/src/modules/meson.build -> pipewire-0.3.82.tar.gz/src/modules/meson.build Changed
28
 
1
@@ -313,6 +313,10 @@
2
   pipewire_module_protocol_deps += systemd_dep
3
 endif
4
 
5
+if selinux_dep.found()
6
+  pipewire_module_protocol_deps += selinux_dep
7
+endif
8
+
9
 pipewire_module_protocol_native = shared_library('pipewire-module-protocol-native',
10
    'module-protocol-native.c',
11
     'module-protocol-native/local-socket.c',
12
@@ -607,12 +611,13 @@
13
 if build_module_raop
14
   pipewire_module_raop_sink = shared_library('pipewire-module-raop-sink',
15
      'module-raop-sink.c',
16
-      'module-raop/rtsp-client.c' ,
17
+      'module-raop/rtsp-client.c',
18
+      'module-rtp/stream.c' ,
19
     include_directories : configinc,
20
     install : true,
21
     install_dir : modules_install_dir,
22
     install_rpath: modules_install_dir,
23
-    dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, openssl_lib,
24
+    dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, opus_dep, openssl_lib,
25
   )
26
 endif
27
 summary({'raop-sink (requires OpenSSL)': build_module_raop}, bool_yn: true, section: 'Optional Modules')
28
pipewire-0.3.81.tar.gz/src/modules/module-access.c -> pipewire-0.3.82.tar.gz/src/modules/module-access.c Changed
21
 
1
@@ -263,17 +263,11 @@
2
 
3
    res = pw_check_flatpak(pid, &flatpak_app_id, NULL);
4
    if (res != 0) {
5
-       if (res < 0) {
6
-           if (res == -EACCES) {
7
-               access = "unrestricted";
8
-               goto granted;
9
-           }
10
+       if (res < 0)
11
            pw_log_warn("%p: client %p sandbox check failed: %s",
12
                impl, client, spa_strerror(res));
13
-       }
14
-       else if (res > 0) {
15
+       else
16
            pw_log_debug(" %p: flatpak client %p added", impl, client);
17
-       }
18
        access = "flatpak";
19
        itemsnitems++ = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id",
20
                flatpak_app_id);
21
pipewire-0.3.81.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.82.tar.gz/src/modules/module-filter-chain.c Changed
21
 
1
@@ -147,7 +147,9 @@
2
  *
3
  * Normally the volume of the sink/source is handled by the stream software volume.
4
  * With the capture.volumes and playback.volumes properties this can be handled
5
- * by a control port in the graph instead.
6
+ * by a control port in the graph instead. Use capture.volumes for the volume of the
7
+ * input of the filter (when for example used as a sink). Use playback,volumes for
8
+ * the volume of the output of the filter (when for example used as a source).
9
  *
10
  * The min and max values (defaults 0.0 and 1.0) respectively can be used to scale
11
  * and translate the volume min and max values.
12
@@ -1947,7 +1949,7 @@
13
 /**
14
  * {
15
  *   control = name:portname
16
- *   min = <float, defaukt 0.0>
17
+ *   min = <float, default 0.0>
18
  *   max = <float, default 1.0>
19
  *   scale = <string, default "linear", options "linear","cubic">
20
  * }
21
pipewire-0.3.81.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-native.c Changed
201
 
1
@@ -15,9 +15,13 @@
2
 #include <fcntl.h>
3
 #include <sys/file.h>
4
 #include <ctype.h>
5
+#include <limits.h>
6
 #ifdef HAVE_PWD_H
7
 #include <pwd.h>
8
 #endif
9
+#ifdef HAVE_GRP_H
10
+#include <grp.h>
11
+#endif
12
 #if defined(__FreeBSD__) || defined(__MidnightBSD__)
13
 #include <sys/ucred.h>
14
 #endif
15
@@ -27,13 +31,19 @@
16
 #include <spa/pod/builder.h>
17
 #include <spa/utils/result.h>
18
 #include <spa/utils/string.h>
19
+#include <spa/utils/json.h>
20
 
21
 #ifdef HAVE_SYSTEMD
22
 #include <systemd/sd-daemon.h>
23
 #endif
24
 
25
+#ifdef HAVE_SELINUX
26
+#include <selinux/selinux.h>
27
+#endif
28
+
29
 #include <pipewire/impl.h>
30
 #include <pipewire/extensions/protocol-native.h>
31
+#include <pipewire/cleanup.h>
32
 
33
 #include "pipewire/private.h"
34
 
35
@@ -63,7 +73,17 @@
36
  *
37
  * ## Module Options
38
  *
39
- * The module has no options.
40
+ * The module supports the following arguments:
41
+ *
42
+ * - `sockets`: ` { name = "socket-name", owner = "owner", group = "group", mode = "mode", selinux.context = "context" }, ... `
43
+ *
44
+ *   Array of Unix socket names and (optionally) owner/permissions to serve,
45
+ *   if the context is a server. If not absolute paths, the sockets are created
46
+ *   in the default runtime directory. If not specified, one socket with
47
+ *   a default name is created.
48
+ *
49
+ *   The permissions have no effect for sockets from Systemd socket activation.
50
+ *   Those should be configured via the systemd.socket(5) mechanism.
51
  *
52
  * ## General Options
53
  *
54
@@ -107,6 +127,13 @@
55
    { name = libpipewire-module-protocol-native }
56
  * 
57
  *\endcode
58
+ *
59
+ *\code{.unparsed}
60
+ * context.modules = 
61
+ *  { name = libpipewire-module-protocol-native,
62
+ *    args = { sockets =  { name = "pipewire-0" }, { name = "pipewire-1" }  } }
63
+ * 
64
+ *\endcode
65
  */
66
 
67
 #ifndef UNIX_PATH_MAX
68
@@ -165,12 +192,23 @@
69
        free(impl);
70
 }
71
 
72
+struct socket_info {
73
+   char *name;
74
+   uid_t uid;
75
+   gid_t gid;
76
+   int mode;
77
+   char *selinux_context;
78
+   unsigned int has_owner:1;
79
+   unsigned int has_mode:1;
80
+};
81
+
82
 struct server {
83
    struct pw_protocol_server this;
84
 
85
    int fd_lock;
86
    struct sockaddr_un addr;
87
    char lock_addrUNIX_PATH_MAX + LOCK_SUFFIXLEN;
88
+   struct socket_info socket_info;
89
 
90
    struct pw_loop *loop;
91
    struct spa_source *source;
92
@@ -540,6 +578,8 @@
93
    if (props == NULL)
94
        goto exit;
95
 
96
+   pw_properties_set(props, PW_KEY_SEC_SOCKET, s->socket_info.name);
97
+
98
 #if defined(__linux__)
99
    len = sizeof(ucred);
100
    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
101
@@ -789,6 +829,31 @@
102
    return res;
103
 }
104
 
105
+static int set_socket_permissions(struct server *s)
106
+{
107
+   struct socket_info *info = &s->socket_info;
108
+   const char *path = s->addr.sun_path;
109
+
110
+   if (info->has_owner)
111
+       if (chown(path, info->uid, info->gid) < 0)
112
+           return -errno;
113
+
114
+   if (info->has_mode)
115
+       if (chmod(path, info->mode) < 0)
116
+           return -errno;
117
+
118
+   if (info->selinux_context) {
119
+#ifdef HAVE_SELINUX
120
+       if (setfilecon(path, info->selinux_context) < 0)
121
+           return -errno;
122
+#else
123
+       return -EOPNOTSUPP;
124
+#endif
125
+   }
126
+
127
+   return 0;
128
+}
129
+
130
 static int add_socket(struct pw_protocol *protocol, struct server *s)
131
 {
132
    socklen_t size;
133
@@ -836,11 +901,22 @@
134
            goto error_close;
135
        }
136
 
137
+       if ((res = set_socket_permissions(s)) < 0) {
138
+           errno = -res;
139
+           pw_log_error("server %p: failed to set socket %s permissions: %m",
140
+                   s, s->socket_info.name);
141
+           goto error_close;
142
+       }
143
+
144
        if (listen(fd, 128) < 0) {
145
            res = -errno;
146
            pw_log_error("server %p: listen() failed with error: %m", s);
147
            goto error_close;
148
        }
149
+   } else {
150
+       if (s->socket_info.has_owner || s->socket_info.has_mode || s->socket_info.selinux_context)
151
+           pw_log_info("server %p: permissions ignored for socket %s from systemd",
152
+                   s, s->socket_info.name);
153
    }
154
 
155
    res = write_socket_address(s);
156
@@ -1250,6 +1326,8 @@
157
        unlink(s->lock_addr);
158
    if (s->fd_lock != -1)
159
        close(s->fd_lock);
160
+   free(s->socket_info.name);
161
+   free(s->socket_info.selinux_context);
162
    free(s);
163
 }
164
 
165
@@ -1311,9 +1389,10 @@
166
 }
167
 
168
 static struct pw_protocol_server *
169
-impl_add_server(struct pw_protocol *protocol,
170
+add_server(struct pw_protocol *protocol,
171
        struct pw_impl_core *core,
172
-                const struct spa_dict *props)
173
+       const struct spa_dict *props,
174
+       struct socket_info *socket_info)
175
 {
176
    struct pw_protocol_server *this;
177
    struct server *s;
178
@@ -1325,7 +1404,16 @@
179
 
180
    this = &s->this;
181
 
182
-   name = get_server_name(props);
183
+   if (socket_info) {
184
+       s->socket_info = *socket_info;
185
+       s->socket_info.name = strdup(socket_info->name);
186
+       s->socket_info.selinux_context = socket_info->selinux_context ?
187
+           strdup(socket_info->selinux_context) : NULL;
188
+       name = socket_info->name;
189
+   } else {
190
+       name = get_server_name(props);
191
+       s->socket_info.name = strdup(name);
192
+   }
193
 
194
    if ((res = init_socket_name(s, name)) < 0)
195
        goto error;
196
@@ -1349,6 +1437,14 @@
197
    return NULL;
198
 }
199
 
200
+static struct pw_protocol_server *
201
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/manager.h -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/manager.h Changed
27
 
1
@@ -9,11 +9,14 @@
2
 extern "C" {
3
 #endif
4
 
5
+#include <stdio.h>
6
+
7
 #include <spa/utils/defs.h>
8
 #include <spa/pod/pod.h>
9
 
10
 #include <pipewire/pipewire.h>
11
 
12
+struct client;
13
 struct pw_manager_object;
14
 
15
 struct pw_manager_events {
16
@@ -68,8 +71,8 @@
17
    struct pw_properties *props;
18
    struct pw_proxy *proxy;
19
    char *message_object_path;
20
-   int (*message_handler)(struct pw_manager *m, struct pw_manager_object *o,
21
-                          const char *message, const char *params, char **response);
22
+   int (*message_handler)(struct client *client, struct pw_manager_object *o,
23
+                          const char *message, const char *params, FILE *response);
24
 
25
    void *info;
26
    struct spa_param_info *params;
27
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/message-handler.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/message-handler.c Changed
119
 
1
@@ -3,8 +3,10 @@
2
 /* SPDX-License-Identifier: MIT */
3
 
4
 #include <stdint.h>
5
+#include <stdio.h>
6
 
7
 #include <regex.h>
8
+#include <malloc.h>
9
 
10
 #include <spa/param/props.h>
11
 #include <spa/pod/builder.h>
12
@@ -15,12 +17,13 @@
13
 
14
 #include <pipewire/pipewire.h>
15
 
16
+#include "client.h"
17
 #include "collect.h"
18
 #include "log.h"
19
 #include "manager.h"
20
 #include "message-handler.h"
21
 
22
-static int bluez_card_object_message_handler(struct pw_manager *m, struct pw_manager_object *o, const char *message, const char *params, char **response)
23
+static int bluez_card_object_message_handler(struct client *client, struct pw_manager_object *o, const char *message, const char *params, FILE *response)
24
 {
25
    struct transport_codec_info codecs64;
26
    uint32_t n_codecs, active;
27
@@ -60,66 +63,62 @@
28
 
29
        pw_device_set_param((struct pw_device *)o->proxy,
30
                SPA_PARAM_Props, 0, param);
31
-       return 0;
32
    } else if (spa_streq(message, "list-codecs")) {
33
        uint32_t i;
34
-       FILE *r;
35
-       size_t size;
36
        bool first = true;
37
 
38
-       r = open_memstream(response, &size);
39
-       if (r == NULL)
40
-           return -errno;
41
-
42
-       fputc('', r);
43
+       fputc('', response);
44
        for (i = 0; i < n_codecs; ++i) {
45
            const char *desc = codecsi.description;
46
-           fprintf(r, "%s{\"name\":\"%d\",\"description\":\"%s\"}",
47
+           fprintf(response, "%s{\"name\":\"%d\",\"description\":\"%s\"}",
48
                    first ? "" : ",",
49
                    (int)codecsi.id, desc ? desc : "Unknown");
50
            first = false;
51
        }
52
-       fputc('', r);
53
-
54
-       return fclose(r) ? -errno : 0;
55
+       fputc('', response);
56
    } else if (spa_streq(message, "get-codec")) {
57
        if (active == SPA_ID_INVALID)
58
-           *response = strdup("null");
59
+           fputs("null", response);
60
        else
61
-           *response = spa_aprintf("\"%d\"", (int)codecsactive.id);
62
-       return *response ? 0 : -ENOMEM;
63
+           fprintf(response, "\"%d\"", (int) codecsactive.id);
64
+   } else {
65
+       return -ENOSYS;
66
    }
67
 
68
-   return -ENOSYS;
69
+   return 0;
70
 }
71
 
72
-static int core_object_message_handler(struct pw_manager *m, struct pw_manager_object *o, const char *message, const char *params, char **response)
73
+static int core_object_message_handler(struct client *client, struct pw_manager_object *o, const char *message, const char *params, FILE *response)
74
 {
75
    pw_log_debug(": core %p object message:'%s' params:'%s'", o, message, params);
76
 
77
    if (spa_streq(message, "list-handlers")) {
78
-       FILE *r;
79
-       size_t size;
80
        bool first = true;
81
 
82
-       r = open_memstream(response, &size);
83
-       if (r == NULL)
84
-           return -errno;
85
-
86
-       fputc('', r);
87
-       spa_list_for_each(o, &m->object_list, link) {
88
+       fputc('', response);
89
+       spa_list_for_each(o, &client->manager->object_list, link) {
90
            if (o->message_object_path) {
91
-               fprintf(r, "%s{\"name\":\"%s\",\"description\":\"%s\"}",
92
+               fprintf(response, "%s{\"name\":\"%s\",\"description\":\"%s\"}",
93
                        first ? "" : ",",
94
                        o->message_object_path, o->type);
95
                first = false;
96
            }
97
        }
98
-       fputc('', r);
99
-       return fclose(r) ? -errno : 0;
100
+       fputc('', response);
101
+#ifdef HAVE_MALLOC_INFO
102
+   } else if (spa_streq(message, "pipewire-pulse:malloc-info")) {
103
+       malloc_info(0, response);
104
+#endif
105
+#ifdef HAVE_MALLOC_TRIM
106
+   } else if (spa_streq(message, "pipewire-pulse:malloc-trim")) {
107
+       int res = malloc_trim(0);
108
+       fprintf(response, "%d", res);
109
+#endif
110
+   } else {
111
+       return -ENOSYS;
112
    }
113
 
114
-   return -ENOSYS;
115
+   return 0;
116
 }
117
 
118
 void register_object_message_handlers(struct pw_manager_object *o)
119
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/pulse-server.c Changed
101
 
1
@@ -1820,6 +1820,8 @@
2
            PW_STREAM_FLAG_MAP_BUFFERS,
3
            params, n_params);
4
 
5
+   stream_update_tag_param(stream);
6
+
7
    return 0;
8
 
9
 error_errno:
10
@@ -3215,7 +3217,8 @@
11
        if (stream == NULL || stream->type == STREAM_TYPE_UPLOAD)
12
            return -ENOENT;
13
 
14
-       pw_stream_update_properties(stream->stream, &props->dict);
15
+       if (pw_stream_update_properties(stream->stream, &props->dict) > 0)
16
+           stream_update_tag_param(stream);
17
    } else {
18
        if (pw_properties_update(client->props, &props->dict) > 0) {
19
            client_update_quirks(client);
20
@@ -5099,12 +5102,12 @@
21
 {
22
    struct impl *impl = client->impl;
23
    struct pw_manager *manager = client->manager;
24
-   const char *object_path = NULL;
25
-   const char *message = NULL;
26
-   const char *params = NULL;
27
-   struct message *reply;
28
+   const char *object_path = NULL, *message = NULL, *params = NULL;
29
    struct pw_manager_object *o;
30
-   int len = 0;
31
+   spa_autofree char *response_str = NULL;
32
+   size_t path_len = 0, response_len = 0;
33
+   FILE *response;
34
+   int res = -ENOENT;
35
 
36
    if (message_get(m,
37
            TAG_STRING, &object_path,
38
@@ -5120,36 +5123,42 @@
39
    if (object_path == NULL || message == NULL)
40
        return -EINVAL;
41
 
42
-   len = strlen(object_path);
43
-   if (len > 0 && object_pathlen - 1 == '/')
44
-       --len;
45
-
46
-   spa_autofree char *path = strndup(object_path, len);
47
+   path_len = strlen(object_path);
48
+   if (path_len > 0 && object_pathpath_len - 1 == '/')
49
+       --path_len;
50
+   spa_autofree char *path = strndup(object_path, path_len);
51
    if (path == NULL)
52
        return -ENOMEM;
53
 
54
-   spa_autofree char *response = NULL;
55
-   int res = -ENOENT;
56
-
57
    spa_list_for_each(o, &manager->object_list, link) {
58
-       if (o->message_object_path && spa_streq(o->message_object_path, path)) {
59
-           if (o->message_handler)
60
-               res = o->message_handler(manager, o, message, params, &response);
61
-           else
62
-               res = -ENOSYS;
63
+       if (spa_streq(o->message_object_path, path))
64
            break;
65
-       }
66
    }
67
+   if (spa_list_is_end(o, &manager->object_list, link))
68
+       return -ENOENT;
69
 
70
-   if (res < 0)
71
-       return res;
72
+   if (o->message_handler == NULL)
73
+       return -ENOSYS;
74
 
75
-   pw_log_debug("%p: object message response:'%s'", impl, response ? response : "<null>");
76
+   response = open_memstream(&response_str, &response_len);
77
+   if (response == NULL)
78
+       return -errno;
79
 
80
-   reply = reply_new(client, tag);
81
-   message_put(reply, TAG_STRING, response, TAG_INVALID);
82
+   res = o->message_handler(client, o, message, params, response);
83
 
84
-   return client_queue_message(client, reply);
85
+   if (fclose(response))
86
+       return -errno;
87
+
88
+   pw_log_debug("%p: object message response: (%d) '%s'", impl, res, response_str ? response_str : "<null>");
89
+
90
+   if (res >= 0) {
91
+       struct message *reply = reply_new(client, tag);
92
+
93
+       message_put(reply, TAG_STRING, response_str, TAG_INVALID);
94
+       res = client_queue_message(client, reply);
95
+   }
96
+
97
+   return res;
98
 }
99
 
100
 static int do_error_access(struct client *client, uint32_t command, uint32_t tag, struct message *m)
101
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/stream.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/stream.c Changed
48
 
1
@@ -8,6 +8,9 @@
2
 
3
 #include <spa/utils/hook.h>
4
 #include <spa/utils/ringbuffer.h>
5
+#include <spa/pod/dynamic.h>
6
+#include <spa/param/tag-utils.h>
7
+
8
 #include <pipewire/log.h>
9
 #include <pipewire/loop.h>
10
 #include <pipewire/map.h>
11
@@ -412,3 +415,36 @@
12
    }
13
    return client_queue_message(client, reply);
14
 }
15
+
16
+int stream_update_tag_param(struct stream *stream)
17
+{
18
+   struct spa_pod_dynamic_builder b;
19
+   const struct pw_properties *props = pw_stream_get_properties(stream->stream);
20
+   const struct spa_pod *param1;
21
+   struct spa_dict_item items64;
22
+   uint32_t i, n_items = 0;
23
+   uint8_t buffer4096;
24
+
25
+   if (props == NULL)
26
+       return -EIO;
27
+
28
+   spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
29
+
30
+   for (i = 0; i < props->dict.n_items; i++) {
31
+       if (n_items < SPA_N_ELEMENTS(items) &&
32
+           spa_strstartswith(props->dict.itemsi.key, "media."))
33
+               itemsn_items++ = props->dict.itemsi;
34
+   }
35
+   if (n_items > 0) {
36
+       struct spa_pod_frame f;
37
+       spa_tag_build_start(&b.b, &f, SPA_PARAM_Tag, SPA_DIRECTION_OUTPUT);
38
+       spa_tag_build_add_dict(&b.b, &SPA_DICT_INIT(items, n_items));
39
+       param0 = spa_tag_build_end(&b.b, &f);
40
+   } else {
41
+       param0 = NULL;
42
+   }
43
+   if (param0 != NULL)
44
+       pw_stream_update_params(stream->stream, param, 1);
45
+   spa_pod_dynamic_builder_clean(&b);
46
+   return 0;
47
+}
48
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/stream.h -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/stream.h Changed
8
 
1
@@ -116,5 +116,6 @@
2
 int stream_send_request(struct stream *stream);
3
 int stream_update_minreq(struct stream *stream, uint32_t minreq);
4
 int stream_send_moved(struct stream *stream, uint32_t peer_index, const char *peer_name);
5
+int stream_update_tag_param(struct stream *stream);
6
 
7
 #endif /* PULSER_SERVER_STREAM_H */
8
pipewire-0.3.81.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.82.tar.gz/src/modules/module-raop-sink.c Changed
201
 
1
@@ -45,6 +45,7 @@
2
 
3
 #include "module-raop/rtsp-client.h"
4
 #include "module-rtp/rtp.h"
5
+#include "module-rtp/stream.h"
6
 
7
 /** \page page_module_raop_sink PipeWire Module: AirPlay Sink
8
  *
9
@@ -121,36 +122,37 @@
10
 PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
11
 #define PW_LOG_TOPIC_DEFAULT mod_topic
12
 
13
-#define FRAMES_PER_TCP_PACKET 4096
14
-#define FRAMES_PER_UDP_PACKET 352
15
+#define BUFFER_SIZE        (1u<<22)
16
+#define BUFFER_MASK        (BUFFER_SIZE-1)
17
+#define BUFFER_SIZE2       (BUFFER_SIZE>>1)
18
+#define BUFFER_MASK2       (BUFFER_SIZE2-1)
19
 
20
-#define RAOP_LATENCY_MIN   11025u
21
-#define DEFAULT_LATENCY_MS "1500"
22
+#define FRAMES_PER_TCP_PACKET  4096
23
+#define FRAMES_PER_UDP_PACKET  352
24
 
25
-#define DEFAULT_TCP_AUDIO_PORT   6000
26
-#define DEFAULT_UDP_AUDIO_PORT   6000
27
-#define DEFAULT_UDP_CONTROL_PORT 6001
28
-#define DEFAULT_UDP_TIMING_PORT  6002
29
+#define RAOP_AUDIO_PORT        6000
30
+#define RAOP_UDP_CONTROL_PORT  6001
31
+#define RAOP_UDP_TIMING_PORT   6002
32
 
33
 #define AES_CHUNK_SIZE     16
34
 #ifndef MD5_DIGEST_LENGTH
35
 #define MD5_DIGEST_LENGTH  16
36
 #endif
37
-#define MD5_HASH_LENGTH (2*MD5_DIGEST_LENGTH)
38
+#define MD5_HASH_LENGTH        (2*MD5_DIGEST_LENGTH)
39
 
40
 #define DEFAULT_USER_NAME  "PipeWire"
41
 #define RAOP_AUTH_USER_NAME    "iTunes"
42
 
43
-#define MAX_PORT_RETRY 128
44
+#define MAX_PORT_RETRY     128
45
 
46
-#define DEFAULT_FORMAT "S16"
47
-#define DEFAULT_RATE 44100
48
-#define DEFAULT_CHANNELS 2
49
-#define DEFAULT_POSITION " FL FR "
50
+#define RAOP_FORMAT        "S16LE"
51
+#define RAOP_STRIDE        (2*DEFAULT_CHANNELS)
52
+#define RAOP_RATE      44100
53
+#define RAOP_LATENCY_MS        250
54
 
55
-#define VOLUME_MAX 0.0
56
-#define VOLUME_MIN -30.0
57
-#define VOLUME_MUTE    -144.0
58
+#define VOLUME_MAX     0.0
59
+#define VOLUME_MIN     -30.0
60
+#define VOLUME_MUTE        -144.0
61
 
62
 #define MODULE_USAGE   "( raop.ip=<ip address of host> ) "                 \
63
            "( raop.port=<remote port> ) "                      \
64
@@ -163,8 +165,8 @@
65
            "( node.latency=<latency as fraction> ) "               \
66
            "( node.name=<name of the nodes> ) "                    \
67
            "( node.description=<description of the nodes> ) "          \
68
-           "( audio.format=<format, default:"DEFAULT_FORMAT"> ) "          \
69
-           "( audio.rate=<sample rate, default: "SPA_STRINGIFY(DEFAULT_RATE)"> ) "         \
70
+           "( audio.format=<format, default:"RAOP_FORMAT"> ) "         \
71
+           "( audio.rate=<sample rate, default: "SPA_STRINGIFY(RAOP_RATE)"> ) "            \
72
            "( audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS)"> ) "   \
73
            "( audio.position=<channel map, default:"DEFAULT_POSITION"> ) "     \
74
            "( stream.props=<properties> ) "
75
@@ -212,10 +214,7 @@
76
    struct spa_hook core_listener;
77
 
78
    struct pw_properties *stream_props;
79
-   struct pw_stream *stream;
80
-   struct spa_hook stream_listener;
81
-   struct spa_audio_info_raw info;
82
-   uint32_t frame_size;
83
+   struct rtp_stream *stream;
84
 
85
    struct pw_rtsp_client *rtsp;
86
    struct spa_hook rtsp_listener;
87
@@ -246,15 +245,15 @@
88
    int server_fd;
89
    struct spa_source *server_source;
90
 
91
-   uint32_t block_size;
92
+   uint32_t psamples;
93
+   uint64_t rate;
94
+   uint32_t mtu;
95
+   uint32_t stride;
96
    uint32_t latency;
97
 
98
-   uint16_t seq, cseq;
99
-   uint32_t rtptime;
100
    uint32_t ssrc;
101
    uint32_t sync;
102
    uint32_t sync_period;
103
-   unsigned int first:1;
104
    unsigned int connected:1;
105
    unsigned int ready:1;
106
    unsigned int recording:1;
107
@@ -262,17 +261,14 @@
108
    bool mute;
109
    float volume;
110
 
111
-   uint8_t bufferFRAMES_PER_TCP_PACKET * 4;
112
+   struct spa_ringbuffer ring;
113
+   uint8_t bufferBUFFER_SIZE;
114
+
115
+   struct spa_io_position *io_position;
116
+
117
    uint32_t filled;
118
 };
119
 
120
-static void stream_destroy(void *d)
121
-{
122
-   struct impl *impl = d;
123
-   spa_hook_remove(&impl->stream_listener);
124
-   impl->stream = NULL;
125
-}
126
-
127
 static inline void bit_writer(uint8_t **p, int *pos, uint8_t data, int len)
128
 {
129
    int rb = 8 - *pos - len;
130
@@ -307,11 +303,9 @@
131
    return timespec_to_ntp(&now);
132
 }
133
 
134
-static int send_udp_sync_packet(struct impl *impl,
135
-       struct sockaddr *dest_addr, socklen_t addrlen)
136
+static int send_udp_sync_packet(struct impl *impl, uint32_t rtptime, unsigned int first)
137
 {
138
    uint32_t out3;
139
-   uint32_t rtptime = impl->rtptime;
140
    uint32_t latency = impl->latency;
141
    uint64_t transmitted;
142
    struct rtp_header header;
143
@@ -321,11 +315,11 @@
144
 
145
    spa_zero(header);
146
    header.v = 2;
147
-   if (impl->first)
148
+   if (first)
149
        header.x = 1;
150
    header.m = 1;
151
    header.pt = 84;
152
-   header.sequence_number = htons(impl->cseq);
153
+   header.sequence_number = 7;
154
    header.timestamp = htonl(rtptime - latency);
155
 
156
    iov0.iov_base = &header;
157
@@ -339,8 +333,8 @@
158
    iov1.iov_base = out;
159
    iov1.iov_len = sizeof(out);
160
 
161
-   msg.msg_name = dest_addr;
162
-   msg.msg_namelen = addrlen;
163
+   msg.msg_name = NULL;
164
+   msg.msg_namelen = 0;
165
    msg.msg_iov = iov;
166
    msg.msg_iovlen = 2;
167
    msg.msg_control = NULL;
168
@@ -353,10 +347,8 @@
169
        pw_log_warn("error sending control packet: %d", res);
170
    }
171
 
172
-   impl->cseq = (impl->cseq + 1) & 0xffff;
173
-
174
-   pw_log_debug("raop control sync: cseq:%d first:%d latency:%u now:%"PRIx64" rtptime:%u",
175
-           impl->cseq, impl->first, latency, transmitted, rtptime);
176
+   pw_log_debug("raop control sync: first:%d latency:%u now:%"PRIx64" rtptime:%u",
177
+           first, latency, transmitted, rtptime);
178
 
179
    return res;
180
 }
181
@@ -440,194 +432,86 @@
182
    return bp - b + 1;
183
 }
184
 
185
-static int flush_to_udp_packet(struct impl *impl)
186
+static ssize_t send_packet(int fd, struct msghdr *msg)
187
 {
188
-   const size_t max = 8 + impl->block_size;
189
-   uint32_t outmax, len, n_frames;
190
-   struct rtp_header header;
191
-   struct iovec iov2;
192
+   ssize_t n;
193
+   n = sendmsg(fd, msg, MSG_NOSIGNAL);
194
+   if (n < 0)
195
+       pw_log_debug("sendmsg() failed: %m");
196
+   return n;
197
+}
198
+
199
+static void stream_send_packet(void *data, struct iovec *iov, size_t iovlen)
200
+{
201
pipewire-0.3.81.tar.gz/src/modules/module-rt.c -> pipewire-0.3.82.tar.gz/src/modules/module-rt.c Changed
19
 
1
@@ -36,7 +36,7 @@
2
 #include <sys/thr.h>
3
 #endif
4
 #if defined(__GNU__)
5
-#include <mach.h>
6
+#include <hurd.h>
7
 #endif
8
 #include <fcntl.h>
9
 #include <unistd.h>
10
@@ -225,7 +225,7 @@
11
    thr_self(&pid);
12
    return (pid_t)pid;
13
 #elif defined(__GNU__)
14
-       mach_port_t thread = mach_thread_self();
15
+       mach_port_t thread = hurd_thread_self();
16
        return (pid_t)thread;
17
 #else
18
 #error "No gettid impl"
19
pipewire-0.3.81.tar.gz/src/modules/module-rtp/audio.c -> pipewire-0.3.82.tar.gz/src/modules/module-rtp/audio.c Changed
26
 
1
@@ -226,6 +226,10 @@
2
    iov0.iov_len = sizeof(header);
3
 
4
    while (avail >= tosend) {
5
+       if (impl->marker_on_first && impl->first)
6
+           header.m = 1;
7
+       else
8
+           header.m = 0;
9
        header.sequence_number = htons(impl->seq);
10
        header.timestamp = htonl(impl->ts_offset + timestamp);
11
 
12
@@ -234,11 +238,12 @@
13
            (timestamp * stride) & BUFFER_MASK,
14
            &iov1, tosend * stride);
15
 
16
-       pw_log_trace("sending %d timestamp:%d", tosend, timestamp);
17
+       pw_log_trace("sending %d avail:%d ts_offset:%d timestamp:%d", tosend, avail, impl->ts_offset, timestamp);
18
 
19
        rtp_stream_emit_send_packet(impl, iov, 3);
20
 
21
        impl->seq++;
22
+       impl->first = false;
23
        timestamp += tosend;
24
        avail -= tosend;
25
    }
26
pipewire-0.3.81.tar.gz/src/modules/module-rtp/stream.c -> pipewire-0.3.82.tar.gz/src/modules/module-rtp/stream.c Changed
115
 
1
@@ -32,6 +32,7 @@
2
                            struct rtp_stream_events, m, v, ##__VA_ARGS__)
3
 #define rtp_stream_emit_destroy(s)     rtp_stream_emit(s, destroy, 0)
4
 #define rtp_stream_emit_state_changed(s,n,e)   rtp_stream_emit(s, state_changed,0,n,e)
5
+#define rtp_stream_emit_param_changed(s,i,p)   rtp_stream_emit(s, param_changed,0,i,p)
6
 #define rtp_stream_emit_send_packet(s,i,l) rtp_stream_emit(s, send_packet,0,i,l)
7
 #define rtp_stream_emit_send_feedback(s,seq)   rtp_stream_emit(s, send_feedback,0,seq)
8
 
9
@@ -58,6 +59,7 @@
10
    unsigned have_ssrc:1;
11
    unsigned ignore_ssrc:1;
12
    unsigned have_seq:1;
13
+   unsigned marker_on_first:1;
14
    uint32_t ts_offset;
15
    uint32_t psamples;
16
    uint32_t mtu;
17
@@ -102,6 +104,7 @@
18
    { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_ALAW, 1, "PCMA", "audio" },
19
    { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_ULAW, 1, "PCMU", "audio" },
20
    { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S16_BE, 2, "L16", "audio" },
21
+   { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S16_LE, 2, "L16", "audio" },
22
    { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S24_BE, 3, "L24", "audio" },
23
    { SPA_MEDIA_SUBTYPE_control, 0, 1, "rtp-midi", "audio" },
24
    { SPA_MEDIA_SUBTYPE_opus, 0, 4, "opus", "audio" },
25
@@ -132,6 +135,8 @@
26
    if (impl->started)
27
        return 0;
28
 
29
+   impl->first = true;
30
+
31
    rtp_stream_emit_state_changed(impl, true, NULL);
32
 
33
    impl->started = true;
34
@@ -176,10 +181,17 @@
35
    }
36
 }
37
 
38
+static void on_stream_param_changed (void *d, uint32_t id, const struct spa_pod *param)
39
+{
40
+   struct impl *impl = d;
41
+   rtp_stream_emit_param_changed(impl, id, param);
42
+};
43
+
44
 static const struct pw_stream_events stream_events = {
45
    PW_VERSION_STREAM_EVENTS,
46
    .destroy = stream_destroy,
47
    .state_changed = on_stream_state_changed,
48
+   .param_changed = on_stream_param_changed,
49
    .io_changed = stream_io_changed,
50
 };
51
 
52
@@ -287,6 +299,12 @@
53
        impl->info.media_subtype = SPA_MEDIA_SUBTYPE_raw;
54
        impl->payload = 127;
55
    }
56
+   else if (spa_streq(str, "raop")) {
57
+       impl->info.media_type = SPA_MEDIA_TYPE_audio;
58
+       impl->info.media_subtype = SPA_MEDIA_SUBTYPE_raw;
59
+       impl->payload = 0x60;
60
+       impl->marker_on_first = 1;
61
+   }
62
    else if (spa_streq(str, "midi")) {
63
        impl->info.media_type = SPA_MEDIA_TYPE_application;
64
        impl->info.media_subtype = SPA_MEDIA_SUBTYPE_control;
65
@@ -364,6 +382,7 @@
66
    if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL)
67
        pw_properties_set(props, PW_KEY_NODE_NETWORK, "true");
68
 
69
+   impl->marker_on_first = pw_properties_get_bool(props, "sess.marker-on-first", false);
70
    impl->ignore_ssrc = pw_properties_get_bool(props, "sess.ignore-ssrc", false);
71
    impl->direct_timestamp = pw_properties_get_bool(props, "sess.ts-direct", false);
72
 
73
@@ -530,3 +549,40 @@
74
    return pos->clock.position * impl->rate *
75
        pos->clock.rate.num / pos->clock.rate.denom;
76
 }
77
+
78
+uint16_t rtp_stream_get_seq(struct rtp_stream *s)
79
+{
80
+   struct impl *impl = (struct impl*)s;
81
+
82
+   return impl->seq;
83
+}
84
+
85
+void rtp_stream_set_first(struct rtp_stream *s)
86
+{
87
+   struct impl *impl = (struct impl*)s;
88
+
89
+   impl->first = true;
90
+}
91
+
92
+enum pw_stream_state rtp_stream_get_state(struct rtp_stream *s, const char **error)
93
+{
94
+   struct impl *impl = (struct impl*)s;
95
+
96
+   return pw_stream_get_state(impl->stream, error);
97
+}
98
+
99
+int rtp_stream_set_param(struct rtp_stream *s, uint32_t id, const struct spa_pod *param)
100
+{
101
+   struct impl *impl = (struct impl*)s;
102
+
103
+   return pw_stream_set_param(impl->stream, id, param);
104
+}
105
+
106
+int rtp_stream_update_params(struct rtp_stream *s,
107
+           const struct spa_pod **params,
108
+           uint32_t n_params)
109
+{
110
+   struct impl *impl = (struct impl*)s;
111
+   
112
+   return pw_stream_update_params(impl->stream, params, n_params);
113
+}
114
\ No newline at end of file
115
pipewire-0.3.81.tar.gz/src/modules/module-rtp/stream.h -> pipewire-0.3.82.tar.gz/src/modules/module-rtp/stream.h Changed
32
 
1
@@ -31,9 +31,11 @@
2
 
3
    void (*state_changed) (void *data, bool started, const char *error);
4
 
5
+   void (*param_changed) (void *data, uint32_t id, const struct spa_pod *param);
6
+
7
    void (*send_packet) (void *data, struct iovec *iov, size_t iovlen);
8
 
9
-   void (*send_feedback) (void *data, uint32_t senum);
10
+   void (*send_feedback) (void *data, uint32_t seqnum);
11
 };
12
 
13
 struct rtp_stream *rtp_stream_new(struct pw_core *core,
14
@@ -46,6 +48,17 @@
15
 
16
 uint64_t rtp_stream_get_time(struct rtp_stream *s, uint64_t *rate);
17
 
18
+uint16_t rtp_stream_get_seq(struct rtp_stream *s);
19
+
20
+void rtp_stream_set_first(struct rtp_stream *s);
21
+
22
+enum pw_stream_state rtp_stream_get_state(struct rtp_stream *s, const char **error);
23
+
24
+int rtp_stream_set_param(struct rtp_stream *s, uint32_t id, const struct spa_pod *param);
25
+
26
+int rtp_stream_update_params(struct rtp_stream *stream,
27
+           const struct spa_pod **params,
28
+           uint32_t n_params);
29
 
30
 #ifdef __cplusplus
31
 }
32
pipewire-0.3.81.tar.gz/src/pipewire/context.c -> pipewire-0.3.82.tar.gz/src/pipewire/context.c Changed
80
 
1
@@ -1027,7 +1027,7 @@
2
            context, n, n->name);
3
 
4
    if (n->info.state >= PW_NODE_STATE_IDLE)
5
-       n->reconfigure = true;
6
+       n->need_resume = !n->pause_on_idle;
7
    pw_impl_node_set_state(n, PW_NODE_STATE_SUSPENDED);
8
 }
9
 
10
@@ -1309,7 +1309,7 @@
11
        uint32_t target_quantum, target_rate, current_rate, current_quantum;
12
        uint64_t quantum_stamp = 0, rate_stamp = 0;
13
        bool force_rate, force_quantum, restore_rate = false, restore_quantum = false;
14
-       bool do_reconfigure = false, was_target_pending;
15
+       bool do_reconfigure = false, need_resume, was_target_pending;
16
        const uint32_t *node_rates;
17
        uint32_t node_n_rates, node_def_rate;
18
        uint32_t node_max_quantum, node_min_quantum, node_def_quantum, node_rate_quantum;
19
@@ -1399,13 +1399,22 @@
20
        if (force_rate)
21
            lock_rate = false;
22
 
23
-       if (n->reconfigure)
24
+       need_resume = n->need_resume;
25
+       if (need_resume) {
26
            running = true;
27
+           n->need_resume = false;
28
+       }
29
 
30
        current_rate = n->target_rate.denom;
31
        if (!restore_rate &&
32
-          (lock_rate || n->reconfigure || !running ||
33
-           (!force_rate && (n->info.state > PW_NODE_STATE_IDLE))))
34
+          (lock_rate || need_resume || !running ||
35
+           (!force_rate && (n->info.state > PW_NODE_STATE_IDLE)))) {
36
+           pw_log_debug("%p: keep rate:1/%u restore:%u lock:%u resume:%u "
37
+                   "running:%u force:%u state:%s", context,
38
+                   current_rate, restore_rate, lock_rate, need_resume,
39
+                   running, force_rate,
40
+                   pw_node_state_as_string(n->info.state));
41
+
42
            /* when we don't need to restore or rate and
43
             * when someone wants us to lock the rate of this driver or
44
             * when we are in the process of reconfiguring the driver or
45
@@ -1413,6 +1422,7 @@
46
             * when the driver is busy and we don't need to force a rate,
47
             * keep the current rate */
48
            target_rate = current_rate;
49
+       }
50
        else {
51
            /* Here we are allowed to change the rate of the driver.
52
             * Start with the default rate. If the desired rate is
53
@@ -1464,9 +1474,15 @@
54
 
55
        current_quantum = n->target_quantum;
56
        if (!restore_quantum &&
57
-          (lock_quantum || n->reconfigure || !running ||
58
-           (!force_quantum && (n->info.state > PW_NODE_STATE_IDLE))))
59
+          (lock_quantum || need_resume || !running ||
60
+           (!force_quantum && (n->info.state > PW_NODE_STATE_IDLE)))) {
61
+           pw_log_debug("%p: keep quantum:%u restore:%u lock:%u resume:%u "
62
+                   "running:%u force:%u state:%s", context,
63
+                   current_quantum, restore_quantum, lock_quantum, need_resume,
64
+                   running, force_quantum,
65
+                   pw_node_state_as_string(n->info.state));
66
            target_quantum = current_quantum;
67
+       }
68
        else {
69
            target_quantum = node_def_quantum;
70
            if (latency.denom != 0)
71
@@ -1474,7 +1490,7 @@
72
            target_quantum = SPA_CLAMP(target_quantum, node_min_quantum, node_max_quantum);
73
            target_quantum = SPA_MIN(target_quantum, lim_quantum);
74
 
75
-           if (settings->clock_power_of_two_quantum)
76
+           if (settings->clock_power_of_two_quantum && !force_quantum)
77
                target_quantum = flp2(target_quantum);
78
        }
79
 
80
pipewire-0.3.81.tar.gz/src/pipewire/filter.c -> pipewire-0.3.82.tar.gz/src/pipewire/filter.c Changed
15
 
1
@@ -1659,10 +1659,10 @@
2
    if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) {
3
        struct spa_fraction q;
4
        if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) {
5
-           pw_properties_setf(filter->properties, PW_KEY_NODE_RATE,
6
+           pw_properties_setf(filter->properties, PW_KEY_NODE_FORCE_RATE,
7
                    "1/%u", q.denom);
8
-           pw_properties_setf(filter->properties, PW_KEY_NODE_LATENCY,
9
-                   "%u/%u", q.num, q.denom);
10
+           pw_properties_setf(filter->properties, PW_KEY_NODE_FORCE_QUANTUM,
11
+                   "%u", q.num);
12
        }
13
    }
14
    if ((str = getenv("PIPEWIRE_LATENCY")) != NULL)
15
pipewire-0.3.81.tar.gz/src/pipewire/impl-client.c -> pipewire-0.3.82.tar.gz/src/pipewire/impl-client.c Changed
74
 
1
@@ -152,30 +152,53 @@
2
    return false;
3
 }
4
 
5
-static int update_properties(struct pw_impl_client *client, const struct spa_dict *dict, bool filter)
6
+static bool check_client_property_update(struct pw_impl_client *client,
7
+       const char *key, const char *old, const char *new)
8
 {
9
    static const char * const ignored = {
10
+       PW_KEY_PROTOCOL,
11
        PW_KEY_OBJECT_ID,
12
+       PW_KEY_OBJECT_SERIAL,
13
+       PW_KEY_ACCESS,
14
        NULL
15
    };
16
 
17
+   /* Refuse specific restricted keys */
18
+   if (has_key(ignored, key))
19
+       goto deny;
20
+
21
+   /* Refuse all security keys */
22
+   if (spa_strstartswith(key, "pipewire.sec."))
23
+       goto deny;
24
+
25
+   /* Restrict other pipewire.* keys */
26
+   if (spa_strstartswith(key, "pipewire.")) {
27
+       /* Refuse changing existing values */
28
+       if (old != NULL)
29
+           goto deny;
30
+   }
31
+
32
+   return true;
33
+
34
+deny:
35
+   if (!spa_streq(old, new))
36
+       pw_log_warn("%p: refuse property update '%s' from '%s' to '%s'",
37
+               client, key, old ? old : "<unset>", new ? new : "<unset>");
38
+   return false;
39
+}
40
+
41
+static int update_properties(struct pw_impl_client *client, const struct spa_dict *dict, bool filter)
42
+{
43
    struct pw_resource *resource;
44
    int changed = 0;
45
    uint32_t i;
46
-   const char *old;
47
 
48
         for (i = 0; i < dict->n_items; i++) {
49
        if (filter) {
50
-           if (spa_strstartswith(dict->itemsi.key, "pipewire.") &&
51
-               (old = pw_properties_get(client->properties, dict->itemsi.key)) != NULL &&
52
-               (dict->itemsi.value == NULL || !spa_streq(old, dict->itemsi.value))) {
53
-               pw_log_warn("%p: refuse property update '%s' from '%s' to '%s'",
54
-                       client, dict->itemsi.key, old,
55
-                       dict->itemsi.value);
56
-               continue;
57
+           const char *old = pw_properties_get(client->properties, dict->itemsi.key);
58
+           const char *new = dict->itemsi.value;
59
 
60
-           }
61
-           if (has_key(ignored, dict->itemsi.key))
62
+           if (!check_client_property_update(client, dict->itemsi.key, old, new))
63
                continue;
64
        }
65
                 changed += pw_properties_set(client->properties, dict->itemsi.key, dict->itemsi.value);
66
@@ -501,6 +524,7 @@
67
        PW_KEY_SEC_UID,
68
        PW_KEY_SEC_GID,
69
        PW_KEY_SEC_LABEL,
70
+       PW_KEY_SEC_SOCKET,
71
        NULL
72
    };
73
 
74
pipewire-0.3.81.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.82.tar.gz/src/pipewire/impl-node.c Changed
16
 
1
@@ -418,14 +418,6 @@
2
        spa_list_for_each(resource, &node->global->resource_list, link)
3
            pw_resource_error(resource, res, error);
4
    }
5
-   if (node->reconfigure) {
6
-       if (state == PW_NODE_STATE_SUSPENDED &&
7
-           node->pause_on_idle) {
8
-           node->reconfigure = false;
9
-       }
10
-       if (state == PW_NODE_STATE_RUNNING)
11
-           node->reconfigure = false;
12
-   }
13
    if (old == PW_NODE_STATE_RUNNING &&
14
        state == PW_NODE_STATE_IDLE &&
15
        node->suspend_on_idle) {
16
pipewire-0.3.81.tar.gz/src/pipewire/keys.h -> pipewire-0.3.82.tar.gz/src/pipewire/keys.h Changed
10
 
1
@@ -38,6 +38,8 @@
2
 #define PW_KEY_SEC_GID         "pipewire.sec.gid"  /**< client gid, set by protocol*/
3
 #define PW_KEY_SEC_LABEL       "pipewire.sec.label"    /**< client security label, set by protocol*/
4
 
5
+#define PW_KEY_SEC_SOCKET      "pipewire.sec.socket"   /**< client socket name, set by protocol */
6
+
7
 #define PW_KEY_LIBRARY_NAME_SYSTEM "library.name.system"   /**< name of the system library to use */
8
 #define PW_KEY_LIBRARY_NAME_LOOP   "library.name.loop" /**< name of the loop library to use */
9
 #define PW_KEY_LIBRARY_NAME_DBUS   "library.name.dbus" /**< name of the dbus library to use */
10
pipewire-0.3.81.tar.gz/src/pipewire/log.c -> pipewire-0.3.82.tar.gz/src/pipewire/log.c Changed
15
 
1
@@ -233,13 +233,6 @@
2
    }
3
 }
4
 
5
-SPA_EXPORT
6
-void
7
-_pw_log_topic_new(struct spa_log_topic *topic)
8
-{
9
-   spa_log_topic_init(global_log, topic);
10
-}
11
-
12
 void
13
 pw_log_init(void)
14
 {
15
pipewire-0.3.81.tar.gz/src/pipewire/log.h -> pipewire-0.3.82.tar.gz/src/pipewire/log.h Changed
19
 
1
@@ -72,17 +72,6 @@
2
        int line, const char *func,
3
        const char *fmt, va_list args) SPA_PRINTF_FUNC(5, 0);
4
 
5
-/** Initialize the log topic. The returned topic is owned by the pipewire
6
- * context and the topic must not be modified or freed.
7
- * Do not use this function directly, use one of PW_LOG_TOPIC_* instead.
8
- *
9
- * \see PW_LOG_TOPIC_STATIC
10
- * \see PW_LOG_TOPIC_EXTERN
11
- * \see PW_LOG_TOPIC
12
- */
13
-void
14
-_pw_log_topic_new(struct spa_log_topic *topic);
15
-
16
 /**
17
  * Declare a static log topic named \a var. The usual usage is:
18
  * \code
19
pipewire-0.3.81.tar.gz/src/pipewire/map.h -> pipewire-0.3.82.tar.gz/src/pipewire/map.h Changed
21
 
1
@@ -189,7 +189,7 @@
2
  * \param id the index to look at
3
  * \return the item at \a id or NULL when no such item exists
4
  */
5
-static inline void *pw_map_lookup(struct pw_map *map, uint32_t id)
6
+static inline void *pw_map_lookup(const struct pw_map *map, uint32_t id)
7
 {
8
    if (SPA_LIKELY(pw_map_check_id(map, id))) {
9
        union pw_map_item *item = pw_map_get_item(map, id);
10
@@ -207,8 +207,8 @@
11
  * \param data data to pass to \a func
12
  * \return the result of the last call to \a func or 0 when all callbacks returned 0.
13
  */
14
-static inline int pw_map_for_each(struct pw_map *map,
15
-                  int (*func) (void *item_data, void *data), void *data)
16
+static inline int pw_map_for_each(const struct pw_map *map,
17
+                 int (*func) (void *item_data, void *data), void *data)
18
 {
19
    union pw_map_item *item;
20
    int res = 0;
21
pipewire-0.3.81.tar.gz/src/pipewire/private.h -> pipewire-0.3.82.tar.gz/src/pipewire/private.h Changed
10
 
1
@@ -671,7 +671,7 @@
2
    unsigned int added:1;       /**< the node was add to graph */
3
    unsigned int pause_on_idle:1;   /**< Pause processing when IDLE */
4
    unsigned int suspend_on_idle:1;
5
-   unsigned int reconfigure:1;
6
+   unsigned int need_resume:1;
7
    unsigned int forced_rate:1;
8
    unsigned int forced_quantum:1;
9
    unsigned int trigger:1;     /**< has the TRIGGER property and needs an extra
10
pipewire-0.3.81.tar.gz/src/pipewire/stream.c -> pipewire-0.3.82.tar.gz/src/pipewire/stream.c Changed
15
 
1
@@ -2034,10 +2034,10 @@
2
    if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) {
3
        struct spa_fraction q;
4
        if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) {
5
-           pw_properties_setf(stream->properties, PW_KEY_NODE_RATE,
6
+           pw_properties_setf(stream->properties, PW_KEY_NODE_FORCE_RATE,
7
                    "1/%u", q.denom);
8
-           pw_properties_setf(stream->properties, PW_KEY_NODE_LATENCY,
9
-                   "%u/%u", q.num, q.denom);
10
+           pw_properties_setf(stream->properties, PW_KEY_NODE_FORCE_QUANTUM,
11
+                   "%u", q.num);
12
        }
13
    }
14
    if ((str = getenv("PIPEWIRE_LATENCY")) != NULL)
15
pipewire-0.3.81.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.82.tar.gz/src/tools/pw-cat.c Changed
11
 
1
@@ -1977,7 +1977,8 @@
2
        uint32_t i, n_items = 0;
3
 
4
        for (i = 0; i < data.props->dict.n_items; i++) {
5
-           if (spa_strstartswith(data.props->dict.itemsi.key, "media."))
6
+           if (n_items < SPA_N_ELEMENTS(items) &&
7
+               spa_strstartswith(data.props->dict.itemsi.key, "media."))
8
                itemsn_items++ = data.props->dict.itemsi;
9
        }
10
        if (n_items > 0) {
11