Changes of Revision 56

pipewire-aptx.changes Changed
x
 
1
@@ -1,4 +1,9 @@
2
 -------------------------------------------------------------------
3
+Tue Jul  1 16:46:10 UTC 2025 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 1.4.6
6
+
7
+-------------------------------------------------------------------
8
 Sat Jun 14 11:49:24 UTC 2025 - Bjørn Lie <zaitor@opensuse.org>
9
 
10
 - Update to version 1.4.5
11
pipewire-aptx.spec Changed
10
 
1
@@ -8,7 +8,7 @@
2
 %define minimum_version 1.4.0
3
 
4
 Name:           pipewire-aptx
5
-Version:        1.4.5
6
+Version:        1.4.6
7
 Release:        0
8
 Summary:        PipeWire Bluetooth aptX codec plugin
9
 License:        MIT
10
_service Changed
10
 
1
@@ -2,6 +2,6 @@
2
   <service name="download_url">
3
     <param name="host">gitlab.freedesktop.org</param>
4
     <param name="protocol">https</param>
5
-    <param name="path">/pipewire/pipewire/-/archive/1.4.5/pipewire-1.4.5.tar.bz2</param>
6
+    <param name="path">/pipewire/pipewire/-/archive/1.4.6/pipewire-1.4.6.tar.bz2</param>
7
   </service>
8
 </services>
9
\ No newline at end of file
10
_service:download_url:pipewire-1.4.5.tar.bz2/NEWS -> _service:download_url:pipewire-1.4.6.tar.bz2/NEWS Changed
49
 
