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 43
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Mon Aug 19 20:39:19 UTC 2024 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 1.2.2
6
+
7
+-------------------------------------------------------------------
8
Sun Jun 30 17:34:39 UTC 2024 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 1.2.0
11
pipewire-aptx.spec
Changed
16
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 1.2.0
6
+Version: 1.2.2
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
URL: https://gitlab.freedesktop.org/pipewire/pipewire
11
-Source: %{url}/-/archive/%{version}/pipewire-%{version}.tar.gz
12
+Source: %{url}/-/archive/%{version}/pipewire-%{version}.tar.bz2
13
14
BuildRequires: c++_compiler
15
BuildRequires: c_compiler
16
pipewire-1.2.0.tar.gz/NEWS -> pipewire-1.2.2.tar.bz2/NEWS
Changed
108
1
2
+# PipeWire 1.2.2 (2024-07-31)
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
+ - Fix some more fallout of the async nodes rewrite. Fixes some
9
+ crackling, xruns and possibly also some crashes in some cases.
10
+ - Fix freewheeling timeouts in case of xruns. This fixes ardour export.
11
+ - Fix event mixdown in JACK. Fixes qsynth and possibly other apps.
12
+ - Some more small fixes and improvements.
13
+
14
+
15
+## PipeWire
16
+ - Add a new SPA_IO_CLOCK_FLAG_XRUN_RECOVER flag when the process function
17
+ is called because of xrun recovery.
18
+ - Properly stop nodes in all cases, this avoids spurious xruns and
19
+ scheduling errors. (#4122)
20
+ - Make sure async nodes receive an async link in all cases. Do the
21
+ processing of source output ports slightly differently to make sure we
22
+ don't cause latency for sources. (#4138) (#4133)
23
+ - Fix some races when negotiating and starting nodes. (#4094)
24
+ - Actually include the config.h header to use malloc_trim() to reduce
25
+ memory usage in pulse-server.
26
+
27
+## Modules
28
+ - Avoid unloading some modules on stream errors because it is possible to
29
+ recover from the error. (#4121)
30
+ - Fix a (harmless) warning in module-rtp because of comparing samples and
31
+ time. (#4095)
32
+
33
+## SPA
34
+ - Let the freewheel driver detect xrun recovery and handle the timeouts
35
+ correctly. This fixes an issue with ardour export.
36
+ - Remove the HDMI/AC3 profiles. they turn out to fail on some hardware
37
+ with no way to detect this.
38
+ - Signal the eventfd when the loop is full to make sure the other thread
39
+ is woken up to process the queue.
40
+
41
+## JACK
42
+ - Don't check timestamps when mixing down events. The timestamps are only
43
+ checked when writing new events with the public API. This fixes an
44
+ issue where qsynth would not receive midi events anymore.
45
+ - Fix the jack_get_time() function, it was returning nano instead of micro
46
+ seconds.
47
+
48
+Older versions:
49
+
50
+
51
+# PipeWire 1.2.1 (2024-07-12)
52
+
53
+This is a bugfix release that is API and ABI compatible with previous
54
+the previous 1.2.0 release and the 1.0.x releases.
55
+
56
+## Highlights
57
+ - Fix a regression in the node activation counters that would break audio
58
+ when using KODI.
59
+ - Fix a regression in ardour export because of mishandling of sync groups.
60
+ - Fix a regression in KDE screen preview because of the new async
61
+ scheduling.
62
+ - Fix a regression in context.exec argument parsing that would break some
63
+ existing scripts.
64
+ - More small bug fixes and improvements.
65
+
66
+
67
+## PipeWire
68
+ - Fix a regression in the node activation counters that would break audio
69
+ when using KODI. (#4087)
70
+ - Fix a regression in ardour export because of mishandling of sync groups.
71
+ (#4083)
72
+ - Fix a regression in KDE screen preview because of the new async
73
+ scheduling. Disable async for driver nodes. (#4092)
74
+ - Slightly improve node shutdown to cause less xruns.
75
+ - Fix a regression in context.exec argument parsing that would break some
76
+ existing scripts.
77
+ - Support custom thread create functions.
78
+
79
+## Modules
80
+ - Improve snapcast address parsing. (#4093)
81
+
82
+## SPA
83
+ - Fix multiple %f parsing in ACP for the new plug+a52 profiles.
84
+ - Improve v4l2 param generation. Improve recovery when framesize or rates
85
+ are unknown, support vivid. (#4063)
86
+
87
+## JACK
88
+ - Use the custom thread create function to correctly let module-rt kit
89
+ manage threads so that we don't end up with priorities on the wrong
90
+ threads. (#4099)
91
+
92
+## GStreamer
93
+ - Fix a crash when destroying a stream.
94
+
95
# PipeWire 1.2.0 (2024-06-27)
96
97
This is the 1.2 release that is API and ABI compatible with previous
98
99
## Bluetooth
100
- Improvements to BAP broadcast code parsing.
101
102
-Older versions:
103
-
104
-
105
# PipeWire 1.1.83 (2024-06-17)
106
107
This is the third and hopefully the last 1.2 release candidate that is
108
pipewire-1.2.0.tar.gz/meson.build -> pipewire-1.2.2.tar.bz2/meson.build
Changed
21
1
2
project('pipewire', 'c' ,
3
- version : '1.2.0',
4
+ version : '1.2.2',
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
flatpak_support = glib2_dep.found()
10
cdata.set('HAVE_GLIB2', flatpak_support)
11
12
-gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : get_option('gsettings'))
13
-summary({'GIO (GSettings)': gio_dep.found()}, bool_yn: true, section: 'Misc dependencies')
14
-if not gio_dep.found() and get_option('gsettings-pulse-schema').enabled()
15
+gsettings_gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : get_option('gsettings'))
16
+summary({'GIO (GSettings)': gsettings_gio_dep.found()}, bool_yn: true, section: 'Misc dependencies')
17
+if not gsettings_gio_dep.found() and get_option('gsettings-pulse-schema').enabled()
18
error('`gsettings-pulse-schema` is enabled but `gio` was not found.')
19
endif
20
21
pipewire-1.2.0.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-1.2.2.tar.bz2/pipewire-jack/src/pipewire-jack.c
Changed
201
1
2
}
3
}
4
5
+static inline jack_midi_data_t* midi_event_reserve(void *port_buffer,
6
+ jack_nframes_t time, size_t data_size)
7
+{
8
+ struct midi_buffer *mb = port_buffer;
9
+ uint8_t *res = NULL;
10
+
11
+ /* Check if data_size is >0 and there is enough space in the buffer for the event. */
12
+ if (SPA_UNLIKELY(data_size <= 0)) {
13
+ pw_log_warn("midi %p: data_size:%zd", port_buffer, data_size);
14
+ } else if (SPA_UNLIKELY(jack_midi_max_event_size (port_buffer) < data_size)) {
15
+ pw_log_warn("midi %p: event too large: data_size:%zd", port_buffer, data_size);
16
+ } else {
17
+ struct midi_event *events = SPA_PTROFF(mb, sizeof(*mb), struct midi_event);
18
+ struct midi_event *ev = &eventsmb->event_count;
19
+
20
+ ev->time = time;
21
+ ev->size = data_size;
22
+ if (SPA_LIKELY(data_size <= MIDI_INLINE_MAX)) {
23
+ res = ev->inline_data;
24
+ } else {
25
+ mb->write_pos += data_size;
26
+ ev->byte_offset = mb->buffer_size - 1 - mb->write_pos;
27
+ res = SPA_PTROFF(mb, ev->byte_offset, uint8_t);
28
+ }
29
+ mb->event_count += 1;
30
+ }
31
+ return res;
32
+}
33
+
34
static inline int midi_event_write(void *port_buffer,
35
jack_nframes_t time,
36
const jack_midi_data_t *data,
37
size_t data_size, bool fix)
38
{
39
- jack_midi_data_t *retbuf = jack_midi_event_reserve (port_buffer, time, data_size);
40
+ jack_midi_data_t *retbuf = midi_event_reserve (port_buffer, time, data_size);
41
if (SPA_UNLIKELY(retbuf == NULL))
42
return -ENOBUFS;
43
memcpy (retbuf, data, data_size);
44
45
void *(*start)(void*), void *arg)
46
{
47
struct client *c = (struct client *) object;
48
- struct spa_thread *thr;
49
- int res = 0;
50
+ struct spa_dict_item *items;
51
+ struct spa_dict copy;
52
+ char creator_ptr64;
53
54
pw_log_info("create thread");
55
if (globals.creator != NULL) {
56
- pthread_t pt;
57
- pthread_attr_t *attr = NULL, attributes;
58
+ uint32_t i, n_items = props ? props->n_items : 0;
59
60
- attr = pw_thread_fill_attr(props, &attributes);
61
+ items = alloca((n_items) + 1 * sizeof(*items));
62
63
- res = -globals.creator(&pt, attr, start, arg);
64
- if (attr)
65
- pthread_attr_destroy(attr);
66
- if (res != 0)
67
- goto error;
68
- thr = (struct spa_thread*)pt;
69
- } else {
70
- thr = spa_thread_utils_create(c->context.old_thread_utils, props, start, arg);
71
- }
72
- return thr;
73
-error:
74
- pw_log_warn("create RT thread failed: %s", strerror(res));
75
- errno = -res;
76
- return NULL;
77
+ for (i = 0; i < n_items; i++)
78
+ itemsi = props->itemsi;
79
80
+ snprintf(creator_ptr, sizeof(creator_ptr), "pointer:%p", globals.creator);
81
+ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_THREAD_CREATOR,
82
+ creator_ptr);
83
+
84
+ copy = SPA_DICT_INIT(items, n_items);
85
+ props = ©
86
+ }
87
+ return spa_thread_utils_create(c->context.old_thread_utils, props, start, arg);
88
}
89
90
static int impl_join(void *object,
91
92
ptr = p->get_buffer(p, frames);
93
}
94
done:
95
- pw_log_trace_fp("%p: port:%p buffer:%p frames:%d", c, p, ptr, frames);
96
+ pw_log_warn("%p: port:%p buffer:%p frames:%d", c, p, ptr, frames);
97
return ptr;
98
}
99
100
101
{
102
struct timespec ts;
103
clock_gettime(CLOCK_MONOTONIC, &ts);
104
- return SPA_TIMESPEC_TO_NSEC(&ts);
105
+ return SPA_TIMESPEC_TO_USEC(&ts);
106
}
107
108
SPA_EXPORT
109
110
}
111
}
112
113
-SPA_EXPORT
114
-jack_midi_data_t* jack_midi_event_reserve(void *port_buffer,
115
- jack_nframes_t time,
116
- size_t data_size)
117
+static inline int midi_buffer_check(void *port_buffer, jack_nframes_t time)
118
{
119
struct midi_buffer *mb = port_buffer;
120
struct midi_event *events;
121
122
if (SPA_UNLIKELY(mb == NULL)) {
123
pw_log_warn("port buffer is NULL");
124
- return NULL;
125
+ return -EINVAL;
126
}
127
if (SPA_UNLIKELY(mb->magic != MIDI_BUFFER_MAGIC)) {
128
pw_log_warn("port buffer is invalid");
129
- return NULL;
130
+ return -EINVAL;
131
}
132
if (SPA_UNLIKELY(time >= mb->nframes)) {
133
pw_log_warn("midi %p: time:%d frames:%d", port_buffer, time, mb->nframes);
134
- goto failed;
135
+ return -EINVAL;
136
}
137
events = SPA_PTROFF(mb, sizeof(*mb), struct midi_event);
138
if (SPA_UNLIKELY(mb->event_count > 0 && time < eventsmb->event_count - 1.time)) {
139
pw_log_warn("midi %p: time:%d ev:%d", port_buffer, time, mb->event_count);
140
- goto failed;
141
+ return -EINVAL;
142
}
143
+ return 0;
144
+}
145
146
- /* Check if data_size is >0 and there is enough space in the buffer for the event. */
147
- if (SPA_UNLIKELY(data_size <= 0)) {
148
- pw_log_warn("midi %p: data_size:%zd", port_buffer, data_size);
149
- goto failed; // return NULL?
150
- } else if (SPA_UNLIKELY(jack_midi_max_event_size (port_buffer) < data_size)) {
151
- pw_log_warn("midi %p: event too large: data_size:%zd", port_buffer, data_size);
152
+SPA_EXPORT
153
+jack_midi_data_t* jack_midi_event_reserve(void *port_buffer,
154
+ jack_nframes_t time,
155
+ size_t data_size)
156
+{
157
+ struct midi_buffer *mb = port_buffer;
158
+ jack_midi_data_t *res;
159
+
160
+ if (midi_buffer_check(port_buffer, time) < 0)
161
goto failed;
162
- } else {
163
- struct midi_event *ev = &eventsmb->event_count;
164
- uint8_t *res;
165
166
- ev->time = time;
167
- ev->size = data_size;
168
- if (SPA_LIKELY(data_size <= MIDI_INLINE_MAX)) {
169
- res = ev->inline_data;
170
- } else {
171
- mb->write_pos += data_size;
172
- ev->byte_offset = mb->buffer_size - 1 - mb->write_pos;
173
- res = SPA_PTROFF(mb, ev->byte_offset, uint8_t);
174
- }
175
- mb->event_count += 1;
176
+ res = midi_event_reserve(port_buffer, time, data_size);
177
+ if (res != NULL)
178
return res;
179
- }
180
failed:
181
mb->lost_events++;
182
return NULL;
183
184
const jack_midi_data_t *data,
185
size_t data_size)
186
{
187
- return midi_event_write(port_buffer, time, data, data_size, false);
188
+ jack_midi_data_t *ptr;
189
+ int res;
190
+
191
+ if ((res = midi_buffer_check(port_buffer, time)) < 0)
192
+ return res;
193
+
194
+ if ((ptr = midi_event_reserve(port_buffer, time, data_size)) == NULL)
195
+ return -ENOBUFS;
196
+
197
+ memcpy (ptr, data, data_size);
198
+ return 0;
199
}
200
201
pipewire-1.2.0.tar.gz/spa/include/spa/node/io.h -> pipewire-1.2.2.tar.bz2/spa/include/spa/node/io.h
Changed
11
1
2
* \ref spa_io_position.clock.id in \ref SPA_IO_Position are the same.
3
*/
4
struct spa_io_clock {
5
-#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0)
6
+#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /* graph is freewheeling */
7
+#define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /* recovering from xrun */
8
uint32_t flags; /**< Clock flags */
9
uint32_t id; /**< Unique clock id, set by host application */
10
char name64; /**< Clock name prefixed with API, set by node when it receives
11
pipewire-1.2.0.tar.gz/spa/include/spa/support/thread.h -> pipewire-1.2.2.tar.bz2/spa/include/spa/support/thread.h
Changed
9
1
2
#define SPA_KEY_THREAD_NAME "thread.name" /* the thread name */
3
#define SPA_KEY_THREAD_STACK_SIZE "thread.stack-size" /* the stack size of the thread */
4
#define SPA_KEY_THREAD_AFFINITY "thread.affinity" /* array of CPUs for this thread */
5
+#define SPA_KEY_THREAD_CREATOR "thread.creator" /* platform specific thread creator function */
6
7
/**
8
* \}
9
pipewire-1.2.0.tar.gz/spa/include/spa/utils/cleanup.h -> pipewire-1.2.2.tar.bz2/spa/include/spa/utils/cleanup.h
Changed
49
1
2
3
/* ========================================================================== */
4
5
+#include <errno.h>
6
#include <unistd.h>
7
8
#define spa_steal_fd(fd) spa_exchange((fd), -1)
9
10
typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \
11
static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \
12
{ \
13
+ int _save_errno = errno; \
14
__VA_ARGS__ \
15
+ errno = _save_errno; \
16
}
17
18
#define spa_auto(name) \
19
20
typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \
21
static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \
22
{ \
23
+ int _save_errno = errno; \
24
__VA_ARGS__ \
25
+ errno = _save_errno; \
26
}
27
28
#define spa_autoptr(name) \
29
30
31
static inline void _spa_autofree_cleanup_func(void *p)
32
{
33
+ int save_errno = errno;
34
free(*(void **) p);
35
+ errno = save_errno;
36
}
37
#define spa_autofree spa_cleanup(_spa_autofree_cleanup_func)
38
39
40
41
static inline void _spa_autoclose_cleanup_func(int *fd)
42
{
43
+ int save_errno = errno;
44
spa_clear_fd(*fd);
45
+ errno = save_errno;
46
}
47
#define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func)
48
49
pipewire-1.2.0.tar.gz/spa/meson.build -> pipewire-1.2.2.tar.bz2/spa/meson.build
Changed
17
1
2
summary({'ALSA': alsa_dep.found()}, bool_yn: true, section: 'Backend')
3
4
bluez_dep = dependency('bluez', version : '>= 4.101', required: get_option('bluez5'))
5
- gio_dep = dependency('gio-2.0', required : get_option('bluez5'))
6
- gio_unix_dep = dependency('gio-unix-2.0', required : get_option('bluez5'))
7
+ bluez_gio_dep = dependency('gio-2.0', required : get_option('bluez5'))
8
+ bluez_gio_unix_dep = dependency('gio-unix-2.0', required : get_option('bluez5'))
9
bluez_glib2_dep = dependency('glib-2.0', required : get_option('bluez5'))
10
sbc_dep = dependency('sbc', required: get_option('bluez5'))
11
summary({'SBC': sbc_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
12
- bluez5_deps = mathlib, dbus_dep, sbc_dep, bluez_dep, bluez_glib2_dep, gio_dep, gio_unix_dep
13
+ bluez5_deps = mathlib, dbus_dep, sbc_dep, bluez_dep, bluez_glib2_dep, bluez_gio_dep, bluez_gio_unix_dep
14
bluez_deps_found = get_option('bluez5').allowed()
15
foreach dep: bluez5_deps
16
if get_option('bluez5').enabled() and not dep.found()
17
pipewire-1.2.0.tar.gz/spa/plugins/alsa/alsa-acp-device.c -> pipewire-1.2.2.tar.bz2/spa/plugins/alsa/alsa-acp-device.c
Changed
57
1
2
return 0;
3
}
4
5
+static int replace_string(const char *str, const char *val, const char *rep,
6
+ char *buf, size_t size)
7
+{
8
+ struct spa_strbuf s;
9
+ const char *p;
10
+ size_t len = strlen(val);
11
+
12
+ spa_assert(len > 0);
13
+ spa_strbuf_init(&s, buf, size);
14
+
15
+ while (1) {
16
+ p = strstr(str, val);
17
+ if (!p)
18
+ break;
19
+
20
+ spa_strbuf_append(&s, "%.*s%s", (int)SPA_PTRDIFF(p, str), str, rep);
21
+ str = p + len;
22
+ }
23
+
24
+ spa_strbuf_append(&s, "%s", str);
25
+ return 0;
26
+}
27
+
28
static int emit_node(struct impl *this, struct acp_device *dev)
29
{
30
struct spa_dict_item *items;
31
32
char positionsSPA_AUDIO_MAX_CHANNELS * 12;
33
struct spa_device_object_info info;
34
struct acp_card *card = this->card;
35
- const char *stream, *devstr, *card_id;
36
+ const char *stream, *card_id;
37
38
info = SPA_DEVICE_OBJECT_INFO_INIT();
39
info.type = SPA_TYPE_INTERFACE_Node;
40
41
card_id = acp_dict_lookup(&card->props, "alsa.id");
42
snprintf(card_name, sizeof(card_name), "%s", card_id ? card_id : card_index);
43
44
- devstr = dev->device_strings0;
45
- p = strstr(devstr, "%f");
46
- if (p) {
47
- snprintf(device_name, sizeof(device_name), "%.*s%d%s",
48
- (int)SPA_PTRDIFF(p, devstr), devstr,
49
- card->index, p+2);
50
- } else {
51
- snprintf(device_name, sizeof(device_name), "%s", devstr);
52
- }
53
+ replace_string(dev->device_strings0, "%f", card_index, device_name, sizeof(device_name));
54
55
snprintf(path, sizeof(path), "alsa:acp:%s:%d:%s", card_name, dev->index, stream);
56
itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_OBJECT_PATH, path);
57
pipewire-1.2.0.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-1.2.2.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
12
1
2
3
state->max_delay = state->buffer_frames / 2;
4
if (spa_strstartswith(state->props.device, "a52") ||
5
- spa_strstartswith(state->props.device, "dca"))
6
+ spa_strstartswith(state->props.device, "dca") ||
7
+ (spa_strstartswith(state->props.device, "plug:") &&
8
+ strstr(state->props.device, "a52:")))
9
state->min_delay = SPA_MIN(2048u, state->buffer_frames);
10
else
11
state->min_delay = 0;
12
pipewire-1.2.0.tar.gz/spa/plugins/alsa/mixer/profile-sets/default.conf -> pipewire-1.2.2.tar.bz2/spa/plugins/alsa/mixer/profile-sets/default.conf
Changed
166
1
2
priority = 6
3
direction = output
4
5
-Mapping hdmi-ac3-surround
6
-description = Digital Surround 5.1 (HDMI/AC3)
7
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,3'"}
8
-paths-output = hdmi-output-0
9
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
10
-priority = 6
11
-direction = output
12
-
13
Mapping hdmi-stereo-extra1
14
description = Digital Stereo (HDMI 2)
15
device-strings = hdmi:%f,1
16
17
priority = 6
18
direction = output
19
20
-Mapping hdmi-ac3-surround-extra1
21
-description = Digital Surround 5.1 (HDMI 2/AC3)
22
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,7'"}
23
-paths-output = hdmi-output-1
24
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
25
-priority = 6
26
-direction = output
27
-
28
Mapping hdmi-stereo-extra2
29
description = Digital Stereo (HDMI 3)
30
device-strings = hdmi:%f,2
31
32
priority = 6
33
direction = output
34
35
-Mapping hdmi-ac3-surround-extra2
36
-description = Digital Surround 5.1 (HDMI 3/AC3)
37
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,8'"}
38
-paths-output = hdmi-output-2
39
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
40
-priority = 6
41
-direction = output
42
-
43
Mapping hdmi-stereo-extra3
44
description = Digital Stereo (HDMI 4)
45
device-strings = hdmi:%f,3
46
47
priority = 6
48
direction = output
49
50
-Mapping hdmi-ac3-surround-extra3
51
-description = Digital Surround 5.1 (HDMI 4/AC3)
52
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,9'"}
53
-paths-output = hdmi-output-3
54
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
55
-priority = 6
56
-direction = output
57
-
58
Mapping hdmi-stereo-extra4
59
description = Digital Stereo (HDMI 5)
60
device-strings = hdmi:%f,4
61
62
priority = 6
63
direction = output
64
65
-Mapping hdmi-ac3-surround-extra4
66
-description = Digital Surround 5.1 (HDMI 5/AC3)
67
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,10'"}
68
-paths-output = hdmi-output-4
69
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
70
-priority = 6
71
-direction = output
72
-
73
Mapping hdmi-stereo-extra5
74
description = Digital Stereo (HDMI 6)
75
device-strings = hdmi:%f,5
76
77
priority = 6
78
direction = output
79
80
-Mapping hdmi-ac3-surround-extra5
81
-description = Digital Surround 5.1 (HDMI 6/AC3)
82
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,11'"}
83
-paths-output = hdmi-output-5
84
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
85
-priority = 6
86
-direction = output
87
-
88
Mapping hdmi-stereo-extra6
89
description = Digital Stereo (HDMI 7)
90
device-strings = hdmi:%f,6
91
92
priority = 6
93
direction = output
94
95
-Mapping hdmi-ac3-surround-extra6
96
-description = Digital Surround 5.1 (HDMI 7/AC3)
97
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,12'"}
98
-paths-output = hdmi-output-6
99
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
100
-priority = 6
101
-direction = output
102
-
103
Mapping hdmi-stereo-extra7
104
description = Digital Stereo (HDMI 8)
105
device-strings = hdmi:%f,7
106
107
priority = 6
108
direction = output
109
110
-Mapping hdmi-ac3-surround-extra7
111
-description = Digital Surround 5.1 (HDMI 8/AC3)
112
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,13'"}
113
-paths-output = hdmi-output-7
114
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
115
-priority = 6
116
-direction = output
117
-
118
Mapping hdmi-stereo-extra8
119
description = Digital Stereo (HDMI 9)
120
device-strings = hdmi:%f,8
121
122
priority = 6
123
direction = output
124
125
-Mapping hdmi-ac3-surround-extra8
126
-description = Digital Surround 5.1 (HDMI 9/AC3)
127
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,14'"}
128
-paths-output = hdmi-output-8
129
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
130
-priority = 6
131
-direction = output
132
-
133
Mapping hdmi-stereo-extra9
134
description = Digital Stereo (HDMI 10)
135
device-strings = hdmi:%f,9
136
137
priority = 6
138
direction = output
139
140
-Mapping hdmi-ac3-surround-extra9
141
-description = Digital Surround 5.1 (HDMI 10/AC3)
142
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,15'"}
143
-paths-output = hdmi-output-9
144
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
145
-priority = 6
146
-direction = output
147
-
148
Mapping hdmi-stereo-extra10
149
description = Digital Stereo (HDMI 11)
150
device-strings = hdmi:%f,10
151
152
priority = 6
153
direction = output
154
155
-Mapping hdmi-ac3-surround-extra10
156
-description = Digital Surround 5.1 (HDMI 11/AC3)
157
-device-strings = plug:{SLAVE="a52:%f,'hw:%f,16'"}
158
-paths-output = hdmi-output-10
159
-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
160
-priority = 6
161
-direction = output
162
-
163
Mapping multichannel-output
164
device-strings = hw:%f
165
channel-map = left,right,rear-left,rear-right
166
pipewire-1.2.0.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-1.2.2.tar.bz2/spa/plugins/audioconvert/audioadapter.c
Changed
70
1
2
res, spa_strerror(res));
3
}
4
5
+ return 0;
6
+}
7
+
8
+static int activate_io(struct impl *this, bool active)
9
+{
10
+ int res;
11
+ struct spa_io_buffers *data = active ? &this->io_buffers : NULL;
12
+ uint32_t size = active ? sizeof(this->io_buffers) : 0;
13
+
14
if (this->follower == this->target)
15
return 0;
16
17
- this->io_buffers = SPA_IO_BUFFERS_INIT;
18
+ if (active)
19
+ this->io_buffers = SPA_IO_BUFFERS_INIT;
20
21
if ((res = spa_node_port_set_io(this->follower,
22
this->direction, 0,
23
- SPA_IO_Buffers,
24
- &this->io_buffers, sizeof(this->io_buffers))) < 0) {
25
+ SPA_IO_Buffers, data, size)) < 0) {
26
spa_log_warn(this->log, "%p: set Buffers on follower failed %d %s", this,
27
res, spa_strerror(res));
28
return res;
29
}
30
else if ((res = spa_node_port_set_io(this->convert,
31
SPA_DIRECTION_REVERSE(this->direction), 0,
32
- SPA_IO_Buffers,
33
- &this->io_buffers, sizeof(this->io_buffers))) < 0) {
34
+ SPA_IO_Buffers, data, size)) < 0) {
35
spa_log_warn(this->log, "%p: set Buffers on convert failed %d %s", this,
36
res, spa_strerror(res));
37
return res;
38
39
this->buffers, this->n_buffers)) < 0)
40
return res;
41
42
+ activate_io(this, true);
43
+
44
return 0;
45
}
46
47
48
uint8_t buffer4096;
49
int res;
50
51
+ spa_log_debug(this->log, "%p: configure format:", this);
52
+
53
if (format == NULL && !this->have_format)
54
return 0;
55
56
- spa_log_debug(this->log, "%p: configure format:", this);
57
- if (format)
58
+
59
+ if (format == NULL) {
60
+ if (!this->have_format)
61
+ return 0;
62
+ activate_io(this, false);
63
+ }
64
+ else {
65
spa_debug_log_format(this->log, SPA_LOG_LEVEL_DEBUG, 0, NULL, format);
66
+ }
67
68
if ((res = spa_node_port_set_param(this->follower,
69
this->direction, 0,
70
pipewire-1.2.0.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-1.2.2.tar.bz2/spa/plugins/audioconvert/audioconvert.c
Changed
61
1
2
3
struct spa_log *log;
4
struct spa_cpu *cpu;
5
+ struct spa_loop *data_loop;
6
7
uint32_t cpu_flags;
8
uint32_t max_align;
9
10
11
port = GET_PORT(this, direction, port_id);
12
13
- spa_log_debug(this->log, "%p: set format", this);
14
+ spa_log_debug(this->log, "%p: %d:%d set format", this, direction, port_id);
15
16
if (format == NULL) {
17
port->have_format = false;
18
19
return 0;
20
}
21
22
+struct io_data {
23
+ struct port *port;
24
+ void *data;
25
+ size_t size;
26
+};
27
+
28
+static int do_set_port_io(struct spa_loop *loop, bool async, uint32_t seq,
29
+ const void *data, size_t size, void *user_data)
30
+{
31
+ const struct io_data *d = user_data;
32
+ d->port->io = d->data;
33
+ return 0;
34
+}
35
+
36
static int
37
impl_node_port_set_io(void *object,
38
enum spa_direction direction, uint32_t port_id,
39
40
41
switch (id) {
42
case SPA_IO_Buffers:
43
- port->io = data;
44
+ if (this->data_loop) {
45
+ struct io_data d = { .port = port, .data = data, .size = size };
46
+ spa_loop_invoke(this->data_loop, do_set_port_io, 0, NULL, 0, true, &d);
47
+ }
48
+ else
49
+ port->io = data;
50
break;
51
case SPA_IO_RateMatch:
52
this->io_rate_match = data;
53
54
55
this = (struct impl *) handle;
56
57
+ this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
58
this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
59
spa_log_topic_init(this->log, &log_topic);
60
61
pipewire-1.2.0.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-1.2.2.tar.bz2/spa/plugins/bluez5/backend-native.c
Changed
11
1
2
3
if (!handler(rfcomm, token)) {
4
spa_log_debug(backend->log, "RFCOMM received unsupported event: %s", token);
5
- rfcomm_send_error(rfcomm, CMEE_OPERATION_NOT_SUPPORTED);
6
+ if (ag)
7
+ rfcomm_send_error(rfcomm, CMEE_OPERATION_NOT_SUPPORTED);
8
}
9
}
10
}
11
pipewire-1.2.0.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-1.2.2.tar.bz2/spa/plugins/bluez5/bluez5-dbus.c
Changed
11
1
2
int options = 0;
3
int skip = 0;
4
int sync_cte_type = 0;
5
- int sync_factor = 1;
6
+ /* sync_factor should be >=2 to avoid invalid extended advertising interval value */
7
+ int sync_factor = 2;
8
int sync_timeout = 2000;
9
int timeout = 2000;
10
11
pipewire-1.2.0.tar.gz/spa/plugins/support/loop.c -> pipewire-1.2.2.tar.bz2/spa/plugins/support/loop.c
Changed
34
1
2
* read index before we call the function because then the item
3
* might get overwritten. */
4
func = spa_steal_ptr(item->func);
5
- if (func)
6
+ if (func) {
7
+ pthread_mutex_unlock(&impl->queue_lock);
8
item->res = func(&impl->loop, true, item->seq, item->data,
9
item->size, item->user_data);
10
+ pthread_mutex_lock(&impl->queue_lock);
11
+ }
12
13
/* if this function did a recursive invoke, it now flushed the
14
* ringbuffer and we can exit */
15
16
spa_log_warn(impl->log, "%p: queue full %d, need %zd (%d suppressed)",
17
queue, avail, need, suppressed);
18
}
19
+ loop_signal_event(impl, impl->wakeup);
20
if (impl->retry_timeout == 0)
21
return -EPIPE;
22
usleep(impl->retry_timeout);
23
24
if (SPA_LIKELY(value)) {
25
its.it_value = *value;
26
} else if (interval) {
27
+ // timer initially fires after one interval
28
its.it_value = *interval;
29
- absolute = true;
30
+ absolute = false;
31
}
32
if (SPA_UNLIKELY(interval))
33
its.it_interval = *interval;
34
pipewire-1.2.0.tar.gz/spa/plugins/support/node-driver.c -> pipewire-1.2.2.tar.bz2/spa/plugins/support/node-driver.c
Changed
20
1
2
#define SPA_LOG_TOPIC_DEFAULT &log_topic
3
4
#define DEFAULT_FREEWHEEL false
5
-#define DEFAULT_FREEWHEEL_WAIT 10
6
+#define DEFAULT_FREEWHEEL_WAIT 5
7
#define DEFAULT_CLOCK_PREFIX "clock.system"
8
#define DEFAULT_CLOCK_ID CLOCK_MONOTONIC
9
#define DEFAULT_RESYNC_MS 10
10
11
spa_return_val_if_fail(this != NULL, -EINVAL);
12
spa_log_trace(this->log, "process %d", this->props.freewheel);
13
14
- if (this->props.freewheel) {
15
+ if (this->props.freewheel &&
16
+ !SPA_FLAG_IS_SET(this->position->clock.flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER)) {
17
this->next_time = gettime_nsec(this, this->timer_clockid);
18
set_timeout(this, this->next_time);
19
}
20
pipewire-1.2.0.tar.gz/spa/plugins/v4l2/v4l2-source.c -> pipewire-1.2.2.tar.bz2/spa/plugins/v4l2/v4l2-source.c
Changed
201
1
2
{
3
struct impl *this = object;
4
struct spa_pod *param;
5
- struct spa_pod_builder b = { 0 };
6
+ spa_auto(spa_pod_dynamic_builder) b = { 0 };
7
+ struct spa_pod_builder_state state;
8
uint8_t buffer1024;
9
struct spa_result_node_params result;
10
uint32_t count = 0;
11
12
spa_return_val_if_fail(this != NULL, -EINVAL);
13
spa_return_val_if_fail(num != 0, -EINVAL);
14
15
+ spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
16
+ spa_pod_builder_get_state(&b.b, &state);
17
+
18
result.id = id;
19
result.next = start;
20
next:
21
result.index = result.next++;
22
23
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
24
+ spa_pod_builder_reset(&b.b, &state);
25
26
switch (id) {
27
case SPA_PARAM_PropInfo:
28
29
30
switch (result.index) {
31
case 0:
32
- param = spa_pod_builder_add_object(&b,
33
+ param = spa_pod_builder_add_object(&b.b,
34
SPA_TYPE_OBJECT_PropInfo, id,
35
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device),
36
SPA_PROP_INFO_description, SPA_POD_String("The V4L2 device"),
37
SPA_PROP_INFO_type, SPA_POD_String(p->device));
38
break;
39
case 1:
40
- param = spa_pod_builder_add_object(&b,
41
+ param = spa_pod_builder_add_object(&b.b,
42
SPA_TYPE_OBJECT_PropInfo, id,
43
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName),
44
SPA_PROP_INFO_description, SPA_POD_String("The V4L2 device name"),
45
SPA_PROP_INFO_type, SPA_POD_String(p->device_name));
46
break;
47
case 2:
48
- param = spa_pod_builder_add_object(&b,
49
+ param = spa_pod_builder_add_object(&b.b,
50
SPA_TYPE_OBJECT_PropInfo, id,
51
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceFd),
52
SPA_PROP_INFO_description, SPA_POD_String("The V4L2 fd"),
53
54
55
switch (result.index) {
56
case 0:
57
- spa_pod_builder_push_object(&b, &f, SPA_TYPE_OBJECT_Props, id);
58
- spa_pod_builder_add(&b,
59
+ spa_pod_builder_push_object(&b.b, &f, SPA_TYPE_OBJECT_Props, id);
60
+ spa_pod_builder_add(&b.b,
61
SPA_PROP_device, SPA_POD_String(p->device),
62
SPA_PROP_deviceName, SPA_POD_String(p->device_name),
63
SPA_PROP_deviceFd, SPA_POD_Int(p->device_fd),
64
65
for (i = 0; i < port->n_controls; i++) {
66
struct control *c = &port->controlsi;
67
68
- spa_pod_builder_prop(&b, c->id, 0);
69
+ spa_pod_builder_prop(&b.b, c->id, 0);
70
switch (c->type) {
71
case SPA_TYPE_Int:
72
- spa_pod_builder_int(&b, c->value);
73
+ spa_pod_builder_int(&b.b, c->value);
74
break;
75
case SPA_TYPE_Bool:
76
- spa_pod_builder_bool(&b, c->value);
77
+ spa_pod_builder_bool(&b.b, c->value);
78
break;
79
default:
80
- spa_pod_builder_int(&b, c->value);
81
+ spa_pod_builder_int(&b.b, c->value);
82
break;
83
}
84
}
85
- param = spa_pod_builder_pop(&b, &f);
86
+ param = spa_pod_builder_pop(&b.b, &f);
87
break;
88
default:
89
return 0;
90
91
return spa_v4l2_enum_format(this, seq, start, num, filter);
92
case SPA_PARAM_Format:
93
if((res = port_get_format(GET_OUT_PORT(this, 0),
94
- result.index, filter, ¶m, &b)) <= 0)
95
+ result.index, filter, ¶m, &b.b)) <= 0)
96
return res;
97
break;
98
default:
99
return -ENOENT;
100
}
101
102
- if (spa_pod_filter(&b, &result.param, param, filter) < 0)
103
+ if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
104
goto next;
105
106
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
107
108
struct impl *this = object;
109
struct port *port;
110
struct spa_pod *param;
111
- struct spa_pod_builder b = { 0 };
112
+ spa_auto(spa_pod_dynamic_builder) b = { 0 };
113
+ struct spa_pod_builder_state state;
114
uint8_t buffer1024;
115
struct spa_result_node_params result;
116
uint32_t count = 0;
117
118
spa_return_val_if_fail(num != 0, -EINVAL);
119
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
120
121
+ spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
122
+ spa_pod_builder_get_state(&b.b, &state);
123
+
124
port = GET_PORT(this, direction, port_id);
125
126
result.id = id;
127
128
next:
129
result.index = result.next++;
130
131
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
132
+ spa_pod_builder_reset(&b.b, &state);
133
134
switch (id) {
135
case SPA_PARAM_PropInfo:
136
137
return spa_v4l2_enum_format(this, seq, start, num, filter);
138
139
case SPA_PARAM_Format:
140
- if((res = port_get_format(port, result.index, filter, ¶m, &b)) <= 0)
141
+ if((res = port_get_format(port, result.index, filter, ¶m, &b.b)) <= 0)
142
return res;
143
break;
144
case SPA_PARAM_Buffers:
145
146
if (result.index > 0)
147
return 0;
148
149
- param = spa_pod_builder_add_object(&b,
150
+ param = spa_pod_builder_add_object(&b.b,
151
SPA_TYPE_OBJECT_ParamBuffers, id,
152
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(4, 1, MAX_BUFFERS),
153
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
154
155
case SPA_PARAM_Meta:
156
switch (result.index) {
157
case 0:
158
- param = spa_pod_builder_add_object(&b,
159
+ param = spa_pod_builder_add_object(&b.b,
160
SPA_TYPE_OBJECT_ParamMeta, id,
161
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
162
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
163
break;
164
case 1:
165
- param = spa_pod_builder_add_object(&b,
166
+ param = spa_pod_builder_add_object(&b.b,
167
SPA_TYPE_OBJECT_ParamMeta, id,
168
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoTransform),
169
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_videotransform)));
170
171
case SPA_PARAM_IO:
172
switch (result.index) {
173
case 0:
174
- param = spa_pod_builder_add_object(&b,
175
+ param = spa_pod_builder_add_object(&b.b,
176
SPA_TYPE_OBJECT_ParamIO, id,
177
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers),
178
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
179
break;
180
case 1:
181
- param = spa_pod_builder_add_object(&b,
182
+ param = spa_pod_builder_add_object(&b.b,
183
SPA_TYPE_OBJECT_ParamIO, id,
184
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Clock),
185
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock)));
186
break;
187
case 2:
188
- param = spa_pod_builder_add_object(&b,
189
+ param = spa_pod_builder_add_object(&b.b,
190
SPA_TYPE_OBJECT_ParamIO, id,
191
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Control),
192
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_sequence)));
193
194
case SPA_PARAM_Latency:
195
switch (result.index) {
196
case 0: case 1:
197
- param = spa_latency_build(&b, id, &this->latencyresult.index);
198
+ param = spa_latency_build(&b.b, id, &this->latencyresult.index);
199
break;
200
default:
201
pipewire-1.2.0.tar.gz/spa/plugins/v4l2/v4l2-utils.c -> pipewire-1.2.2.tar.bz2/spa/plugins/v4l2/v4l2-utils.c
Changed
201
1
2
#include <sys/mman.h>
3
#include <poll.h>
4
5
+#include <spa/pod/dynamic.h>
6
+#include <spa/utils/cleanup.h>
7
#include <spa/utils/result.h>
8
9
static int xioctl(int fd, int request, void *arg)
10
11
uint32_t filter_media_type, filter_media_subtype;
12
struct spa_v4l2_device *dev = &port->dev;
13
uint8_t buffer1024;
14
- struct spa_pod_builder b = { 0 };
15
+ spa_auto(spa_pod_dynamic_builder) b = { 0 };
16
+ struct spa_pod_builder_state state;
17
struct spa_pod_frame f2;
18
struct spa_result_node_params result;
19
uint32_t count = 0;
20
21
if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
22
return res;
23
24
+ spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
25
+ spa_pod_builder_get_state(&b.b, &state);
26
+
27
result.id = SPA_PARAM_EnumFormat;
28
result.next = start;
29
30
31
}
32
do_frmsize:
33
if ((res = xioctl(dev->fd, VIDIOC_ENUM_FRAMESIZES, &port->frmsize)) < 0) {
34
- if (errno == EINVAL || errno == ENOTTY)
35
+ if (errno == ENOTTY)
36
goto next_fmtdesc;
37
+ if (errno == EINVAL) {
38
+ if (port->frmsize.index == 0) {
39
+ port->frmsize.type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
40
+ port->frmsize.stepwise.min_width = 16;
41
+ port->frmsize.stepwise.min_height = 16;
42
+ port->frmsize.stepwise.max_width = 16384;
43
+ port->frmsize.stepwise.max_height = 16384;
44
+ port->frmsize.stepwise.step_width = 16;
45
+ port->frmsize.stepwise.step_height = 16;
46
+ port->fmtdesc.index++;
47
+ port->next_fmtdesc = true;
48
+ goto do_frmsize_filter;
49
+ }
50
+ else
51
+ goto next_fmtdesc;
52
+ }
53
54
res = -errno;
55
spa_log_error(this->log, "'%s' VIDIOC_ENUM_FRAMESIZES: %m",
56
this->props.device);
57
goto exit;
58
}
59
+do_frmsize_filter:
60
if (filter) {
61
static const struct spa_rectangle step = {1, 1};
62
63
64
}
65
}
66
67
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
68
- spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
69
- spa_pod_builder_add(&b,
70
+ spa_pod_builder_reset(&b.b, &state);
71
+ spa_pod_builder_push_object(&b.b, &f0, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
72
+ spa_pod_builder_add(&b.b,
73
SPA_FORMAT_mediaType, SPA_POD_Id(info->media_type),
74
SPA_FORMAT_mediaSubtype, SPA_POD_Id(info->media_subtype),
75
0);
76
77
if (info->media_subtype == SPA_MEDIA_SUBTYPE_raw) {
78
- spa_pod_builder_prop(&b, SPA_FORMAT_VIDEO_format, 0);
79
- spa_pod_builder_id(&b, info->format);
80
+ spa_pod_builder_prop(&b.b, SPA_FORMAT_VIDEO_format, 0);
81
+ spa_pod_builder_id(&b.b, info->format);
82
}
83
- spa_pod_builder_prop(&b, SPA_FORMAT_VIDEO_size, 0);
84
+
85
+ spa_pod_builder_prop(&b.b, SPA_FORMAT_VIDEO_size, 0);
86
if (port->frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
87
- spa_pod_builder_rectangle(&b,
88
+ spa_pod_builder_rectangle(&b.b,
89
port->frmsize.discrete.width,
90
port->frmsize.discrete.height);
91
} else if (port->frmsize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS ||
92
port->frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
93
- spa_pod_builder_push_choice(&b, &f1, SPA_CHOICE_None, 0);
94
- choice = (struct spa_pod_choice*)spa_pod_builder_frame(&b, &f1);
95
+ spa_pod_builder_push_choice(&b.b, &f1, SPA_CHOICE_None, 0);
96
+ choice = (struct spa_pod_choice*)spa_pod_builder_frame(&b.b, &f1);
97
98
- spa_pod_builder_rectangle(&b,
99
+ spa_pod_builder_rectangle(&b.b,
100
port->frmsize.stepwise.min_width,
101
port->frmsize.stepwise.min_height);
102
- spa_pod_builder_rectangle(&b,
103
+ spa_pod_builder_rectangle(&b.b,
104
port->frmsize.stepwise.min_width,
105
port->frmsize.stepwise.min_height);
106
- spa_pod_builder_rectangle(&b,
107
+ spa_pod_builder_rectangle(&b.b,
108
port->frmsize.stepwise.max_width,
109
port->frmsize.stepwise.max_height);
110
111
112
choice->body.type = SPA_CHOICE_Range;
113
} else {
114
choice->body.type = SPA_CHOICE_Step;
115
- spa_pod_builder_rectangle(&b,
116
+ spa_pod_builder_rectangle(&b.b,
117
port->frmsize.stepwise.max_width,
118
port->frmsize.stepwise.max_height);
119
}
120
- spa_pod_builder_pop(&b, &f1);
121
+ spa_pod_builder_pop(&b.b, &f1);
122
}
123
124
- spa_pod_builder_prop(&b, SPA_FORMAT_VIDEO_framerate, 0);
125
+ spa_pod_builder_prop(&b.b, SPA_FORMAT_VIDEO_framerate, 0);
126
127
n_fractions = 0;
128
129
- spa_pod_builder_push_choice(&b, &f1, SPA_CHOICE_None, 0);
130
- choice = (struct spa_pod_choice*)spa_pod_builder_frame(&b, &f1);
131
+ spa_pod_builder_push_choice(&b.b, &f1, SPA_CHOICE_None, 0);
132
+ choice = (struct spa_pod_choice*)spa_pod_builder_frame(&b.b, &f1);
133
port->frmival.index = 0;
134
135
while (true) {
136
if ((res = xioctl(dev->fd, VIDIOC_ENUM_FRAMEINTERVALS, &port->frmival)) < 0) {
137
res = -errno;
138
+ port->frmsize.index++;
139
+ port->next_frmsize = true;
140
if (errno == EINVAL || errno == ENOTTY) {
141
- port->frmsize.index++;
142
- port->next_frmsize = true;
143
- if (port->frmival.index == 0)
144
- goto next_frmsize;
145
- break;
146
+ if (port->frmival.index == 0) {
147
+ port->frmival.type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
148
+ port->frmival.stepwise.min.denominator = 1;
149
+ port->frmival.stepwise.min.numerator = 1;
150
+ port->frmival.stepwise.max.denominator = 120;
151
+ port->frmival.stepwise.max.numerator = 1;
152
+ goto do_frminterval_filter;
153
+ }
154
+ else
155
+ break;
156
}
157
spa_log_error(this->log, "'%s' VIDIOC_ENUM_FRAMEINTERVALS: %m",
158
this->props.device);
159
goto exit;
160
}
161
+do_frminterval_filter:
162
if (filter) {
163
static const struct spa_fraction step = {1, 1};
164
165
166
if (port->frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
167
choice->body.type = SPA_CHOICE_Enum;
168
if (n_fractions == 0)
169
- spa_pod_builder_fraction(&b,
170
+ spa_pod_builder_fraction(&b.b,
171
port->frmival.discrete.denominator,
172
port->frmival.discrete.numerator);
173
- spa_pod_builder_fraction(&b,
174
+ spa_pod_builder_fraction(&b.b,
175
port->frmival.discrete.denominator,
176
port->frmival.discrete.numerator);
177
port->frmival.index++;
178
179
} else if (port->frmival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS ||
180
port->frmival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
181
if (n_fractions == 0)
182
- spa_pod_builder_fraction(&b, 25, 1);
183
- spa_pod_builder_fraction(&b,
184
+ spa_pod_builder_fraction(&b.b, 25, 1);
185
+ spa_pod_builder_fraction(&b.b,
186
port->frmival.stepwise.min.denominator,
187
port->frmival.stepwise.min.numerator);
188
- spa_pod_builder_fraction(&b,
189
+ spa_pod_builder_fraction(&b.b,
190
port->frmival.stepwise.max.denominator,
191
port->frmival.stepwise.max.numerator);
192
193
194
n_fractions += 2;
195
} else {
196
choice->body.type = SPA_CHOICE_Step;
197
- spa_pod_builder_fraction(&b,
198
+ spa_pod_builder_fraction(&b.b,
199
port->frmival.stepwise.step.denominator,
200
port->frmival.stepwise.step.numerator);
201
pipewire-1.2.0.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-1.2.2.tar.bz2/src/gst/gstpipewiresrc.c
Changed
64
1
2
src->autoconnect = DEFAULT_AUTOCONNECT;
3
src->min_latency = 0;
4
src->max_latency = GST_CLOCK_TIME_NONE;
5
+
6
+ src->transform_value = UINT32_MAX;
7
}
8
9
static gboolean
10
11
GstPipeWirePoolData *data;
12
struct spa_meta_header *h;
13
struct spa_meta_region *crop;
14
- struct spa_meta_videotransform *videotransform;
15
+ enum spa_meta_videotransform_value transform_value;
16
struct pw_time time;
17
guint i;
18
19
20
}
21
}
22
23
- videotransform = data->videotransform;
24
- if (videotransform) {
25
- if (pwsrc->transform_value != videotransform->transform) {
26
- GstEvent *tag_event;
27
- const char* tag_string;
28
+ transform_value = data->videotransform ? data->videotransform->transform :
29
+ SPA_META_TRANSFORMATION_None;
30
+ if (transform_value != pwsrc->transform_value) {
31
+ GstEvent *tag_event;
32
+ const char* tag_string;
33
34
- tag_string =
35
- spa_transform_value_to_gst_image_orientation(videotransform->transform);
36
+ tag_string = spa_transform_value_to_gst_image_orientation(transform_value);
37
38
- GST_LOG_OBJECT (pwsrc, "got new videotransform: %u / %s",
39
- videotransform->transform, tag_string);
40
+ GST_LOG_OBJECT (pwsrc, "got new videotransform: %u / %s",
41
+ transform_value, tag_string);
42
43
- tag_event = gst_event_new_tag(gst_tag_list_new(GST_TAG_IMAGE_ORIENTATION,
44
- tag_string, NULL));
45
- gst_pad_push_event (GST_BASE_SRC_PAD (pwsrc), tag_event);
46
+ tag_event = gst_event_new_tag(gst_tag_list_new(GST_TAG_IMAGE_ORIENTATION,
47
+ tag_string, NULL));
48
+ gst_pad_push_event (GST_BASE_SRC_PAD (pwsrc), tag_event);
49
50
- pwsrc->transform_value = videotransform->transform;
51
- }
52
+ pwsrc->transform_value = transform_value;
53
}
54
55
if (pwsrc->is_video) {
56
57
pwsrc->eos = false;
58
gst_buffer_replace (&pwsrc->last_buffer, NULL);
59
gst_caps_replace(&pwsrc->caps, NULL);
60
+ pwsrc->transform_value = UINT32_MAX;
61
pw_thread_loop_unlock (pwsrc->stream->core->loop);
62
63
return TRUE;
64
pipewire-1.2.0.tar.gz/src/gst/gstpipewirestream.c -> pipewire-1.2.2.tar.bz2/src/gst/gstpipewirestream.c
Changed
15
1
2
3
/* destroy the pw stream */
4
pw_thread_loop_lock (self->core->loop);
5
- g_clear_pointer (&self->pwstream, pw_stream_destroy);
6
+ if (self->pwstream) {
7
+ /* Do not use g_clear_pointer() here as pw_stream_destroy() may chain up to
8
+ * code requiring the pointer to still be around */
9
+ pw_stream_destroy (self->pwstream);
10
+ self->pwstream = NULL;
11
+ }
12
pw_thread_loop_unlock (self->core->loop);
13
14
/* release the core */
15
pipewire-1.2.0.tar.gz/src/modules/meson.build -> pipewire-1.2.2.tar.bz2/src/modules/meson.build
Changed
15
1
2
cdata.set('HAVE_AVAHI', true)
3
endif
4
5
-if gio_dep.found()
6
+if gsettings_gio_dep.found()
7
pipewire_module_protocol_pulse_sources +=
8
'module-protocol-pulse/modules/module-gsettings.c',
9
10
- pipewire_module_protocol_pulse_deps += gio_dep
11
+ pipewire_module_protocol_pulse_deps += gsettings_gio_dep
12
cdata.set('HAVE_GIO', true)
13
if get_option('gsettings-pulse-schema').enabled()
14
install_data('module-protocol-pulse/modules/org.freedesktop.pulseaudio.gschema.xml',
15
pipewire-1.2.0.tar.gz/src/modules/module-ffado-driver.c -> pipewire-1.2.2.tar.bz2/src/modules/module-ffado-driver.c
Changed
12
1
2
struct impl *impl = s->impl;
3
switch (state) {
4
case PW_FILTER_STATE_ERROR:
5
- pw_log_error("filter state %d error: %s", state, error);
6
- SPA_FALLTHROUGH;
7
+ pw_log_warn("filter state %d error: %s", state, error);
8
+ break;
9
case PW_FILTER_STATE_UNCONNECTED:
10
pw_impl_module_schedule_destroy(impl->module);
11
break;
12
pipewire-1.2.0.tar.gz/src/modules/module-jack-tunnel.c -> pipewire-1.2.2.tar.bz2/src/modules/module-jack-tunnel.c
Changed
15
1
2
struct stream *s = d;
3
struct impl *impl = s->impl;
4
switch (state) {
5
- case PW_FILTER_STATE_ERROR:
6
case PW_FILTER_STATE_UNCONNECTED:
7
pw_impl_module_schedule_destroy(impl->module);
8
break;
9
+ case PW_FILTER_STATE_ERROR:
10
+ pw_log_warn("stream %p: error: %s", s, error);
11
+ break;
12
case PW_FILTER_STATE_PAUSED:
13
s->running = false;
14
break;
15
pipewire-1.2.0.tar.gz/src/modules/module-jack-tunnel/weakjack.h -> pipewire-1.2.2.tar.bz2/src/modules/module-jack-tunnel/weakjack.h
Changed
10
1
2
3
hnd = dlopen(path, RTLD_NOW);
4
if (hnd == NULL)
5
- return -errno;
6
+ return -ENOENT;
7
8
pw_log_info("opened libjack: %s", path);
9
10
pipewire-1.2.0.tar.gz/src/modules/module-netjack2-driver.c -> pipewire-1.2.2.tar.bz2/src/modules/module-netjack2-driver.c
Changed
10
1
2
struct impl *impl = s->impl;
3
switch (state) {
4
case PW_FILTER_STATE_ERROR:
5
+ pw_log_warn("stream %p: error: %s", s, error);
6
+ break;
7
case PW_FILTER_STATE_UNCONNECTED:
8
pw_impl_module_schedule_destroy(impl->module);
9
break;
10
pipewire-1.2.0.tar.gz/src/modules/module-netjack2-manager.c -> pipewire-1.2.2.tar.bz2/src/modules/module-netjack2-manager.c
Changed
10
1
2
struct impl *impl = s->impl;
3
switch (state) {
4
case PW_FILTER_STATE_ERROR:
5
+ pw_log_warn("stream %p: error: %s", s, error);
6
+ break;
7
case PW_FILTER_STATE_UNCONNECTED:
8
pw_impl_module_schedule_destroy(impl->module);
9
break;
10
pipewire-1.2.0.tar.gz/src/modules/module-protocol-simple.c -> pipewire-1.2.2.tar.bz2/src/modules/module-protocol-simple.c
Changed
131
1
2
* sink for each connected client.
3
* - `playback`: boolean if playback is enabled. This will create a playback or
4
* source stream for each connected client.
5
+ * - `local.ifname = <str>`: interface name to use
6
+ * - `local.ifaddress = <str>`: interface address to use
7
* - `server.address = `: an array of server addresses to listen on as
8
* tcp:(<ip>:)<port>.
9
* - `capture.props`: optional properties for the capture stream
10
11
struct pw_properties *capture_props;
12
struct pw_properties *playback_props;
13
14
+ char *ifname;
15
+ char *ifaddress;
16
bool capture;
17
bool playback;
18
19
20
return;
21
}
22
23
-static uint16_t parse_port(const char *str, uint16_t def)
24
-{
25
- uint32_t val;
26
- if (spa_atou32(str, &val, 0) && val <= 65535u)
27
- return val;
28
- return def;
29
-}
30
-
31
-static int make_tcp_socket(struct server *server, const char *name)
32
+static int make_tcp_socket(struct server *server, const char *name, const char *ifname,
33
+ const char *ifaddress)
34
{
35
struct sockaddr_storage addr;
36
int res, fd, on;
37
- uint16_t port;
38
- char *br = NULL, *col, *n;
39
socklen_t len = 0;
40
41
- n = strdupa(name);
42
-
43
- col = strrchr(n, ':');
44
- if (n0 == '') {
45
- br = strchr(n, '');
46
- if (br == NULL)
47
- return -EINVAL;
48
- n++;
49
- *br = 0;
50
- } else {
51
- }
52
- if (br && col && col < br)
53
- col = NULL;
54
-
55
- if (col) {
56
- *col = '\0';
57
- port = parse_port(col+1, DEFAULT_PORT);
58
- } else {
59
- port = parse_port(n, DEFAULT_PORT);
60
- n = strdupa("0.0.0.0");
61
- }
62
-
63
- if ((res = pw_net_parse_address(n, port, &addr, &len)) < 0) {
64
- pw_log_error("%p: can't parse address:%s port:%d: %s", server,
65
- n, port, spa_strerror(res));
66
+ if ((res = pw_net_parse_address_port(name, ifaddress, DEFAULT_PORT, &addr, &len)) < 0) {
67
+ pw_log_error("%p: can't parse address %s: %s", server,
68
+ name, spa_strerror(res));
69
goto error;
70
}
71
72
73
pw_log_error("%p: socket() failed: %m", server);
74
goto error;
75
}
76
-
77
+#ifdef SO_BINDTODEVICE
78
+ if (ifname && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) {
79
+ res = -errno;
80
+ pw_log_error("%p: setsockopt(SO_BINDTODEVICE) failed: %m", server);
81
+ goto error;
82
+ }
83
+#endif
84
on = 1;
85
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0)
86
pw_log_warn("%p: setsockopt(): %m", server);
87
88
spa_list_append(&impl->server_list, &server->link);
89
90
if (spa_strstartswith(address, "tcp:")) {
91
- fd = make_tcp_socket(server, address+4);
92
+ fd = make_tcp_socket(server, address+4, impl->ifname, impl->ifaddress);
93
} else {
94
pw_log_error("address %s does not start with tcp:", address);
95
fd = -EINVAL;
96
97
pw_properties_free(impl->capture_props);
98
pw_properties_free(impl->playback_props);
99
pw_properties_free(impl->props);
100
+ free(impl->ifname);
101
+ free(impl->ifaddress);
102
free(impl);
103
}
104
105
106
pw_properties_setf(impl->playback_props, PW_KEY_NODE_RATE,
107
"1/%u", impl->playback_info.rate);
108
109
+ str = pw_properties_get(impl->props, "local.ifname");
110
+ impl->ifname = str ? strdup(str) : NULL;
111
+ str = pw_properties_get(impl->props, "local.ifaddress");
112
+ impl->ifaddress = str ? strdup(str) : NULL;
113
+
114
if ((str = pw_properties_get(impl->props, "server.address")) == NULL)
115
str = DEFAULT_SERVER;
116
117
118
uint16_t port = 0;
119
bool ipv4;
120
121
- if (pw_net_get_ip(&s->addr, ip, sizeof(ip), &ipv4, &port) >= 0)
122
- fprintf(f, " \"%s%s%s:%d\"", ipv4 ? "" : "",
123
- ip, ipv4 ? "" : "", port);
124
+ if (pw_net_get_ip(&s->addr, ip, sizeof(ip), &ipv4, &port) < 0)
125
+ continue;
126
+
127
+ fprintf(f, " \"%s%s%s:%d\"", ipv4 ? "" : "", ip, ipv4 ? "" : "", port);
128
}
129
fprintf(f, " ");
130
fclose(f);
131
pipewire-1.2.0.tar.gz/src/modules/module-raop-sink.c -> pipewire-1.2.2.tar.bz2/src/modules/module-raop-sink.c
Changed
23
1
2
#endif
3
#include <openssl/rand.h>
4
#include <openssl/rsa.h>
5
-#include <openssl/engine.h>
6
#include <openssl/aes.h>
7
#include <openssl/md5.h>
8
#include <openssl/evp.h>
9
10
impl->volume = volume;
11
12
rtsp_send_volume(impl);
13
+ spa_pod_builder_prop(&b, SPA_PROP_softVolumes, 0);
14
+ spa_pod_builder_array(&b, sizeof(float), SPA_TYPE_Float,
15
+ n_vols, soft_vols);
16
}
17
- spa_pod_builder_prop(&b, SPA_PROP_softVolumes, 0);
18
- spa_pod_builder_array(&b, sizeof(float), SPA_TYPE_Float,
19
- n_vols, soft_vols);
20
spa_pod_builder_raw_padded(&b, prop, SPA_POD_PROP_SIZE(prop));
21
break;
22
}
23
pipewire-1.2.0.tar.gz/src/modules/module-rtp/stream.c -> pipewire-1.2.2.tar.bz2/src/modules/module-rtp/stream.c
Changed
31
1
2
min_samples = msec_to_samples(impl, min_ptime);
3
max_samples = msec_to_samples(impl, max_ptime);
4
5
- float ptime = 0;
6
+ float ptime = 0.0f;
7
if ((str = pw_properties_get(props, "rtp.ptime")) != NULL)
8
if (!spa_atof(str, &ptime))
9
ptime = 0.0f;
10
11
impl->target_buffer = msec_to_samples(impl, latency_msec);
12
impl->max_error = msec_to_samples(impl, ERROR_MSEC);
13
14
- if (impl->target_buffer < ptime) {
15
- pw_log_warn("sess.latency.msec cannot be lower than rtp.ptime");
16
+ if (impl->target_buffer < impl->psamples) {
17
+ pw_log_warn("sess.latency.msec %f cannot be lower than rtp.ptime %f",
18
+ latency_msec, ptime);
19
impl->target_buffer = impl->psamples;
20
}
21
22
/* We're not expecting odd ptimes, so this modulo should be 0 */
23
- if (fmodf(impl->target_buffer, ptime) != 0) {
24
- pw_log_warn("sess.latency.msec should be an integer multiple of rtp.ptime");
25
+ if (fmodf(impl->target_buffer, impl->psamples) != 0) {
26
+ pw_log_warn("sess.latency.msec %f should be an integer multiple of rtp.ptime %f",
27
+ latency_msec, ptime);
28
impl->target_buffer = (uint32_t)((impl->target_buffer / ptime) * impl->psamples);
29
}
30
31
pipewire-1.2.0.tar.gz/src/modules/module-snapcast-discover.c -> pipewire-1.2.2.tar.bz2/src/modules/module-snapcast-discover.c
Changed
113
1
2
#include "module-protocol-pulse/format.h"
3
#include "module-zeroconf-discover/avahi-poll.h"
4
5
+#include "network-utils.h"
6
+
7
/** \page page_module_snapcast_discover Snapcast Discover
8
*
9
* Automatically creates a Snapcast sink device based on zeroconf
10
11
*
12
*\code{.unparsed}
13
* context.modules =
14
- * { name = libpipewire-snapcast-discover
15
+ * { name = libpipewire-module-snapcast-discover
16
* args = {
17
* stream.rules =
18
* { matches =
19
20
AvahiServiceBrowser *sink_browser;
21
22
struct spa_list tunnel_list;
23
+ uint32_t id;
24
};
25
26
struct tunnel_info {
27
28
int res;
29
socklen_t len;
30
char *str;
31
+ struct impl *impl = t->impl;
32
33
len = sizeof(res);
34
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &res, &len) < 0) {
35
36
t->connecting = false;
37
pw_log_info("connected");
38
39
- str = "{\"id\":8,\"jsonrpc\": \"2.0\",\"method\":\"Server.GetRPCVersion\"}\r\n";
40
+ str = spa_aprintf("{\"id\":%u,\"jsonrpc\": \"2.0\",\"method\":\"Server.GetRPCVersion\"}\r\n",
41
+ impl->id++);
42
res = write(t->source->fd, str, strlen(str));
43
pw_log_info("wrote %s: %d", str, res);
44
+ free(str);
45
46
- str = spa_aprintf("{\"id\":4,\"jsonrpc\":\"2.0\",\"method\":\"Stream.RemoveStream\","
47
- "\"params\":{\"id\":\"%s\"}}\r\n", t->stream_name);
48
+ str = spa_aprintf("{\"id\":%u,\"jsonrpc\":\"2.0\",\"method\":\"Stream.RemoveStream\","
49
+ "\"params\":{\"id\":\"%s\"}}\r\n", impl->id++, t->stream_name);
50
res = write(t->source->fd, str, strlen(str));
51
pw_log_info("wrote %s: %d", str, res);
52
free(str);
53
54
- str = spa_aprintf("{\"id\":4,\"jsonrpc\":\"2.0\",\"method\":\"Stream.AddStream\""
55
+ str = spa_aprintf("{\"id\":%u,\"jsonrpc\":\"2.0\",\"method\":\"Stream.AddStream\""
56
",\"params\":{\"streamUri\":\"tcp://%s?name=%s&mode=client&"
57
- "sampleformat=%d:%d:%d&codec=pcm&chunk_ms=20\"}}\r\n",
58
+ "sampleformat=%d:%d:%d&codec=pcm&chunk_ms=20\"}}\r\n", impl->id++,
59
t->server_address, t->stream_name, t->audio_info.rate,
60
get_bps(t->audio_info.format), t->audio_info.channels);
61
-
62
res = write(t->source->fd, str, strlen(str));
63
pw_log_info("wrote %s: %d", str, res);
64
free(str);
65
66
67
while (true) {
68
res = read(t->source->fd, buffer, sizeof(buffer));
69
- pw_log_info("%d", res);
70
if (res == 0)
71
return -EPIPE;
72
if (res < 0) {
73
74
}
75
}
76
77
- pw_log_info("%s", buffer);
78
+ pw_log_info("received: %s", buffer);
79
return 0;
80
}
81
82
83
while (spa_json_get_string(&it1, v, sizeof(v)) > 0) {
84
t->server_address = strdup(v);
85
snapcast_connect(t);
86
- break;
87
+ return 0;
88
}
89
- return 0;
90
+ return -ENOENT;
91
}
92
93
static inline uint32_t format_from_name(const char *name, size_t len)
94
95
ifreq.ifr_ifindex = interface;
96
ioctl(fd, SIOCGIFNAME, &ifreq, sizeof(ifreq));
97
pw_properties_setf(props, "snapcast.ifname", "%s", ifreq.ifr_name);
98
+ pw_properties_setf(props, "local.ifname", "%s", ifreq.ifr_name);
99
100
struct ifaddrs *if_addr, *ifp;
101
if (getifaddrs(&if_addr) < 0)
102
103
family == AF_INET ? "" : "",
104
hbuf,
105
family == AF_INET ? "" : "");
106
+ pw_properties_setf(props, "local.ifaddress", "%s%s%s",
107
+ family == AF_INET ? "" : "",
108
+ hbuf,
109
+ family == AF_INET ? "" : "");
110
} else {
111
pw_log_warn("error: %m %d %s", res, gai_strerror(res));
112
}
113
pipewire-1.2.0.tar.gz/src/modules/network-utils.h -> pipewire-1.2.2.tar.bz2/src/modules/network-utils.h
Changed
64
1
2
return 0;
3
}
4
5
+static inline uint16_t pw_net_parse_port(const char *str, uint16_t def)
6
+{
7
+ uint32_t val;
8
+ if (spa_atou32(str, &val, 0) && val <= 65535u)
9
+ return val;
10
+ return def;
11
+}
12
+
13
+static inline int pw_net_parse_address_port(const char *address,
14
+ const char *default_address, uint16_t default_port,
15
+ struct sockaddr_storage *addr, socklen_t *len)
16
+{
17
+ uint16_t port;
18
+ char *br = NULL, *col, *n;
19
+
20
+ n = strdupa(address);
21
+
22
+ col = strrchr(n, ':');
23
+ if (n0 == '') {
24
+ br = strchr(n, '');
25
+ if (br == NULL)
26
+ return -EINVAL;
27
+ n++;
28
+ *br = 0;
29
+ }
30
+ if (br && col && col < br)
31
+ col = NULL;
32
+
33
+ if (col) {
34
+ *col = '\0';
35
+ port = pw_net_parse_port(col+1, default_port);
36
+ } else {
37
+ port = pw_net_parse_port(n, default_port);
38
+ n = strdupa(default_address ? default_address : "0.0.0.0");
39
+ }
40
+ return pw_net_parse_address(n, port, addr, len);
41
+}
42
+
43
static inline int pw_net_get_ip(const struct sockaddr_storage *sa, char *ip, size_t len, bool *ip4, uint16_t *port)
44
{
45
if (sa->ss_family == AF_INET) {
46
47
return ip;
48
}
49
50
+static inline bool pw_net_addr_is_any(struct sockaddr_storage *addr)
51
+{
52
+ if (addr->ss_family == AF_INET) {
53
+ struct sockaddr_in *sa = (struct sockaddr_in*)addr;
54
+ return sa->sin_addr.s_addr == INADDR_ANY;
55
+ } else if (addr->ss_family == AF_INET6) {
56
+ struct sockaddr_in6 *sa = (struct sockaddr_in6*)addr;
57
+ return memcmp(&sa->sin6_addr, &in6addr_any, sizeof(sa->sin6_addr));
58
+ }
59
+ return false;
60
+}
61
+
62
+
63
#endif /* NETWORK_UTILS_H */
64
pipewire-1.2.0.tar.gz/src/pipewire/conf.c -> pipewire-1.2.2.tar.bz2/src/pipewire/conf.c
Changed
154
1
2
3
n = realloc(strv, sizeof(char*) * (len + 2));
4
if (n == NULL) {
5
- free(strv);
6
+ pw_free_strv(strv);
7
return NULL;
8
}
9
+
10
strv = n;
11
12
memmove(strv+pos+1, strv+pos, sizeof(char*) * (len+1-pos));
13
14
return strv;
15
}
16
17
-static int do_exec(struct pw_context *context, const char *path, const char *args)
18
+static int do_exec(struct pw_context *context, char *const *argv)
19
{
20
int pid, res;
21
22
pid = fork();
23
24
if (pid == 0) {
25
- char **arg;
26
- int n_args;
27
+ char buf1024;
28
+ char *const *p;
29
+ struct spa_strbuf s;
30
31
/* Double fork to avoid zombies; we don't want to set SIGCHLD handler */
32
pid = fork();
33
34
exit(0);
35
}
36
37
- arg = pw_strv_parse(args, strlen(args), INT_MAX, &n_args);
38
- if (arg == NULL) {
39
- pw_log_error("error parsing arguments: %m");
40
- goto done;
41
- }
42
- arg = pw_strv_insert_at(arg, n_args, 0, path);
43
- if (arg == NULL) {
44
- pw_log_error("error constructing arguments: %m");
45
- goto done;
46
- }
47
- pw_log_info("exec %s '%s'", path, args);
48
- res = execvp(path, arg);
49
- pw_free_strv(arg);
50
+ spa_strbuf_init(&s, buf, sizeof(buf));
51
+ for (p = argv; *p; ++p)
52
+ spa_strbuf_append(&s, " '%s'", *p);
53
+
54
+ pw_log_info("exec%s", s.buffer);
55
+ res = execvp(argv0, argv);
56
57
if (res == -1) {
58
res = -errno;
59
- pw_log_error("execvp error '%s': %m", path);
60
+ pw_log_error("execvp error '%s': %m", argv0);
61
}
62
done:
63
exit(1);
64
65
* }
66
*
67
*/
68
+
69
+static char **make_exec_argv(const char *path, const char *value, int len)
70
+{
71
+ char **argv = NULL;
72
+ int n_args;
73
+
74
+ if (spa_json_is_container(value, len)) {
75
+ if (!spa_json_is_array(value, len)) {
76
+ errno = EINVAL;
77
+ return NULL;
78
+ }
79
+ argv = pw_strv_parse(value, len, INT_MAX, &n_args);
80
+ } else {
81
+ spa_autofree char *s = calloc(1, len + 1);
82
+ if (!s)
83
+ return NULL;
84
+
85
+ if (spa_json_parse_stringn(value, len, s, len + 1) < 0) {
86
+ errno = EINVAL;
87
+ return NULL;
88
+ }
89
+ argv = pw_split_strv(s, " \t", INT_MAX, &n_args);
90
+ }
91
+
92
+ if (!argv)
93
+ return NULL;
94
+
95
+ return pw_strv_insert_at(argv, n_args, 0, path);
96
+}
97
+
98
static int parse_exec(void *user_data, const char *location,
99
const char *section, const char *str, size_t len)
100
{
101
102
}
103
104
while ((r = spa_json_enter_object(&it1, &it2)) > 0) {
105
- char *path = NULL, *args = NULL;
106
+ char *path = NULL;
107
+ const char *args_val = "";
108
+ int args_len = 2;
109
bool have_match = true;
110
111
while (spa_json_get_string(&it2, key, sizeof(key)) > 0) {
112
113
} else if (spa_streq(key, "args")) {
114
if (spa_json_is_container(val, l))
115
l = spa_json_container_len(&it2, val, l);
116
- args = (char*)val;
117
- spa_json_parse_stringn(val, l, args, l+1);
118
+ args_val = val;
119
+ args_len = l;
120
} else if (spa_streq(key, "condition")) {
121
if (!spa_json_is_array(val, l)) {
122
pw_log_warn("expected array for condition in '%.*s'",
123
(int)len, str);
124
- break;
125
+ goto next;
126
}
127
spa_json_enter(&it2, &it3);
128
have_match = find_match(&it3, &context->properties->dict, true);
129
130
continue;
131
132
if (path != NULL) {
133
- res = do_exec(context, path, args);
134
+ char **argv = make_exec_argv(path, args_val, args_len);
135
+
136
+ if (!argv) {
137
+ pw_log_warn("expected array or string for args in '%.*s'",
138
+ (int)len, str);
139
+ goto next;
140
+ }
141
+
142
+ res = do_exec(context, argv);
143
+ pw_free_strv(argv);
144
if (res < 0)
145
break;
146
d->count++;
147
}
148
+
149
+ next:
150
+ continue;
151
}
152
if (r < 0)
153
pw_log_warn("malformed object array in '%.*s'", (int)len, str);
154
pipewire-1.2.0.tar.gz/src/pipewire/context.c -> pipewire-1.2.2.tar.bz2/src/pipewire/context.c
Changed
127
1
2
* This ensures that we only activate the paths from the runnable nodes to the
3
* driver nodes and leave the other nodes idle.
4
*/
5
-static int collect_nodes(struct pw_context *context, struct pw_impl_node *node, struct spa_list *collect,
6
- char **sync)
7
+static int collect_nodes(struct pw_context *context, struct pw_impl_node *node, struct spa_list *collect)
8
{
9
struct spa_list queue;
10
struct pw_impl_node *n, *t;
11
struct pw_impl_port *p;
12
struct pw_impl_link *l;
13
+ uint32_t n_sync;
14
+ char *syncMAX_SYNC+1;
15
16
pw_log_debug("node %p: '%s'", node, node->name);
17
18
19
spa_list_append(&queue, &node->sort_link);
20
node->visited = true;
21
22
+ n_sync = 0;
23
+ sync0 = NULL;
24
+
25
/* now follow all the links from the nodes in the queue
26
* and add the peers to the queue. */
27
spa_list_consume(n, &queue, sort_link) {
28
spa_list_remove(&n->sort_link);
29
spa_list_append(collect, &n->sort_link);
30
31
- pw_log_debug(" next node %p: '%s' runnable:%u", n, n->name, n->runnable);
32
+ pw_log_debug(" next node %p: '%s' runnable:%u active:%d",
33
+ n, n->name, n->runnable, n->active);
34
35
if (!n->active)
36
continue;
37
38
- if (sync0 != NULL) {
39
- if (pw_strv_find_common(n->sync_groups, sync) < 0)
40
- continue;
41
+ if (n->sync) {
42
+ for (uint32_t i = 0; n->sync_groupsi; i++) {
43
+ if (n_sync >= MAX_SYNC)
44
+ break;
45
+ if (pw_strv_find(sync, n->sync_groupsi) >= 0)
46
+ continue;
47
+ syncn_sync++ = n->sync_groupsi;
48
+ syncn_sync = NULL;
49
+ }
50
}
51
52
spa_list_for_each(p, &n->input_ports, link) {
53
54
spa_list_for_each(t, &context->node_list, link) {
55
if (t->exported || !t->active || t->visited)
56
continue;
57
+ /* the other node will be scheduled with this one if it's in
58
+ * the same group or link group */
59
if (pw_strv_find_common(t->groups, n->groups) < 0 &&
60
pw_strv_find_common(t->link_groups, n->link_groups) < 0 &&
61
pw_strv_find_common(t->sync_groups, sync) < 0)
62
63
spa_list_append(&queue, &t->sort_link);
64
}
65
}
66
- pw_log_debug(" next node %p: '%s' runnable:%u", n, n->name, n->runnable);
67
+ pw_log_debug(" next node %p: '%s' runnable:%u %p %p %p", n, n->name, n->runnable,
68
+ n->groups, n->link_groups, sync);
69
}
70
spa_list_for_each(n, collect, sort_link)
71
if (!n->driving && n->runnable) {
72
73
struct pw_impl_node *n, *s, *target, *fallback;
74
const uint32_t *rates;
75
uint32_t max_quantum, min_quantum, def_quantum, rate_quantum, floor_quantum, ceil_quantum;
76
- uint32_t n_rates, def_rate, n_sync;
77
+ uint32_t n_rates, def_rate;
78
bool freewheel, global_force_rate, global_force_quantum, transport_start;
79
struct spa_list collect;
80
- char *syncMAX_SYNC+1;
81
82
pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason);
83
84
85
freewheel = false;
86
transport_start = false;
87
88
- /* clean up the flags first and collect sync */
89
- n_sync = 0;
90
- sync0 = NULL;
91
+ /* clean up the flags first */
92
spa_list_for_each(n, &context->node_list, link) {
93
n->visited = false;
94
n->checked = 0;
95
n->runnable = n->always_process && n->active;
96
- if (n->sync) {
97
- for (uint32_t i = 0; n->sync_groupsi; i++) {
98
- if (n_sync >= MAX_SYNC)
99
- break;
100
- if (pw_strv_find(sync, n->sync_groupsi) >= 0)
101
- continue;
102
- syncn_sync++ = n->sync_groupsi;
103
- syncn_sync = NULL;
104
- }
105
- }
106
}
107
108
get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &rate_quantum,
109
110
111
if (!n->visited) {
112
spa_list_init(&collect);
113
- collect_nodes(context, n, &collect, sync);
114
+ collect_nodes(context, n, &collect);
115
move_to_driver(context, &collect, n);
116
}
117
/* from now on we are only interested in active driving nodes
118
119
120
/* collect all nodes in this group */
121
spa_list_init(&collect);
122
- collect_nodes(context, n, &collect, sync);
123
+ collect_nodes(context, n, &collect);
124
125
driver = NULL;
126
spa_list_for_each(t, &collect, sort_link) {
127
pipewire-1.2.0.tar.gz/src/pipewire/impl-link.c -> pipewire-1.2.2.tar.bz2/src/pipewire/impl-link.c
Changed
27
1
2
pw_impl_port_recalc_latency(this->input);
3
pw_impl_port_recalc_tag(this->input);
4
5
- if ((res = pw_impl_port_use_buffers(port, mix, 0, NULL, 0)) < 0) {
6
+ if ((res = port_set_io(this, this->input, SPA_IO_Buffers, NULL, 0, mix)) < 0)
7
+ pw_log_warn("%p: port %p set_io error %s", this, port, spa_strerror(res));
8
+ if ((res = pw_impl_port_use_buffers(port, mix, 0, NULL, 0)) < 0)
9
pw_log_warn("%p: port %p clear error %s", this, port, spa_strerror(res));
10
- }
11
+
12
pw_impl_port_release_mix(port, mix);
13
14
pw_work_queue_cancel(impl->work, &this->input_link, SPA_ID_INVALID);
15
16
this->name = spa_aprintf("%d.%d.%d -> %d.%d.%d",
17
output_node->info.id, output->port_id, this->rt.out_mix.port.port_id,
18
input_node->info.id, input->port_id, this->rt.in_mix.port.port_id);
19
- pw_log_info("(%s) (%s) -> (%s) async:%04x:%04x:%d", this->name, output_node->name,
20
- input_node->name, output->flags, input->flags, impl->async);
21
+ pw_log_info("(%s) (%s) -> (%s) async:%d:%04x:%04x:%d", this->name, output_node->name,
22
+ input_node->name, output_node->driving,
23
+ output->flags, input->flags, impl->async);
24
25
pw_impl_port_emit_link_added(output, this);
26
pw_impl_port_emit_link_added(input, this);
27
pipewire-1.2.0.tar.gz/src/pipewire/impl-node.c -> pipewire-1.2.2.tar.bz2/src/pipewire/impl-node.c
Changed
201
1
2
#include <malloc.h>
3
#include <limits.h>
4
5
+#include "config.h"
6
+
7
#include <spa/support/system.h>
8
#include <spa/pod/parser.h>
9
#include <spa/pod/filter.h>
10
11
{
12
struct pw_node_activation_state *state = &t->activation->state0;
13
if (!t->active) {
14
- if ((!node->async || node->driving) && !node->exported) {
15
- SPA_ATOMIC_INC(state->required);
16
- SPA_ATOMIC_INC(state->pending);
17
+ if (!node->async) {
18
+ if (!node->exported) {
19
+ SPA_ATOMIC_INC(state->required);
20
+ SPA_ATOMIC_INC(state->pending);
21
+ }
22
}
23
t->active = true;
24
- pw_log_debug("%p: target state:%p id:%d pending:%d/%d",
25
- node, state, t->id, state->pending, state->required);
26
+ pw_log_debug("%p: target state:%p id:%d pending:%d/%d %d:%d:%d",
27
+ node, state, t->id, state->pending, state->required,
28
+ node->async, node->driving, node->exported);
29
}
30
}
31
32
33
{
34
if (t->active) {
35
struct pw_node_activation_state *state = &t->activation->state0;
36
- if (!node->async || node->driving) {
37
+ if (!node->async) {
38
/* the driver copies the required to the pending state
39
* so first try to resume the node and then decrement the
40
* required state. This way we either resume with the old value
41
42
SPA_ATOMIC_DEC(state->required);
43
}
44
t->active = false;
45
- pw_log_debug("%p: target state:%p id:%d pending:%d/%d trigger:%"PRIu64,
46
- node, state, t->id, state->pending, state->required, trigger);
47
+ pw_log_debug("%p: target state:%p id:%d pending:%d/%d %d:%d:%d trigger:%"PRIu64,
48
+ node, state, t->id, state->pending, state->required,
49
+ node->async, node->driving, node->exported, trigger);
50
}
51
}
52
53
54
uint64_t dummy;
55
int res;
56
57
- pw_log_trace("%p: prepare %d remote:%d", this, this->rt.prepared, this->remote);
58
+ pw_log_trace("%p: prepare %d remote:%d exported:%d", this, this->rt.prepared,
59
+ this->remote, this->exported);
60
61
if (this->rt.prepared)
62
return 0;
63
64
int old_state;
65
uint64_t trigger = 0;
66
67
- pw_log_trace("%p: unprepare %d remote:%d", this, this->rt.prepared, this->remote);
68
+ pw_log_trace("%p: unprepare %d remote:%d exported:%d", this, this->rt.prepared,
69
+ this->remote, this->exported);
70
71
- if (!this->rt.prepared)
72
- return 0;
73
-
74
- if (!this->remote || this->rt.target.activation->client_version < 1) {
75
+ if (!this->exported) {
76
/* We mark ourself as finished now, this will avoid going further into the process loop
77
* in case our fd was ready (removing ourselfs from the loop should avoid that as well).
78
* If we were supposed to be scheduled make sure we continue the graph for the peers we
79
* were supposed to trigger */
80
old_state = SPA_ATOMIC_XCHG(this->rt.target.activation->status, PW_NODE_ACTIVATION_INACTIVE);
81
- if (old_state != PW_NODE_ACTIVATION_FINISHED)
82
+ if (PW_NODE_ACTIVATION_PENDING_TRIGGER(old_state))
83
trigger = get_time_ns(this->rt.target.system);
84
}
85
+ if (!this->rt.prepared)
86
+ return 0;
87
+
88
if (!this->remote)
89
spa_loop_remove_source(loop, &this->source);
90
91
92
if (node->rt.prepared) {
93
int old_state = SPA_ATOMIC_LOAD(node->rt.target.activation->status);
94
uint64_t trigger = 0;
95
- if (old_state != PW_NODE_ACTIVATION_FINISHED)
96
+ if (PW_NODE_ACTIVATION_PENDING_TRIGGER(old_state))
97
trigger = get_time_ns(node->rt.target.system);
98
deactivate_target(node, t, trigger);
99
}
100
101
102
remove_segment_owner(old, node->info.id);
103
104
- was_driving = node->driving;
105
-
106
- /* When a node was driver (and is waiting for all nodes to complete
107
- * the Start command) cancel the pending state and let the new driver
108
- * calculate a new state so that the Start command is sent to the
109
- * node */
110
- if (was_driving && !node->driving)
111
- impl->pending_state = node->info.state;
112
-
113
- pw_log_debug("%p: driver %p driving:%u", node,
114
- driver, node->driving);
115
+ pw_log_debug("%p: driver %p driving:%u", node, driver, node->driving);
116
pw_log_info("(%s-%u) -> change driver (%s-%d -> %s-%d)",
117
node->name, node->info.id,
118
old->name, old->info.id, driver->name, driver->info.id);
119
120
* scheduled so it won't trigger yet */
121
node->to_driver_peer = pw_node_peer_ref(node, driver);
122
123
+ was_driving = node->driving;
124
+
125
/* then set the new driver node activation */
126
pw_impl_node_set_io(node, SPA_IO_Position,
127
&driver->rt.target.activation->position,
128
sizeof(struct spa_io_position));
129
130
+ /* When a node was driver (and is waiting for all nodes to complete
131
+ * the Start command) cancel the pending state and let the new driver
132
+ * calculate a new state so that the Start command is sent to the
133
+ * node */
134
+ if (was_driving && !node->driving)
135
+ impl->pending_state = node->info.state;
136
+
137
/* and then make the driver trigger the node */
138
node->from_driver_peer = pw_node_peer_ref(driver, node);
139
140
141
recalc_reason = "transport changed";
142
}
143
async = pw_properties_get_bool(node->properties, PW_KEY_NODE_ASYNC, false);
144
+ async &= !node->driver;
145
if (async != node->async) {
146
pw_log_info("%p: async %d -> %d", node, node->async, async);
147
node->async = async;
148
149
struct pw_impl_node *node = data;
150
struct pw_impl_node *driver = node->driver_node;
151
struct pw_node_activation *a = node->rt.target.activation;
152
+ struct pw_node_activation_state *state = &a->state0;
153
struct spa_system *data_system = node->rt.target.system;
154
struct pw_node_target *t, *reposition_target = NULL;;
155
struct pw_impl_port *p;
156
- uint64_t nsec;
157
+ struct spa_io_clock *cl = &node->rt.position->clock;
158
+ int sync_type, all_ready, update_sync, target_sync, old_status;
159
+ uint32_t owner2, reposition_owner, pending;
160
+ uint64_t min_timeout = UINT64_MAX, nsec;
161
162
pw_log_trace_fp("%p: ready driver:%d exported:%d %p status:%d prepared:%d", node,
163
node->driver, node->exported, driver, status, node->rt.prepared);
164
165
pw_log_info("%p: ready non-active node %s in state %d", node, node->name, node->info.state);
166
return -EIO;
167
}
168
+ if (SPA_UNLIKELY(node != driver)) {
169
+ pw_log_warn("%p: ready non-driver node %s", node, node->name);
170
+ return -EIO;
171
+ }
172
173
nsec = get_time_ns(data_system);
174
175
- if (SPA_LIKELY(node == driver)) {
176
- struct pw_node_activation_state *state = &a->state0;
177
- struct spa_io_clock *cl = &node->rt.position->clock;
178
- int sync_type, all_ready, update_sync, target_sync;
179
- uint32_t owner2, reposition_owner;
180
- uint64_t min_timeout = UINT64_MAX;
181
- int32_t pending;
182
- int old_status;
183
-
184
- if (SPA_UNLIKELY((pending = pw_node_activation_state_xchg(state)) > 0)) {
185
- pw_impl_node_rt_emit_incomplete(driver);
186
- old_status = SPA_ATOMIC_LOAD(a->status);
187
- if (old_status != PW_NODE_ACTIVATION_FINISHED) {
188
- SPA_ATOMIC_STORE(a->status, PW_NODE_ACTIVATION_TRIGGERED);
189
- process_node(node, nsec);
190
- debug_xrun_graph(node, nsec);
191
- }
192
+ if (SPA_UNLIKELY((pending = pw_node_activation_state_xchg(state)) > 0)) {
193
+ pw_impl_node_rt_emit_incomplete(driver);
194
+ old_status = SPA_ATOMIC_LOAD(a->status);
195
+ if (old_status != PW_NODE_ACTIVATION_FINISHED) {
196
+ SPA_ATOMIC_STORE(a->status, PW_NODE_ACTIVATION_TRIGGERED);
197
+ SPA_FLAG_SET(cl->flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER);
198
+ process_node(node, nsec);
199
+ SPA_FLAG_CLEAR(cl->flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER);
200
+ debug_xrun_graph(node, nsec);
201
pipewire-1.2.0.tar.gz/src/pipewire/impl-port.c -> pipewire-1.2.2.tar.bz2/src/pipewire/impl-port.c
Changed
126
1
2
int pw_impl_port_init_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mix)
3
{
4
uint32_t port_id;
5
- struct pw_impl_node *node = port->node;
6
int res = 0;
7
8
port_id = pw_map_insert_new(&port->mix_port_map, mix);
9
10
port->n_mix, port->port_id, mix->port.port_id,
11
mix->id, mix->peer_id, mix->io, spa_strerror(res));
12
13
- if (port->n_mix == 1) {
14
- pw_log_debug("%p: setting port io", port);
15
- spa_node_port_set_io(node->node,
16
- port->direction, port->port_id,
17
- SPA_IO_Buffers,
18
- &port->rt.io, sizeof(port->rt.io));
19
- }
20
return res;
21
22
error_remove_port:
23
24
{
25
int res = 0;
26
uint32_t port_id = mix->port.port_id;
27
- struct pw_impl_node *node = port->node;
28
29
pw_map_remove(&port->mix_port_map, port_id);
30
spa_list_remove(&mix->link);
31
32
33
if (port->n_mix == 0) {
34
pw_log_debug("%p: clearing port io", port);
35
- spa_node_port_set_io(node->node,
36
- port->direction, port->port_id,
37
- SPA_IO_Buffers,
38
- NULL, 0);
39
-
40
pw_impl_port_set_param(port, SPA_PARAM_Format, 0, NULL);
41
}
42
return res;
43
44
spa_list_for_each(mix, &port->mix_list, link)
45
spa_node_add_port(port->mix, mix->port.direction, mix->port.port_id, NULL);
46
47
- spa_node_port_set_io(port->mix,
48
- pw_direction_reverse(port->direction), 0,
49
- SPA_IO_Buffers,
50
- &port->rt.io, sizeof(port->rt.io));
51
-
52
if (port->node && port->node->rt.position) {
53
spa_node_set_io(port->mix,
54
SPA_IO_Position,
55
56
57
pw_log_debug("%p: %d set param %d %p", port, port->state, id, param);
58
59
+ if (id == SPA_PARAM_Format) {
60
+ pw_loop_invoke(node->data_loop, do_remove_port, SPA_ID_INVALID, NULL, 0, true, port);
61
+ spa_node_port_set_io(node->node,
62
+ port->direction, port->port_id,
63
+ SPA_IO_Buffers, NULL, 0);
64
+ }
65
+
66
/* set parameter on node */
67
res = spa_node_port_set_param(node->node,
68
port->direction, port->port_id,
69
70
}
71
72
if (id == SPA_PARAM_Format) {
73
- pw_log_debug("%p: %d %p %d", port, port->state, param, res);
74
-
75
- pw_loop_invoke(node->data_loop, do_remove_port, SPA_ID_INVALID, NULL, 0, true, port);
76
/* setting the format always destroys the negotiated buffers */
77
if (port->direction == PW_DIRECTION_OUTPUT) {
78
struct pw_impl_link *l;
79
80
port, port->direction, port->port_id, n_buffers, node->node,
81
alloc_flags);
82
83
+ spa_node_port_set_io(node->node,
84
+ port->direction, port->port_id,
85
+ SPA_IO_Buffers, NULL, 0);
86
+
87
pw_loop_invoke(node->data_loop, do_remove_port, SPA_ID_INVALID, NULL, 0, true, port);
88
89
pw_buffers_clear(&port->mix_buffers);
90
91
pw_direction_reverse(port->direction), 0,
92
0, buffers, n_buffers);
93
}
94
- if (n_buffers > 0)
95
+ if (n_buffers > 0) {
96
+ spa_node_port_set_io(node->node,
97
+ port->direction, port->port_id,
98
+ SPA_IO_Buffers,
99
+ &port->rt.io, sizeof(port->rt.io));
100
+ spa_node_port_set_io(port->mix,
101
+ pw_direction_reverse(port->direction), 0,
102
+ SPA_IO_Buffers,
103
+ &port->rt.io, sizeof(port->rt.io));
104
pw_loop_invoke(node->data_loop, do_add_port, SPA_ID_INVALID, NULL, 0, false, port);
105
+ }
106
return res;
107
}
108
109
110
mix->have_buffers = false;
111
if (port->n_mix == 1)
112
pw_impl_port_update_state(port, PW_IMPL_PORT_STATE_READY, 0, NULL);
113
+
114
+ spa_node_port_set_io(port->mix,
115
+ mix->port.direction, mix->port.port_id,
116
+ SPA_IO_Buffers, NULL, 0);
117
}
118
119
/* first negotiate with the node, this makes it possible to let the
120
* node allocate buffer memory if needed */
121
- if (port->state == PW_IMPL_PORT_STATE_READY) {
122
+ if (port->state == PW_IMPL_PORT_STATE_READY && !port->destroying) {
123
res = negotiate_mixer_buffers(port, flags, buffers, n_buffers);
124
125
if (res < 0) {
126
pipewire-1.2.0.tar.gz/src/pipewire/private.h -> pipewire-1.2.2.tar.bz2/src/pipewire/private.h
Changed
10
1
2
*/
3
#define PW_VERSION_NODE_ACTIVATION 1
4
5
+#define PW_NODE_ACTIVATION_PENDING_TRIGGER(status) ((status) <= PW_NODE_ACTIVATION_AWAKE)
6
+
7
/* nodes start as INACTIVE, when they are ready to be scheduled, they add their
8
* fd to the loop and change status to FINISHED. When the node shuts down, the
9
* status is set back to INACTIVE.
10
pipewire-1.2.0.tar.gz/src/pipewire/thread.c -> pipewire-1.2.2.tar.bz2/src/pipewire/thread.c
Changed
19
1
2
pthread_attr_t *attr = NULL, attributes;
3
const char *str;
4
int err;
5
+ int (*create_func)(pthread_t *, const pthread_attr_t *attr, void *(*start)(void*), void *) = NULL;
6
7
attr = pw_thread_fill_attr(props, &attributes);
8
9
- err = pthread_create(&pt, attr, start, arg);
10
+ if (props == NULL ||
11
+ (str = spa_dict_lookup(props, SPA_KEY_THREAD_CREATOR)) == NULL ||
12
+ sscanf(str, "pointer:%p", &create_func) != 1)
13
+ create_func = pthread_create;
14
+
15
+ err = create_func(&pt, attr, start, arg);
16
17
if (attr)
18
pthread_attr_destroy(attr);
19