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 44
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Mon Sep 16 18:48:10 UTC 2024 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 1.2.3
6
+
7
+-------------------------------------------------------------------
8
Mon Aug 19 20:39:19 UTC 2024 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 1.2.2
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 1.2.2
6
+Version: 1.2.3
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-1.2.2.tar.bz2/NEWS -> pipewire-1.2.3.tar.bz2/NEWS
Changed
59
1
2
+# PipeWire 1.2.3 (2024-08-22)
3
+
4
+This is a bugfix release that is API and ABI compatible with the
5
+previous 1.2.x and 1.0.x releases.
6
+
7
+## Highlights
8
+ - Implement freewheeling support in the FFADO driver. Also improve
9
+ buffersize and samplerate handling.
10
+ - Improve some locking on spa_loop. Remove a possible deadlock when
11
+ the queue was full.
12
+ - Allocate more space for the libcamera devices string to properly
13
+ deduplicate libcamera and v4l2 devices.
14
+ - Some more bugfixes and improvements.
15
+
16
+
17
+## PipeWire
18
+ - Improve activation state changes and xrun detection some more.
19
+ (#4182)
20
+ - Avoid a memory leak when a link in error is destroyed.
21
+
22
+## Modules
23
+ - Improve samplerate and buffersize handling in FFADO driver so that
24
+ it is possible to force a rate and buffer size.
25
+ - Implement freewheeling support in the ffado driver.
26
+ - Always set the server side clock.quantum-limit on nodes. This fixes
27
+ a buffer size problem in Midi-bridge. (#4005)
28
+
29
+## SPA
30
+ - Improve some locking on spa_loop. Remove a possible deadlock when
31
+ the queue was full. (#4114)
32
+ - Allocate more space for the libcamera devices string to properly
33
+ deduplicate libcamera and v4l2 devices.
34
+ - Fix a potential race when enumerating v4l2 udev devices. (#3960)
35
+
36
+## Bluetooth
37
+ - Improve compatibility with some devices (Soundcore Motion 300).
38
+
39
+## Tools
40
+ - pw-cli can now handle arbitrarily large input and params. (#4166)
41
+ - Avoid some compiler warnings in pw-top.
42
+
43
+Older versions:
44
+
45
+
46
# PipeWire 1.2.2 (2024-07-31)
47
48
This is a bugfix release that is API and ABI compatible with the
49
50
- Fix the jack_get_time() function, it was returning nano instead of micro
51
seconds.
52
53
-Older versions:
54
-
55
-
56
# PipeWire 1.2.1 (2024-07-12)
57
58
This is a bugfix release that is API and ABI compatible with previous
59
pipewire-1.2.2.tar.bz2/meson.build -> pipewire-1.2.3.tar.bz2/meson.build
Changed
26
1
2
project('pipewire', 'c' ,
3
- version : '1.2.2',
4
+ version : '1.2.3',
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
9
sdl_dep = dependency('sdl2', required : get_option('sdl2'))
10
summary({'SDL2 (video examples)': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies')
11
drm_dep = dependency('libdrm', required : false)
12
-readline_dep = dependency('readline', required : get_option('readline'))
13
14
-if not readline_dep.found()
15
- readline_dep = cc.find_library('readline', required : get_option('readline'))
16
+if get_option('readline').disabled()
17
+ readline_dep = dependency('', required: false)
18
+else
19
+ readline_dep = dependency('readline', required : false)
20
+ if not readline_dep.found()
21
+ readline_dep = cc.find_library('readline', required : get_option('readline'))
22
+ endif
23
endif
24
25
# Both the FFmpeg SPA plugin and the pw-cat FFmpeg integration use libavcodec.
26
pipewire-1.2.2.tar.bz2/pipewire-jack/src/pipewire-jack.c -> pipewire-1.2.3.tar.bz2/pipewire-jack/src/pipewire-jack.c
Changed
18
1
2
struct link *l;
3
4
pw_log_debug("%p prepared:%d ", c, c->rt.prepared);
5
- if (!c->rt.prepared)
6
- return 0;
7
8
old_state = SPA_ATOMIC_XCHG(c->activation->status, PW_NODE_ACTIVATION_INACTIVE);
9
if (old_state != PW_NODE_ACTIVATION_FINISHED)
10
trigger = get_time_ns(c->l->system);
11
12
+ if (!c->rt.prepared)
13
+ return 0;
14
+
15
spa_list_for_each(l, &c->rt.target_links, target_link) {
16
if (!c->async && trigger != 0)
17
l->trigger(l, trigger);
18
pipewire-1.2.2.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> pipewire-1.2.3.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
14
1
2
last_pitch = (uint64_t)(1000000 / state->last_rate);
3
}
4
5
- /* The pitch adjustment is limited to 1 ppm */
6
- if (pitch == last_pitch)
7
+ /* The pitch adjustment is limited to 1 ppm according to the spec, but
8
+ * let's avoid very granular changes so that we don't spam the host
9
+ * (and ourselves, if bind-ctls are enabled). */
10
+ if (SPA_ABS((int)pitch - (int)last_pitch) < 10)
11
return 0;
12
13
snd_ctl_elem_value_set_integer(state->pitch_elem, 0, pitch);
14
pipewire-1.2.2.tar.bz2/spa/plugins/bluez5/backend-native.c -> pipewire-1.2.3.tar.bz2/spa/plugins/bluez5/backend-native.c
Changed
15
1
2
}
3
4
rfcomm_send_reply(rfcomm, "OK");
5
+ } else if (spa_strstartswith(buf, "AT+CCWA=")) {
6
+ /*
7
+ * Claim that call waiting notifications are supported.
8
+ * Required for some devices (e.g. Soundcore Motion 300),
9
+ * as they stop sending commands if the reply to CCWA is not OK.
10
+ */
11
+ rfcomm_send_reply(rfcomm, "OK");
12
} else if (spa_strstartswith(buf, "AT+CLCC")) {
13
struct spa_list *calls;
14
struct call *call;
15
pipewire-1.2.2.tar.bz2/spa/plugins/libcamera/libcamera-device.cpp -> pipewire-1.2.3.tar.bz2/spa/plugins/libcamera/libcamera-device.cpp
Changed
10
1
2
uint32_t n_items = 0;
3
struct spa_device_info info;
4
struct spa_param_info params2;
5
- char path256, name256, devices_str128;
6
+ char path256, name256, devices_str256;
7
struct spa_strbuf buf;
8
9
info = SPA_DEVICE_INFO_INIT();
10
pipewire-1.2.2.tar.bz2/spa/plugins/support/loop.c -> pipewire-1.2.3.tar.bz2/spa/plugins/support/loop.c
Changed
201
1
2
#define ITEM_ALIGN 8
3
#define DATAS_SIZE (4096*8)
4
#define MAX_EP 32
5
-#define DEFAULT_RETRY (1 * SPA_USEC_PER_SEC)
6
7
/** \cond */
8
9
10
struct spa_list destroy_list;
11
struct spa_list queue_list;
12
struct spa_hook_list hooks_list;
13
- int retry_timeout;
14
15
int poll_fd;
16
pthread_t thread;
17
18
struct impl *impl;
19
struct spa_list link;
20
21
+#define QUEUE_FLAG_NONE (0)
22
+#define QUEUE_FLAG_ACK_FD (1<<0)
23
+ uint32_t flags;
24
+ struct queue *overflow;
25
+
26
int ack_fd;
27
struct spa_ratelimit rate_limit;
28
29
30
return res;
31
}
32
33
+static struct queue *loop_create_queue(void *object, uint32_t flags)
34
+{
35
+ struct impl *impl = object;
36
+ struct queue *queue;
37
+ int res;
38
+
39
+ queue = calloc(1, sizeof(struct queue));
40
+ if (queue == NULL)
41
+ return NULL;
42
+
43
+ queue->impl = impl;
44
+ queue->flags = flags;
45
+
46
+ queue->rate_limit.interval = 2 * SPA_NSEC_PER_SEC;
47
+ queue->rate_limit.burst = 1;
48
+
49
+ queue->buffer_data = SPA_PTR_ALIGN(queue->buffer_mem, MAX_ALIGN, uint8_t);
50
+ spa_ringbuffer_init(&queue->buffer);
51
+
52
+ if (flags & QUEUE_FLAG_ACK_FD) {
53
+ if ((res = spa_system_eventfd_create(impl->system,
54
+ SPA_FD_EVENT_SEMAPHORE | SPA_FD_CLOEXEC)) < 0) {
55
+ spa_log_error(impl->log, "%p: can't create ack event: %s",
56
+ impl, spa_strerror(res));
57
+ goto error;
58
+ }
59
+ queue->ack_fd = res;
60
+ } else {
61
+ queue->ack_fd = -1;
62
+ }
63
+
64
+ pthread_mutex_lock(&impl->queue_lock);
65
+ spa_list_append(&impl->queue_list, &queue->link);
66
+ pthread_mutex_unlock(&impl->queue_lock);
67
+
68
+ spa_log_info(impl->log, "%p created queue %p", impl, queue);
69
+
70
+ return queue;
71
+
72
+error:
73
+ free(queue);
74
+ errno = -res;
75
+ return NULL;
76
+}
77
+
78
+
79
static inline int32_t item_compare(struct invoke_item *a, struct invoke_item *b)
80
{
81
return (int32_t)(a->count - b->count);
82
83
pthread_mutex_lock(&impl->queue_lock);
84
flush_count = ++impl->flush_count;
85
while (true) {
86
- struct queue *cqueue, *queue;
87
+ struct queue *cqueue, *queue = NULL;
88
struct invoke_item *citem, *item = NULL;
89
uint32_t cindex, index;
90
spa_invoke_func_t func;
91
92
block = item->block;
93
spa_ringbuffer_read_update(&queue->buffer, index);
94
95
- if (block) {
96
+ if (block && queue->ack_fd != -1) {
97
if ((res = spa_system_eventfd_write(impl->system, queue->ack_fd, 1)) < 0)
98
spa_log_warn(impl->log, "%p: failed to write event fd:%d: %s",
99
queue, queue->ack_fd, spa_strerror(res));
100
101
} else {
102
loop_signal_event(impl, impl->wakeup);
103
104
- if (block) {
105
+ if (block && queue->ack_fd != -1) {
106
uint64_t count = 1;
107
108
spa_loop_control_hook_before(&impl->hooks_list);
109
110
return res;
111
112
xrun:
113
- nsec = get_time_ns(impl->system);
114
- if ((suppressed = spa_ratelimit_test(&queue->rate_limit, nsec)) >= 0) {
115
- spa_log_warn(impl->log, "%p: queue full %d, need %zd (%d suppressed)",
116
- queue, avail, need, suppressed);
117
+ if (queue->overflow == NULL) {
118
+ nsec = get_time_ns(impl->system);
119
+ if ((suppressed = spa_ratelimit_test(&queue->rate_limit, nsec)) >= 0) {
120
+ spa_log_warn(impl->log, "%p: queue full %d, need %zd (%d suppressed)",
121
+ queue, avail, need, suppressed);
122
+ }
123
+ queue->overflow = loop_create_queue(impl, QUEUE_FLAG_NONE);
124
+ if (queue->overflow == NULL)
125
+ return -errno;
126
+ queue->overflow->ack_fd = queue->ack_fd;
127
}
128
- loop_signal_event(impl, impl->wakeup);
129
- if (impl->retry_timeout == 0)
130
- return -EPIPE;
131
- usleep(impl->retry_timeout);
132
+ queue = queue->overflow;
133
goto retry;
134
}
135
136
137
spa_list_remove(&queue->link);
138
pthread_mutex_unlock(&impl->queue_lock);
139
140
- spa_system_close(impl->system, queue->ack_fd);
141
+ if (queue->flags & QUEUE_FLAG_ACK_FD)
142
+ spa_system_close(impl->system, queue->ack_fd);
143
free(queue);
144
}
145
146
-static struct queue *loop_create_queue(void *object, uint32_t flags)
147
-{
148
- struct impl *impl = object;
149
- struct queue *queue;
150
- int res;
151
-
152
- queue = calloc(1, sizeof(struct queue));
153
- if (queue == NULL)
154
- return NULL;
155
-
156
- queue->impl = impl;
157
-
158
- queue->rate_limit.interval = 2 * SPA_NSEC_PER_SEC;
159
- queue->rate_limit.burst = 1;
160
-
161
- queue->buffer_data = SPA_PTR_ALIGN(queue->buffer_mem, MAX_ALIGN, uint8_t);
162
- spa_ringbuffer_init(&queue->buffer);
163
-
164
- if ((res = spa_system_eventfd_create(impl->system,
165
- SPA_FD_EVENT_SEMAPHORE | SPA_FD_CLOEXEC)) < 0) {
166
- spa_log_error(impl->log, "%p: can't create ack event: %s",
167
- impl, spa_strerror(res));
168
- goto error;
169
- }
170
- queue->ack_fd = res;
171
-
172
- pthread_mutex_lock(&impl->queue_lock);
173
- spa_list_append(&impl->queue_list, &queue->link);
174
- pthread_mutex_unlock(&impl->queue_lock);
175
-
176
- spa_log_info(impl->log, "%p created queue %p", impl, queue);
177
-
178
- return queue;
179
-
180
-error:
181
- free(queue);
182
- errno = -res;
183
- return NULL;
184
-}
185
-
186
static int loop_invoke(void *object, spa_invoke_func_t func, uint32_t seq,
187
const void *data, size_t size, bool block, void *user_data)
188
{
189
190
struct queue *local_queue = tss_get(impl->queue_tss_id);
191
192
if (local_queue == NULL) {
193
- local_queue = loop_create_queue(impl, 0);
194
+ local_queue = loop_create_queue(impl, QUEUE_FLAG_ACK_FD);
195
if (local_queue == NULL)
196
return -errno;
197
tss_set(impl->queue_tss_id, local_queue);
198
199
SPA_VERSION_LOOP_UTILS,
200
&impl_loop_utils, impl);
201
pipewire-1.2.2.tar.bz2/spa/plugins/v4l2/v4l2-udev.c -> pipewire-1.2.3.tar.bz2/spa/plugins/v4l2/v4l2-udev.c
Changed
24
1
2
3
spa_loop_add_source(this->main_loop, &this->notify);
4
5
- for (size_t i = 0; i < this->n_devices; i++)
6
- start_watching_device(this, &this->devicesi);
7
-
8
return 0;
9
}
10
11
12
13
emit_device_info(this, true);
14
15
- if ((res = enum_devices(this)) < 0)
16
+ if ((res = start_monitor(this)) < 0)
17
return res;
18
19
- if ((res = start_monitor(this)) < 0)
20
+ if ((res = enum_devices(this)) < 0)
21
return res;
22
23
spa_hook_list_join(&this->hooks, &save);
24
pipewire-1.2.2.tar.bz2/src/daemon/pipewire.conf.in -> pipewire-1.2.3.tar.bz2/src/daemon/pipewire.conf.in
Changed
19
1
2
node.name = Dummy-Driver
3
node.group = pipewire.dummy
4
node.sync-group = sync.dummy
5
- priority.driver = 20000
6
+ priority.driver = 200000
7
#clock.id = monotonic # realtime | tai | monotonic-raw | boottime
8
#clock.name = "clock.system.monotonic"
9
}
10
11
args = {
12
factory.name = support.node.driver
13
node.name = Freewheel-Driver
14
- priority.driver = 19000
15
+ priority.driver = 190000
16
node.group = pipewire.freewheel
17
node.sync-group = sync.dummy
18
node.freewheel = true
19
pipewire-1.2.2.tar.bz2/src/modules/module-ffado-driver.c -> pipewire-1.2.3.tar.bz2/src/modules/module-ffado-driver.c
Changed
201
1
2
*
3
* - `driver.mode`: the driver mode, sink|source|duplex, default duplex
4
* - `ffado.devices`: array of devices to open, default "hw:0"
5
- * - `ffado.period-size`: period size,default 1024
6
+ * - `ffado.period-size`: period size,default 1024. A value of 0 will use the graph duration.
7
* - `ffado.period-num`: period number,default 3
8
- * - `ffado.sample-rate`: sample-rate, default 48000
9
+ * - `ffado.sample-rate`: sample-rate, default 48000. A value of 0 will use the graph rate.
10
* - `ffado.slave-mode`: slave mode
11
* - `ffado.snoop-mode`: snoop mode
12
* - `ffado.verbose`: ffado verbose level
13
14
15
unsigned int ready:1;
16
unsigned int running:1;
17
- unsigned int transfered:1;
18
+
19
+ struct {
20
+ unsigned int transfered:1;
21
+ } rt;
22
};
23
24
struct impl {
25
26
uint32_t output_latency;
27
uint32_t quantum_limit;
28
29
- uint32_t pw_xrun;
30
- uint32_t ffado_xrun;
31
uint32_t frame_time;
32
33
unsigned int do_disconnect:1;
34
unsigned int fix_midi:1;
35
unsigned int started:1;
36
+ unsigned int freewheel:1;
37
38
pthread_t thread;
39
40
- unsigned int done:1;
41
- unsigned int triggered:1;
42
- unsigned int new_xrun:1;
43
+ struct {
44
+ unsigned int done:1;
45
+ unsigned int triggered:1;
46
+ unsigned int new_xrun:1;
47
+ uint32_t pw_xrun;
48
+ uint32_t ffado_xrun;
49
+ } rt;
50
};
51
52
static int stop_ffado_device(struct impl *impl);
53
54
struct impl *impl = s->impl;
55
uint32_t i, n_samples = position->clock.duration;
56
57
- pw_log_trace_fp("process %d", impl->triggered);
58
- if (impl->mode == MODE_SINK && impl->triggered) {
59
- impl->triggered = false;
60
+ pw_log_trace_fp("process %d", impl->rt.triggered);
61
+ if (impl->mode == MODE_SINK && impl->rt.triggered) {
62
+ impl->rt.triggered = false;
63
return;
64
}
65
66
67
p->cleared = false;
68
}
69
ffado_streaming_transfer_playback_buffers(impl->dev);
70
- s->transfered = true;
71
+ s->rt.transfered = true;
72
73
if (impl->mode == MODE_SINK) {
74
pw_log_trace_fp("done %u", impl->frame_time);
75
- impl->done = true;
76
+ impl->rt.done = true;
77
set_timeout(impl, position->clock.nsec);
78
}
79
}
80
81
for (i = 0; i < s->n_ports; i++) {
82
struct port *p = s->portsi;
83
if (p != NULL)
84
- clear_port_buffer(p, impl->period_size);
85
+ clear_port_buffer(p, impl->device_options.period_size);
86
}
87
ffado_streaming_transfer_playback_buffers(impl->dev);
88
- s->transfered = true;
89
+ s->rt.transfered = true;
90
}
91
92
static void source_process(void *d, struct spa_io_position *position)
93
94
struct impl *impl = s->impl;
95
uint32_t i, n_samples = position->clock.duration;
96
97
- pw_log_trace_fp("process %d", impl->triggered);
98
+ pw_log_trace_fp("process %d", impl->rt.triggered);
99
+
100
+ if (SPA_FLAG_IS_SET(impl->position->clock.flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER))
101
+ return;
102
103
- if (!impl->triggered) {
104
+ if (!impl->rt.triggered) {
105
pw_log_trace_fp("done %u", impl->frame_time);
106
- impl->done = true;
107
- if (!impl->sink.transfered)
108
+ impl->rt.done = true;
109
+ if (!impl->sink.rt.transfered)
110
silence_playback(impl);
111
set_timeout(impl, position->clock.nsec);
112
return;
113
}
114
115
- impl->triggered = false;
116
+ impl->rt.triggered = false;
117
118
ffado_streaming_transfer_capture_buffers(impl->dev);
119
- s->transfered = true;
120
+ s->rt.transfered = true;
121
122
for (i = 0; i < s->n_ports; i++) {
123
struct port *p = s->portsi;
124
125
{
126
struct stream *s = data;
127
struct impl *impl = s->impl;
128
+ bool freewheel;
129
+
130
if (port_data == NULL) {
131
switch (id) {
132
case SPA_IO_Position:
133
impl->position = area;
134
+ freewheel = impl->position != NULL &&
135
+ SPA_FLAG_IS_SET(impl->position->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL);
136
+ if (impl->freewheel != freewheel) {
137
+ pw_log_info("freewheel: %d -> %d", impl->freewheel, freewheel);
138
+ impl->freewheel = freewheel;
139
+ if (impl->started) {
140
+ if (freewheel) {
141
+ set_timeout(impl, 0);
142
+ ffado_streaming_stop(impl->dev);
143
+ } else {
144
+ ffado_streaming_start(impl->dev);
145
+ impl->rt.done = true;
146
+ set_timeout(impl, get_time_ns(impl));
147
+ }
148
+ }
149
+ }
150
break;
151
default:
152
break;
153
154
.process = source_process,
155
};
156
157
+static int update_stream_format(struct stream *s, uint32_t samplerate)
158
+{
159
+ uint8_t buffer1024;
160
+ struct spa_pod_builder b;
161
+ uint32_t n_params;
162
+ const struct spa_pod *params2;
163
+
164
+ if (s->info.rate == samplerate)
165
+ return 0;
166
+
167
+ s->info.rate = samplerate;
168
+
169
+ if (s->filter == NULL)
170
+ return 0;
171
+
172
+ n_params = 0;
173
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
174
+ paramsn_params++ = spa_format_audio_raw_build(&b,
175
+ SPA_PARAM_EnumFormat, &s->info);
176
+ paramsn_params++ = spa_format_audio_raw_build(&b,
177
+ SPA_PARAM_Format, &s->info);
178
+
179
+ return pw_filter_update_params(s->filter, NULL, params, n_params);
180
+}
181
+
182
static int make_stream(struct stream *s, const char *name)
183
{
184
struct impl *impl = s->impl;
185
186
const struct spa_pod *params4;
187
uint8_t buffer1024;
188
struct spa_pod_builder b;
189
- struct spa_latency_info latency;
190
-
191
- spa_zero(latency);
192
- n_params = 0;
193
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
194
195
s->filter = pw_filter_new(impl->core, name, pw_properties_copy(s->props));
196
if (s->filter == NULL)
197
198
199
reset_volume(&s->volume, s->info.channels);
200
201
pipewire-1.2.2.tar.bz2/src/modules/module-portal.c -> pipewire-1.2.3.tar.bz2/src/modules/module-portal.c
Changed
10
1
2
* ## Example configuration
3
*\code{.unparsed}
4
* context.modules =
5
- * { name = libpipewire-portal }
6
+ * { name = libpipewire-module-portal }
7
*
8
*\endcode
9
*
10
pipewire-1.2.2.tar.bz2/src/modules/module-raop-discover.c -> pipewire-1.2.3.tar.bz2/src/modules/module-raop-discover.c
Changed
10
1
2
*
3
*\code{.unparsed}
4
* context.modules =
5
- * { name = libpipewire-raop-discover
6
+ * { name = libpipewire-module-raop-discover
7
* args = {
8
* #roap.discover-local = false;
9
* #raop.latency.ms = 1000
10
pipewire-1.2.2.tar.bz2/src/modules/module-x11-bell.c -> pipewire-1.2.3.tar.bz2/src/modules/module-x11-bell.c
Changed
10
1
2
* ## Example configuration
3
*\code{.unparsed}
4
* context.modules =
5
- * { name = libpipewire-x11-bell }
6
+ * { name = libpipewire-module-x11-bell }
7
* args = {
8
* #sink.name = @DEFAULT_SINK@
9
* sample.name = "bell-window-system"
10
pipewire-1.2.2.tar.bz2/src/modules/spa/spa-node.c -> pipewire-1.2.3.tar.bz2/src/modules/spa/spa-node.c
Changed
21
1
2
struct pw_loop *loop;
3
struct match match;
4
5
- if (properties) {
6
- p = pw_context_get_properties(context);
7
- pw_properties_set(properties, "clock.quantum-limit",
8
- pw_properties_get(p, "default.clock.quantum-limit"));
9
- } else {
10
+ if (properties == NULL) {
11
properties = pw_properties_new(NULL, NULL);
12
if (properties == NULL)
13
return NULL;
14
}
15
+ p = pw_context_get_properties(context);
16
+ pw_properties_set(properties, "clock.quantum-limit",
17
+ pw_properties_get(p, "default.clock.quantum-limit"));
18
19
match = MATCH_INIT(properties);
20
pw_context_conf_section_match_rules(context, "node.rules",
21
pipewire-1.2.2.tar.bz2/src/pipewire/impl-link.c -> pipewire-1.2.3.tar.bz2/src/pipewire/impl-link.c
Changed
9
1
2
3
free(link->name);
4
free(link->info.format);
5
+ free((char *) link->info.error);
6
free(impl);
7
}
8
9
pipewire-1.2.2.tar.bz2/src/pipewire/impl-node.c -> pipewire-1.2.3.tar.bz2/src/pipewire/impl-node.c
Changed
182
1
2
pw_log_trace("%p: unprepare %d remote:%d exported:%d", this, this->rt.prepared,
3
this->remote, this->exported);
4
5
- if (!this->exported) {
6
- /* We mark ourself as finished now, this will avoid going further into the process loop
7
- * in case our fd was ready (removing ourselfs from the loop should avoid that as well).
8
- * If we were supposed to be scheduled make sure we continue the graph for the peers we
9
- * were supposed to trigger */
10
- old_state = SPA_ATOMIC_XCHG(this->rt.target.activation->status, PW_NODE_ACTIVATION_INACTIVE);
11
- if (PW_NODE_ACTIVATION_PENDING_TRIGGER(old_state))
12
- trigger = get_time_ns(this->rt.target.system);
13
- }
14
+ /* We mark ourself as finished now, this will avoid going further into the process loop
15
+ * in case our fd was ready (removing ourselfs from the loop should avoid that as well).
16
+ * If we were supposed to be scheduled make sure we continue the graph for the peers we
17
+ * were supposed to trigger */
18
+ old_state = SPA_ATOMIC_XCHG(this->rt.target.activation->status, PW_NODE_ACTIVATION_INACTIVE);
19
+ if (PW_NODE_ACTIVATION_PENDING_TRIGGER(old_state))
20
+ trigger = get_time_ns(this->rt.target.system);
21
+
22
if (!this->rt.prepared)
23
return 0;
24
25
26
str_status(status), suppressed);
27
}
28
29
-static inline void debug_xrun_graph(struct pw_impl_node *driver, uint64_t nsec)
30
+static inline void debug_xrun_graph(struct pw_impl_node *driver, uint64_t nsec, uint32_t old_status)
31
{
32
int suppressed;
33
enum spa_log_level level = SPA_LOG_LEVEL_DEBUG;
34
35
if ((suppressed = spa_ratelimit_test(&driver->rt.rate_limit, nsec)) >= 0)
36
level = SPA_LOG_LEVEL_WARN;
37
38
- pw_log(level, "(%s-%u) graph xrun (%d suppressed)",
39
- driver->name, driver->info.id, suppressed);
40
+ pw_log(level, "(%s-%u) graph xrun %s (%d suppressed)",
41
+ driver->name, driver->info.id, str_status(old_status), suppressed);
42
43
spa_list_for_each(t, &driver->rt.target_list, link) {
44
struct pw_node_activation *a = t->activation;
45
struct pw_node_activation_state *state = &a->state0;
46
+ uint32_t status = SPA_ATOMIC_LOAD(a->status);
47
48
- if (a->status == PW_NODE_ACTIVATION_TRIGGERED ||
49
- a->status == PW_NODE_ACTIVATION_AWAKE) {
50
+ if (status == PW_NODE_ACTIVATION_TRIGGERED ||
51
+ status == PW_NODE_ACTIVATION_AWAKE) {
52
pw_log(level, "(%s-%u) xrun state:%p pending:%d/%d s:%"PRIu64" a:%"PRIu64" f:%"PRIu64
53
" waiting:%"PRIu64" process:%"PRIu64" status:%s",
54
t->name, t->id, state,
55
56
a->finish_time,
57
a->awake_time - a->signal_time,
58
a->finish_time - a->awake_time,
59
- str_status(a->status));
60
+ str_status(status));
61
62
}
63
}
64
65
spa_list_for_each(t, &driver->rt.target_list, link) {
66
struct pw_node_activation *a = t->activation;
67
struct pw_node_activation_state *state = &a->state0;
68
+ uint32_t status = SPA_ATOMIC_LOAD(a->status);
69
70
if (!a->pending_sync)
71
continue;
72
73
a->finish_time,
74
a->awake_time - a->signal_time,
75
a->finish_time - a->awake_time,
76
- str_status(a->status));
77
+ str_status(status));
78
}
79
}
80
81
82
struct pw_impl_port *p;
83
struct pw_node_activation *a = this->rt.target.activation;
84
struct spa_system *data_system = this->rt.target.system;
85
- int status, old_status;
86
+ int status;
87
+ bool was_awake;
88
89
if (!SPA_ATOMIC_CAS(a->status,
90
PW_NODE_ACTIVATION_TRIGGERED,
91
92
return 0;
93
94
a->awake_time = nsec;
95
- pw_log_trace_fp("%p: %s process remote:%u exported:%u %"PRIu64" %"PRIu64,
96
- this, this->name, this->remote, this->exported,
97
+ pw_log_trace_fp("%p: %s-%d process remote:%u exported:%u %"PRIu64" %"PRIu64,
98
+ this, this->name, this->info.id, this->remote, this->exported,
99
a->signal_time, nsec);
100
101
/* when transport sync is not supported, just clear the flag */
102
103
a->state0.status = status;
104
105
nsec = get_time_ns(data_system);
106
- old_status = SPA_ATOMIC_XCHG(a->status, PW_NODE_ACTIVATION_FINISHED);
107
+ was_awake = SPA_ATOMIC_CAS(a->status,
108
+ PW_NODE_ACTIVATION_AWAKE,
109
+ PW_NODE_ACTIVATION_FINISHED);
110
a->finish_time = nsec;
111
112
- pw_log_trace_fp("%p: finished status:%d %"PRIu64, this, status, nsec);
113
+ pw_log_trace_fp("%p: finished status:%d %"PRIu64" was_awake:%d",
114
+ this, status, nsec, was_awake);
115
116
/* we don't need to trigger targets when the node was driving the
117
* graph because that means we finished the graph. */
118
if (SPA_LIKELY(!this->driving)) {
119
- if ((!this->async || a->server_version < 1) && old_status == PW_NODE_ACTIVATION_AWAKE)
120
+ if ((!this->async || a->server_version < 1) && was_awake)
121
trigger_targets(this, status, nsec);
122
} else {
123
/* calculate CPU time when finished */
124
125
nsec / 1000, 0);
126
}
127
128
- pw_log_trace_fp("%p: remote:%u exported:%u %s got process %"PRIu64,
129
- this, this->remote, this->exported, this->name, nsec);
130
+ pw_log_trace_fp("%p: remote:%u exported:%u %s-%d got process %"PRIu64,
131
+ this, this->remote, this->exported, this->name, this->info.id,
132
+ nsec);
133
134
process_node(this, nsec);
135
}
136
137
struct pw_impl_node *node = data;
138
struct pw_impl_node *driver = node->driver_node;
139
struct pw_node_activation *a = node->rt.target.activation;
140
- struct pw_node_activation_state *state = &a->state0;
141
struct spa_system *data_system = node->rt.target.system;
142
struct pw_node_target *t, *reposition_target = NULL;;
143
struct pw_impl_port *p;
144
struct spa_io_clock *cl = &node->rt.position->clock;
145
int sync_type, all_ready, update_sync, target_sync, old_status;
146
- uint32_t owner2, reposition_owner, pending;
147
+ uint32_t owner2, reposition_owner;
148
uint64_t min_timeout = UINT64_MAX, nsec;
149
150
pw_log_trace_fp("%p: ready driver:%d exported:%d %p status:%d prepared:%d", node,
151
152
153
nsec = get_time_ns(data_system);
154
155
- if (SPA_UNLIKELY((pending = pw_node_activation_state_xchg(state)) > 0)) {
156
- pw_impl_node_rt_emit_incomplete(driver);
157
+ while (true) {
158
old_status = SPA_ATOMIC_LOAD(a->status);
159
- if (old_status != PW_NODE_ACTIVATION_FINISHED) {
160
- SPA_ATOMIC_STORE(a->status, PW_NODE_ACTIVATION_TRIGGERED);
161
+ if (SPA_LIKELY(old_status == PW_NODE_ACTIVATION_FINISHED))
162
+ /* all good, graph completed */
163
+ break;
164
+ if (SPA_ATOMIC_CAS(a->status, old_status, PW_NODE_ACTIVATION_TRIGGERED)) {
165
+ /* if we got triggered but did not run the processing yet we don't
166
+ * really have an error so we can skip the error reporting. We need
167
+ * to run recovery anyway because the ready callback is already
168
+ * emitted */
169
+ if (old_status != PW_NODE_ACTIVATION_TRIGGERED) {
170
+ /* otherwise, something was wrong and we debug */
171
+ debug_xrun_graph(node, nsec, old_status);
172
+ pw_impl_node_rt_emit_incomplete(driver);
173
+ }
174
SPA_FLAG_SET(cl->flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER);
175
process_node(node, nsec);
176
SPA_FLAG_CLEAR(cl->flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER);
177
- debug_xrun_graph(node, nsec);
178
+ break;
179
}
180
}
181
182
pipewire-1.2.2.tar.bz2/src/pipewire/keys.h -> pipewire-1.2.3.tar.bz2/src/pipewire/keys.h
Changed
23
1
2
#define PW_KEY_LOOP_CLASS "loop.class" /**< the classes this loop handles, array of strings */
3
#define PW_KEY_LOOP_RT_PRIO "loop.rt-prio" /**< realtime priority of the loop */
4
#define PW_KEY_LOOP_CANCEL "loop.cancel" /**< if the loop can be canceled */
5
-#define PW_KEY_LOOP_RETRY_TIMEOUT "loop.retry-timeout" /**< when the loop invoke queue is full, the timeout
6
- * in microseconds before retrying.
7
- * default = 1 second, 0 = disable */
8
9
/* context */
10
#define PW_KEY_CONTEXT_PROFILE_MODULES "context.profile.modules" /**< a context profile for modules, deprecated */
11
12
# ifdef PW_ENABLE_DEPRECATED
13
# define PW_KEY_PRIORITY_MASTER "priority.master" /**< deprecated, use priority.driver */
14
# define PW_KEY_NODE_TARGET "node.target" /**< deprecated since 0.3.64, use target.object. */
15
+# define PW_KEY_LOOP_RETRY_TIMEOUT "loop.retry-timeout" /**< deprecated since 1.3.0 */
16
# else
17
# define PW_KEY_PRIORITY_MASTER PW_DEPRECATED("priority.master")
18
# define PW_KEY_NODE_TARGET PW_DEPRECATED("node.target")
19
+# define PW_KEY_LOOP_RETRY_TIMEOUT PW_DEPRECATED("loop.retry-timeout")
20
# endif /* PW_ENABLE_DEPRECATED */
21
#endif /* PW_REMOVE_DEPRECATED */
22
23
pipewire-1.2.2.tar.bz2/src/pipewire/private.h -> pipewire-1.2.3.tar.bz2/src/pipewire/private.h
Changed
40
1
2
{
3
struct pw_node_activation *a = t->activation;
4
struct pw_node_activation_state *state = &a->state0;
5
+ int32_t pending = SPA_ATOMIC_DEC(state->pending);
6
7
pw_log_trace_fp("%p: (%s-%u) state:%p pending:%d/%d", t->node,
8
- t->name, t->id, state, state->pending, state->required);
9
+ t->name, t->id, state, pending, state->required);
10
11
- if (pw_node_activation_state_dec(state)) {
12
+ if (pending == 0) {
13
if (SPA_ATOMIC_CAS(a->status,
14
PW_NODE_ACTIVATION_NOT_TRIGGERED,
15
PW_NODE_ACTIVATION_TRIGGERED)) {
16
a->signal_time = nsec;
17
if (SPA_UNLIKELY(spa_system_eventfd_write(t->system, t->fd, 1) < 0))
18
pw_log_warn("%p: write failed %m", t->node);
19
+ } else {
20
+ pw_log_trace_fp("%p: (%s-%u) not ready %d", t->node,
21
+ t->name, t->id, a->status);
22
}
23
}
24
}
25
26
{
27
struct pw_node_activation *a = t->activation;
28
struct pw_node_activation_state *state = &a->state0;
29
+ int32_t pending = SPA_ATOMIC_DEC(state->pending);
30
31
pw_log_trace_fp("%p: (%s-%u) state:%p pending:%d/%d", t->node,
32
- t->name, t->id, state, state->pending, state->required);
33
+ t->name, t->id, state, pending, state->required);
34
35
- if (pw_node_activation_state_dec(state)) {
36
+ if (pending == 0) {
37
SPA_ATOMIC_STORE(a->status, PW_NODE_ACTIVATION_TRIGGERED);
38
a->signal_time = nsec;
39
if (SPA_UNLIKELY(spa_system_eventfd_write(t->system, t->fd, 1) < 0))
40
pipewire-1.2.2.tar.bz2/src/tools/pw-cli.c -> pipewire-1.2.3.tar.bz2/src/tools/pw-cli.c
Changed
100
1
2
#include <spa/debug/pod.h>
3
#include <spa/utils/keys.h>
4
#include <spa/utils/json-pod.h>
5
-#include <spa/pod/builder.h>
6
+#include <spa/pod/dynamic.h>
7
8
#include <pipewire/impl.h>
9
#include <pipewire/i18n.h>
10
11
uint32_t param_id;
12
struct global *global;
13
uint8_t buffer1024;
14
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
15
+ spa_auto(spa_pod_dynamic_builder) b = { 0 };
16
const struct spa_type_info *ti;
17
struct spa_pod *pod;
18
19
+ spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
20
+
21
n = pw_split_ip(args, WHITESPACE, 3, a);
22
if (n < 3) {
23
*error = spa_aprintf("%s <object-id> <param-id> <param-json>", cmd);
24
25
*error = spa_aprintf("%s: unknown param type: %s", cmd, a1);
26
return false;
27
}
28
- if ((res = spa_json_to_pod(&b, 0, ti, a2, strlen(a2))) < 0) {
29
+ if ((res = spa_json_to_pod(&b.b, 0, ti, a2, strlen(a2))) < 0) {
30
*error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res));
31
return false;
32
}
33
- if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) {
34
+ if ((pod = spa_pod_builder_deref(&b.b, 0)) == NULL) {
35
*error = spa_aprintf("%s: can't make pod", cmd);
36
return false;
37
}
38
39
int res, n;
40
struct global *global;
41
uint8_t buffer1024;
42
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
43
+ spa_auto(spa_pod_dynamic_builder) b = { 0 };
44
const struct spa_type_info *ti;
45
struct spa_pod *pod;
46
47
+ spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
48
+
49
n = pw_split_ip(args, WHITESPACE, 3, a);
50
if (n < 3) {
51
*error = spa_aprintf("%s <object-id> <command-id> <command-json>", cmd);
52
53
*error = spa_aprintf("%s: unknown node command type: %s", cmd, a1);
54
return false;
55
}
56
- if ((res = spa_json_to_pod(&b, 0, ti, a2, strlen(a2))) < 0) {
57
+ if ((res = spa_json_to_pod(&b.b, 0, ti, a2, strlen(a2))) < 0) {
58
*error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res));
59
return false;
60
}
61
- if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) {
62
+ if ((pod = spa_pod_builder_deref(&b.b, 0)) == NULL) {
63
*error = spa_aprintf("%s: can't make pod", cmd);
64
return false;
65
}
66
67
readline_cleanup();
68
#endif
69
} else {
70
- char buf4096, *p, *error;
71
+ FILE *buf;
72
+ char *error, *ptr;
73
+ size_t size;
74
75
- p = buf;
76
- for (i = optind; i < argc; i++) {
77
- p = stpcpy(p, argvi);
78
- p = stpcpy(p, " ");
79
- }
80
+ buf = open_memstream(&ptr, &size);
81
+ for (i = optind; i < argc; i++)
82
+ fprintf(buf, "%s%s", i == optind ? "" : " ", argvi);
83
+ fclose(buf);
84
85
// If we're monitoring, surface info changes as well
86
data.monitoring_info = monitor;
87
88
pw_main_loop_run(data.loop);
89
90
- if (!parse(&data, buf, &error)) {
91
+ if (!parse(&data, ptr, &error)) {
92
fprintf(stderr, "Error: \"%s\"\n", error);
93
free(error);
94
}
95
+ free(ptr);
96
+
97
if (data.current != NULL)
98
data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0);
99
100
pipewire-1.2.2.tar.bz2/src/tools/pw-top.c -> pipewire-1.2.3.tar.bz2/src/tools/pw-top.c
Changed
12
1
2
{
3
struct spa_audio_info_iec958 info = { 0 };
4
if (spa_format_audio_iec958_parse(param, &info) >= 0) {
5
- snprintf(n->format, sizeof(n->format), "IEC958 %s %d",
6
+ /* MAX_FORMAT is 16 bytes + \0: 8 bytes in this string, upto 6 bytes for the rate,
7
+ * leaving us 2 for the format */
8
+ snprintf(n->format, sizeof(n->format), "IEC958 %2.2s %d",
9
spa_debug_type_find_short_name(
10
spa_type_audio_iec958_codec, info.codec),
11
info.rate);
12