1
@@ -1,3 +1,37 @@
2
+# PipeWire 1.4.6 (2025-06-27)
3
+
4
+This is a bugfix release that is API and ABI compatible with
5
+previous 1.x releases.
6
+
7
+## Highlights
8
+  - Fix a crasher bug in filter-chain and one in the ALSA plugin.
9
+  - Improve latency reporting in module-combine-stream.
10
+  - Some smaller fixes and cleanups.
11
+
12
+
13
+## modules
14
+  - Improve latency handling in module-combine-stream. (#4731)
15
+  - Improve save activation/deactivation of the filter-graph in
16
+    module-filter-chain to avoid crashes. (#4700, #4750)
17
+  - Add an option to disable RAOP with a context.property.
18
+
19
+## SPA
20
+  - Handle NULL io in alsa wakeup code. This can happen when there
21
+    is negotiation happening. (#4734)
22
+  - Enable interrupts after an ALSA error to keep the dataflow
23
+    going.
24
+  - Reset some stats better after an ALSA error.
25
+  - Support the alsa.use-ucm property for the ALSA udev plugin.
26
+
27
+# pulse-server
28
+  - Mark empty buffers. This improves some code paths in the mixer.
29
+
30
+## GStreamer
31
+  - Fix a refcount issue in the device provider.
32
+
33
+
34
+Older versions:
35
+
36
 # PipeWire 1.4.5 (2025-06-04)
37
 
38
 This is a quick bugfix release that is API and ABI compatible with
39
@@ -22,9 +56,6 @@
40
   - Fix a potential deadlock when calling _drop and _drain at the
41
     same time. (#4728)
42
 
43
-
44
-Older versions:
45
-
46
 # PipeWire 1.4.4 (2025-05-29)
47
 
48
 This is a quick bugfix release that is API and ABI compatible with
49
_service:download_url:pipewire-1.4.5.tar.bz2/doc/DoxygenLayout.xml -> _service:download_url:pipewire-1.4.6.tar.bz2/doc/DoxygenLayout.xml Changed
13
 
1
@@ -41,6 +41,11 @@
2
       <tab type="globals" visible="no" title="" intro=""/>
3
     </tab>
4
     <tab type="examples" visible="yes" title="" intro=""/>
5
+    <tab type="usergroup" title="PipeWire Versions">
6
+      <tab type="user" url="https://docs.pipewire.org/1.2/" title="1.2.x"/>
7
+      <tab type="user" url="https://docs.pipewire.org/1.4/" title="1.4.x"/>
8
+      <tab type="user" url="https://docs.pipewire.org/devel/" title="Development"/>
9
+    </tab>
10
   </navindex>
11
 
12
   <!-- Layout definition for a class page -->
13
_service:download_url:pipewire-1.4.5.tar.bz2/meson.build -> _service:download_url:pipewire-1.4.6.tar.bz2/meson.build Changed
8
 
1
@@ -1,5 +1,5 @@
2
 project('pipewire', 'c' ,
3
-  version : '1.4.5',
4
+  version : '1.4.6',
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
_service:download_url:pipewire-1.4.5.tar.bz2/spa/include/spa/param/audio/raw-types.h -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/include/spa/param/audio/raw-types.h Changed
17
 
1
@@ -274,6 +274,15 @@
2
    return spa_type_to_short_name(type, spa_type_audio_channel, "UNK");
3
 }
4
 
5
+#define SPA_TYPE_INFO_AudioVolumeRampScale     SPA_TYPE_INFO_ENUM_BASE "AudioVolumeRampScale"
6
+#define SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE SPA_TYPE_INFO_AudioVolumeRampScale ":"
7
+
8
+static const struct spa_type_info spa_type_audio_volume_ramp_scale = {
9
+   { SPA_AUDIO_VOLUME_RAMP_INVALID, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE "INVALID", NULL },
10
+   { SPA_AUDIO_VOLUME_RAMP_LINEAR, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE "LINEAR", NULL },
11
+   { SPA_AUDIO_VOLUME_RAMP_CUBIC, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE "CUBIC", NULL },
12
+   { 0, 0, NULL, NULL },
13
+};
14
 
15
 /**
16
  * \}
17
_service:download_url:pipewire-1.4.5.tar.bz2/spa/include/spa/param/props-types.h -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/include/spa/param/props-types.h Changed
26
 
1
@@ -41,12 +41,12 @@
2
    { SPA_PROP_bluetoothAudioCodec, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "bluetoothAudioCodec", spa_type_bluetooth_audio_codec },
3
    { SPA_PROP_bluetoothOffloadActive, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "bluetoothOffloadActive", NULL },
4
 
5
-   { SPA_PROP_waveType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "waveType", NULL },
6
+   { SPA_PROP_waveType, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "waveType", NULL },
7
    { SPA_PROP_frequency, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "frequency", NULL },
8
    { SPA_PROP_volume, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "volume", NULL },
9
    { SPA_PROP_mute, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "mute", NULL },
10
-   { SPA_PROP_patternType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "patternType", NULL },
11
-   { SPA_PROP_ditherType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "ditherType", NULL },
12
+   { SPA_PROP_patternType, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "patternType", NULL },
13
+   { SPA_PROP_ditherType, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "ditherType", NULL },
14
    { SPA_PROP_truncate, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "truncate", NULL },
15
    { SPA_PROP_channelVolumes, SPA_TYPE_Array, SPA_TYPE_INFO_PROPS_BASE "channelVolumes", spa_type_prop_float_array },
16
    { SPA_PROP_volumeBase, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "volumeBase", NULL },
17
@@ -62,7 +62,7 @@
18
    { SPA_PROP_volumeRampStepSamples, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "volumeRampStepSamples", NULL },
19
    { SPA_PROP_volumeRampTime, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "volumeRampTime", NULL },
20
    { SPA_PROP_volumeRampStepTime, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "volumeRampStepTime", NULL },
21
-   { SPA_PROP_volumeRampScale, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "volumeRampScale", NULL },
22
+   { SPA_PROP_volumeRampScale, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "volumeRampScale", spa_type_audio_volume_ramp_scale },
23
 
24
    { SPA_PROP_brightness, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "brightness", NULL },
25
    { SPA_PROP_contrast, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "contrast", NULL },
26
_service:download_url:pipewire-1.4.5.tar.bz2/spa/include/spa/support/loop.h -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/include/spa/support/loop.h Changed
11
 
1
@@ -121,6 +121,9 @@
2
     * \param block If \true, do not return until func has been called. Otherwise,
3
     *              returns immediately. Passing \true does not risk a deadlock because
4
     *              the data thread is never allowed to wait on any other thread.
5
+    *              It the loop requires some locking, it must be acquired before
6
+    *              calling this function because a blocking invoke will release
7
+    *              the lock while blocking.
8
     * \param user_data An opaque pointer passed to func.
9
     * \return `-EPIPE` if the internal ring buffer filled up,
10
     *         if block is \false, 0 if seq was SPA_ID_INVALID or
11
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/alsa/alsa-pcm.c Changed
179
 
1
@@ -2574,6 +2574,7 @@
2
    state->alsa_sync = true;
3
    state->alsa_sync_warning = false;
4
    state->alsa_started = false;
5
+   spa_dll_init(&state->dll);
6
 
7
    return 0;
8
 }
9
@@ -2606,6 +2607,7 @@
10
 }
11
 
12
 static inline int check_position_config(struct state *state, bool starting);
13
+static void update_sources(struct state *state, bool active);
14
 
15
 static int alsa_recover(struct state *state)
16
 {
17
@@ -2685,6 +2687,8 @@
18
        if (follower != driver && follower->linked)
19
            do_start(follower);
20
    }
21
+
22
+   update_sources(state, true);
23
    return 0;
24
 }
25
 
26
@@ -2797,6 +2801,12 @@
27
    double err, corr, avg;
28
    int32_t diff;
29
 
30
+   if (SPA_UNLIKELY(state->dll.bw == 0.0)) {
31
+       spa_dll_set_bw(&state->dll, SPA_DLL_BW_MAX, state->threshold, state->rate);
32
+       state->next_time = current_time;
33
+       state->base_time = current_time;
34
+   }
35
+
36
    if (state->disable_tsched && !follower) {
37
        err = (int64_t)(current_time - state->next_time);
38
        err = err / 1e9 * state->rate;
39
@@ -2807,11 +2817,6 @@
40
            err = target - delay;
41
    }
42
 
43
-   if (SPA_UNLIKELY(state->dll.bw == 0.0)) {
44
-       spa_dll_set_bw(&state->dll, SPA_DLL_BW_MAX, state->threshold, state->rate);
45
-       state->next_time = current_time;
46
-       state->base_time = current_time;
47
-   }
48
    diff = (int32_t) (state->last_threshold - state->threshold);
49
 
50
    if (SPA_UNLIKELY(diff != 0)) {
51
@@ -2888,9 +2893,9 @@
52
        state->clock->next_nsec = state->next_time;
53
    }
54
 
55
-   spa_log_trace_fp(state->log, "%p: follower:%d %"PRIu64" %f %ld %ld %f %f %u",
56
-           state, follower, current_time, corr, delay, target, err, state->threshold * corr,
57
-           state->threshold);
58
+   spa_log_trace_fp(state->log, "%p: follower:%d %"PRIu64" %"PRIu64" %f %ld %ld %f %f %u",
59
+           state, follower, current_time, state->next_time, corr, delay, target,
60
+           err, state->threshold * corr, state->threshold);
61
 
62
    return 0;
63
 }
64
@@ -3000,28 +3005,30 @@
65
    if (SPA_UNLIKELY((res = update_time(state, current_time, delay, target, following)) < 0))
66
        return res;
67
 
68
-   if (following && state->alsa_started && !state->linked) {
69
+   if (following && state->alsa_started) {
70
        if (SPA_UNLIKELY(state->alsa_sync)) {
71
            enum spa_log_level lev;
72
 
73
-           if (SPA_UNLIKELY(state->alsa_sync_warning))
74
-               lev = SPA_LOG_LEVEL_WARN;
75
-           else
76
-               lev = SPA_LOG_LEVEL_INFO;
77
-
78
-           if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0)
79
-               lev = SPA_LOG_LEVEL_DEBUG;
80
-
81
-           spa_log_lev(state->log, lev, "%s: follower avail:%lu delay:%ld "
82
-                   "target:%ld thr:%u, resync (%d suppressed)",
83
-                   state->name, avail, delay,
84
-                   target, state->threshold, suppressed);
85
-
86
-           if (avail > target)
87
-               snd_pcm_rewind(state->hndl, avail - target);
88
-           else if (avail < target)
89
-               spa_alsa_silence(state, target - avail);
90
-           avail = target;
91
+           if (!state->linked) {
92
+               if (SPA_UNLIKELY(state->alsa_sync_warning))
93
+                   lev = SPA_LOG_LEVEL_WARN;
94
+               else
95
+                   lev = SPA_LOG_LEVEL_INFO;
96
+
97
+               if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0)
98
+                   lev = SPA_LOG_LEVEL_DEBUG;
99
+
100
+               spa_log_lev(state->log, lev, "%s: follower avail:%lu delay:%ld "
101
+                       "target:%ld thr:%u, resync (%d suppressed)",
102
+                       state->name, avail, delay,
103
+                       target, state->threshold, suppressed);
104
+
105
+               if (avail > target)
106
+                   snd_pcm_rewind(state->hndl, avail - target);
107
+               else if (avail < target)
108
+                   spa_alsa_silence(state, target - avail);
109
+               avail = target;
110
+           }
111
            spa_dll_init(&state->dll);
112
            state->alsa_sync = false;
113
        } else
114
@@ -3266,27 +3273,28 @@
115
        return res;
116
 
117
    max_read = state->buffer_frames;
118
-   if (following && !state->linked) {
119
+   if (following) {
120
        if (state->alsa_sync) {
121
-           enum spa_log_level lev;
122
-
123
-           if (SPA_UNLIKELY(state->alsa_sync_warning))
124
-               lev = SPA_LOG_LEVEL_WARN;
125
-           else
126
-               lev = SPA_LOG_LEVEL_INFO;
127
-
128
-           if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0)
129
-               lev = SPA_LOG_LEVEL_DEBUG;
130
-
131
-           spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u "
132
-                   "resample:%d, resync (%d suppressed)", state->name, delay,
133
-                   target, state->threshold, state->resample, suppressed);
134
-
135
-           if (avail < target)
136
-               max_read = target - avail;
137
-           else if (avail > target) {
138
-               snd_pcm_forward(state->hndl, avail - target);
139
-               avail = target;
140
+           if (!state->linked) {
141
+               enum spa_log_level lev;
142
+               if (SPA_UNLIKELY(state->alsa_sync_warning))
143
+                   lev = SPA_LOG_LEVEL_WARN;
144
+               else
145
+                   lev = SPA_LOG_LEVEL_INFO;
146
+
147
+               if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0)
148
+                   lev = SPA_LOG_LEVEL_DEBUG;
149
+
150
+               spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u "
151
+                       "resample:%d, resync (%d suppressed)", state->name, delay,
152
+                       target, state->threshold, state->resample, suppressed);
153
+
154
+               if (avail < target)
155
+                   max_read = target - avail;
156
+               else if (avail > target) {
157
+                   snd_pcm_forward(state->hndl, avail - target);
158
+                   avail = target;
159
+               }
160
            }
161
            state->alsa_sync = false;
162
            spa_dll_init(&state->dll);
163
@@ -3409,11 +3417,13 @@
164
 {
165
    struct spa_io_buffers *io = state->io;
166
 
167
-   spa_log_trace_fp(state->log, "%p: %d", state, io->status);
168
+   spa_log_trace_fp(state->log, "%p: %d", state, io ? io->status : 0);
169
 
170
    update_sources(state, false);
171
 
172
-   io->status = SPA_STATUS_NEED_DATA;
173
+   if (io != NULL)
174
+       io->status = SPA_STATUS_NEED_DATA;
175
+
176
    return spa_node_call_ready(&state->callbacks, SPA_STATUS_NEED_DATA);
177
 }
178
 
179
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/alsa/alsa-seq.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/alsa/alsa-seq.c Changed
10
 
1
@@ -330,7 +330,7 @@
2
            state->port_info(state->port_info_data, addr, NULL);
3
            break;
4
        default:
5
-           spa_log_info(state->log, "unhandled event %d: %d:%d",
6
+           spa_log_debug(state->log, "unhandled event %d: %d:%d",
7
                    type, addr->client, addr->port);
8
            break;
9
 
10
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/alsa/alsa-udev.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/alsa/alsa-udev.c Changed
45
 
1
@@ -94,6 +94,7 @@
2
    struct spa_source notify;
3
    unsigned int use_acp:1;
4
    unsigned int expose_busy:1;
5
+   int use_ucm;
6
 };
7
 
8
 static int impl_udev_open(struct impl *this)
9
@@ -500,7 +501,7 @@
10
    if (num_pcm_devices > 0) {
11
        struct spa_device_object_info info;
12
        char *cn = NULL, *cln = NULL;
13
-       struct spa_dict_item items25;
14
+       struct spa_dict_item items26;
15
        unsigned int n_items = 0;
16
 
17
        card->pcm_device_id = calc_pcm_device_id(card);
18
@@ -521,6 +522,9 @@
19
        itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ENUM_API, "udev");
20
        itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API,  "alsa");
21
        itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Device");
22
+       if (this->use_ucm != -1)
23
+           itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_USE_UCM,
24
+                   this->use_ucm ? "true" : "false");
25
        itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_PATH, path);
26
        itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_CARD, path+3);
27
        if (snd_card_get_name(card->card_nr, &cn) >= 0)
28
@@ -1105,6 +1109,7 @@
29
    alsa_log_topic_init(this->log);
30
    this->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
31
    this->main_system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_System);
32
+   this->use_ucm = -1;
33
 
34
    if (this->main_loop == NULL) {
35
        spa_log_error(this->log, "a main-loop is needed");
36
@@ -1131,6 +1136,8 @@
37
            this->use_acp = spa_atob(str);
38
        else if ((str = spa_dict_lookup(info, "alsa.udev.expose-busy")) != NULL)
39
            this->expose_busy = spa_atob(str);
40
+       else if ((str = spa_dict_lookup(info, "alsa.use-ucm")) != NULL)
41
+           this->use_ucm = spa_atob(str) ? 1 : 0;
42
    }
43
 
44
    return 0;
45
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/audioconvert/audioconvert.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/audioconvert/audioconvert.c Changed
27
 
1
@@ -291,7 +291,6 @@
2
    unsigned int started:1;
3
    unsigned int setup:1;
4
    unsigned int resample_peaks:1;
5
-   unsigned int is_passthrough:1;
6
    unsigned int ramp_volume:1;
7
    unsigned int drained:1;
8
    unsigned int rate_adjust:1;
9
@@ -3014,9 +3013,6 @@
10
                spa_log_warn(this->log, "%p: memory %d on buffer %d not aligned",
11
                        this, j, i);
12
            }
13
-           if (direction == SPA_DIRECTION_OUTPUT &&
14
-               !SPA_FLAG_IS_SET(dj.flags, SPA_DATA_FLAG_DYNAMIC))
15
-               this->is_passthrough = false;
16
 
17
            b->datasj = dj.data;
18
 
19
@@ -3597,6 +3593,7 @@
20
            if (io->status & SPA_STATUS_DRAINED) {
21
                spa_log_debug(this->log, "%p: port %d drained", this, port->id);
22
                in_avail = flush_in = draining = true;
23
+               in_empty = false;
24
            } else {
25
                spa_log_trace_fp(this->log, "%p: empty input port %d %p %d %d %d",
26
                        this, port->id, io, io->status, io->buffer_id,
27
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/audioconvert/test-audioconvert.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/audioconvert/test-audioconvert.c Changed
19
 
1
@@ -598,7 +598,7 @@
2
 
3
        for (j = 0; j < in_data->planes; j++, k++) {
4
            b->datasj.type = SPA_DATA_MemPtr;
5
-           b->datasj.flags = 0;
6
+           b->datasj.flags = SPA_DATA_FLAG_READABLE;
7
            b->datasj.fd = -1;
8
            b->datasj.mapoffset = 0;
9
            b->datasj.maxsize = in_data->size;
10
@@ -629,7 +629,7 @@
11
 
12
        for (j = 0; j < out_data->planes; j++) {
13
            b->datasj.type = SPA_DATA_MemPtr;
14
-           b->datasj.flags = 0;
15
+           b->datasj.flags = SPA_DATA_FLAG_READWRITE;
16
            b->datasj.fd = -1;
17
            b->datasj.mapoffset = 0;
18
            b->datasj.maxsize = out_data->size;
19
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/test/fakesrc.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/test/fakesrc.c Changed
19
 
1
@@ -130,7 +130,7 @@
2
        param = spa_pod_builder_add_object(&b,
3
            SPA_TYPE_OBJECT_Props, id,
4
            SPA_PROP_live,        SPA_POD_Bool(p->live),
5
-           SPA_PROP_patternType, SPA_POD_CHOICE_ENUM_Id(2, p->pattern, p->pattern));
6
+           SPA_PROP_patternType, SPA_POD_CHOICE_ENUM_Int(2, p->pattern, p->pattern));
7
        break;
8
    }
9
    default:
10
@@ -173,7 +173,7 @@
11
        spa_pod_parse_object(param,
12
            SPA_TYPE_OBJECT_Props, NULL,
13
            SPA_PROP_live,        SPA_POD_OPT_Bool(&p->live),
14
-           SPA_PROP_patternType, SPA_POD_OPT_Id(&p->pattern));
15
+           SPA_PROP_patternType, SPA_POD_OPT_Int(&p->pattern));
16
 
17
        if (p->live)
18
            port->info.flags |= SPA_PORT_FLAG_LIVE;
19
_service:download_url:pipewire-1.4.5.tar.bz2/src/daemon/pipewire.conf.avail/50-raop.conf.in -> _service:download_url:pipewire-1.4.6.tar.bz2/src/daemon/pipewire.conf.avail/50-raop.conf.in Changed
9
 
1
@@ -1,4 +1,6 @@
2
 context.modules = 
3
     # Use mDNS to detect and load module-raop-sink
4
-    { name = libpipewire-module-raop-discover }
5
+    { name = libpipewire-module-raop-discover
6
+        condition =  { module.raop = !false } 
7
+    }
8
 
9
_service:download_url:pipewire-1.4.5.tar.bz2/src/gst/gstpipewiredeviceprovider.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/gst/gstpipewiredeviceprovider.c Changed
10
 
1
@@ -324,7 +324,7 @@
2
 
3
     if(self->list_only) {
4
       self->devices = g_list_insert_sorted (self->devices,
5
-                                            gst_object_ref_sink (device),
6
+                                            gst_object_ref (device),
7
                                             compare_device_session_priority);
8
     } else {
9
       gst_object_ref (device);
10
_service:download_url:pipewire-1.4.5.tar.bz2/src/modules/module-combine-stream.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/modules/module-combine-stream.c Changed
122
 
1
@@ -319,6 +319,7 @@
2
 
3
    int64_t delay_samples;      /* for main loop */
4
    int64_t data_delay_samples; /* for data loop */
5
+   int64_t compensate_samples; /* for main loop */
6
 
7
    unsigned int ready:1;
8
    unsigned int added:1;
9
@@ -574,6 +575,7 @@
10
 
11
        max_delay = SPA_MAX(max_delay, delay);
12
        s->delay_samples = delay;
13
+       s->compensate_samples = 0;
14
    }
15
 
16
    spa_list_for_each(s, &impl->streams, link) {
17
@@ -581,9 +583,9 @@
18
 
19
        if (s->delay_samples != INT64_MIN) {
20
            int64_t delay = max_delay - s->delay_samples;
21
+           s->compensate_samples = delay;
22
            size = delay * sizeof(float);
23
        }
24
-
25
        resize_delay(s, size);
26
    }
27
 
28
@@ -653,6 +655,40 @@
29
    }
30
 }
31
 
32
+static void param_latency_changed(struct impl *impl, const struct spa_pod *param)
33
+{
34
+   if (param == NULL)
35
+       return;
36
+
37
+   pw_log_debug("latency update");
38
+   struct stream *s;
39
+   struct spa_latency_info info;
40
+   const struct spa_pod *params1;
41
+
42
+   if (spa_latency_parse(param, &info) < 0)
43
+       return;
44
+
45
+   spa_list_for_each(s, &impl->streams, link) {
46
+       uint8_t buffer1024;
47
+       struct spa_pod_builder b;
48
+
49
+       if (s->stream == NULL)
50
+           continue;
51
+
52
+       pw_log_debug("updating stream %d", s->id);
53
+       if (impl->latency_compensate) {
54
+           struct spa_latency_info other = info;
55
+           other.min_rate += s->compensate_samples;
56
+           other.max_rate += s->compensate_samples;
57
+           spa_pod_builder_init(&b, buffer, sizeof(buffer));
58
+           params0 = spa_latency_build(&b, SPA_PARAM_Latency, &other);
59
+       } else {
60
+           params0 = param;
61
+       }
62
+       pw_stream_update_params(s->stream, params, 1);
63
+   }
64
+}
65
+
66
 static int do_remove_stream(struct spa_loop *loop, bool async, uint32_t seq,
67
                 const void *data, size_t size, void *user_data)
68
 {
69
@@ -730,6 +766,9 @@
70
    case PW_STREAM_STATE_UNCONNECTED:
71
        stream_destroy(s);
72
        break;
73
+   case PW_STREAM_STATE_STREAMING:
74
+       update_latency(s->impl);
75
+       break;
76
    default:
77
        break;
78
    }
79
@@ -1070,6 +1109,7 @@
80
        enum pw_stream_state state, const char *error)
