We truncated the diff of some files because they were too big.
If you want to see the full diff for every file, click here.
Changes of Revision 56
pipewire-aptx.changes
Changed
x
1
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
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
<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
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
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
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
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
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
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
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
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
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
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
18
if (follower != driver && follower->linked)
19
do_start(follower);
20
}
21
+
22
+ update_sources(state, true);
23
return 0;
24
}
25
26
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
18
stream->buffer, MAXLENGTH,
19
index % MAXLENGTH,
20
p, avail);
21
+ empty = false;
22
}
23
index += size;
24
pd.read_inc = size;
25
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