81
 {
82
    struct impl *impl = d;
83
+   struct stream *s;
84
    switch (state) {
85
    case PW_STREAM_STATE_ERROR:
86
    case PW_STREAM_STATE_UNCONNECTED:
87
@@ -1077,6 +1117,10 @@
88
        break;
89
    case PW_STREAM_STATE_PAUSED:
90
        clear_delaybuf(impl);
91
+       spa_list_for_each(s, &impl->streams, link) {
92
+           pw_stream_flush(s->stream, false);
93
+       }
94
+       pw_stream_flush(impl->combine, false);
95
        impl->combine_id = pw_stream_get_node_id(impl->combine);
96
        pw_log_info("got combine id %d", impl->combine_id);
97
        break;
98
@@ -1291,10 +1335,12 @@
99
        update_latency(impl);
100
        break;
101
    }
102
-   case SPA_PARAM_Tag: {
103
+   case SPA_PARAM_Tag:
104
        param_tag_changed(impl, param);
105
        break;
106
-   }
107
+   case SPA_PARAM_Latency:
108
+       param_latency_changed(impl, param);
109
+       break;
110
    default:
111
        break;
112
    }
113
@@ -1489,7 +1535,7 @@
114
    spa_list_init(&impl->streams);
115
 
116
    if (args == NULL)
117
-       args = "";
118
+       args = "{}";
119
 
120
    props = pw_properties_new_string_checked(args, strlen(args), &loc);
121
    if (props == NULL) {
122
_service:download_url:pipewire-1.4.5.tar.bz2/src/modules/module-filter-chain.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/modules/module-filter-chain.c Changed
201
 
1
@@ -844,6 +844,7 @@
2
    struct spa_hook graph_listener;
3
    uint32_t n_inputs;
4
    uint32_t n_outputs;
5
+   bool graph_active;
6
 };
7
 
8
 static void capture_destroy(void *d)
9
@@ -863,6 +864,8 @@
10
            struct pw_buffer *t;
11
            if ((t = pw_stream_dequeue_buffer(impl->capture)) == NULL)
12
                break;
13
+           /* playback part is not ready, consume, discard and recycle
14
+            * the capture buffers */
15
            pw_stream_queue_buffer(impl->capture, t);
16
        }
17
    }
18
@@ -929,7 +932,8 @@
19
    pw_log_trace_fp("%p: stride:%d size:%d requested:%"PRIu64" (%"PRIu64")", impl,
20
            stride, data_size, out->requested, out->requested * stride);
21
 
22
-   spa_filter_graph_process(impl->graph, cin, cout, data_size / sizeof(float));
23
+   if (impl->graph_active)
24
+       spa_filter_graph_process(impl->graph, cin, cout, data_size / sizeof(float));
25
 
26
 done:
27
    if (in != NULL)
28
@@ -938,6 +942,61 @@
29
        pw_stream_queue_buffer(impl->playback, out);
30
 }
31
 
32
+static int do_deactivate(struct spa_loop *loop, bool async, uint32_t seq,
33
+                const void *data, size_t size, void *user_data)
34
+{
35
+   struct impl *impl = user_data;
36
+   impl->graph_active = false;
37
+   return 0;
38
+}
39
+
40
+static int activate_graph(struct impl *impl)
41
+{
42
+   char rate64;
43
+   int res;
44
+
45
+   if (impl->graph_active)
46
+       return 0;
47
+
48
+   snprintf(rate, sizeof(rate), "%lu", impl->rate);
49
+   res = spa_filter_graph_activate(impl->graph, &SPA_DICT_ITEMS(
50
+               SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, rate)));
51
+
52
+   if (res >= 0)
53
+       impl->graph_active = true;
54
+
55
+   return res;
56
+}
57
+
58
+static int deactivate_graph(struct impl *impl)
59
+{
60
+   struct pw_loop *data_loop;
61
+
62
+   if (!impl->graph_active)
63
+       return 0;
64
+
65
+   data_loop = pw_stream_get_data_loop(impl->playback);
66
+   pw_loop_invoke(data_loop, do_deactivate, 0, NULL, 0, true, impl);
67
+
68
+   return spa_filter_graph_deactivate(impl->graph);
69
+}
70
+
71
+static int reset_graph(struct impl *impl)
72
+{
73
+   struct pw_loop *data_loop;
74
+   int res;
75
+   bool old_active = impl->graph_active;
76
+
77
+   data_loop = pw_stream_get_data_loop(impl->playback);
78
+   pw_loop_invoke(data_loop, do_deactivate, 0, NULL, 0, true, impl);
79
+
80
+   res = spa_filter_graph_reset(impl->graph);
81
+
82
+   impl->graph_active = old_active;
83
+
84
+   return res;
85
+}
86
+
87
 static void param_latency_changed(struct impl *impl, const struct spa_pod *param)
88
 {
89
    struct spa_latency_info latency;
90
@@ -976,14 +1035,10 @@
91
        enum pw_stream_state state, const char *error)
92
 {
93
    struct impl *impl = data;
94
-   struct spa_filter_graph *graph = impl->graph;
95
-   int res;
96
 
97
    switch (state) {
98
    case PW_STREAM_STATE_PAUSED:
99
-       pw_stream_flush(impl->playback, false);
100
        pw_stream_flush(impl->capture, false);
101
-       spa_filter_graph_reset(graph);
102
        break;
103
    case PW_STREAM_STATE_UNCONNECTED:
104
        pw_log_info("module %p: unconnected", impl);
105
@@ -993,34 +1048,10 @@
106
        pw_log_info("module %p: error: %s", impl, error);
107
        break;
108
    case PW_STREAM_STATE_STREAMING:
109
-   {
110
-       uint32_t target = impl->info.rate;
111
-       if (target == 0)
112
-           target = impl->position ?
113
-               impl->position->clock.target_rate.denom : DEFAULT_RATE;
114
-       if (target == 0) {
115
-           res = -EINVAL;
116
-           goto error;
117
-       }
118
-       if (impl->rate != target) {
119
-           char rate64;
120
-           impl->rate = target;
121
-           snprintf(rate, sizeof(rate), "%lu", impl->rate);
122
-           spa_filter_graph_deactivate(graph);
123
-           if ((res = spa_filter_graph_activate(graph,
124
-                   &SPA_DICT_ITEMS(
125
-                       SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, rate)))) < 0)
126
-               goto error;
127
-       }
128
-       break;
129
-   }
130
    default:
131
        break;
132
    }
133
    return;
134
-error:
135
-   pw_stream_set_error(impl->capture, res, "can't start graph: %s",
136
-           spa_strerror(res));
137
 }
138
 
139
 static void io_changed(void *data, uint32_t id, void *area, uint32_t size)
140
@@ -1039,7 +1070,6 @@
141
        bool capture)
142
 {
143
    struct impl *impl = data;
144
-   struct spa_filter_graph *graph = impl->graph;
145
    int res;
146
 
147
    switch (id) {
148
@@ -1049,8 +1079,8 @@
149
        spa_zero(info);
150
        if (param == NULL) {
151
            pw_log_info("module %p: filter deactivate", impl);
152
-           if (capture)
153
-               spa_filter_graph_deactivate(graph);
154
+           if (!capture)
155
+               deactivate_graph(impl);
156
            impl->rate = 0;
157
        } else {
158
            if ((res = spa_format_audio_raw_parse(param, &info)) < 0)
159
@@ -1093,6 +1123,51 @@
160
    .param_changed = capture_param_changed
161
 };
162
 
163
+static void playback_state_changed(void *data, enum pw_stream_state old,
164
+       enum pw_stream_state state, const char *error)
165
+{
166
+   struct impl *impl = data;
167
+   int res;
168
+
169
+   switch (state) {
170
+   case PW_STREAM_STATE_PAUSED:
171
+       pw_stream_flush(impl->playback, false);
172
+       reset_graph(impl);
173
+       break;
174
+   case PW_STREAM_STATE_UNCONNECTED:
175
+       pw_log_info("module %p: unconnected", impl);
176
+       pw_impl_module_schedule_destroy(impl->module);
177
+       break;
178
+   case PW_STREAM_STATE_ERROR:
179
+       pw_log_info("module %p: error: %s", impl, error);
180
+       break;
181
+   case PW_STREAM_STATE_STREAMING:
182
+   {
183
+       uint32_t target = impl->info.rate;
184
+       if (target == 0)
185
+           target = impl->position ?
186
+               impl->position->clock.target_rate.denom : DEFAULT_RATE;
187
+       if (target == 0) {
188
+           res = -EINVAL;
189
+           goto error;
190
+       }
191
+       if (impl->rate != target) {
192
+           impl->rate = target;
193
+           deactivate_graph(impl);
194
+       }
195
+       if ((res = activate_graph(impl)) < 0)
196
+           goto error;
197
+       break;
198
+   }
199
+   default:
200
+       break;
201
_service:download_url:pipewire-1.4.5.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c Changed
33
 
1
@@ -1379,6 +1379,7 @@
2
 
3
    if (stream->direction == PW_DIRECTION_OUTPUT) {
4
        int32_t avail = spa_ringbuffer_get_read_index(&stream->ring, &index);
5
+       bool empty = false;
6
 
7
        minreq = buffer->requested * stream->frame_size;
8
        if (minreq == 0)
9
@@ -1391,6 +1392,7 @@
10
            /* underrun, produce a silence buffer */
11
            size = SPA_MIN(d->maxsize, minreq);
12
            sample_spec_silence(&stream->ss, p, size);
13
+           empty = true;
14
 
15
            if (stream->draining && !stream->corked) {
16
                stream->draining = false;
17
@@ -1406,6 +1408,7 @@
18
                        stream->buffer, MAXLENGTH,
19
                        index % MAXLENGTH,
20
                        p, avail);
21
+                   empty = false;
22
                }
23
                index += size;
24
                pd.read_inc = size;
25
@@ -1446,6 +1449,7 @@
26
        d->chunk->offset = 0;
27
        d->chunk->stride = stream->frame_size;
28
        d->chunk->size = size;
29
+       SPA_FLAG_UPDATE(d->chunk->flags, SPA_CHUNK_FLAG_EMPTY, empty);
30
        buffer->size = size / stream->frame_size;
31
    } else  {
32
        int32_t filled = spa_ringbuffer_get_write_index(&stream->ring, &index);
33