Overview
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Wed Jul 26 14:05:18 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.74
6
+
7
+-------------------------------------------------------------------
8
Thu Jun 29 10:47:58 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.72
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.72
6
+Version: 0.3.74
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.72.tar.gz/.gitignore -> pipewire-0.3.74.tar.gz/.gitignore
Changed
10
1
2
.*
3
-.tarball-version
4
-.version
5
-.*.swp
6
+!.gitlab
7
ABOUT-NLS
8
*~
9
*.tar.gz
10
pipewire-0.3.72.tar.gz/.gitlab/ci/check_missing_headers.sh -> pipewire-0.3.74.tar.gz/.gitlab/ci/check_missing_headers.sh
Changed
16
1
2
3
LIST=""
4
5
-for i in $(find spa/include -name '*.h' | sed s#spa/include/##);
6
+for i in $(find spa/include -name '*.h' -a -not -path 'spa/include/spa/utils/cleanup.h' | sed s#spa/include/##);
7
do
8
-f "$PREFIX/include/spa-0.2/$i" || LIST="$i $LIST"
9
done
10
11
-for i in $(find src/pipewire -name '*.h' -a -not -name '*private.h' | sed s#src/##);
12
+for i in $(find src/pipewire -name '*.h' -a -not -name '*private.h' -a -not -name 'cleanup.h' | sed s#src/##);
13
do
14
-f "$PREFIX/include/pipewire-0.3/$i" || LIST="$i $LIST"
15
done
16
pipewire-0.3.72.tar.gz/NEWS -> pipewire-0.3.74.tar.gz/NEWS
Changed
124
1
2
+# PipeWire 0.3.74 (2023-07-12)
3
+
4
+This is a quick bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+ - Fix a critical bug where audio to bluetooth devices would cut out
9
+ randomly. (#3316)
10
+ - Improve RAOP compatibility.
11
+ - Avoid crashes after an update.
12
+ - Small fixes and improvements.
13
+
14
+
15
+## PipeWire
16
+ - Mix info on port is now created explicitly.
17
+ - Remove the node as a driver peer when stopping. This caused some problem
18
+ with playback on and other remote bluetooth devices. (#3316)
19
+ - Work on avoiding crashes when loading new modules that use internal API
20
+ with old libpipewire. This is typical after an update where the old library is
21
+ still loaded by an application but when a new stream is created, updated
22
+ modules are loaded. (#3243)
23
+
24
+## Modules
25
+ - The RTP source module now has an option to ignore the SSRC, which is
26
+ useful to continue to receive the stream when the sender is restarted.
27
+ - The native protocol will refuse to load twice now instead of silently
28
+ ignoring the error.
29
+ - module-raop is compatible with more devices. (#3247)
30
+
31
+## SPA
32
+ - plugins will now warn when running out of buffers. This is always a bad
33
+ thing.
34
+ - Merge scope based cleanup macros.
35
+ - Add ratelimit function.
36
+
37
+Older versions:
38
+
39
+
40
+# PipeWire 0.3.73 (2023-07-06)
41
+
42
+This is a bugfix release that is API and ABI compatible with previous
43
+0.3.x releases.
44
+
45
+## Highlights
46
+ - Fixes an ALSA resume after suspend error.
47
+ - Handle and disable seemingly wrong hires timestamps from ALSA.
48
+ - Filter-chain now has loadable plugin modules. The LV2 and sofa plugins are
49
+ moved to a separate .so file to make things more modular.
50
+ - Rate changes in the graph should now be handled more gracefully by loopback
51
+ and filter-chain.
52
+ - A regression in the rtp-sap module was fixed where it would in some cases
53
+ fail to start.
54
+ - A potential crash in the peaks resampler was fixed.
55
+ - Many cleanups and other small bug fixes.
56
+
57
+
58
+## PipeWire
59
+ - Fix a potential segfault when no fallback driver was set in the config.
60
+ - Improve OPUS detection.
61
+ - Add ASYNC flag to pw-filter and pw-stream when queue/dequeue is not called
62
+ from the process function. This ensure we allocate an extra buffer.
63
+ - Discard pending process callbacks when disconnecting. (#3314)
64
+ - Cleanups and improvements to the debug environment variable parsing.
65
+ - The graph rate was tweaked to better handle very low rates such as those
66
+ requested by pavucontrol when it does the signal monitoring.
67
+
68
+## Modules
69
+ - An example filter module was added.
70
+ - Filter-chain and loopback now disable the resamplers if no rate is specified
71
+ and will always follow the graph rate.
72
+ - Improve setup of filter-chain. The graph is now created when starting
73
+ because this ensure the target graph rate is known.
74
+ - Filter-chain can now link notify ports to control ports in the graph.
75
+ - Filter-chain now has loadable plugin modules. The LV2 and sofa plugins are
76
+ moved to a separate .so file.
77
+ - A regression in the rtp-sap module was fixed where it would in some cases
78
+ fail to start.
79
+ - Module-rt now has options to disable rlimits, portal and rtkit.
80
+ - module-raop-discover now has an options to set the latency. (#3247)
81
+
82
+## Tools
83
+ - pw-cat now supports overriding all stream properties.
84
+
85
+## SPA
86
+ - Disable rate negotiation when the resampler is disabled. We will always
87
+ follow the graph rate.
88
+ - Set device.icon property for UCM ports as well.
89
+ - Improve ALSA recover when using hires timestamps. This fixes some problems
90
+ after resume from suspend. (#3315)
91
+ - ALSA will now warn and disable hires timestamp when they seem wrong.
92
+ They can also be disabled manually with a property.
93
+ - V4l2 will now gracefully handle ENOTTY when enumerating frame sizes and
94
+ frame rates. (#3325)
95
+ - A potential crash in the peaks resampler was fixed. (#3320)
96
+
97
+## pulse-server
98
+ - A client crash in pavucontrol is avoided by always setting a card name.
99
+ - The graph rate is now taken correctly when using the FIX flags. (#3317)
100
+ - An option was added to ignore the FIX flags of a stream. Also the
101
+ documentation for those options was updated. (#3317)
102
+ - module-raop-discover now support latency_msec. (#3247)
103
+
104
+## Bluetooth
105
+ - Remove an assert and issue a warning/recover instead when a buffer is too
106
+ small.
107
+
108
+## GStreamer
109
+ - The device provider does locking when destroying the registry.
110
+
111
# PipeWire 0.3.72 (2023-06-26)
112
113
This is a bugfix release that is API and ABI compatible with previous
114
115
## GStreamer
116
- Fill default strides instead of 0 on pipewire video buffers. (#3236)
117
118
-Older versions:
119
-
120
-
121
# PipeWire 0.3.71 (2023-05-17)
122
123
This is a bugfix release that is API and ABI compatible with previous
124
pipewire-0.3.72.tar.gz/doc/pipewire-modules.dox -> pipewire-0.3.74.tar.gz/doc/pipewire-modules.dox
Changed
9
1
2
- \subpage page_module_client_node
3
- \subpage page_module_combine_stream
4
- \subpage page_module_echo_cancel
5
+- \subpage page_module_example_filter
6
- \subpage page_module_example_sink
7
- \subpage page_module_example_source
8
- \subpage page_module_fallback_sink
9
pipewire-0.3.72.tar.gz/meson.build -> pipewire-0.3.74.tar.gz/meson.build
Changed
46
1
2
project('pipewire', 'c' ,
3
- version : '0.3.72',
4
+ version : '0.3.74',
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
'-Wno-missing-field-initializers',
10
'-Wno-unused-parameter',
11
'-Wno-pedantic',
12
- '-Wold-style-declaration',
13
'-Wdeprecated-declarations',
14
'-Wunused-result',
15
+ '-Werror=return-type',
16
17
18
cc_flags = common_flags +
19
20
# '-DSPA_DEBUG_MEMCPY',
21
'-Werror=implicit-function-declaration',
22
'-Werror=int-conversion',
23
+ '-Werror=old-style-declaration',
24
+ '-Werror=old-style-definition',
25
+ '-Werror=missing-parameter-type',
26
+ '-Werror=strict-prototypes',
27
28
add_project_arguments(cc.get_supported_arguments(cc_flags), language: 'c')
29
30
31
cdata.set('HAVE_SNDFILE', sndfile_dep.found())
32
libmysofa_dep = dependency('libmysofa', required : get_option('libmysofa'))
33
summary({'libmysofa': libmysofa_dep.found()}, bool_yn: true, section: 'filter-chain')
34
-cdata.set('HAVE_LIBMYSOFA', libmysofa_dep.found())
35
pulseaudio_dep = dependency('libpulse', required : get_option('libpulse'))
36
summary({'libpulse': pulseaudio_dep.found()}, bool_yn: true, section: 'Streaming between daemons')
37
avahi_dep = dependency('avahi-client', required : get_option('avahi'))
38
39
40
lilv_lib = dependency('lilv-0', required: get_option('lv2'))
41
summary({'lilv (for lv2 plugins)': lilv_lib.found()}, bool_yn: true)
42
-cdata.set('HAVE_LILV', lilv_lib.found())
43
44
libffado_dep = dependency('libffado', required: get_option('libffado'))
45
summary({'ffado': libffado_dep.found()}, bool_yn: true)
46
pipewire-0.3.72.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.74.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
120
1
2
#include <math.h>
3
4
#include <jack/jack.h>
5
+#include <jack/intclient.h>
6
#include <jack/session.h>
7
#include <jack/thread.h>
8
#include <jack/midiport.h>
9
10
#include <spa/support/cpu.h>
11
#include <spa/param/audio/format-utils.h>
12
#include <spa/param/video/format-utils.h>
13
+#include <spa/param/latency-utils.h>
14
#include <spa/debug/types.h>
15
#include <spa/debug/pod.h>
16
#include <spa/utils/json.h>
17
+#include <spa/utils/result.h>
18
#include <spa/utils/string.h>
19
#include <spa/utils/ringbuffer.h>
20
21
22
char *load_init; /* initialization string */
23
jack_uuid_t session_id; /* requested session_id */
24
25
+ struct pw_loop *l;
26
struct pw_data_loop *loop;
27
struct pw_properties *props;
28
29
30
return mix;
31
}
32
33
-static struct mix *ensure_mix(struct client *c, struct port *port, uint32_t mix_id)
34
-{
35
- struct mix *mix;
36
- if ((mix = find_mix(c, port, mix_id)) != NULL)
37
- return mix;
38
- return create_mix(c, port, mix_id, SPA_ID_INVALID);
39
-}
40
-
41
static int clear_buffers(struct client *c, struct mix *mix)
42
{
43
struct port *port = mix->port;
44
45
static void client_remove_source(struct client *c)
46
{
47
if (c->socket_source) {
48
- pw_loop_destroy_source(c->loop->loop, c->socket_source);
49
+ pw_loop_destroy_source(c->l, c->socket_source);
50
c->socket_source = NULL;
51
}
52
}
53
54
c, readfd, writefd, c->node_id);
55
56
close(writefd);
57
- c->socket_source = pw_loop_add_io(c->loop->loop,
58
+ c->socket_source = pw_loop_add_io(c->l,
59
readfd,
60
SPA_IO_ERR | SPA_IO_HUP,
61
true, on_rtsocket_condition, c);
62
63
case SPA_NODE_COMMAND_Suspend:
64
case SPA_NODE_COMMAND_Pause:
65
if (c->started) {
66
- pw_loop_update_io(c->loop->loop,
67
+ pw_loop_update_io(c->l,
68
c->socket_source, SPA_IO_ERR | SPA_IO_HUP);
69
70
c->started = false;
71
72
73
case SPA_NODE_COMMAND_Start:
74
if (!c->started) {
75
- pw_loop_update_io(c->loop->loop,
76
+ pw_loop_update_io(c->l,
77
c->socket_source,
78
SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP);
79
c->started = true;
80
81
res = -EINVAL;
82
goto done;
83
}
84
- if ((mix = ensure_mix(c, p, mix_id)) == NULL) {
85
+ if ((mix = find_mix(c, p, mix_id)) == NULL) {
86
res = -ENOMEM;
87
goto done;
88
}
89
90
goto exit;
91
}
92
93
- if ((mix = ensure_mix(c, p, mix_id)) == NULL) {
94
+ if ((mix = find_mix(c, p, mix_id)) == NULL) {
95
res = -ENOMEM;
96
goto exit;
97
}
98
99
&thread_utils_impl, client);
100
101
client->loop = pw_context_get_data_loop(client->context.context);
102
+ client->l = pw_data_loop_get_loop(client->loop);
103
pw_data_loop_stop(client->loop);
104
105
pw_context_set_object(client->context.context,
106
107
param_latency_other(c, p, ¶msn_params++, &b);
108
109
pw_thread_loop_lock(c->context.loop);
110
+ if (create_mix(c, p, SPA_ID_INVALID, SPA_ID_INVALID) == NULL) {
111
+ res = -errno;
112
+ pw_log_warn("can't create mix for port %s: %m", port_name);
113
+ pw_thread_loop_unlock(c->context.loop);
114
+ goto error_free;
115
+ }
116
+
117
freeze_callbacks(c);
118
119
pw_client_node_port_update(c->node,
120
pipewire-0.3.72.tar.gz/spa/examples/adapter-control.c -> pipewire-0.3.74.tar.gz/spa/examples/adapter-control.c
Changed
10
1
2
return res;
3
}
4
5
-int init_data(struct data *data)
6
+static int init_data(struct data *data)
7
{
8
int res;
9
const char *str;
10
pipewire-0.3.72.tar.gz/spa/examples/example-control.c -> pipewire-0.3.74.tar.gz/spa/examples/example-control.c
Changed
10
1
2
return -EBADF;
3
}
4
5
-int init_data(struct data *data)
6
+static int init_data(struct data *data)
7
{
8
int res;
9
const char *str;
10
pipewire-0.3.72.tar.gz/spa/include/meson.build -> pipewire-0.3.74.tar.gz/spa/include/meson.build
Changed
11
1
2
3
spa_headers = 'spa' # used by doxygen
4
install_subdir('spa',
5
- install_dir : get_option('includedir') / spa_name
6
+ install_dir : get_option('includedir') / spa_name,
7
+ exclude_files :
8
+ 'utils/cleanup.h',
9
+ ,
10
)
11
pipewire-0.3.74.tar.gz/spa/include/spa/utils/cleanup.h
Added
100
1
2
+/* Simple Plugin API */
3
+/* SPDX-FileCopyrightText: Copyright © 2023 PipeWire authors */
4
+/* SPDX-License-Identifier: MIT */
5
+
6
+#ifndef SPA_UTILS_CLEANUP_H
7
+#define SPA_UTILS_CLEANUP_H
8
+
9
+#if !defined(__has_attribute) || !__has_attribute(__cleanup__)
10
+#error "attribute `cleanup` is required"
11
+#endif
12
+
13
+#define spa_cleanup(func) __attribute__((__cleanup__(func)))
14
+
15
+#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \
16
+typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \
17
+static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \
18
+{ \
19
+ __VA_ARGS__ \
20
+}
21
+
22
+#define spa_auto(name) \
23
+ spa_cleanup(_spa_auto_cleanup_func_ ## name) \
24
+ _spa_auto_cleanup_type_ ## name
25
+
26
+#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) \
27
+typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \
28
+static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \
29
+{ \
30
+ __VA_ARGS__ \
31
+}
32
+
33
+#define spa_autoptr(name) \
34
+ spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \
35
+ _spa_autoptr_cleanup_type_ ## name
36
+
37
+#define spa_exchange(var, new_value) \
38
+__extension__ ({ \
39
+ __typeof__(var) _old_value = (var); \
40
+ (var) = (new_value); \
41
+ _old_value; \
42
+})
43
+
44
+#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL))
45
+#define spa_steal_fd(fd) spa_exchange((fd), -1)
46
+
47
+/* ========================================================================== */
48
+
49
+#include <stdlib.h>
50
+
51
+#define spa_clear_ptr(ptr, destructor) \
52
+__extension__ ({ \
53
+ __typeof__(*(ptr)) *_old_value = spa_steal_ptr(ptr); \
54
+ if (_old_value) \
55
+ destructor(_old_value); \
56
+ (void) 0; \
57
+})
58
+
59
+static inline void _spa_autofree_cleanup_func(void *p)
60
+{
61
+ free(*(void **) p);
62
+}
63
+#define spa_autofree spa_cleanup(_spa_autofree_cleanup_func)
64
+
65
+/* ========================================================================== */
66
+
67
+#include <unistd.h>
68
+
69
+#define spa_clear_fd(fd) \
70
+__extension__ ({ \
71
+ int _old_value = spa_steal_fd(fd), _res = 0; \
72
+ if (_old_value >= 0) \
73
+ _res = close(_old_value); \
74
+ _res; \
75
+})
76
+
77
+static inline void _spa_autoclose_cleanup_func(int *fd)
78
+{
79
+ spa_clear_fd(*fd);
80
+}
81
+#define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func)
82
+
83
+/* ========================================================================== */
84
+
85
+#include <stdio.h>
86
+
87
+SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, {
88
+ spa_clear_ptr(*thing, fclose);
89
+})
90
+
91
+/* ========================================================================== */
92
+
93
+#include <dirent.h>
94
+
95
+SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, {
96
+ spa_clear_ptr(*thing, closedir);
97
+})
98
+
99
+#endif /* SPA_UTILS_CLEANUP_H */
100
pipewire-0.3.74.tar.gz/spa/include/spa/utils/ratelimit.h
Added
45
1
2
+/* Ratelimit */
3
+/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */
4
+/* SPDX-License-Identifier: MIT */
5
+
6
+#ifndef SPA_RATELIMIT_H
7
+#define SPA_RATELIMIT_H
8
+
9
+#ifdef __cplusplus
10
+extern "C" {
11
+#endif
12
+
13
+#include <inttypes.h>
14
+#include <stddef.h>
15
+
16
+struct spa_ratelimit {
17
+ uint64_t interval;
18
+ uint64_t begin;
19
+ unsigned burst;
20
+ unsigned n_printed;
21
+ unsigned n_missed;
22
+};
23
+
24
+static inline int spa_ratelimit_test(struct spa_ratelimit *r, uint64_t now)
25
+{
26
+ unsigned missed = 0;
27
+ if (r->begin + r->interval < now) {
28
+ missed = r->n_missed;
29
+ r->begin = now;
30
+ r->n_printed = 0;
31
+ r->n_missed = 0;
32
+ } else if (r->n_printed >= r->burst) {
33
+ r->n_missed++;
34
+ return -1;
35
+ }
36
+ r->n_printed++;
37
+ return missed;
38
+}
39
+
40
+#ifdef __cplusplus
41
+} /* extern "C" */
42
+#endif
43
+
44
+#endif /* SPA_RATELIMIT_H */
45
pipewire-0.3.72.tar.gz/spa/include/spa/utils/ringbuffer.h -> pipewire-0.3.74.tar.gz/spa/include/spa/utils/ringbuffer.h
Changed
19
1
2
* \param len number of bytes to read
3
*/
4
static inline void
5
-spa_ringbuffer_read_data(struct spa_ringbuffer *rbuf,
6
+spa_ringbuffer_read_data(struct spa_ringbuffer *rbuf SPA_UNUSED,
7
const void *buffer, uint32_t size,
8
uint32_t offset, void *data, uint32_t len)
9
{
10
11
* \param len number of bytes to write
12
*/
13
static inline void
14
-spa_ringbuffer_write_data(struct spa_ringbuffer *rbuf,
15
+spa_ringbuffer_write_data(struct spa_ringbuffer *rbuf SPA_UNUSED,
16
void *buffer, uint32_t size,
17
uint32_t offset, const void *data, uint32_t len)
18
{
19
pipewire-0.3.72.tar.gz/spa/plugins/alsa/acp/alsa-ucm.c -> pipewire-0.3.74.tar.gz/spa/plugins/alsa/acp/alsa-ucm.c
Changed
50
1
2
}
3
}
4
5
+static void ucm_add_port_props(
6
+ pa_device_port *port,
7
+ bool is_sink)
8
+{
9
+ const char *icon;
10
+
11
+ if (is_sink) {
12
+ switch (port->type) {
13
+ case PA_DEVICE_PORT_TYPE_HEADPHONES:
14
+ icon = "audio-headphones";
15
+ break;
16
+ case PA_DEVICE_PORT_TYPE_HDMI:
17
+ icon = "video-display";
18
+ break;
19
+ case PA_DEVICE_PORT_TYPE_SPEAKER:
20
+ default:
21
+ icon = "audio-speakers";
22
+ break;
23
+ }
24
+ } else {
25
+ switch (port->type) {
26
+ case PA_DEVICE_PORT_TYPE_HEADSET:
27
+ icon = "audio-headset";
28
+ break;
29
+ case PA_DEVICE_PORT_TYPE_MIC:
30
+ default:
31
+ icon = "audio-input-microphone";
32
+ break;
33
+ }
34
+ }
35
+
36
+ pa_proplist_sets(port->proplist, "device.icon_name", icon);
37
+}
38
+
39
static void ucm_add_port_combination(
40
pa_hashmap *hash,
41
pa_alsa_ucm_mapping_context *context,
42
43
44
pa_hashmap_put(ports, port->name, port);
45
pa_log_debug("Add port %s: %s", port->name, port->description);
46
+ ucm_add_port_props(port, is_sink);
47
48
if (num == 1) {
49
/* To keep things simple and not worry about stacking controls, we only support hardware volumes on non-combination
50
pipewire-0.3.72.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.74.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
202
1
2
state->props.use_chmap = spa_atob(s);
3
} else if (spa_streq(k, "api.alsa.multi-rate")) {
4
state->multi_rate = spa_atob(s);
5
+ } else if (spa_streq(k, "api.alsa.htimestamp")) {
6
+ state->htimestamp = spa_atob(s);
7
} else if (spa_streq(k, "latency.internal.rate")) {
8
state->process_latency.rate = atoi(s);
9
} else if (spa_streq(k, "latency.internal.ns")) {
10
11
case 14:
12
param = spa_pod_builder_add_object(b,
13
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
14
+ SPA_PROP_INFO_name, SPA_POD_String("api.alsa.htimestamp"),
15
+ SPA_PROP_INFO_description, SPA_POD_String("Use hires timestamps"),
16
+ SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool(state->htimestamp),
17
+ SPA_PROP_INFO_params, SPA_POD_Bool(true));
18
+ break;
19
+ case 15:
20
+ param = spa_pod_builder_add_object(b,
21
+ SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
22
SPA_PROP_INFO_name, SPA_POD_String("latency.internal.rate"),
23
SPA_PROP_INFO_description, SPA_POD_String("Internal latency in samples"),
24
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(state->process_latency.rate,
25
0, 65536),
26
SPA_PROP_INFO_params, SPA_POD_Bool(true));
27
break;
28
- case 15:
29
+ case 16:
30
param = spa_pod_builder_add_object(b,
31
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
32
SPA_PROP_INFO_name, SPA_POD_String("latency.internal.ns"),
33
34
0LL, 2 * SPA_NSEC_PER_SEC),
35
SPA_PROP_INFO_params, SPA_POD_Bool(true));
36
break;
37
- case 16:
38
+ case 17:
39
param = spa_pod_builder_add_object(b,
40
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
41
SPA_PROP_INFO_name, SPA_POD_String("clock.name"),
42
43
spa_pod_builder_string(b, "api.alsa.multi-rate");
44
spa_pod_builder_bool(b, state->multi_rate);
45
46
+ spa_pod_builder_string(b, "api.alsa.htimestamp");
47
+ spa_pod_builder_bool(b, state->htimestamp);
48
+
49
spa_pod_builder_string(b, "latency.internal.rate");
50
spa_pod_builder_int(b, state->process_latency.rate);
51
52
53
snd_config_update_free_global();
54
55
state->multi_rate = true;
56
+ state->htimestamp = true;
57
for (i = 0; info && i < info->n_items; i++) {
58
const char *k = info->itemsi.key;
59
const char *s = info->itemsi.value;
60
61
return do_start(state);
62
}
63
64
-#if 0
65
static int get_avail(struct state *state, uint64_t current_time, snd_pcm_uframes_t *delay)
66
{
67
int res, missed;
68
69
if ((res = alsa_recover(state, avail)) < 0)
70
return res;
71
if ((avail = snd_pcm_avail(state->hndl)) < 0) {
72
- if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
73
+ if ((missed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) {
74
spa_log_warn(state->log, "%s: (%d missed) snd_pcm_avail after recover: %s",
75
state->props.device, missed, snd_strerror(avail));
76
}
77
78
state->alsa_recovering = false;
79
}
80
*delay = avail;
81
- return avail;
82
-}
83
84
-#else
85
-static int get_avail(struct state *state, uint64_t current_time, snd_pcm_uframes_t *delay)
86
-{
87
- int res, missed;
88
- snd_pcm_uframes_t avail;
89
- snd_htimestamp_t tstamp;
90
- uint64_t then;
91
+ if (state->htimestamp) {
92
+ snd_pcm_uframes_t havail;
93
+ snd_htimestamp_t tstamp;
94
+ uint64_t then;
95
96
- avail = snd_pcm_avail(state->hndl);
97
- if ((res = snd_pcm_htimestamp(state->hndl, &avail, &tstamp)) < 0) {
98
- if ((res = alsa_recover(state, res)) < 0)
99
- return res;
100
- if ((res = snd_pcm_htimestamp(state->hndl, &avail, &tstamp)) < 0) {
101
- if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
102
+ if ((res = snd_pcm_htimestamp(state->hndl, &havail, &tstamp)) < 0) {
103
+ if ((missed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) {
104
spa_log_warn(state->log, "%s: (%d missed) snd_pcm_htimestamp error: %s",
105
state->props.device, missed, snd_strerror(res));
106
}
107
- avail = state->threshold * 2;
108
+ return avail;
109
}
110
- } else {
111
- state->alsa_recovering = false;
112
- }
113
- *delay = avail;
114
-
115
- if ((then = SPA_TIMESPEC_TO_NSEC(&tstamp)) != 0) {
116
- int64_t diff;
117
+ avail = havail;
118
+ *delay = havail;
119
+ if ((then = SPA_TIMESPEC_TO_NSEC(&tstamp)) != 0) {
120
+ int64_t diff;
121
122
- if (then < current_time)
123
- diff = ((int64_t)(current_time - then)) * state->rate / SPA_NSEC_PER_SEC;
124
- else
125
- diff = -((int64_t)(then - current_time)) * state->rate / SPA_NSEC_PER_SEC;
126
+ if (then < current_time)
127
+ diff = ((int64_t)(current_time - then)) * state->rate / SPA_NSEC_PER_SEC;
128
+ else
129
+ diff = -((int64_t)(then - current_time)) * state->rate / SPA_NSEC_PER_SEC;
130
131
- spa_log_trace_fp(state->log, "%"PRIu64" %"PRIu64" %"PRIi64, current_time, then, diff);
132
+ spa_log_trace_fp(state->log, "%"PRIu64" %"PRIu64" %"PRIi64, current_time, then, diff);
133
134
- *delay += diff;
135
+ if (SPA_ABS(diff) < state->threshold * 3) {
136
+ *delay += SPA_CLAMP(diff, -((int64_t)state->threshold), (int64_t)state->threshold);
137
+ state->htimestamp_error = 0;
138
+ } else {
139
+ if (++state->htimestamp_error > MAX_HTIMESTAMP_ERROR) {
140
+ spa_log_error(state->log, "%s: wrong htimestamps from driver, disabling",
141
+ state->props.device);
142
+ state->htimestamp_error = 0;
143
+ state->htimestamp = false;
144
+ }
145
+ else if ((missed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) {
146
+ spa_log_warn(state->log, "%s: (%d missed) impossible htimestamp diff:%"PRIi64,
147
+ state->props.device, missed, diff);
148
+ }
149
+ }
150
+ }
151
}
152
- return SPA_MIN(avail, state->buffer_frames);
153
+ return avail;
154
}
155
-#endif
156
157
static int get_status(struct state *state, uint64_t current_time, snd_pcm_uframes_t *avail,
158
snd_pcm_uframes_t *delay, snd_pcm_uframes_t *target)
159
160
else
161
lev = SPA_LOG_LEVEL_INFO;
162
163
- if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
164
+ if ((missed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) {
165
spa_log_lev(state->log, lev, "%s: follower avail:%lu delay:%ld "
166
"target:%ld thr:%u, resync (%d missed)",
167
state->props.device, avail, delay,
168
169
if (SPA_UNLIKELY((res = snd_pcm_mmap_begin(hndl, &my_areas, &offset, &frames)) < 0)) {
170
spa_log_error(state->log, "%s: snd_pcm_mmap_begin error: %s",
171
state->props.device, snd_strerror(res));
172
+ alsa_recover(state, res);
173
return res;
174
}
175
spa_log_trace_fp(state->log, "%p: begin offset:%ld avail:%ld threshold:%d",
176
177
else
178
lev = SPA_LOG_LEVEL_INFO;
179
180
- if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
181
+ if ((missed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) {
182
spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u, "
183
"resync (%d missed)", state->props.device, delay,
184
target, state->threshold, missed);
185
186
if ((res = snd_pcm_mmap_begin(hndl, &my_areas, &offset, &to_read)) < 0) {
187
spa_log_error(state->log, "%s: snd_pcm_mmap_begin error: %s",
188
state->props.device, snd_strerror(res));
189
+ alsa_recover(state, res);
190
return res;
191
}
192
spa_log_trace_fp(state->log, "%p: begin offs:%ld frames:%ld to_read:%ld thres:%d", state,
193
194
if (!state->disable_tsched &&
195
(state->next_time > current_time + SPA_NSEC_PER_SEC ||
196
current_time > state->next_time + SPA_NSEC_PER_SEC)) {
197
- if ((missed = ratelimit_test(&state->rate_limit, current_time)) >= 0) {
198
+ if ((missed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) {
199
spa_log_error(state->log, "%s: impossible timeout %lu %lu %lu %"
200
PRIu64" %"PRIu64" %"PRIi64" %d %"PRIi64" (%d missed)",
201
state->props.device, avail, delay, target,
202
pipewire-0.3.72.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.74.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
80
1
2
#include <spa/utils/list.h>
3
#include <spa/utils/json.h>
4
#include <spa/utils/dll.h>
5
+#include <spa/utils/ratelimit.h>
6
7
#include <spa/node/node.h>
8
#include <spa/node/utils.h>
9
10
#define DEFAULT_CHANNELS 2u
11
#define DEFAULT_USE_CHMAP false
12
13
+#define MAX_HTIMESTAMP_ERROR 64
14
+
15
struct props {
16
char device64;
17
char device_name128;
18
19
uint32_t rate;
20
};
21
22
-struct ratelimit {
23
- uint64_t interval;
24
- uint64_t begin;
25
- unsigned burst;
26
- unsigned n_printed, n_missed;
27
-};
28
-
29
struct state {
30
struct spa_handle handle;
31
struct spa_node node;
32
33
struct spa_loop *data_loop;
34
35
FILE *log_file;
36
- struct ratelimit rate_limit;
37
+ struct spa_ratelimit rate_limit;
38
39
uint32_t card_index;
40
struct card *card;
41
42
uint32_t start_delay;
43
uint32_t min_delay;
44
uint32_t max_delay;
45
+ uint32_t htimestamp_error;
46
47
uint32_t duration;
48
unsigned int alsa_started:1;
49
50
unsigned int is_iec958:1;
51
unsigned int is_hdmi:1;
52
unsigned int multi_rate:1;
53
+ unsigned int htimestamp:1;
54
55
uint64_t iec958_codecs;
56
57
58
return i;
59
}
60
61
-static inline int ratelimit_test(struct ratelimit *r, uint64_t now)
62
-{
63
- unsigned missed = 0;
64
- if (r->begin + r->interval < now) {
65
- missed = r->n_missed;
66
- r->begin = now;
67
- r->n_printed = 0;
68
- r->n_missed = 0;
69
- } else if (r->n_printed >= r->burst) {
70
- r->n_missed++;
71
- return -1;
72
- }
73
- r->n_printed++;
74
- return missed;
75
-}
76
-
77
/* This function is also as snd_pcm_channel_area_addr() since 1.2.6 which is not yet
78
* in ubuntu and I can't figure out how to do the ALSA version check. */
79
static inline void *channel_area_addr(const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset)
80
pipewire-0.3.72.tar.gz/spa/plugins/alsa/alsa-udev.c -> pipewire-0.3.74.tar.gz/spa/plugins/alsa/alsa-udev.c
Changed
146
1
2
#include <libudev.h>
3
#include <alsa/asoundlib.h>
4
5
+#include <spa/utils/cleanup.h>
6
#include <spa/utils/type.h>
7
#include <spa/utils/keys.h>
8
#include <spa/utils/names.h>
9
10
11
static int check_device_pcm_class(const char *devname)
12
{
13
- FILE *f;
14
char pathPATH_MAX;
15
char buf16;
16
size_t sz;
17
18
/* Check device class */
19
- spa_scnprintf(path, sizeof(path), "/sys/class/sound/%s/pcm_class",
20
- devname);
21
- f = fopen(path, "re");
22
+ spa_scnprintf(path, sizeof(path), "/sys/class/sound/%s/pcm_class", devname);
23
+
24
+ spa_autoptr(FILE) f = fopen(path, "re");
25
if (f == NULL)
26
return -errno;
27
sz = fread(buf, 1, sizeof(buf) - 1, f);
28
bufsz = '\0';
29
- fclose(f);
30
return spa_strstartswith(buf, "modem") ? -ENXIO : 0;
31
}
32
33
static int get_num_pcm_devices(unsigned int card_id)
34
{
35
char prefix32;
36
- DIR *snd = NULL;
37
struct dirent *entry;
38
int num_dev = 0;
39
int res;
40
41
42
spa_scnprintf(prefix, sizeof(prefix), "pcmC%uD", card_id);
43
44
- if ((snd = opendir("/dev/snd")) == NULL)
45
+ spa_autoptr(DIR) snd = opendir("/dev/snd");
46
+ if (snd == NULL)
47
return -errno;
48
49
while ((errno = 0, entry = readdir(snd)) != NULL) {
50
51
++num_dev;
52
}
53
}
54
- if (errno != 0)
55
- res = -errno;
56
- else
57
- res = num_dev;
58
59
- closedir(snd);
60
- return res;
61
+ return errno != 0 ? -errno : num_dev;
62
}
63
64
static int check_device_available(struct impl *this, struct device *device, int *num_pcm)
65
{
66
char pathPATH_MAX;
67
- DIR *card = NULL, *pcm = NULL;
68
- FILE *f;
69
char buf16;
70
size_t sz;
71
struct dirent *entry, *entry_pcm;
72
73
74
spa_scnprintf(path, sizeof(path), "/proc/asound/card%u", (unsigned int)device->id);
75
76
- if ((card = opendir(path)) == NULL)
77
+ spa_autoptr(DIR) card = opendir(path);
78
+ if (card == NULL)
79
goto done;
80
81
while ((errno = 0, entry = readdir(card)) != NULL) {
82
83
/* Check busy status */
84
spa_scnprintf(path, sizeof(path), "/proc/asound/card%u/%s",
85
(unsigned int)device->id, entry->d_name);
86
- if ((pcm = opendir(path)) == NULL)
87
+
88
+ spa_autoptr(DIR) pcm = opendir(path);
89
+ if (pcm == NULL)
90
goto done;
91
92
while ((errno = 0, entry_pcm = readdir(pcm)) != NULL) {
93
94
spa_scnprintf(path, sizeof(path), "/proc/asound/card%u/%s/%s/status",
95
(unsigned int)device->id, entry->d_name, entry_pcm->d_name);
96
97
- f = fopen(path, "re");
98
+ spa_autoptr(FILE) f = fopen(path, "re");
99
if (f == NULL)
100
goto done;
101
sz = fread(buf, 1, 6, f);
102
bufsz = '\0';
103
- fclose(f);
104
105
if (!spa_strstartswith(buf, "closed")) {
106
spa_log_debug(this->log, "card %u pcm device %s busy",
107
108
}
109
if (errno != 0)
110
goto done;
111
-
112
- closedir(pcm);
113
- pcm = NULL;
114
}
115
if (errno != 0)
116
goto done;
117
118
spa_log_info(this->log, "card %u: failed to find busy status (%s)",
119
(unsigned int)device->id, spa_strerror(-errno));
120
}
121
- if (card)
122
- closedir(card);
123
- if (pcm)
124
- closedir(pcm);
125
+
126
return res;
127
}
128
129
130
static bool check_access(struct impl *this, struct device *device)
131
{
132
char path128, prefix32;
133
- DIR *snd = NULL;
134
+ spa_autoptr(DIR) snd = NULL;
135
struct dirent *entry;
136
bool accessible = false;
137
138
139
break;
140
}
141
}
142
- closedir(snd);
143
}
144
145
if (accessible != device->accessible)
146
pipewire-0.3.72.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.74.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
60
1
2
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
3
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
4
} else {
5
+ struct spa_pod_frame f1;
6
uint32_t rate = this->io_position ?
7
this->io_position->clock.target_rate.denom : DEFAULT_RATE;
8
9
- *param = spa_pod_builder_add_object(builder,
10
- SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
11
+ spa_pod_builder_push_object(builder, &f0,
12
+ SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
13
+ spa_pod_builder_add(builder,
14
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
15
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
16
SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(25,
17
18
SPA_AUDIO_FORMAT_U8,
19
SPA_AUDIO_FORMAT_ULAW,
20
SPA_AUDIO_FORMAT_ALAW),
21
- SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(
22
- rate, 1, INT32_MAX),
23
+ 0);
24
+ if (!this->props.resample_disabled) {
25
+ spa_pod_builder_add(builder,
26
+ SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(
27
+ rate, 1, INT32_MAX),
28
+ 0);
29
+ }
30
+ spa_pod_builder_add(builder,
31
SPA_FORMAT_AUDIO_channels, SPA_POD_CHOICE_RANGE_Int(
32
- DEFAULT_CHANNELS, 1, SPA_AUDIO_MAX_CHANNELS));
33
+ DEFAULT_CHANNELS, 1, SPA_AUDIO_MAX_CHANNELS),
34
+ 0);
35
+ *param = spa_pod_builder_pop(builder, &f0);
36
}
37
break;
38
default:
39
40
return res;
41
}
42
if (info.info.raw.format == 0 ||
43
- info.info.raw.rate == 0 ||
44
+ (!this->props.resample_disabled && info.info.raw.rate == 0) ||
45
info.info.raw.channels == 0 ||
46
info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) {
47
spa_log_error(this->log, "invalid format:%d rate:%d channels:%d",
48
49
struct buffer *b;
50
51
if (spa_list_is_empty(&port->queue)) {
52
- spa_log_trace_fp(this->log, "%p: out of buffers on port %d %d",
53
- this, port->id, port->n_buffers);
54
+ if (port->n_buffers > 0)
55
+ spa_log_warn(this->log, "%p: out of buffers on port %d %d",
56
+ this, port->id, port->n_buffers);
57
return NULL;
58
}
59
60
pipewire-0.3.72.tar.gz/spa/plugins/audioconvert/crossover.c -> pipewire-0.3.74.tar.gz/spa/plugins/audioconvert/crossover.c
Changed
65
1
2
3
void lr4_process(struct lr4 *lr4, float *dst, const float *src, const float vol, int samples)
4
{
5
- float lx1 = lr4->x1;
6
- float lx2 = lr4->x2;
7
- float ly1 = lr4->y1;
8
- float ly2 = lr4->y2;
9
- float lz1 = lr4->z1;
10
- float lz2 = lr4->z2;
11
- float lb0 = lr4->bq.b0;
12
- float lb1 = lr4->bq.b1;
13
- float lb2 = lr4->bq.b2;
14
- float la1 = lr4->bq.a1;
15
- float la2 = lr4->bq.a2;
16
+ float x1 = lr4->x1;
17
+ float x2 = lr4->x2;
18
+ float y1 = lr4->y1;
19
+ float y2 = lr4->y2;
20
+ float b0 = lr4->bq.b0;
21
+ float b1 = lr4->bq.b1;
22
+ float b2 = lr4->bq.b2;
23
+ float a1 = lr4->bq.a1;
24
+ float a2 = lr4->bq.a2;
25
+ float x, y, z;
26
int i;
27
28
if (vol == 0.0f) {
29
30
}
31
32
for (i = 0; i < samples; i++) {
33
- float x, y, z;
34
- x = srci;
35
- y = lb0*x + lb1*lx1 + lb2*lx2 - la1*ly1 - la2*ly2;
36
- z = lb0*y + lb1*ly1 + lb2*ly2 - la1*lz1 - la2*lz2;
37
- lx2 = lx1;
38
- lx1 = x;
39
- ly2 = ly1;
40
- ly1 = y;
41
- lz2 = lz1;
42
- lz1 = z;
43
+ x = srci;
44
+ y = b0 * x + x1;
45
+ x1 = b1 * x - a1 * y + x2;
46
+ x2 = b2 * x - a2 * y;
47
+ z = b0 * y + y1;
48
+ y1 = b1 * y - a1 * z + y2;
49
+ y2 = b2 * y - a2 * z;
50
dsti = z * vol;
51
}
52
#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x))
53
- lr4->x1 = F(lx1);
54
- lr4->x2 = F(lx2);
55
- lr4->y1 = F(ly1);
56
- lr4->y2 = F(ly2);
57
- lr4->z1 = F(lz1);
58
- lr4->z2 = F(lz2);
59
+ lr4->x1 = F(x1);
60
+ lr4->x2 = F(x2);
61
+ lr4->y1 = F(y1);
62
+ lr4->y2 = F(y2);
63
#undef F
64
}
65
pipewire-0.3.72.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c -> pipewire-0.3.74.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c
Changed
38
1
2
}
3
}
4
5
-void
6
+static void
7
conv_s24_to_f32d_1s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
8
uint32_t n_channels, uint32_t n_samples)
9
{
10
11
conv_s24_to_f32d_1s_avx2(conv, &dsti, &s3*i, n_channels, n_samples);
12
}
13
14
-
15
-void
16
+static void
17
conv_s32_to_f32d_4s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
18
uint32_t n_channels, uint32_t n_samples)
19
{
20
21
}
22
}
23
24
-void
25
+static void
26
conv_s32_to_f32d_2s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
27
uint32_t n_channels, uint32_t n_samples)
28
{
29
30
}
31
}
32
33
-void
34
+static void
35
conv_s32_to_f32d_1s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
36
uint32_t n_channels, uint32_t n_samples)
37
{
38
pipewire-0.3.72.tar.gz/spa/plugins/audioconvert/fmt-ops-sse2.c -> pipewire-0.3.74.tar.gz/spa/plugins/audioconvert/fmt-ops-sse2.c
Changed
11
1
2
conv_s24_to_f32d_1s_sse2(conv, &dsti, &s3*i, n_channels, n_samples);
3
}
4
5
-
6
-void
7
+static void
8
conv_s32_to_f32d_1s_sse2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
9
uint32_t n_channels, uint32_t n_samples)
10
{
11
pipewire-0.3.72.tar.gz/spa/plugins/audioconvert/resample-peaks.c -> pipewire-0.3.74.tar.gz/spa/plugins/audioconvert/resample-peaks.c
Changed
31
1
2
end = ((uint64_t) (o_count + 1)
3
* r->i_rate) / r->o_rate;
4
end = end > i_count ? end - i_count : 0;
5
- chunk = SPA_MIN(end, *in_len);
6
+ chunk = SPA_MIN(end, *in_len - i);
7
8
- m = peaks_abs_max(&pd->peaks, &si, chunk - i, m);
9
+ m = peaks_abs_max(&pd->peaks, &si, chunk, m);
10
11
i += chunk;
12
+ i_count += chunk;
13
14
- if (i == end) {
15
+ if (chunk == end) {
16
do++ = m;
17
m = 0.0f;
18
o_count++;
19
20
*out_len = o;
21
*in_len = i;
22
pd->o_count = o_count;
23
- pd->i_count = i_count + i;
24
+ pd->i_count = i_count;
25
26
- while (pd->i_count >= r->i_rate) {
27
+ while (pd->i_count >= r->i_rate && pd->o_count >= r->o_rate) {
28
pd->i_count -= r->i_rate;
29
pd->o_count -= r->o_rate;
30
}
31
pipewire-0.3.72.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.74.tar.gz/spa/plugins/audiomixer/audiomixer.c
Changed
13
1
2
3
outb = dequeue_buffer(this, outport);
4
if (SPA_UNLIKELY(outb == NULL)) {
5
- spa_log_trace(this->log, "%p: out of buffers (%d)", this,
6
- outport->n_buffers);
7
+ if (outport->n_buffers > 0)
8
+ spa_log_warn(this->log, "%p: out of buffers (%d)", this,
9
+ outport->n_buffers);
10
return -EPIPE;
11
}
12
13
pipewire-0.3.72.tar.gz/spa/plugins/audiomixer/mixer-dsp.c -> pipewire-0.3.74.tar.gz/spa/plugins/audiomixer/mixer-dsp.c
Changed
12
1
2
3
outb = dequeue_buffer(this, outport);
4
if (SPA_UNLIKELY(outb == NULL)) {
5
- spa_log_trace(this->log, "%p: out of buffers", this);
6
+ if (outport->n_buffers > 0)
7
+ spa_log_warn(this->log, "%p: out of buffers (%d)", this,
8
+ outport->n_buffers);
9
return -EPIPE;
10
}
11
12
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
31
1
2
return NULL;
3
4
t = spa_bt_transport_create(backend->monitor, pathfd, sizeof(struct transport_data));
5
- if (t == NULL)
6
- goto finish;
7
+ if (t == NULL) {
8
+ free(pathfd);
9
+ return NULL;
10
+ }
11
spa_bt_transport_set_implementation(t, &sco_transport_impl, t);
12
13
t->device = rfcomm->device;
14
15
16
spa_bt_transport_add_listener(t, &rfcomm->transport_listener, &transport_events, rfcomm);
17
18
-finish:
19
return t;
20
}
21
22
23
}
24
}
25
26
-void set_battery_level(unsigned int level, void *user_data)
27
+static void set_battery_level(unsigned int level, void *user_data)
28
{
29
struct impl *backend = user_data;
30
31
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/backend-ofono.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/backend-ofono.c
Changed
10
1
2
.release = ofono_audio_release,
3
};
4
5
-bool activate_transport(struct spa_bt_transport *t, const void *data)
6
+static bool activate_transport(struct spa_bt_transport *t, const void *data)
7
{
8
struct impl *backend = (void *)data;
9
struct transport_data *td = t->user_data;
10
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
65
1
2
static int device_start_timer(struct spa_bt_device *device);
3
static int device_stop_timer(struct spa_bt_device *device);
4
5
+static void media_codec_switch_free(struct spa_bt_media_codec_switch *sw);
6
+
7
// Working with BlueZ Battery Provider.
8
// Developed using https://github.com/dgreid/adhd/commit/655b58f as an example of DBus calls.
9
10
// Name of battery, formatted as /org/freedesktop/pipewire/battery/org/bluez/hciX/dev_XX_XX_XX_XX_XX_XX
11
static char *battery_get_name(const char *device_path)
12
{
13
- char *path = malloc(strlen(PIPEWIRE_BATTERY_PROVIDER) + strlen(device_path) + 1);
14
- sprintf(path, PIPEWIRE_BATTERY_PROVIDER "%s", device_path);
15
- return path;
16
+ return spa_aprintf(PIPEWIRE_BATTERY_PROVIDER "%s", device_path);
17
}
18
19
// Unregister virtual battery of device
20
21
return d;
22
}
23
24
-static int device_stop_timer(struct spa_bt_device *device);
25
-
26
-static void media_codec_switch_free(struct spa_bt_media_codec_switch *sw);
27
-
28
static void device_clear_sub(struct spa_bt_device *device)
29
{
30
battery_remove(device);
31
32
struct spa_bt_monitor *monitor = transport->monitor;
33
DBusMessage *m;
34
DBusMessageIter it2;
35
- DBusError err;
36
const char *interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE;
37
const char *name = "Volume";
38
int res = 0;
39
40
dbus_message_iter_append_basic(&it1, DBUS_TYPE_UINT16, &value);
41
dbus_message_iter_close_container(&it0, &it1);
42
43
- dbus_error_init(&err);
44
-
45
ret = dbus_connection_send_with_reply(monitor->conn, m, &transport->volume_call, -1);
46
dbus_message_unref(m);
47
48
49
{
50
struct spa_bt_monitor *monitor = transport->monitor;
51
DBusMessage *m;
52
- DBusError err;
53
dbus_bool_t ret;
54
struct spa_bt_transport *t_linked;
55
56
57
if (m == NULL)
58
return -ENOMEM;
59
60
- dbus_error_init(&err);
61
-
62
ret = dbus_connection_send_with_reply(monitor->conn, m, &transport->acquire_call, -1);
63
dbus_message_unref(m);
64
65
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/iso-io.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/iso-io.c
Changed
10
1
2
free(group);
3
}
4
5
-struct stream *stream_create(struct spa_bt_transport *t, struct group *group)
6
+static struct stream *stream_create(struct spa_bt_transport *t, struct group *group)
7
{
8
struct stream *stream;
9
void *codec_data = NULL;
10
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/media-source.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/media-source.c
Changed
45
1
2
spa_bt_decode_buffer_set_target_latency(&port->buffer, samples);
3
}
4
5
+#define WARN_ONCE(cond, ...) \
6
+ if (SPA_UNLIKELY(cond)) { static bool __once; if (!__once) { __once = true; spa_log_warn(__VA_ARGS__); } }
7
+
8
static void process_buffering(struct impl *this)
9
{
10
struct port *port = &this->port;
11
12
struct spa_data *datas;
13
uint32_t data_size;
14
15
+ buffer = spa_list_first(&port->free, struct buffer, link);
16
+ datas = buffer->buf->datas;
17
+
18
data_size = samples * port->frame_size;
19
20
+ WARN_ONCE(datas0.maxsize < data_size && !this->following,
21
+ this->log, "source buffer too small (%u < %u)",
22
+ datas0.maxsize, data_size);
23
+
24
+ data_size = SPA_MIN(data_size, SPA_ROUND_DOWN(datas0.maxsize, port->frame_size));
25
+
26
avail = SPA_MIN(avail, data_size);
27
28
spa_bt_decode_buffer_read(&port->buffer, avail);
29
30
- buffer = spa_list_first(&port->free, struct buffer, link);
31
spa_list_remove(&buffer->link);
32
33
spa_log_trace(this->log, "dequeue %d", buffer->id);
34
35
buffer->h->dts_offset = 0;
36
}
37
38
- datas = buffer->buf->datas;
39
-
40
- spa_assert(datas0.maxsize >= data_size);
41
-
42
datas0.chunk->offset = 0;
43
datas0.chunk->size = data_size;
44
datas0.chunk->stride = port->frame_size;
45
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/meson.build
Changed
27
1
2
3
if ldac_dep.found()
4
ldac_args = codec_args
5
- ldac_dep = ldac_dep
6
if ldac_abr_dep.found()
7
ldac_args += '-DENABLE_LDAC_ABR'
8
- ldac_dep += ldac_abr_dep
9
endif
10
bluez_codec_ldac = shared_library('spa-codec-bluez5-ldac',
11
'a2dp-codec-ldac.c', 'media-codecs.c' ,
12
include_directories : configinc ,
13
c_args : ldac_args,
14
- dependencies : spa_dep, ldac_dep ,
15
+ dependencies : spa_dep, ldac_dep, ldac_abr_dep ,
16
install : true,
17
install_dir : spa_plugindir / 'bluez5')
18
endif
19
20
21
if get_option('bluez5-codec-opus').allowed() and opus_dep.found()
22
opus_args = codec_args
23
- opus_dep = opus_dep
24
bluez_codec_opus = shared_library('spa-codec-bluez5-opus',
25
'a2dp-codec-opus.c', 'media-codecs.c' ,
26
include_directories : configinc ,
27
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/midi-enum.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/midi-enum.c
Changed
10
1
2
return 0;
3
}
4
5
-Bluez5GattDescriptor1 *find_dsc(struct impl *impl, MidiEnumCharacteristicProxy *chr)
6
+static Bluez5GattDescriptor1 *find_dsc(struct impl *impl, MidiEnumCharacteristicProxy *chr)
7
{
8
const char *path = g_dbus_proxy_get_object_path(G_DBUS_PROXY(chr));
9
Bluez5GattDescriptor1 *found = NULL;;
10
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/modemmanager.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/modemmanager.c
Changed
10
1
2
return this->modem.path != NULL;
3
}
4
5
-unsigned int mm_supported_features()
6
+unsigned int mm_supported_features(void)
7
{
8
return SPA_BT_HFP_AG_FEATURE_REJECT_CALL | SPA_BT_HFP_AG_FEATURE_ENHANCED_CALL_STATUS;
9
}
10
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/modemmanager.h -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/modemmanager.h
Changed
81
1
2
const struct mm_ops *ops, void *user_data);
3
void mm_unregister(void *data);
4
bool mm_is_available(void *modemmanager);
5
-unsigned int mm_supported_features();
6
+unsigned int mm_supported_features(void);
7
bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error);
8
bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error);
9
bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error);
10
11
const char *mm_get_incoming_call_number(void *modemmanager);
12
struct spa_list *mm_get_calls(void *modemmanager);
13
#else
14
-void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_dict *info,
15
+static inline void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_dict *info,
16
const struct mm_ops *ops, void *user_data)
17
{
18
return NULL;
19
}
20
21
-void mm_unregister(void *data)
22
+static inline void mm_unregister(void *data)
23
{
24
}
25
26
-bool mm_is_available(void *modemmanager)
27
+static inline bool mm_is_available(void *modemmanager)
28
{
29
return false;
30
}
31
32
-unsigned int mm_supported_features(void)
33
+static inline unsigned int mm_supported_features(void)
34
{
35
return 0;
36
}
37
38
-bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error)
39
+static inline bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error)
40
{
41
if (error)
42
*error = CMEE_OPERATION_NOT_SUPPORTED;
43
return false;
44
}
45
46
-bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error)
47
+static inline bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error)
48
{
49
if (error)
50
*error = CMEE_OPERATION_NOT_SUPPORTED;
51
return false;
52
}
53
54
-bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error)
55
+static inline bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error)
56
{
57
if (error)
58
*error = CMEE_OPERATION_NOT_SUPPORTED;
59
return false;
60
}
61
62
-bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error)
63
+static inline bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error)
64
{
65
if (error)
66
*error = CMEE_OPERATION_NOT_SUPPORTED;
67
return false;
68
}
69
70
-const char *mm_get_incoming_call_number(void *modemmanager)
71
+static inline const char *mm_get_incoming_call_number(void *modemmanager)
72
{
73
return NULL;
74
}
75
76
-struct spa_list *mm_get_calls(void *modemmanager)
77
+static inline struct spa_list *mm_get_calls(void *modemmanager)
78
{
79
return NULL;
80
}
81
pipewire-0.3.72.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.74.tar.gz/spa/plugins/bluez5/sco-source.c
Changed
42
1
2
return samples;
3
}
4
5
+#define WARN_ONCE(cond, ...) \
6
+ if (SPA_UNLIKELY(cond)) { static bool __once; if (!__once) { __once = true; spa_log_warn(__VA_ARGS__); } }
7
+
8
static void process_buffering(struct impl *this)
9
{
10
struct port *port = &this->port;
11
12
struct spa_data *datas;
13
uint32_t data_size;
14
15
+ buffer = spa_list_first(&port->free, struct buffer, link);
16
+ datas = buffer->buf->datas;
17
+
18
data_size = samples * port->frame_size;
19
20
+ WARN_ONCE(datas0.maxsize < data_size && !this->following,
21
+ this->log, "source buffer too small (%u < %u)",
22
+ datas0.maxsize, data_size);
23
+
24
+ data_size = SPA_MIN(data_size, SPA_ROUND_DOWN(datas0.maxsize, port->frame_size));
25
+
26
avail = SPA_MIN(avail, data_size);
27
28
spa_bt_decode_buffer_read(&port->buffer, avail);
29
30
- buffer = spa_list_first(&port->free, struct buffer, link);
31
spa_list_remove(&buffer->link);
32
33
spa_log_trace(this->log, "dequeue %d", buffer->id);
34
35
- datas = buffer->buf->datas;
36
-
37
- spa_assert(datas0.maxsize >= data_size);
38
-
39
datas0.chunk->offset = 0;
40
datas0.chunk->size = data_size;
41
datas0.chunk->stride = port->frame_size;
42
pipewire-0.3.72.tar.gz/spa/plugins/control/mixer.c -> pipewire-0.3.74.tar.gz/spa/plugins/control/mixer.c
Changed
12
1
2
3
/* get output buffer */
4
if ((outb = dequeue_buffer(this, outport)) == NULL) {
5
- spa_log_trace(this->log, NAME " %p: out of buffers", this);
6
+ if (outport->n_buffers > 0)
7
+ spa_log_warn(this->log, NAME " %p: out of buffers (%d)",
8
+ this, outport->n_buffers);
9
return -EPIPE;
10
}
11
12
pipewire-0.3.72.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp -> pipewire-0.3.74.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp
Changed
12
1
2
if (impl->config)
3
return;
4
5
- StreamRoles roles;
6
- roles.push_back(StreamRole::VideoRecording);
7
- impl->config = impl->camera->generateConfiguration(roles);
8
+ impl->config = impl->camera->generateConfiguration({ StreamRole::VideoRecording });
9
}
10
11
static int spa_libcamera_buffer_recycle(struct impl *impl, struct port *port, uint32_t buffer_id)
12
pipewire-0.3.72.tar.gz/spa/plugins/support/cpu.c -> pipewire-0.3.74.tar.gz/spa/plugins/support/cpu.c
Changed
10
1
2
uint32_t vm_type;
3
};
4
5
-char *spa_cpu_read_file(const char *name, char *buffer, size_t len)
6
+static char *spa_cpu_read_file(const char *name, char *buffer, size_t len)
7
{
8
int n, fd;
9
10
pipewire-0.3.72.tar.gz/spa/plugins/v4l2/v4l2-utils.c -> pipewire-0.3.74.tar.gz/spa/plugins/v4l2/v4l2-utils.c
Changed
19
1
2
}
3
do_frmsize:
4
if ((res = xioctl(dev->fd, VIDIOC_ENUM_FRAMESIZES, &port->frmsize)) < 0) {
5
- if (errno == EINVAL)
6
+ if (errno == EINVAL || errno == ENOTTY)
7
goto next_fmtdesc;
8
9
res = -errno;
10
11
while (true) {
12
if ((res = xioctl(dev->fd, VIDIOC_ENUM_FRAMEINTERVALS, &port->frmival)) < 0) {
13
res = -errno;
14
- if (errno == EINVAL) {
15
+ if (errno == EINVAL || errno == ENOTTY) {
16
port->frmsize.index++;
17
port->next_frmsize = true;
18
if (port->frmival.index == 0)
19
pipewire-0.3.72.tar.gz/src/gst/gstpipewiredeviceprovider.c -> pipewire-0.3.74.tar.gz/src/gst/gstpipewiredeviceprovider.c
Changed
13
1
2
{
3
GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider);
4
5
+ pw_thread_loop_lock (self->core->loop);
6
GST_DEBUG_OBJECT (self, "stopping provider");
7
8
g_clear_pointer ((struct pw_proxy**)&self->registry, pw_proxy_destroy);
9
+ pw_thread_loop_unlock (self->core->loop);
10
g_clear_pointer (&self->core, gst_pipewire_core_release);
11
}
12
13
pipewire-0.3.72.tar.gz/src/modules/flatpak-utils.h -> pipewire-0.3.74.tar.gz/src/modules/flatpak-utils.h
Changed
62
1
2
#ifndef FLATPAK_UTILS_H
3
#define FLATPAK_UTILS_H
4
5
+#include "config.h"
6
+
7
#include <stdio.h>
8
#include <string.h>
9
#include <fcntl.h>
10
11
#include <glib.h>
12
#endif
13
14
+#include <spa/utils/cleanup.h>
15
#include <spa/utils/result.h>
16
#include <pipewire/log.h>
17
18
19
{
20
#if defined(__linux__)
21
char root_path2048;
22
- int root_fd, info_fd, res;
23
struct stat stat_buf;
24
+ int res;
25
26
if (app_id)
27
*app_id = NULL;
28
29
*devices = NULL;
30
31
snprintf(root_path, sizeof(root_path), "/proc/%d/root", (int)pid);
32
- root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
33
- if (root_fd == -1) {
34
+
35
+ spa_autoclose int root_fd = openat(AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
36
+ if (root_fd < 0) {
37
res = -errno;
38
if (res == -EACCES) {
39
struct statfs buf;
40
41
pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res));
42
return res;
43
}
44
- info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY);
45
- close (root_fd);
46
- if (info_fd == -1) {
47
+
48
+ spa_autoclose int info_fd = openat(root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY);
49
+ if (info_fd < 0) {
50
if (errno == ENOENT) {
51
pw_log_debug("no .flatpak-info, client on the host");
52
/* No file => on the host */
53
54
pw_log_error("PID %d .flatpak-info parsing failed: %s",
55
(int)pid, spa_strerror(res));
56
}
57
- close(info_fd);
58
+
59
return 1;
60
#else
61
return 0;
62
pipewire-0.3.72.tar.gz/src/modules/meson.build -> pipewire-0.3.74.tar.gz/src/modules/meson.build
Changed
101
1
2
'module-client-node.c',
3
'module-combine-stream.c',
4
'module-echo-cancel.c',
5
+ 'module-example-filter.c',
6
'module-example-sink.c',
7
'module-example-source.c',
8
'module-fallback-sink.c',
9
10
'module-filter-chain/biquad.c',
11
'module-filter-chain/ladspa_plugin.c',
12
'module-filter-chain/builtin_plugin.c',
13
- 'module-filter-chain/sofa_plugin.c',
14
'module-filter-chain/convolver.c'
15
16
filter_chain_dependencies =
17
- mathlib, dl_lib, pipewire_dep, sndfile_dep, audioconvert_dep, libmysofa_dep
18
+ mathlib, dl_lib, pipewire_dep, sndfile_dep, audioconvert_dep
19
20
21
-if lilv_lib.found()
22
- filter_chain_sources +=
23
- 'module-filter-chain/lv2_plugin.c'
24
-
25
- filter_chain_dependencies += lilv_lib
26
-endif
27
-
28
-
29
pipewire_module_filter_chain = shared_library('pipewire-module-filter-chain',
30
filter_chain_sources,
31
include_directories : configinc,
32
33
dependencies : filter_chain_dependencies,
34
)
35
36
-pipewire_module_echo_cancel_sources =
37
- 'module-echo-cancel.c',
38
-
39
+if libmysofa_dep.found()
40
+pipewire_module_filter_chain_sofa = shared_library('pipewire-module-filter-chain-sofa',
41
+ 'module-filter-chain/sofa_plugin.c',
42
+ 'module-filter-chain/convolver.c' ,
43
+ include_directories : configinc,
44
+ install : true,
45
+ install_dir : modules_install_dir,
46
+ install_rpath: modules_install_dir,
47
+ link_with : simd_dependencies,
48
+ dependencies : filter_chain_dependencies, libmysofa_dep
49
+)
50
+endif
51
+
52
+if lilv_lib.found()
53
+pipewire_module_filter_chain_lv2 = shared_library('pipewire-module-filter-chain-lv2',
54
+ 'module-filter-chain/lv2_plugin.c' ,
55
+ include_directories : configinc,
56
+ install : true,
57
+ install_dir : modules_install_dir,
58
+ install_rpath: modules_install_dir,
59
+ dependencies : filter_chain_dependencies, lilv_lib
60
+)
61
+endif
62
+
63
64
pipewire_module_combine_stream = shared_library('pipewire-module-combine-stream',
65
'module-combine-stream.c' ,
66
67
)
68
69
pipewire_module_echo_cancel = shared_library('pipewire-module-echo-cancel',
70
- pipewire_module_echo_cancel_sources,
71
+ 'module-echo-cancel.c' ,
72
include_directories : configinc,
73
install : true,
74
install_dir : modules_install_dir,
75
76
summary({'ffado-driver': build_module_ffado_driver}, bool_yn: true, section: 'Optional Modules')
77
78
opus_custom_h = cc.has_header('opus/opus_custom.h', dependencies: opus_dep)
79
-if opus_custom_h
80
+# One would imagine that opus_dep is a requirement but for some reason it's not, so we need to manually check that
81
+if opus_dep.found() and opus_custom_h
82
opus_custom_dep = declare_dependency(compile_args: '-DHAVE_OPUS_CUSTOM', dependencies: opus_dep)
83
else
84
opus_custom_dep = dependency('', required: false)
85
86
dependencies : pipewire_module_protocol_deps,
87
)
88
89
+pipewire_module_example_filter = shared_library('pipewire-module-example-filter',
90
+ 'module-example-filter.c' ,
91
+ include_directories : configinc,
92
+ install : false,
93
+ install_dir : modules_install_dir,
94
+ install_rpath: modules_install_dir,
95
+ dependencies : spa_dep, mathlib, dl_lib, pipewire_dep,
96
+)
97
+
98
pipewire_module_example_sink = shared_library('pipewire-module-example-sink',
99
'module-example-sink.c' ,
100
include_directories : configinc,
101
pipewire-0.3.72.tar.gz/src/modules/module-avb/acmp.h -> pipewire-0.3.74.tar.gz/src/modules/module-avb/acmp.h
Changed
8
1
2
#define AVB_PACKET_ACMP_GET_STATUS(p) AVB_PACKET_GET_SUB2(&(p)->hdr)
3
4
struct avb_acmp *avb_acmp_register(struct server *server);
5
+void avb_acmp_unregister(struct avb_acmp *acmp);
6
7
#endif /* AVB_ACMP_H */
8
pipewire-0.3.72.tar.gz/src/modules/module-avb/adp.h -> pipewire-0.3.74.tar.gz/src/modules/module-avb/adp.h
Changed
8
1
2
#define AVB_PACKET_ADP_GET_VALID_TIME(p) AVB_PACKET_GET_SUB2(&(p)->hdr)
3
4
struct avb_adp *avb_adp_register(struct server *server);
5
+void avb_adp_unregister(struct avb_adp *adp);
6
7
#endif /* AVB_ADP_H */
8
pipewire-0.3.72.tar.gz/src/modules/module-avb/avb.c -> pipewire-0.3.74.tar.gz/src/modules/module-avb/avb.c
Changed
9
1
2
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */
3
/* SPDX-License-Identifier: MIT */
4
5
+#include "avb.h"
6
#include "internal.h"
7
8
#include <spa/support/cpu.h>
9
pipewire-0.3.72.tar.gz/src/modules/module-avb/avb.h -> pipewire-0.3.74.tar.gz/src/modules/module-avb/avb.h
Changed
10
1
2
#ifndef PIPEWIRE_AVB_H
3
#define PIPEWIRE_AVB_H
4
5
+#include <stddef.h>
6
+
7
#ifdef __cplusplus
8
extern "C" {
9
#endif
10
pipewire-0.3.72.tar.gz/src/modules/module-avb/descriptors.h -> pipewire-0.3.74.tar.gz/src/modules/module-avb/descriptors.h
Changed
15
1
2
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */
3
/* SPDX-License-Identifier: MIT */
4
5
+#include "adp.h"
6
#include "aecp-aem.h"
7
#include "aecp-aem-descriptors.h"
8
#include "internal.h"
9
10
-void init_descriptors(struct server *server)
11
+static inline void init_descriptors(struct server *server)
12
{
13
server_add_descriptor(server, AVB_AEM_DESC_STRINGS, 0,
14
sizeof(struct avb_aem_desc_strings),
15
pipewire-0.3.72.tar.gz/src/modules/module-client-device/client-device.h -> pipewire-0.3.74.tar.gz/src/modules/module-client-device/client-device.h
Changed
10
1
2
3
#define CLIENT_DEVICE_USAGE ""PW_KEY_DEVICE_NAME"=<string>"
4
5
-struct pw_device *
6
+struct pw_impl_device *
7
pw_client_device_new(struct pw_resource *resource,
8
struct pw_properties *properties);
9
10
pipewire-0.3.72.tar.gz/src/modules/module-client-device/resource-device.c -> pipewire-0.3.74.tar.gz/src/modules/module-client-device/resource-device.c
Changed
10
1
2
3
#include <pipewire/impl.h>
4
5
+#include "client-device.h"
6
+
7
struct impl {
8
struct pw_context *context;
9
struct pw_impl_device *device;
10
pipewire-0.3.72.tar.gz/src/modules/module-client-node/client-node.c -> pipewire-0.3.74.tar.gz/src/modules/module-client-node/client-node.c
Changed
243
1
2
struct pw_impl_client_node this;
3
4
struct pw_context *context;
5
+ struct pw_mempool *context_pool;
6
7
struct spa_node node;
8
9
10
11
struct pw_resource *resource;
12
struct pw_impl_client *client;
13
+ struct pw_mempool *client_pool;
14
15
struct spa_source data_source;
16
17
18
mix->n_buffers = 0;
19
}
20
21
-static struct mix *ensure_mix(struct impl *impl, struct port *p, uint32_t mix_id)
22
+static struct mix *create_mix(struct impl *impl, struct port *p, uint32_t mix_id)
23
{
24
struct mix *mix;
25
26
- if ((mix = find_mix(p, mix_id)) == NULL)
27
+ if ((mix = find_mix(p, mix_id)) == NULL || mix->valid)
28
return NULL;
29
- if (mix->valid)
30
- return mix;
31
mix_init(mix, p, mix_id);
32
return mix;
33
}
34
35
struct pw_memblock *m;
36
37
id = SPA_PTR_TO_UINT32(d->data);
38
- m = pw_mempool_find_id(impl->client->pool, id);
39
+ m = pw_mempool_find_id(impl->client_pool, id);
40
if (m) {
41
pw_log_debug("%p: mem %d", impl, m->id);
42
pw_memblock_unref(m);
43
44
if (impl->this.flags & 1)
45
return 0;
46
47
- old = pw_mempool_find_tag(impl->client->pool, tag, sizeof(tag));
48
+ old = pw_mempool_find_tag(impl->client_pool, tag, sizeof(tag));
49
50
if (data) {
51
- mm = pw_mempool_import_map(impl->client->pool,
52
- impl->context->pool, data, size, tag);
53
+ mm = pw_mempool_import_map(impl->client_pool,
54
+ impl->context_pool, data, size, tag);
55
if (mm == NULL)
56
return -errno;
57
58
59
if ((mix = find_mix(port, mix_id)) == NULL || !mix->valid)
60
return -EINVAL;
61
62
- old = pw_mempool_find_tag(impl->client->pool, tag, sizeof(tag));
63
+ old = pw_mempool_find_tag(impl->client_pool, tag, sizeof(tag));
64
65
if (data) {
66
- mm = pw_mempool_import_map(impl->client->pool,
67
- impl->context->pool, data, size, tag);
68
+ mm = pw_mempool_import_map(impl->client_pool,
69
+ impl->context_pool, data, size, tag);
70
if (mm == NULL)
71
return -errno;
72
73
74
direction == SPA_DIRECTION_INPUT ? "input" : "output",
75
port_id, mix_id, buffers, n_buffers, flags);
76
77
+ if (direction == SPA_DIRECTION_OUTPUT)
78
+ mix_id = SPA_ID_INVALID;
79
+
80
if ((mix = find_mix(p, mix_id)) == NULL || !mix->valid)
81
return -EINVAL;
82
83
- if (direction == SPA_DIRECTION_OUTPUT) {
84
- mix_id = SPA_ID_INVALID;
85
- if ((mix = find_mix(p, mix_id)) == NULL || !mix->valid)
86
- return -EINVAL;
87
- }
88
-
89
clear_buffers(impl, mix);
90
91
if (n_buffers > 0) {
92
93
else
94
return -EINVAL;
95
96
- if ((mem = pw_mempool_find_ptr(impl->context->pool, baseptr)) == NULL)
97
+ if ((mem = pw_mempool_find_ptr(impl->context_pool, baseptr)) == NULL)
98
return -EINVAL;
99
100
endptr = SPA_PTROFF(baseptr, buffersi->n_datas * sizeof(struct spa_chunk), void);
101
102
for (j = 0; j < buffersi->n_datas; j++) {
103
struct spa_data *d = &buffersi->datasj;
104
if (d->type == SPA_DATA_MemPtr) {
105
- if ((m = pw_mempool_find_ptr(impl->context->pool, d->data)) == NULL ||
106
+ if ((m = pw_mempool_find_ptr(impl->context_pool, d->data)) == NULL ||
107
m != mem)
108
return -EINVAL;
109
endptr = SPA_MAX(endptr, SPA_PTROFF(d->data, d->maxsize, void));
110
111
if (endptr > SPA_PTROFF(baseptr, mem->size, void))
112
return -EINVAL;
113
114
- m = pw_mempool_import_block(impl->client->pool, mem);
115
+ m = pw_mempool_import_block(impl->client_pool, mem);
116
if (m == NULL)
117
return -errno;
118
119
120
flags |= PW_MEMBLOCK_FLAG_WRITABLE;
121
122
spa_log_debug(impl->log, "mem %d type:%d fd:%d", j, d->type, (int)d->fd);
123
- m = pw_mempool_import(impl->client->pool,
124
+ m = pw_mempool_import(impl->client_pool,
125
flags, d->type, d->fd);
126
if (m == NULL)
127
return -errno;
128
129
struct impl *impl = data;
130
struct pw_memblock *m;
131
132
- m = pw_mempool_import_block(impl->client->pool, peer->activation);
133
+ m = pw_mempool_import_block(impl->client_pool, peer->activation);
134
if (m == NULL) {
135
pw_log_warn("%p: can't ensure mem: %m", impl);
136
return;
137
}
138
139
- pw_log_debug("%p: peer %p/%p id:%u added mem_id:%u", impl, peer,
140
- impl->this.node, peer->info.id, m->id);
141
+ pw_log_debug("%p: peer %p/%p id:%u added mem_id:%u %p %d", impl, peer,
142
+ impl->this.node, peer->info.id, m->id, m, m->ref);
143
144
if (impl->resource == NULL)
145
return;
146
147
struct impl *impl = data;
148
struct pw_memblock *m;
149
150
- m = pw_mempool_find_fd(impl->client->pool, peer->activation->fd);
151
+ m = pw_mempool_find_fd(impl->client_pool, peer->activation->fd);
152
if (m == NULL) {
153
pw_log_warn("%p: unknown peer %p fd:%d", impl, peer,
154
peer->source.fd);
155
156
157
pw_log_debug("%p: %d", &impl->node, node_id);
158
159
- impl->activation = pw_mempool_import_block(client->pool, node->activation);
160
+ impl->activation = pw_mempool_import_block(impl->client_pool, node->activation);
161
if (impl->activation == NULL) {
162
pw_log_debug("%p: can't import block: %m", &impl->node);
163
return;
164
165
166
size = sizeof(struct spa_io_buffers) * AREA_SIZE;
167
168
- area = pw_mempool_alloc(impl->context->pool,
169
+ area = pw_mempool_alloc(impl->context_pool,
170
PW_MEMBLOCK_FLAG_READWRITE |
171
PW_MEMBLOCK_FLAG_MAP |
172
PW_MEMBLOCK_FLAG_SEAL,
173
174
175
spa_hook_remove(&impl->node_listener);
176
177
- while ((mm = pw_mempool_find_tag(impl->client->pool, tag, sizeof(uint32_t))) != NULL)
178
+ while ((mm = pw_mempool_find_tag(impl->client_pool, tag, sizeof(uint32_t))) != NULL)
179
pw_memmap_free(mm);
180
181
- if (impl->resource)
182
- pw_resource_destroy(impl->resource);
183
-
184
if (impl->activation)
185
pw_memblock_free(impl->activation);
186
187
188
}
189
pw_array_clear(&impl->io_areas);
190
191
+ if (impl->resource)
192
+ pw_resource_destroy(impl->resource);
193
+
194
pw_map_clear(&impl->ports0);
195
pw_map_clear(&impl->ports1);
196
pw_map_clear(&impl->io_map);
197
198
uint32_t idx, pos, len;
199
struct pw_memblock *area;
200
201
- if ((m = ensure_mix(impl, port, mix->port.port_id)) == NULL)
202
+ if ((m = create_mix(impl, port, mix->port.port_id)) == NULL)
203
return -ENOMEM;
204
205
mix->id = pw_map_insert_new(&impl->io_map, NULL);
206
207
SPA_TYPE_INTERFACE_Node,
208
SPA_VERSION_NODE,
209
&impl_port_mix, p);
210
- ensure_mix(impl, p, SPA_ID_INVALID);
211
+ create_mix(impl, p, SPA_ID_INVALID);
212
213
pw_map_insert_at(&impl->portsp->direction, p->id, p);
214
return;
215
216
this = &impl->this;
217
218
impl->context = context;
219
+ impl->context_pool = pw_context_get_mempool(context);
220
impl->data_source.fd = -1;
221
pw_log_debug("%p: new", &impl->node);
222
223
224
impl_init(impl, NULL, support, n_support);
225
impl->resource = resource;
226
impl->client = client;
227
+ impl->client_pool = pw_impl_client_get_mempool(client);
228
this->flags = do_register ? 0 : 1;
229
230
pw_map_init(&impl->ports0, 64, 64);
231
232
if (this->node == NULL)
233
goto error_no_node;
234
235
+ if (this->node->data_loop == NULL) {
236
+ errno = EIO;
237
+ goto error_no_node;
238
+ }
239
+
240
impl->data_loop = this->node->data_loop->loop;
241
impl->data_system = this->node->data_loop->system;
242
243
pipewire-0.3.72.tar.gz/src/modules/module-client-node/remote-node.c -> pipewire-0.3.74.tar.gz/src/modules/module-client-node/remote-node.c
Changed
242
1
2
struct mix {
3
struct spa_list link;
4
struct pw_impl_port *port;
5
- uint32_t mix_id;
6
- uint32_t peer_id;
7
struct pw_impl_port_mix mix;
8
struct pw_array buffers;
9
};
10
11
{
12
pw_log_debug("port %p: mix init %d.%d", port, port->port_id, mix_id);
13
mix->port = port;
14
- mix->mix_id = mix_id;
15
- mix->peer_id = peer_id;
16
- pw_impl_port_init_mix(port, &mix->mix);
17
+ mix->mix.id = mix_id;
18
+ mix->mix.peer_id = peer_id;
19
+ if (mix_id != SPA_ID_INVALID)
20
+ pw_impl_port_init_mix(port, &mix->mix);
21
pw_array_init(&mix->buffers, 32);
22
pw_array_ensure_size(&mix->buffers, sizeof(struct buffer) * 64);
23
}
24
25
26
spa_list_for_each(mix, &data->mixdirection, link) {
27
if (mix->port->port_id == port_id &&
28
- mix->mix_id == mix_id) {
29
+ mix->mix.id == mix_id) {
30
pw_log_debug("port %p: found mix %d:%d.%d", mix->port,
31
direction, port_id, mix_id);
32
return mix;
33
34
return NULL;
35
}
36
37
-static struct mix *create_mix(struct node_data *data,
38
- enum spa_direction direction, uint32_t port_id,
39
+static struct mix *create_mix(struct node_data *data, struct pw_impl_port *port,
40
uint32_t mix_id, uint32_t peer_id)
41
{
42
struct mix *mix;
43
- struct pw_impl_port *port;
44
-
45
- port = pw_impl_node_find_port(data->node, direction, port_id);
46
- if (port == NULL)
47
- return NULL;
48
49
if (spa_list_is_empty(&data->free_mix)) {
50
if ((mix = calloc(1, sizeof(*mix))) == NULL)
51
52
spa_list_remove(&mix->link);
53
}
54
mix_init(mix, port, mix_id, peer_id);
55
- spa_list_append(&data->mixdirection, &mix->link);
56
+ spa_list_append(&data->mixport->direction, &mix->link);
57
58
return mix;
59
}
60
61
-static struct mix *ensure_mix(struct node_data *data,
62
- enum spa_direction direction, uint32_t port_id,
63
- uint32_t mix_id)
64
-{
65
- struct mix *mix;
66
- if ((mix = find_mix(data, direction, port_id, mix_id)))
67
- return mix;
68
- return create_mix(data, direction, port_id, mix_id, SPA_ID_INVALID);
69
-}
70
-
71
static int client_node_transport(void *_data,
72
int readfd, int writefd, uint32_t mem_id, uint32_t offset, uint32_t size)
73
{
74
75
76
pw_log_debug("port %p: clear %zd buffers mix:%d", port,
77
pw_array_get_len(&mix->buffers, struct buffer *),
78
- mix->mix_id);
79
+ mix->mix.id);
80
81
if ((res = pw_impl_port_use_buffers(port, &mix->mix, 0, NULL, 0)) < 0) {
82
pw_log_error("port %p: error clear buffers %s", port, spa_strerror(res));
83
84
struct mix *mix;
85
int res, prot;
86
87
- mix = ensure_mix(data, direction, port_id, mix_id);
88
+ mix = find_mix(data, direction, port_id, mix_id);
89
if (mix == NULL) {
90
res = -ENOENT;
91
goto error_exit;
92
93
error_exit_cleanup:
94
clear_buffers(data, mix);
95
error_exit:
96
- pw_log_error("port %p: use_buffers: %d %s", mix, res, spa_strerror(res));
97
- pw_proxy_errorf(proxy, res, "port_use_buffers error: %s", spa_strerror(res));
98
+ pw_log_error("port %p: use_buffers(%u:%u:%d): %d %s", mix,
99
+ direction, port_id, mix_id, res, spa_strerror(res));
100
+ pw_proxy_errorf(proxy, res, "port_use_buffers(%u:%u:%d) error: %s",
101
+ direction, port_id, mix_id, spa_strerror(res));
102
return res;
103
}
104
105
106
int res = 0;
107
uint32_t tag5 = { data->remote_id, direction, port_id, mix_id, id };
108
109
- mix = ensure_mix(data, direction, port_id, mix_id);
110
+ mix = find_mix(data, direction, port_id, mix_id);
111
if (mix == NULL) {
112
res = -ENOENT;
113
goto exit;
114
115
pw_loop_invoke(data->data_loop,
116
do_activate_link, SPA_ID_INVALID, NULL, 0, false, link);
117
118
- pw_log_debug("node %p: link %p: fd:%d id:%u state %p required %d, pending %d",
119
- node, link, signalfd,
120
- link->target.activation->position.clock.id,
121
+ pw_log_debug("node %p: add link %p: memid:%u fd:%d id:%u state:%p pending:%d/%d",
122
+ node, link, memid, signalfd, node_id,
123
&link->target.activation->state0,
124
- link->target.activation->state0.required,
125
- link->target.activation->state0.pending);
126
+ link->target.activation->state0.pending,
127
+ link->target.activation->state0.required);
128
} else {
129
link = find_activation(&data->links, node_id);
130
if (link == NULL) {
131
res = -ENOENT;
132
goto error_exit;
133
}
134
+ pw_log_debug("node %p: remove link %p: id:%u state:%p pending:%d/%d",
135
+ node, link, node_id,
136
+ &link->target.activation->state0,
137
+ link->target.activation->state0.pending,
138
+ link->target.activation->state0.required);
139
clear_link(data, link);
140
}
141
return res;
142
143
144
static void clear_mix(struct node_data *data, struct mix *mix)
145
{
146
- pw_log_debug("port %p: mix clear %d.%d", mix->port, mix->port->port_id, mix->mix_id);
147
+ pw_log_debug("port %p: mix clear %d.%d", mix->port, mix->port->port_id, mix->mix.id);
148
149
spa_node_port_set_io(mix->port->mix, mix->mix.port.direction,
150
mix->mix.port.port_id, SPA_IO_Buffers, NULL, 0);
151
152
pw_array_clear(&mix->buffers);
153
154
spa_list_append(&data->free_mix, &mix->link);
155
- pw_impl_port_release_mix(mix->port, &mix->mix);
156
+ if (mix->mix.id != SPA_ID_INVALID)
157
+ pw_impl_port_release_mix(mix->port, &mix->mix);
158
}
159
160
static int client_node_port_set_mix_info(void *_data,
161
162
return -EINVAL;
163
clear_mix(data, mix);
164
} else {
165
+ struct pw_impl_port *port;
166
if (mix != NULL)
167
return -EEXIST;
168
- mix = create_mix(data, direction, port_id, mix_id, peer_id);
169
+ port = pw_impl_node_find_port(data->node, direction, port_id);
170
+ if (port == NULL)
171
+ return -ENOENT;
172
+ mix = create_mix(data, port, mix_id, peer_id);
173
if (mix == NULL)
174
return -errno;
175
}
176
177
static void do_node_init(struct node_data *data)
178
{
179
struct pw_impl_port *port;
180
+ struct mix *mix;
181
182
pw_log_debug("%p: node %p init", data, data->node);
183
add_node_update(data, PW_CLIENT_NODE_UPDATE_PARAMS |
184
185
SPA_NODE_CHANGE_MASK_PARAMS);
186
187
spa_list_for_each(port, &data->node->input_ports, link) {
188
+ mix = create_mix(data, port, SPA_ID_INVALID, SPA_ID_INVALID);
189
+ if (mix == NULL)
190
+ pw_log_error("%p: failed to create port mix: %m", data->node);
191
add_port_update(data, port,
192
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
193
PW_CLIENT_NODE_PORT_UPDATE_INFO);
194
}
195
spa_list_for_each(port, &data->node->output_ports, link) {
196
+ mix = create_mix(data, port, SPA_ID_INVALID, SPA_ID_INVALID);
197
+ if (mix == NULL)
198
+ pw_log_error("%p: failed to create port mix: %m", data->node);
199
add_port_update(data, port,
200
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
201
PW_CLIENT_NODE_PORT_UPDATE_INFO);
202
203
add_port_update(d, port, change_mask);
204
}
205
206
+static void node_port_added(void *data, struct pw_impl_port *port)
207
+{
208
+ struct node_data *d = data;
209
+ struct mix *mix;
210
+
211
+ pw_log_debug("added %p", d);
212
+
213
+ if (d->client_node == NULL)
214
+ return;
215
+
216
+ mix = create_mix(d, port, SPA_ID_INVALID, SPA_ID_INVALID);
217
+ if (mix == NULL)
218
+ pw_log_error("%p: failed to create port mix: %m", d->node);
219
+}
220
+
221
static void node_port_removed(void *data, struct pw_impl_port *port)
222
{
223
struct node_data *d = data;
224
225
.free = node_free,
226
.info_changed = node_info_changed,
227
.port_info_changed = node_port_info_changed,
228
+ .port_added = node_port_added,
229
.port_removed = node_port_removed,
230
.active_changed = node_active_changed,
231
.event = node_event,
232
233
struct pw_proxy *client_node;
234
struct node_data *data;
235
236
+ if (node->data_loop == NULL)
237
+ goto error;
238
+
239
user_data_size = SPA_ROUND_UP_N(user_data_size, __alignof__(struct node_data));
240
241
client_node = pw_core_create_object(core,
242
pipewire-0.3.72.tar.gz/src/modules/module-client-node/v0/client-node.c -> pipewire-0.3.74.tar.gz/src/modules/module-client-node/v0/client-node.c
Changed
83
1
2
#include <spa/node/node.h>
3
#include <spa/node/utils.h>
4
#include <spa/node/io.h>
5
+#include <spa/node/type-info.h>
6
#include <spa/pod/filter.h>
7
#include <spa/utils/keys.h>
8
+#include <spa/utils/result.h>
9
10
#define PW_ENABLE_DEPRECATED
11
12
#include "pipewire/pipewire.h"
13
-#include "pipewire/private.h"
14
15
#include "pipewire/context.h"
16
#include "modules/spa/spa-node.h"
17
18
bool client_reuse;
19
20
struct pw_context *context;
21
+ struct pw_mempool *context_pool;
22
23
struct node node;
24
25
26
27
static int send_clock_update(struct node *this)
28
{
29
- struct pw_impl_client *client = this->resource->client;
30
+ struct pw_impl_client *client = pw_resource_get_client(this->resource);
31
uint32_t type = pw_protocol_native0_name_to_v2(client, SPA_TYPE_INFO_NODE_COMMAND_BASE "ClockUpdate");
32
struct timespec ts;
33
int64_t now;
34
35
}
36
for (i = 0; i < port->n_params; i++) {
37
port->paramsi = paramsi ?
38
- pw_protocol_native0_pod_from_v2(this->resource->client, paramsi) : NULL;
39
+ pw_protocol_native0_pod_from_v2(pw_resource_get_client(this->resource), paramsi) : NULL;
40
41
if (port->paramsi && spa_pod_is_object_id(port->paramsi, SPA_PARAM_Format))
42
port->have_format = true;
43
44
45
46
if (data) {
47
- if ((mem = pw_mempool_find_ptr(impl->context->pool, data)) == NULL)
48
+ if ((mem = pw_mempool_find_ptr(impl->context_pool, data)) == NULL)
49
return -EINVAL;
50
51
mem_offset = SPA_PTRDIFF(data, mem->map->ptr);
52
53
else
54
return -EINVAL;
55
56
- if ((mem = pw_mempool_find_ptr(impl->context->pool, baseptr)) == NULL)
57
+ if ((mem = pw_mempool_find_ptr(impl->context_pool, baseptr)) == NULL)
58
return -EINVAL;
59
60
data_size = 0;
61
62
struct node *this = object;
63
struct impl *impl = this->impl;
64
struct pw_impl_node *n = impl->this.node;
65
-
66
- return impl_node_process_input(n->node);
67
+ return impl_node_process_input(pw_impl_node_get_implementation(n));
68
}
69
70
static int handle_node_message(struct node *this, struct pw_client_node0_message *message)
71
72
}
73
convert_properties(properties);
74
75
- pw_properties_setf(properties, PW_KEY_CLIENT_ID, "%d", client->global->id);
76
+ pw_properties_setf(properties, PW_KEY_CLIENT_ID, "%d", pw_global_get_id(pw_impl_client_get_global(client)));
77
78
impl->context = context;
79
+ impl->context_pool = pw_context_get_mempool(context);
80
impl->fds0 = impl->fds1 = -1;
81
pw_log_debug("client-node %p: new", impl);
82
83
pipewire-0.3.72.tar.gz/src/modules/module-client-node/v0/client-node.h -> pipewire-0.3.74.tar.gz/src/modules/module-client-node/v0/client-node.h
Changed
18
1
2
struct spa_command_node0_clock_update_body body;
3
};
4
5
+enum spa_node0_event {
6
+ SPA_NODE0_EVENT_START = SPA_TYPE_VENDOR_PipeWire,
7
+ SPA_NODE0_EVENT_RequestClockUpdate,
8
+};
9
+
10
+enum spa_node0_command {
11
+ SPA_NODE0_COMMAND_START = SPA_TYPE_VENDOR_PipeWire,
12
+ SPA_NODE0_COMMAND_ClockUpdate,
13
+};
14
+
15
#define SPA_COMMAND_NODE0_CLOCK_UPDATE_INIT(type,change_mask,rate,ticks,monotonic_time,offset,scale,state,flags,latency) \
16
SPA_COMMAND_INIT_FULL(struct spa_command_node0_clock_update, \
17
sizeof(struct spa_command_node0_clock_update_body), 0, type, \
18
pipewire-0.3.72.tar.gz/src/modules/module-client-node/v0/transport.c -> pipewire-0.3.74.tar.gz/src/modules/module-client-node/v0/transport.c
Changed
18
1
2
#include <spa/node/io.h>
3
4
#include <pipewire/impl.h>
5
-#include <pipewire/private.h>
6
7
#include "ext-client-node.h"
8
9
10
trans = &impl->trans;
11
impl->offset = 0;
12
13
- impl->mem = pw_mempool_alloc(context->pool,
14
+ impl->mem = pw_mempool_alloc(pw_context_get_mempool(context),
15
PW_MEMBLOCK_FLAG_READWRITE |
16
PW_MEMBLOCK_FLAG_MAP |
17
PW_MEMBLOCK_FLAG_SEAL,
18
pipewire-0.3.72.tar.gz/src/modules/module-combine-stream.c -> pipewire-0.3.74.tar.gz/src/modules/module-combine-stream.c
Changed
9
1
2
} else {
3
direction = PW_DIRECTION_INPUT;
4
s->stream_events.process = stream_input_process;
5
+ flags |= PW_STREAM_FLAG_ASYNC;
6
}
7
8
pw_stream_add_listener(s->stream,
9
pipewire-0.3.74.tar.gz/src/modules/module-example-filter.c
Added
641
1
2
+/* PipeWire */
3
+/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */
4
+/* SPDX-License-Identifier: MIT */
5
+
6
+#include <string.h>
7
+#include <stdio.h>
8
+#include <errno.h>
9
+#include <sys/types.h>
10
+#include <sys/stat.h>
11
+#include <fcntl.h>
12
+#include <unistd.h>
13
+
14
+#include "config.h"
15
+
16
+#include <spa/utils/result.h>
17
+#include <spa/utils/string.h>
18
+#include <spa/utils/json.h>
19
+#include <spa/utils/ringbuffer.h>
20
+#include <spa/param/latency-utils.h>
21
+#include <spa/debug/types.h>
22
+
23
+#include <pipewire/impl.h>
24
+#include <pipewire/extensions/profiler.h>
25
+
26
+/** \page page_module_example_filter PipeWire Module: Example Filter
27
+ *
28
+ * The example filter is a good starting point for writing a custom
29
+ * filter. We refer to the source code for more information.
30
+ *
31
+ * ## Module Options
32
+ *
33
+ * - `node.description`: a human readable name for the filter streams
34
+ * - `capture.props = {}`: properties to be passed to the input stream
35
+ * - `playback.props = {}`: properties to be passed to the output stream
36
+ *
37
+ * ## General options
38
+ *
39
+ * Options with well-known behavior. Most options can be added to the global
40
+ * configuration or the individual streams:
41
+ *
42
+ * - \ref PW_KEY_REMOTE_NAME
43
+ * - \ref PW_KEY_AUDIO_RATE
44
+ * - \ref PW_KEY_AUDIO_CHANNELS
45
+ * - \ref SPA_KEY_AUDIO_POSITION
46
+ * - \ref PW_KEY_MEDIA_NAME
47
+ * - \ref PW_KEY_NODE_LATENCY
48
+ * - \ref PW_KEY_NODE_DESCRIPTION
49
+ * - \ref PW_KEY_NODE_GROUP
50
+ * - \ref PW_KEY_NODE_LINK_GROUP
51
+ * - \ref PW_KEY_NODE_VIRTUAL
52
+ * - \ref PW_KEY_NODE_NAME: See notes below. If not specified, defaults to
53
+ * 'filter-<pid>-<module-id>'.
54
+ *
55
+ * Stream only properties:
56
+ *
57
+ * - \ref PW_KEY_MEDIA_CLASS
58
+ * - \ref PW_KEY_NODE_NAME: if not given per stream, the global node.name will be
59
+ * prefixed with 'input.' and 'output.' to generate a capture and playback
60
+ * stream node.name respectively.
61
+ *
62
+ * ## Example configuration of a virtual source
63
+ *
64
+ *\code{.unparsed}
65
+ * context.modules =
66
+ * { name = libpipewire-module-example-filter
67
+ * args = {
68
+ * node.description = "Example Filter"
69
+ * capture.props = {
70
+ * audio.position = FL FR
71
+ * node.passive = true
72
+ * }
73
+ * playback.props = {
74
+ * node.name = "Example Filter"
75
+ * media.class = "Audio/Source"
76
+ * audio.position = FL FR
77
+ * }
78
+ * }
79
+ * }
80
+ *
81
+ *\endcode
82
+ *
83
+ *\code{.unparsed}
84
+ * pw-cli -m lm libpipewire-module-example-filter '{ audio.position=FL FR }'
85
+ *\endcode
86
+ *
87
+ */
88
+
89
+#define NAME "example-filter"
90
+
91
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
92
+#define PW_LOG_TOPIC_DEFAULT mod_topic
93
+
94
+static const struct spa_dict_item module_props = {
95
+ { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
96
+ { PW_KEY_MODULE_DESCRIPTION, "Create example filter streams" },
97
+ { PW_KEY_MODULE_USAGE, " ( remote.name=<remote> ) "
98
+ "( node.latency=<latency as fraction> ) "
99
+ "( node.description=<description of the nodes> ) "
100
+ "( audio.rate=<sample rate> ) "
101
+ "( audio.channels=<number of channels> ) "
102
+ "( audio.position=<channel map> ) "
103
+ "( capture.props=<properties> ) "
104
+ "( playback.props=<properties> ) " },
105
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
106
+};
107
+
108
+#include <stdlib.h>
109
+#include <signal.h>
110
+#include <getopt.h>
111
+#include <limits.h>
112
+#include <math.h>
113
+
114
+#include <spa/pod/builder.h>
115
+#include <spa/param/audio/format-utils.h>
116
+#include <spa/param/audio/raw.h>
117
+
118
+#include <pipewire/pipewire.h>
119
+
120
+struct impl {
121
+ struct pw_context *context;
122
+
123
+ struct pw_impl_module *module;
124
+
125
+ struct spa_hook module_listener;
126
+
127
+ struct pw_core *core;
128
+ struct spa_hook core_proxy_listener;
129
+ struct spa_hook core_listener;
130
+
131
+ struct pw_properties *capture_props;
132
+ struct pw_stream *capture;
133
+ struct spa_hook capture_listener;
134
+ struct spa_audio_info_raw capture_info;
135
+ struct spa_latency_info capture_latency;
136
+
137
+ struct pw_properties *playback_props;
138
+ struct pw_stream *playback;
139
+ struct spa_hook playback_listener;
140
+ struct spa_audio_info_raw playback_info;
141
+ struct spa_latency_info playback_latency;
142
+
143
+ unsigned int do_disconnect:1;
144
+};
145
+
146
+static void capture_destroy(void *d)
147
+{
148
+ struct impl *impl = d;
149
+ spa_hook_remove(&impl->capture_listener);
150
+ impl->capture = NULL;
151
+}
152
+
153
+static void capture_process(void *d)
154
+{
155
+ struct impl *impl = d;
156
+ pw_stream_trigger_process(impl->playback);
157
+}
158
+
159
+static void playback_process(void *d)
160
+{
161
+ struct impl *impl = d;
162
+ struct pw_buffer *in, *out;
163
+ uint32_t i;
164
+
165
+ in = NULL;
166
+ while (true) {
167
+ struct pw_buffer *t;
168
+ if ((t = pw_stream_dequeue_buffer(impl->capture)) == NULL)
169
+ break;
170
+ if (in)
171
+ pw_stream_queue_buffer(impl->capture, in);
172
+ in = t;
173
+ }
174
+ if (in == NULL)
175
+ pw_log_debug("%p: out of capture buffers: %m", impl);
176
+
177
+ if ((out = pw_stream_dequeue_buffer(impl->playback)) == NULL)
178
+ pw_log_debug("%p: out of playback buffers: %m", impl);
179
+
180
+ if (in != NULL && out != NULL) {
181
+ uint32_t outsize = UINT32_MAX;
182
+ int32_t stride = 0;
183
+ struct spa_data *d;
184
+ const void *srcin->buffer->n_datas;
185
+ void *dstout->buffer->n_datas;
186
+
187
+ for (i = 0; i < in->buffer->n_datas; i++) {
188
+ uint32_t offs, size;
189
+
190
+ d = &in->buffer->datasi;
191
+ offs = SPA_MIN(d->chunk->offset, d->maxsize);
192
+ size = SPA_MIN(d->chunk->size, d->maxsize - offs);
193
+
194
+ srci = SPA_PTROFF(d->data, offs, void);
195
+ outsize = SPA_MIN(outsize, size);
196
+ stride = SPA_MAX(stride, d->chunk->stride);
197
+ }
198
+ for (i = 0; i < out->buffer->n_datas; i++) {
199
+ d = &out->buffer->datasi;
200
+
201
+ outsize = SPA_MIN(outsize, d->maxsize);
202
+ dsti = d->data;
203
+
204
+ if (i < in->buffer->n_datas) {
205
+ /* do filtering here, samples are a single
206
+ * channel float */
207
+ memcpy(dsti, srci, outsize);
208
+ } else {
209
+ memset(dsti, 0, outsize);
210
+ }
211
+ d->chunk->offset = 0;
212
+ d->chunk->size = outsize;
213
+ d->chunk->stride = stride;
214
+ }
215
+ }
216
+
217
+ if (in != NULL)
218
+ pw_stream_queue_buffer(impl->capture, in);
219
+ if (out != NULL)
220
+ pw_stream_queue_buffer(impl->playback, out);
221
+}
222
+
223
+static void param_latency_changed(struct impl *impl, const struct spa_pod *param,
224
+ struct spa_latency_info *info, struct pw_stream *other)
225
+{
226
+ struct spa_latency_info latency;
227
+ uint8_t buffer1024;
228
+ struct spa_pod_builder b;
229
+ const struct spa_pod *params1;
230
+
231
+ if (spa_latency_parse(param, &latency) < 0)
232
+ return;
233
+
234
+ *info = latency;
235
+
236
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
237
+ params0 = spa_latency_build(&b, SPA_PARAM_Latency, &latency);
238
+ pw_stream_update_params(other, params, 1);
239
+}
240
+
241
+static void stream_state_changed(void *data, enum pw_stream_state old,
242
+ enum pw_stream_state state, const char *error)
243
+{
244
+ struct impl *impl = data;
245
+ switch (state) {
246
+ case PW_STREAM_STATE_PAUSED:
247
+ pw_stream_flush(impl->playback, false);
248
+ pw_stream_flush(impl->capture, false);
249
+ break;
250
+ case PW_STREAM_STATE_UNCONNECTED:
251
+ pw_log_info("module %p: unconnected", impl);
252
+ pw_impl_module_schedule_destroy(impl->module);
253
+ break;
254
+ case PW_STREAM_STATE_ERROR:
255
+ pw_log_info("module %p: error: %s", impl, error);
256
+ break;
257
+ default:
258
+ break;
259
+ }
260
+}
261
+
262
+static void capture_param_changed(void *data, uint32_t id, const struct spa_pod *param)
263
+{
264
+ struct impl *impl = data;
265
+
266
+ switch (id) {
267
+ case SPA_PARAM_Format:
268
+ {
269
+ struct spa_audio_info_raw info;
270
+ if (param == NULL)
271
+ return;
272
+ if (spa_format_audio_raw_parse(param, &info) < 0)
273
+ return;
274
+ if (info.rate == 0 ||
275
+ info.channels == 0 ||
276
+ info.channels > SPA_AUDIO_MAX_CHANNELS)
277
+ return;
278
+ break;
279
+ }
280
+ case SPA_PARAM_Latency:
281
+ param_latency_changed(impl, param, &impl->capture_latency, impl->playback);
282
+ break;
283
+ }
284
+}
285
+
286
+static const struct pw_stream_events in_stream_events = {
287
+ PW_VERSION_STREAM_EVENTS,
288
+ .destroy = capture_destroy,
289
+ .process = capture_process,
290
+ .state_changed = stream_state_changed,
291
+ .param_changed = capture_param_changed,
292
+};
293
+
294
+static void playback_destroy(void *d)
295
+{
296
+ struct impl *impl = d;
297
+ spa_hook_remove(&impl->playback_listener);
298
+ impl->playback = NULL;
299
+}
300
+
301
+static void playback_param_changed(void *data, uint32_t id, const struct spa_pod *param)
302
+{
303
+ struct impl *impl = data;
304
+
305
+ switch (id) {
306
+ case SPA_PARAM_Latency:
307
+ param_latency_changed(impl, param, &impl->playback_latency, impl->capture);
308
+ break;
309
+ }
310
+}
311
+static const struct pw_stream_events out_stream_events = {
312
+ PW_VERSION_STREAM_EVENTS,
313
+ .destroy = playback_destroy,
314
+ .process = playback_process,
315
+ .state_changed = stream_state_changed,
316
+ .param_changed = playback_param_changed,
317
+};
318
+
319
+static int setup_streams(struct impl *impl)
320
+{
321
+ int res;
322
+ uint32_t n_params;
323
+ const struct spa_pod *params1;
324
+ uint8_t buffer1024;
325
+ struct spa_pod_builder b;
326
+
327
+ impl->capture = pw_stream_new(impl->core,
328
+ "filter capture", impl->capture_props);
329
+ impl->capture_props = NULL;
330
+ if (impl->capture == NULL)
331
+ return -errno;
332
+
333
+ pw_stream_add_listener(impl->capture,
334
+ &impl->capture_listener,
335
+ &in_stream_events, impl);
336
+
337
+ impl->playback = pw_stream_new(impl->core,
338
+ "filter playback", impl->playback_props);
339
+ impl->playback_props = NULL;
340
+ if (impl->playback == NULL)
341
+ return -errno;
342
+
343
+ pw_stream_add_listener(impl->playback,
344
+ &impl->playback_listener,
345
+ &out_stream_events, impl);
346
+
347
+ /* connect playback first to activate it before capture triggers it */
348
+ n_params = 0;
349
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
350
+ paramsn_params++ = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat,
351
+ &impl->playback_info);
352
+ if ((res = pw_stream_connect(impl->playback,
353
+ PW_DIRECTION_OUTPUT,
354
+ PW_ID_ANY,
355
+ PW_STREAM_FLAG_AUTOCONNECT |
356
+ PW_STREAM_FLAG_MAP_BUFFERS |
357
+ PW_STREAM_FLAG_RT_PROCESS |
358
+ PW_STREAM_FLAG_TRIGGER,
359
+ params, n_params)) < 0)
360
+ return res;
361
+
362
+ n_params = 0;
363
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
364
+ paramsn_params++ = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat,
365
+ &impl->capture_info);
366
+ if ((res = pw_stream_connect(impl->capture,
367
+ PW_DIRECTION_INPUT,
368
+ PW_ID_ANY,
369
+ PW_STREAM_FLAG_AUTOCONNECT |
370
+ PW_STREAM_FLAG_MAP_BUFFERS |
371
+ PW_STREAM_FLAG_RT_PROCESS |
372
+ PW_STREAM_FLAG_ASYNC,
373
+ params, n_params)) < 0)
374
+ return res;
375
+
376
+ return 0;
377
+}
378
+
379
+static void core_error(void *data, uint32_t id, int seq, int res, const char *message)
380
+{
381
+ struct impl *impl = data;
382
+
383
+ if (res == -ENOENT) {
384
+ pw_log_info("message id:%u seq:%d res:%d (%s): %s",
385
+ id, seq, res, spa_strerror(res), message);
386
+ } else {
387
+ pw_log_warn("error id:%u seq:%d res:%d (%s): %s",
388
+ id, seq, res, spa_strerror(res), message);
389
+ }
390
+
391
+ if (id == PW_ID_CORE && res == -EPIPE)
392
+ pw_impl_module_schedule_destroy(impl->module);
393
+}
394
+
395
+static const struct pw_core_events core_events = {
396
+ PW_VERSION_CORE_EVENTS,
397
+ .error = core_error,
398
+};
399
+
400
+static void core_destroy(void *d)
401
+{
402
+ struct impl *impl = d;
403
+ spa_hook_remove(&impl->core_listener);
404
+ impl->core = NULL;
405
+ pw_impl_module_schedule_destroy(impl->module);
406
+}
407
+
408
+static const struct pw_proxy_events core_proxy_events = {
409
+ .destroy = core_destroy,
410
+};
411
+
412
+static void impl_destroy(struct impl *impl)
413
+{
414
+ /* deactivate both streams before destroying any of them */
415
+ if (impl->capture)
416
+ pw_stream_set_active(impl->capture, false);
417
+ if (impl->playback)
418
+ pw_stream_set_active(impl->playback, false);
419
+
420
+ if (impl->capture)
421
+ pw_stream_destroy(impl->capture);
422
+ if (impl->playback)
423
+ pw_stream_destroy(impl->playback);
424
+
425
+ if (impl->core && impl->do_disconnect)
426
+ pw_core_disconnect(impl->core);
427
+
428
+ pw_properties_free(impl->capture_props);
429
+ pw_properties_free(impl->playback_props);
430
+ free(impl);
431
+}
432
+
433
+static void module_destroy(void *data)
434
+{
435
+ struct impl *impl = data;
436
+ spa_hook_remove(&impl->module_listener);
437
+ impl_destroy(impl);
438
+}
439
+
440
+static const struct pw_impl_module_events module_events = {
441
+ PW_VERSION_IMPL_MODULE_EVENTS,
442
+ .destroy = module_destroy,
443
+};
444
+
445
+static uint32_t channel_from_name(const char *name)
446
+{
447
+ int i;
448
+ for (i = 0; spa_type_audio_channeli.name; i++) {
449
+ if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channeli.name)))
450
+ return spa_type_audio_channeli.type;
451
+ }
452
+ return SPA_AUDIO_CHANNEL_UNKNOWN;
453
+}
454
+
455
+static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
456
+{
457
+ struct spa_json it2;
458
+ char v256;
459
+
460
+ spa_json_init(&it0, val, len);
461
+ if (spa_json_enter_array(&it0, &it1) <= 0)
462
+ spa_json_init(&it1, val, len);
463
+
464
+ info->channels = 0;
465
+ while (spa_json_get_string(&it1, v, sizeof(v)) > 0 &&
466
+ info->channels < SPA_AUDIO_MAX_CHANNELS) {
467
+ info->positioninfo->channels++ = channel_from_name(v);
468
+ }
469
+}
470
+
471
+static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info)
472
+{
473
+ const char *str;
474
+
475
+ *info = SPA_AUDIO_INFO_RAW_INIT(
476
+ .format = SPA_AUDIO_FORMAT_F32P);
477
+ info->rate = pw_properties_get_int32(props, PW_KEY_AUDIO_RATE, 0);
478
+ info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0);
479
+ info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
480
+ if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
481
+ parse_position(info, str, strlen(str));
482
+}
483
+
484
+static void copy_props(struct impl *impl, struct pw_properties *props, const char *key)
485
+{
486
+ const char *str;
487
+ if ((str = pw_properties_get(props, key)) != NULL) {
488
+ if (pw_properties_get(impl->capture_props, key) == NULL)
489
+ pw_properties_set(impl->capture_props, key, str);
490
+ if (pw_properties_get(impl->playback_props, key) == NULL)
491
+ pw_properties_set(impl->playback_props, key, str);
492
+ }
493
+}
494
+
495
+SPA_EXPORT
496
+int pipewire__module_init(struct pw_impl_module *module, const char *args)
497
+{
498
+ struct pw_context *context = pw_impl_module_get_context(module);
499
+ struct pw_properties *props;
500
+ struct impl *impl;
501
+ uint32_t id = pw_global_get_id(pw_impl_module_get_global(module));
502
+ uint32_t pid = getpid();
503
+ const char *str;
504
+ int res;
505
+
506
+ PW_LOG_TOPIC_INIT(mod_topic);
507
+
508
+ impl = calloc(1, sizeof(struct impl));
509
+ if (impl == NULL)
510
+ return -errno;
511
+
512
+ pw_log_debug("module %p: new %s", impl, args);
513
+
514
+ if (args)
515
+ props = pw_properties_new_string(args);
516
+ else
517
+ props = pw_properties_new(NULL, NULL);
518
+ if (props == NULL) {
519
+ res = -errno;
520
+ pw_log_error( "can't create properties: %m");
521
+ goto error;
522
+ }
523
+
524
+ impl->capture_props = pw_properties_new(NULL, NULL);
525
+ impl->playback_props = pw_properties_new(NULL, NULL);
526
+ if (impl->capture_props == NULL || impl->playback_props == NULL) {
527
+ res = -errno;
528
+ pw_log_error( "can't create properties: %m");
529
+ goto error;
530
+ }
531
+
532
+ impl->module = module;
533
+ impl->context = context;
534
+
535
+ if (pw_properties_get(props, PW_KEY_NODE_GROUP) == NULL)
536
+ pw_properties_setf(props, PW_KEY_NODE_GROUP, "filter-%u-%u", pid, id);
537
+ if (pw_properties_get(props, PW_KEY_NODE_LINK_GROUP) == NULL)
538
+ pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "filter-%u-%u", pid, id);
539
+ if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL)
540
+ pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
541
+ if (pw_properties_get(props, "resample.prefill") == NULL)
542
+ pw_properties_set(props, "resample.prefill", "true");
543
+
544
+ if ((str = pw_properties_get(props, "capture.props")) != NULL)
545
+ pw_properties_update_string(impl->capture_props, str, strlen(str));
546
+ if ((str = pw_properties_get(props, "playback.props")) != NULL)
547
+ pw_properties_update_string(impl->playback_props, str, strlen(str));
548
+
549
+ copy_props(impl, props, PW_KEY_AUDIO_RATE);
550
+ copy_props(impl, props, PW_KEY_AUDIO_CHANNELS);
551
+ copy_props(impl, props, SPA_KEY_AUDIO_POSITION);
552
+ copy_props(impl, props, PW_KEY_NODE_DESCRIPTION);
553
+ copy_props(impl, props, PW_KEY_NODE_GROUP);
554
+ copy_props(impl, props, PW_KEY_NODE_LINK_GROUP);
555
+ copy_props(impl, props, PW_KEY_NODE_LATENCY);
556
+ copy_props(impl, props, PW_KEY_NODE_VIRTUAL);
557
+ copy_props(impl, props, PW_KEY_MEDIA_NAME);
558
+ copy_props(impl, props, "resample.prefill");
559
+
560
+ if ((str = pw_properties_get(props, PW_KEY_NODE_NAME)) == NULL) {
561
+ pw_properties_setf(props, PW_KEY_NODE_NAME,
562
+ "filter-%u-%u", pid, id);
563
+ str = pw_properties_get(props, PW_KEY_NODE_NAME);
564
+ }
565
+ if (pw_properties_get(impl->capture_props, PW_KEY_NODE_NAME) == NULL)
566
+ pw_properties_setf(impl->capture_props, PW_KEY_NODE_NAME,
567
+ "input.%s", str);
568
+ if (pw_properties_get(impl->playback_props, PW_KEY_NODE_NAME) == NULL)
569
+ pw_properties_setf(impl->playback_props, PW_KEY_NODE_NAME,
570
+ "output.%s", str);
571
+ if (pw_properties_get(impl->capture_props, PW_KEY_NODE_DESCRIPTION) == NULL)
572
+ pw_properties_set(impl->capture_props, PW_KEY_NODE_DESCRIPTION, str);
573
+ if (pw_properties_get(impl->playback_props, PW_KEY_NODE_DESCRIPTION) == NULL)
574
+ pw_properties_set(impl->playback_props, PW_KEY_NODE_DESCRIPTION, str);
575
+
576
+ parse_audio_info(impl->capture_props, &impl->capture_info);
577
+ parse_audio_info(impl->playback_props, &impl->playback_info);
578
+
579
+ if (!impl->capture_info.rate && !impl->playback_info.rate) {
580
+ if (pw_properties_get(impl->playback_props, "resample.disable") == NULL)
581
+ pw_properties_set(impl->playback_props, "resample.disable", "true");
582
+ if (pw_properties_get(impl->capture_props, "resample.disable") == NULL)
583
+ pw_properties_set(impl->capture_props, "resample.disable", "true");
584
+ } else if (impl->capture_info.rate && !impl->playback_info.rate)
585
+ impl->playback_info.rate = impl->capture_info.rate;
586
+ else if (impl->playback_info.rate && !impl->capture_info.rate)
587
+ impl->capture_info.rate = !impl->playback_info.rate;
588
+ else if (impl->capture_info.rate != impl->playback_info.rate) {
589
+ pw_log_warn("Both capture and playback rate are set, but"
590
+ " they are different. Using the highest of two. This behaviour"
591
+ " is deprecated, please use equal rates in the module config");
592
+ impl->playback_info.rate = impl->capture_info.rate =
593
+ SPA_MAX(impl->playback_info.rate, impl->capture_info.rate);
594
+ }
595
+
596
+ if (pw_properties_get(impl->capture_props, PW_KEY_MEDIA_NAME) == NULL)
597
+ pw_properties_setf(impl->capture_props, PW_KEY_MEDIA_NAME, "%s input",
598
+ pw_properties_get(impl->capture_props, PW_KEY_NODE_DESCRIPTION));
599
+ if (pw_properties_get(impl->playback_props, PW_KEY_MEDIA_NAME) == NULL)
600
+ pw_properties_setf(impl->playback_props, PW_KEY_MEDIA_NAME, "%s output",
601
+ pw_properties_get(impl->playback_props, PW_KEY_NODE_DESCRIPTION));
602
+
603
+ impl->core = pw_context_get_object(impl->context, PW_TYPE_INTERFACE_Core);
604
+ if (impl->core == NULL) {
605
+ str = pw_properties_get(props, PW_KEY_REMOTE_NAME);
606
+ impl->core = pw_context_connect(impl->context,
607
+ pw_properties_new(
608
+ PW_KEY_REMOTE_NAME, str,
609
+ NULL),
610
+ 0);
611
+ impl->do_disconnect = true;
612
+ }
613
+ if (impl->core == NULL) {
614
+ res = -errno;
615
+ pw_log_error("can't connect: %m");
616
+ goto error;
617
+ }
618
+
619
+ pw_properties_free(props);
620
+
621
+ pw_proxy_add_listener((struct pw_proxy*)impl->core,
622
+ &impl->core_proxy_listener,
623
+ &core_proxy_events, impl);
624
+ pw_core_add_listener(impl->core,
625
+ &impl->core_listener,
626
+ &core_events, impl);
627
+
628
+ setup_streams(impl);
629
+
630
+ pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
631
+
632
+ pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
633
+
634
+ return 0;
635
+
636
+error:
637
+ pw_properties_free(props);
638
+ impl_destroy(impl);
639
+ return res;
640
+}
641
pipewire-0.3.72.tar.gz/src/modules/module-ffado-driver.c -> pipewire-0.3.74.tar.gz/src/modules/module-ffado-driver.c
Changed
30
1
2
3
#include <pipewire/impl.h>
4
#include <pipewire/i18n.h>
5
-#include <pipewire/private.h>
6
#include <pipewire/thread.h>
7
8
#include <libffado/ffado.h>
9
10
return NULL;
11
}
12
13
-static int
14
-do_schedule_destroy(struct spa_loop *loop,
15
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
16
-{
17
- struct impl *impl = user_data;
18
- pw_impl_module_schedule_destroy(impl->module);
19
- return 0;
20
-}
21
-
22
-void module_schedule_destroy(struct impl *impl)
23
-{
24
- pw_loop_invoke(impl->main_loop, do_schedule_destroy, 1, NULL, 0, false, impl);
25
-}
26
-
27
static int open_ffado_device(struct impl *impl)
28
{
29
ffado_streaming_stream_type stream_type;
30
pipewire-0.3.72.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.74.tar.gz/src/modules/module-filter-chain.c
Changed
452
1
2
*
3
* The mixer plugin has up to 8 input ports labeled "In 1" to "In 8" and each with
4
* a gain control labeled "Gain 1" to "Gain 8". There is an output port labeled
5
- * "Out". Unused input ports will be ignoded and not cause overhead.
6
+ * "Out". Unused input ports will be ignored and not cause overhead.
7
*
8
* ### Copy
9
*
10
11
#define MAX_HNDL 64
12
#define MAX_SAMPLES 8192
13
14
+#define DEFAULT_RATE 48000
15
+
16
static float silence_dataMAX_SAMPLES;
17
static float discard_dataMAX_SAMPLES;
18
19
+struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
20
+ struct dsp_ops *dsp, const char *path, const char *config);
21
+struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
22
+ struct dsp_ops *dsp, const char *path, const char *config);
23
+
24
struct plugin {
25
struct spa_list link;
26
int ref;
27
28
struct spa_list descriptor_list;
29
};
30
31
+struct plugin_func {
32
+ struct spa_list link;
33
+ char type256;
34
+ fc_plugin_load_func *func;
35
+ void *hndl;
36
+};
37
+
38
struct descriptor {
39
struct spa_list link;
40
int ref;
41
42
43
uint32_t n_control;
44
struct port **control_port;
45
+
46
+ unsigned instantiated:1;
47
};
48
49
struct impl {
50
51
struct dsp_ops dsp;
52
53
struct spa_list plugin_list;
54
+ struct spa_list plugin_func_list;
55
56
struct pw_properties *capture_props;
57
struct pw_stream *capture;
58
59
struct spa_hook playback_listener;
60
struct spa_audio_info_raw playback_info;
61
62
+ struct spa_audio_info_raw info;
63
+
64
+ struct spa_io_position *position;
65
+
66
unsigned int do_disconnect:1;
67
68
long unsigned rate;
69
70
struct fc_port *p = &d->portsport->p;
71
float def, min, max;
72
char name512;
73
- uint32_t rate = impl->rate ? impl->rate : 48000;
74
+ uint32_t rate = impl->rate ? impl->rate : DEFAULT_RATE;
75
76
if (p->hint & FC_HINT_SAMPLE_RATE) {
77
def = p->def * rate;
78
79
{
80
struct impl *impl = data;
81
struct graph *graph = &impl->graph;
82
+ int res;
83
84
switch (state) {
85
case PW_STREAM_STATE_PAUSED:
86
87
case PW_STREAM_STATE_ERROR:
88
pw_log_info("module %p: error: %s", impl, error);
89
break;
90
+ case PW_STREAM_STATE_STREAMING:
91
+ {
92
+ uint32_t target = impl->info.rate;
93
+ if (target == 0)
94
+ target = impl->position ?
95
+ impl->position->clock.target_rate.denom : DEFAULT_RATE;
96
+ if (target == 0) {
97
+ res = -EINVAL;
98
+ goto error;
99
+ }
100
+ if (impl->rate != target) {
101
+ impl->rate = target;
102
+ graph_cleanup(graph);
103
+ if ((res = graph_instantiate(graph)) < 0)
104
+ goto error;
105
+ }
106
+ break;
107
+ }
108
+ default:
109
+ break;
110
+ }
111
+ return;
112
+error:
113
+ pw_stream_set_error(impl->capture, res, "can't start graph: %s",
114
+ spa_strerror(res));
115
+}
116
+
117
+static void io_changed(void *data, uint32_t id, void *area, uint32_t size)
118
+{
119
+ struct impl *impl = data;
120
+ switch (id) {
121
+ case SPA_IO_Position:
122
+ impl->position = area;
123
+ break;
124
default:
125
break;
126
}
127
128
129
switch (id) {
130
case SPA_PARAM_Format:
131
+ {
132
+ struct spa_audio_info_raw info;
133
+ spa_zero(info);
134
if (param == NULL) {
135
graph_cleanup(graph);
136
+ impl->rate = 0;
137
} else {
138
- struct spa_audio_info_raw info;
139
- spa_zero(info);
140
if ((res = spa_format_audio_raw_parse(param, &info)) < 0)
141
goto error;
142
- if (info.rate == 0) {
143
- res = -EINVAL;
144
- goto error;
145
- }
146
- impl->rate = info.rate;
147
- if ((res = graph_instantiate(graph)) < 0)
148
- goto error;
149
}
150
+ impl->info = info;
151
break;
152
+ }
153
case SPA_PARAM_Props:
154
if (param != NULL)
155
param_props_changed(impl, param);
156
157
PW_VERSION_STREAM_EVENTS,
158
.destroy = capture_destroy,
159
.process = capture_process,
160
+ .io_changed = io_changed,
161
.state_changed = state_changed,
162
.param_changed = param_changed
163
};
164
165
PW_VERSION_STREAM_EVENTS,
166
.destroy = playback_destroy,
167
.process = playback_process,
168
+ .io_changed = io_changed,
169
.state_changed = state_changed,
170
- .param_changed = param_changed
171
+ .param_changed = param_changed,
172
};
173
174
static int setup_streams(struct impl *impl)
175
176
PW_ID_ANY,
177
PW_STREAM_FLAG_AUTOCONNECT |
178
PW_STREAM_FLAG_MAP_BUFFERS |
179
- PW_STREAM_FLAG_RT_PROCESS,
180
+ PW_STREAM_FLAG_RT_PROCESS |
181
+ PW_STREAM_FLAG_ASYNC,
182
params, n_params);
183
184
spa_pod_dynamic_builder_clean(&b);
185
186
free(hndl);
187
}
188
189
+
190
+static struct plugin_func *add_plugin_func(struct impl *impl, const char *type,
191
+ fc_plugin_load_func *func, void *hndl)
192
+{
193
+ struct plugin_func *pl;
194
+
195
+ pl = calloc(1, sizeof(*pl));
196
+ if (pl == NULL)
197
+ return NULL;
198
+
199
+ snprintf(pl->type, sizeof(pl->type), "%s", type);
200
+ pl->func = func;
201
+ pl->hndl = hndl;
202
+ spa_list_append(&impl->plugin_func_list, &pl->link);
203
+ return pl;
204
+}
205
+
206
+static void free_plugin_func(struct plugin_func *pl)
207
+{
208
+ spa_list_remove(&pl->link);
209
+ if (pl->hndl)
210
+ dlclose(pl->hndl);
211
+ free(pl);
212
+}
213
+
214
+static fc_plugin_load_func *find_plugin_func(struct impl *impl, const char *type)
215
+{
216
+ fc_plugin_load_func *func = NULL;
217
+ void *hndl = NULL;
218
+ int res;
219
+ struct plugin_func *pl;
220
+ char modulePATH_MAX;
221
+ const char *module_dir;
222
+ const char *state = NULL, *p;
223
+ size_t len;
224
+
225
+ spa_list_for_each(pl, &impl->plugin_func_list, link) {
226
+ if (spa_streq(pl->type, type))
227
+ return pl->func;
228
+ }
229
+ module_dir = getenv("PIPEWIRE_MODULE_DIR");
230
+ if (module_dir == NULL)
231
+ module_dir = MODULEDIR;
232
+ pw_log_debug("moduledir set to: %s", module_dir);
233
+
234
+ while ((p = pw_split_walk(module_dir, ":", &len, &state))) {
235
+ if ((res = spa_scnprintf(module, sizeof(module),
236
+ "%.*s/libpipewire-module-filter-chain-%s.so",
237
+ (int)len, p, type)) <= 0)
238
+ continue;
239
+
240
+ hndl = dlopen(module, RTLD_NOW | RTLD_LOCAL);
241
+ if (hndl != NULL)
242
+ break;
243
+
244
+ pw_log_debug("open plugin module %s failed: %s", module, dlerror());
245
+ }
246
+ if (hndl == NULL) {
247
+ errno = ENOENT;
248
+ return NULL;
249
+ }
250
+ func = dlsym(hndl, FC_PLUGIN_LOAD_FUNC);
251
+ if (func != NULL) {
252
+ pw_log_info("opened plugin module %s", module);
253
+ pl = add_plugin_func(impl, type, func, hndl);
254
+ if (pl == NULL)
255
+ goto error_close;
256
+ } else {
257
+ errno = ENOSYS;
258
+ pw_log_error("%s is not a filter chain plugin: %m", module);
259
+ goto error_close;
260
+ }
261
+ return func;
262
+
263
+error_close:
264
+ dlclose(hndl);
265
+ return NULL;
266
+}
267
+
268
static struct plugin *plugin_load(struct impl *impl, const char *type, const char *path)
269
{
270
struct fc_plugin *pl = NULL;
271
struct plugin *hndl;
272
const struct spa_support *support;
273
uint32_t n_support;
274
+ fc_plugin_load_func *plugin_func;
275
276
spa_list_for_each(hndl, &impl->plugin_list, link) {
277
if (spa_streq(hndl->type, type) &&
278
279
}
280
support = pw_context_get_support(impl->context, &n_support);
281
282
- if (spa_streq(type, "builtin")) {
283
- pl = load_builtin_plugin(support, n_support, &impl->dsp, path, NULL);
284
- }
285
- else if (spa_streq(type, "sofa")) {
286
- pl = load_sofa_plugin(support, n_support, &impl->dsp, path, NULL);
287
- }
288
- else if (spa_streq(type, "ladspa")) {
289
- pl = load_ladspa_plugin(support, n_support, &impl->dsp, path, NULL);
290
- }
291
- else if (spa_streq(type, "lv2")) {
292
-#ifdef HAVE_LILV
293
- pl = load_lv2_plugin(support, n_support, &impl->dsp, path, NULL);
294
-#else
295
- pw_log_error("filter-chain is compiled without lv2 support");
296
+ plugin_func = find_plugin_func(impl, type);
297
+ if (plugin_func == NULL) {
298
+ pw_log_error("can't load plugin type '%s': %m", type);
299
pl = NULL;
300
- errno = ENOTSUP;
301
-#endif
302
} else {
303
- pw_log_error("invalid plugin type '%s'", type);
304
- pl = NULL;
305
- errno = EINVAL;
306
+ pl = plugin_func(support, n_support, &impl->dsp, path, NULL);
307
}
308
if (pl == NULL)
309
goto exit;
310
311
snprintf(hndl->type, sizeof(hndl->type), "%s", type);
312
snprintf(hndl->path, sizeof(hndl->path), "%s", path);
313
314
- pw_log_info("successfully opened '%s'", path);
315
+ pw_log_info("successfully opened '%s':'%s'", type, path);
316
317
hndl->plugin = pl;
318
319
320
char output256 = "";
321
char input256 = "";
322
const char *val;
323
- struct node *def_node;
324
+ struct node *def_in_node, *def_out_node;
325
struct port *in_port, *out_port;
326
struct link *link;
327
328
329
else if (spa_json_next(json, &val) < 0)
330
break;
331
}
332
- def_node = spa_list_first(&graph->node_list, struct node, link);
333
- if ((out_port = find_port(def_node, output, FC_PORT_OUTPUT)) == NULL) {
334
- pw_log_error("unknown output port %s", output);
335
- return -ENOENT;
336
+ def_out_node = spa_list_first(&graph->node_list, struct node, link);
337
+ def_in_node = spa_list_last(&graph->node_list, struct node, link);
338
+
339
+ out_port = find_port(def_out_node, output, FC_PORT_OUTPUT);
340
+ in_port = find_port(def_in_node, input, FC_PORT_INPUT);
341
+
342
+ if (out_port == NULL && out_port == NULL) {
343
+ /* try control ports */
344
+ out_port = find_port(def_out_node, output, FC_PORT_OUTPUT | FC_PORT_CONTROL);
345
+ in_port = find_port(def_in_node, input, FC_PORT_INPUT | FC_PORT_CONTROL);
346
}
347
- def_node = spa_list_last(&graph->node_list, struct node, link);
348
- if ((in_port = find_port(def_node, input, FC_PORT_INPUT)) == NULL) {
349
- pw_log_error("unknown input port %s", input);
350
+ if (in_port == NULL || out_port == NULL) {
351
+ if (out_port == NULL)
352
+ pw_log_error("unknown output port %s", output);
353
+ if (in_port == NULL)
354
+ pw_log_error("unknown input port %s", input);
355
return -ENOENT;
356
}
357
+
358
if (in_port->n_links > 0) {
359
pw_log_info("Can't have more than 1 link to %s, use a mixer", input);
360
return -ENOTSUP;
361
362
for (i = 0; i < node->n_hndl; i++) {
363
if (node->hndli == NULL)
364
continue;
365
+ pw_log_info("cleanup %s %d", d->name, i);
366
if (d->deactivate)
367
d->deactivate(node->hndli);
368
d->cleanup(node->hndli);
369
370
static void graph_cleanup(struct graph *graph)
371
{
372
struct node *node;
373
+ if (!graph->instantiated)
374
+ return;
375
+ graph->instantiated = false;
376
spa_list_for_each(node, &graph->node_list, link)
377
node_cleanup(node);
378
}
379
380
uint32_t i, j;
381
int res;
382
383
+ if (graph->instantiated)
384
+ return 0;
385
+
386
+ graph->instantiated = true;
387
+
388
spa_list_for_each(node, &graph->node_list, link) {
389
float *sd = silence_data, *dd = discard_data;
390
391
392
393
for (i = 0; i < node->n_hndl; i++) {
394
pw_log_info("instantiate %s %d rate:%lu", d->name, i, impl->rate);
395
+ errno = EINVAL;
396
if ((node->hndli = d->instantiate(d, impl->rate, i, node->config)) == NULL) {
397
- pw_log_error("cannot create plugin instance: %m");
398
+ pw_log_error("cannot create plugin instance %d rate:%lu: %m", i, impl->rate);
399
res = -errno;
400
goto error;
401
}
402
403
for (j = 0; j < desc->n_control; j++) {
404
port = &node->control_portj;
405
d->connect_port(node->hndli, port->p, &port->control_data);
406
+
407
+ spa_list_for_each(link, &port->link_list, input_link) {
408
+ struct port *peer = link->output;
409
+ pw_log_info("connect control port %s%d:%s %p",
410
+ node->name, i, d->portsport->p.name,
411
+ &peer->control_data);
412
+ d->connect_port(node->hndli, port->p, &peer->control_data);
413
+ }
414
}
415
for (j = 0; j < desc->n_notify; j++) {
416
port = &node->notify_portj;
417
+ pw_log_info("connect notify port %s%d:%s %p",
418
+ node->name, i, d->portsport->p.name,
419
+ &port->control_data);
420
d->connect_port(node->hndli, port->p, &port->control_data);
421
}
422
if (d->activate)
423
424
425
static void impl_destroy(struct impl *impl)
426
{
427
+ struct plugin_func *pl;
428
+
429
/* disconnect both streams before destroying any of them */
430
if (impl->capture)
431
pw_stream_disconnect(impl->capture);
432
433
pw_properties_free(impl->capture_props);
434
pw_properties_free(impl->playback_props);
435
graph_free(&impl->graph);
436
+ spa_list_consume(pl, &impl->plugin_func_list, link)
437
+ free_plugin_func(pl);
438
free(impl);
439
}
440
441
442
impl->graph.impl = impl;
443
444
spa_list_init(&impl->plugin_list);
445
+ spa_list_init(&impl->plugin_func_list);
446
+
447
+ add_plugin_func(impl, "builtin", load_builtin_plugin, NULL);
448
+ add_plugin_func(impl, "ladspa", load_ladspa_plugin, NULL);
449
450
support = pw_context_get_support(impl->context, &n_support);
451
452
pipewire-0.3.72.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.74.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
9
1
2
#include <sndfile.h>
3
#endif
4
#include <unistd.h>
5
+#include <limits.h>
6
7
#include <spa/utils/json.h>
8
#include <spa/utils/result.h>
9
pipewire-0.3.72.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c -> pipewire-0.3.74.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c
Changed
40
1
2
void dsp_biquad_run_c(struct dsp_ops *ops, struct biquad *bq,
3
float *out, const float *in, uint32_t n_samples)
4
{
5
- float x1, x2, y1, y2;
6
+ float x, y, x1, x2;
7
float b0, b1, b2, a1, a2;
8
uint32_t i;
9
10
x1 = bq->x1;
11
x2 = bq->x2;
12
- y1 = bq->y1;
13
- y2 = bq->y2;
14
b0 = bq->b0;
15
b1 = bq->b1;
16
b2 = bq->b2;
17
a1 = bq->a1;
18
a2 = bq->a2;
19
for (i = 0; i < n_samples; i++) {
20
- float x = ini;
21
- float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
22
+ x = ini;
23
+ y = b0 * x + x1;
24
+ x1 = b1 * x - a1 * y + x2;
25
+ x2 = b2 * x - a2 * y;
26
outi = y;
27
- x2 = x1;
28
- x1 = x;
29
- y2 = y1;
30
- y1 = y;
31
}
32
#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x))
33
bq->x1 = F(x1);
34
bq->x2 = F(x2);
35
- bq->y1 = F(y1);
36
- bq->y2 = F(y2);
37
#undef F
38
}
39
40
pipewire-0.3.72.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c -> pipewire-0.3.74.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c
Changed
9
1
2
3
#include <dlfcn.h>
4
#include <math.h>
5
+#include <limits.h>
6
7
#include <spa/utils/defs.h>
8
#include <spa/utils/list.h>
9
pipewire-0.3.72.tar.gz/src/modules/module-filter-chain/lv2_plugin.c -> pipewire-0.3.74.tar.gz/src/modules/module-filter-chain/lv2_plugin.c
Changed
11
1
2
free(p);
3
}
4
5
-struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support,
6
+SPA_EXPORT
7
+struct fc_plugin *pipewire__filter_chain_plugin_load(const struct spa_support *support, uint32_t n_support,
8
struct dsp_ops *ops, const char *plugin_uri, const char *config)
9
{
10
struct context *c;
11
pipewire-0.3.72.tar.gz/src/modules/module-filter-chain/plugin.h -> pipewire-0.3.74.tar.gz/src/modules/module-filter-chain/plugin.h
Changed
34
1
2
3
#include <stdint.h>
4
#include <stddef.h>
5
-#include <errno.h>
6
-#include <stdio.h>
7
-#include <limits.h>
8
9
#include <spa/support/plugin.h>
10
-#include <spa/utils/defs.h>
11
-#include <spa/utils/list.h>
12
-#include <spa/utils/string.h>
13
14
#include "dsp-ops.h"
15
16
17
desc->free(desc);
18
}
19
20
-struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
21
- struct dsp_ops *dsp, const char *path, const char *config);
22
-struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support,
23
- struct dsp_ops *dsp, const char *path, const char *config);
24
-struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
25
- struct dsp_ops *dsp, const char *path, const char *config);
26
-struct fc_plugin *load_sofa_plugin(const struct spa_support *support, uint32_t n_support,
27
+#define FC_PLUGIN_LOAD_FUNC "pipewire__filter_chain_plugin_load"
28
+
29
+typedef struct fc_plugin *(fc_plugin_load_func)(const struct spa_support *support, uint32_t n_support,
30
struct dsp_ops *dsp, const char *path, const char *config);
31
32
+
33
#endif /* PLUGIN_H */
34
pipewire-0.3.72.tar.gz/src/modules/module-filter-chain/sofa_plugin.c -> pipewire-0.3.74.tar.gz/src/modules/module-filter-chain/sofa_plugin.c
Changed
114
1
2
#include "config.h"
3
4
+#include <limits.h>
5
+
6
#include <spa/utils/json.h>
7
#include <spa/support/loop.h>
8
9
#include <pipewire/log.h>
10
+
11
#include "plugin.h"
12
#include "convolver.h"
13
#include "dsp-ops.h"
14
#include "pffft.h"
15
16
-#ifdef HAVE_LIBMYSOFA
17
#include <mysofa.h>
18
19
#define MAX_SAMPLES 8192u
20
-#endif
21
22
static struct dsp_ops *dsp_ops;
23
static struct spa_loop *data_loop;
24
25
int n_samples, blocksize, tailsize;
26
float *tmp2;
27
28
-#ifdef HAVE_LIBMYSOFA
29
struct MYSOFA_EASY *sofa;
30
-#endif
31
unsigned int interpolate:1;
32
struct convolver *l_conv3;
33
struct convolver *r_conv3;
34
35
static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
36
unsigned long SampleRate, int index, const char *config)
37
{
38
-#ifdef HAVE_LIBMYSOFA
39
struct spatializer_impl *impl;
40
struct spa_json it2;
41
const char *val;
42
43
mysofa_close_cached(impl->sofa);
44
free(impl);
45
return NULL;
46
-#else
47
- pw_log_error("libmysofa is required for spatializer, but disabled at compile time");
48
- errno = EINVAL;
49
- return NULL;
50
-#endif
51
}
52
53
-#ifdef HAVE_LIBMYSOFA
54
static int
55
do_switch(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
56
size_t size, void *user_data)
57
58
convolver_free(fd->item1);
59
return 0;
60
}
61
-#endif
62
63
static void spatializer_run(void * Instance, unsigned long SampleCount)
64
{
65
-#ifdef HAVE_LIBMYSOFA
66
struct spatializer_impl *impl = Instance;
67
68
if (impl->interpolate) {
69
70
convolver_run(impl->l_conv0, impl->port2, impl->port0, SampleCount);
71
convolver_run(impl->r_conv0, impl->port2, impl->port1, SampleCount);
72
}
73
-#endif
74
}
75
76
static void spatializer_connect_port(void * Instance, unsigned long Port,
77
78
if (impl->r_convi)
79
convolver_free(impl->r_convi);
80
}
81
-#ifdef HAVE_LIBMYSOFA
82
if (impl->sofa)
83
mysofa_close_cached(impl->sofa);
84
-#endif
85
free(impl->tmp0);
86
free(impl->tmp1);
87
88
89
90
static void spatializer_control_changed(void * Instance)
91
{
92
-#ifdef HAVE_LIBMYSOFA
93
pw_log_info("control changed");
94
spatializer_reload(Instance);
95
-#endif
96
}
97
98
static void spatializer_deactivate(void * Instance)
99
100
.make_desc = sofa_make_desc
101
};
102
103
-struct fc_plugin *load_sofa_plugin(const struct spa_support *support, uint32_t n_support,
104
+SPA_EXPORT
105
+struct fc_plugin *pipewire__filter_chain_plugin_load(const struct spa_support *support, uint32_t n_support,
106
struct dsp_ops *dsp, const char *plugin, const char *config)
107
{
108
dsp_ops = dsp;
109
110
111
return &builtin_plugin;
112
}
113
-
114
pipewire-0.3.72.tar.gz/src/modules/module-jack-tunnel.c -> pipewire-0.3.74.tar.gz/src/modules/module-jack-tunnel.c
Changed
18
1
2
3
#include <pipewire/impl.h>
4
#include <pipewire/i18n.h>
5
-#include <pipewire/private.h>
6
7
#include "module-jack-tunnel/weakjack.h"
8
9
10
return 0;
11
}
12
13
-void module_schedule_destroy(struct impl *impl)
14
+static void module_schedule_destroy(struct impl *impl)
15
{
16
pw_loop_invoke(impl->main_loop, do_schedule_destroy, 1, NULL, 0, false, impl);
17
}
18
pipewire-0.3.72.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.74.tar.gz/src/modules/module-loopback.c
Changed
181
1
2
{ PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
3
};
4
5
+#define DEFAULT_RATE 48000
6
+
7
#include <stdlib.h>
8
#include <signal.h>
9
#include <getopt.h>
10
11
unsigned int do_disconnect:1;
12
unsigned int recalc_delay:1;
13
14
- struct spa_audio_info_raw delay_info;
15
+ struct spa_io_position *position;
16
+ struct spa_audio_info_raw info;
17
+ uint32_t rate;
18
float target_delay;
19
struct spa_ringbuffer buffer;
20
uint8_t *buffer_data;
21
22
23
static void recalculate_delay(struct impl *impl)
24
{
25
- uint32_t target = impl->delay_info.rate * impl->target_delay, cdelay, pdelay;
26
+ uint32_t target = impl->rate * impl->target_delay, cdelay, pdelay;
27
uint32_t delay, w;
28
struct pw_time pwt;
29
30
31
impl->recalc_delay = true;
32
}
33
34
-static void stream_state_changed(void *data, enum pw_stream_state old,
35
- enum pw_stream_state state, const char *error)
36
-{
37
- struct impl *impl = data;
38
- switch (state) {
39
- case PW_STREAM_STATE_PAUSED:
40
- pw_stream_flush(impl->playback, false);
41
- pw_stream_flush(impl->capture, false);
42
- impl->recalc_delay = true;
43
- break;
44
- case PW_STREAM_STATE_UNCONNECTED:
45
- pw_log_info("module %p: unconnected", impl);
46
- pw_impl_module_schedule_destroy(impl->module);
47
- break;
48
- case PW_STREAM_STATE_ERROR:
49
- pw_log_info("module %p: error: %s", impl, error);
50
- break;
51
- default:
52
- break;
53
- }
54
-}
55
-
56
static void recalculate_buffer(struct impl *impl)
57
{
58
if (impl->target_delay > 0.0f) {
59
- uint32_t delay = impl->delay_info.rate * impl->target_delay;
60
+ uint32_t delay = impl->rate * impl->target_delay;
61
void *data;
62
63
impl->buffer_size = (delay + (1u<<15)) * 4;
64
- data = realloc(impl->buffer_data, impl->buffer_size * impl->delay_info.channels);
65
+ data = realloc(impl->buffer_data, impl->buffer_size * impl->info.channels);
66
if (data == NULL) {
67
pw_log_warn("can't allocate delay buffer, delay disabled: %m");
68
impl->buffer_size = 0;
69
70
impl->recalc_delay = true;
71
}
72
73
+static void stream_state_changed(void *data, enum pw_stream_state old,
74
+ enum pw_stream_state state, const char *error)
75
+{
76
+ struct impl *impl = data;
77
+ switch (state) {
78
+ case PW_STREAM_STATE_PAUSED:
79
+ pw_stream_flush(impl->playback, false);
80
+ pw_stream_flush(impl->capture, false);
81
+ impl->recalc_delay = true;
82
+ break;
83
+ case PW_STREAM_STATE_UNCONNECTED:
84
+ pw_log_info("module %p: unconnected", impl);
85
+ pw_impl_module_schedule_destroy(impl->module);
86
+ break;
87
+ case PW_STREAM_STATE_ERROR:
88
+ pw_log_info("module %p: error: %s", impl, error);
89
+ break;
90
+ case PW_STREAM_STATE_STREAMING:
91
+ {
92
+ uint32_t target = impl->info.rate;
93
+ if (target == 0)
94
+ target = impl->position ?
95
+ impl->position->clock.target_rate.denom : DEFAULT_RATE;
96
+ if (impl->rate != target) {
97
+ impl->rate = target;
98
+ recalculate_buffer(impl);
99
+ }
100
+ break;
101
+ }
102
+ default:
103
+ break;
104
+ }
105
+}
106
+
107
static void capture_param_changed(void *data, uint32_t id, const struct spa_pod *param)
108
{
109
struct impl *impl = data;
110
111
case SPA_PARAM_Format:
112
{
113
struct spa_audio_info_raw info;
114
- if (param == NULL)
115
- return;
116
- if (spa_format_audio_raw_parse(param, &info) < 0)
117
- return;
118
- if (info.rate == 0 ||
119
- info.channels == 0 ||
120
- info.channels > SPA_AUDIO_MAX_CHANNELS)
121
- return;
122
-
123
- impl->delay_info = info;
124
- recalculate_buffer(impl);
125
+ spa_zero(info);
126
+ if (param != NULL) {
127
+ if (spa_format_audio_raw_parse(param, &info) < 0 ||
128
+ info.channels == 0 ||
129
+ info.channels > SPA_AUDIO_MAX_CHANNELS)
130
+ return;
131
+ }
132
+ impl->rate = 0;
133
+ impl->info = info;
134
break;
135
}
136
case SPA_PARAM_Latency:
137
138
}
139
}
140
141
+static void io_changed(void *data, uint32_t id, void *area, uint32_t size)
142
+{
143
+ struct impl *impl = data;
144
+ switch (id) {
145
+ case SPA_IO_Position:
146
+ impl->position = area;
147
+ break;
148
+ default:
149
+ break;
150
+ }
151
+}
152
+
153
static const struct pw_stream_events in_stream_events = {
154
PW_VERSION_STREAM_EVENTS,
155
.destroy = capture_destroy,
156
.process = capture_process,
157
.state_changed = stream_state_changed,
158
.param_changed = capture_param_changed,
159
+ .io_changed = io_changed,
160
};
161
162
static void playback_destroy(void *d)
163
164
.process = playback_process,
165
.state_changed = stream_state_changed,
166
.param_changed = playback_param_changed,
167
+ .io_changed = io_changed,
168
};
169
170
static int setup_streams(struct impl *impl)
171
172
PW_ID_ANY,
173
PW_STREAM_FLAG_AUTOCONNECT |
174
PW_STREAM_FLAG_MAP_BUFFERS |
175
- PW_STREAM_FLAG_RT_PROCESS,
176
+ PW_STREAM_FLAG_RT_PROCESS |
177
+ PW_STREAM_FLAG_ASYNC,
178
params, n_params)) < 0)
179
return res;
180
181
pipewire-0.3.72.tar.gz/src/modules/module-netjack2-driver.c -> pipewire-0.3.74.tar.gz/src/modules/module-netjack2-driver.c
Changed
102
1
2
3
#include <pipewire/impl.h>
4
#include <pipewire/i18n.h>
5
-#include <pipewire/private.h>
6
7
#include "module-netjack2/packets.h"
8
#include "module-netjack2/peer.c"
9
10
struct impl {
11
struct pw_context *context;
12
struct pw_loop *main_loop;
13
- struct pw_data_loop *data_loop;
14
+ struct pw_loop *data_loop;
15
struct spa_system *system;
16
17
#define MODE_SINK (1<<0)
18
19
20
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
21
pw_log_warn("error:%08x", mask);
22
- pw_loop_update_io(impl->data_loop->loop, impl->socket, 0);
23
+ pw_loop_update_io(impl->data_loop, impl->socket, 0);
24
return;
25
}
26
if (mask & SPA_IO_IN) {
27
28
}
29
}
30
31
-static int
32
-do_schedule_destroy(struct spa_loop *loop,
33
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
34
-{
35
- struct impl *impl = user_data;
36
- pw_impl_module_schedule_destroy(impl->module);
37
- return 0;
38
-}
39
-
40
-void module_schedule_destroy(struct impl *impl)
41
-{
42
- pw_loop_invoke(impl->main_loop, do_schedule_destroy, 1, NULL, 0, false, impl);
43
-}
44
-
45
static int parse_address(const char *address, uint16_t port,
46
struct sockaddr_storage *addr, socklen_t *len)
47
{
48
49
send(impl->socket->fd, params, sizeof(*params), 0);
50
51
impl->done = true;
52
- pw_loop_update_io(impl->data_loop->loop, impl->socket, SPA_IO_IN);
53
+ pw_loop_update_io(impl->data_loop, impl->socket, SPA_IO_IN);
54
55
return 0;
56
connect_error:
57
58
goto out;
59
}
60
61
- impl->socket = pw_loop_add_io(impl->data_loop->loop, fd,
62
+ impl->socket = pw_loop_add_io(impl->data_loop, fd,
63
0, false, on_data_io, impl);
64
if (impl->socket == NULL) {
65
res = -errno;
66
67
68
impl->started = false;
69
if (impl->socket)
70
- pw_loop_update_io(impl->data_loop->loop, impl->socket, 0);
71
+ pw_loop_update_io(impl->data_loop, impl->socket, 0);
72
73
pw_log_info("sending STOP_DRIVER");
74
nj2_session_params_hton(¶ms, &impl->peer.params);
75
76
update_timer(impl, 0);
77
78
if (impl->socket) {
79
- pw_loop_destroy_source(impl->data_loop->loop, impl->socket);
80
+ pw_loop_destroy_source(impl->data_loop, impl->socket);
81
impl->socket = NULL;
82
}
83
if (impl->setup_socket) {
84
85
{
86
struct pw_context *context = pw_impl_module_get_context(module);
87
struct pw_properties *props = NULL;
88
+ struct pw_data_loop *data_loop;
89
struct impl *impl;
90
const char *str;
91
int res;
92
93
goto error;
94
}
95
impl->props = props;
96
- impl->data_loop = pw_context_get_data_loop(context);
97
+ data_loop = pw_context_get_data_loop(context);
98
+ impl->data_loop = pw_data_loop_get_loop(data_loop);
99
100
impl->sink.props = pw_properties_new(NULL, NULL);
101
impl->source.props = pw_properties_new(NULL, NULL);
102
pipewire-0.3.72.tar.gz/src/modules/module-netjack2-manager.c -> pipewire-0.3.74.tar.gz/src/modules/module-netjack2-manager.c
Changed
101
1
2
3
#include <pipewire/impl.h>
4
#include <pipewire/i18n.h>
5
-#include <pipewire/private.h>
6
7
#include "module-netjack2/packets.h"
8
9
10
struct impl {
11
struct pw_context *context;
12
struct pw_loop *main_loop;
13
- struct pw_data_loop *data_loop;
14
+ struct pw_loop *data_loop;
15
struct spa_system *system;
16
17
#define MODE_SINK (1<<0)
18
19
netjack2_send_data(&follower->peer, nframes, midi, n_midi, audio, n_audio);
20
21
if (follower->socket)
22
- pw_loop_update_io(s->impl->data_loop->loop, follower->socket, SPA_IO_IN);
23
+ pw_loop_update_io(s->impl->data_loop, follower->socket, SPA_IO_IN);
24
}
25
26
static void source_process(void *d, struct spa_io_position *position)
27
28
pw_properties_free(follower->sink.props);
29
30
if (follower->socket)
31
- pw_loop_destroy_source(impl->data_loop->loop, follower->socket);
32
+ pw_loop_destroy_source(impl->data_loop, follower->socket);
33
if (follower->setup_socket)
34
pw_loop_destroy_source(impl->main_loop, follower->setup_socket);
35
36
37
38
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
39
pw_log_warn("error:%08x", mask);
40
- pw_loop_destroy_source(impl->data_loop->loop, follower->socket);
41
+ pw_loop_destroy_source(impl->data_loop, follower->socket);
42
follower->socket = NULL;
43
pw_loop_invoke(impl->main_loop, do_stop_follower, 1, NULL, 0, false, follower);
44
return;
45
}
46
if (mask & SPA_IO_IN) {
47
- pw_loop_update_io(impl->data_loop->loop, follower->socket, 0);
48
+ pw_loop_update_io(impl->data_loop, follower->socket, 0);
49
50
pw_filter_trigger_process(follower->source.filter);
51
}
52
53
return res;
54
}
55
56
-
57
-static int
58
-do_schedule_destroy(struct spa_loop *loop,
59
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
60
-{
61
- struct impl *impl = user_data;
62
- pw_impl_module_schedule_destroy(impl->module);
63
- return 0;
64
-}
65
-
66
-void module_schedule_destroy(struct impl *impl)
67
-{
68
- pw_loop_invoke(impl->main_loop, do_schedule_destroy, 1, NULL, 0, false, impl);
69
-}
70
-
71
static int parse_address(const char *address, uint16_t port,
72
struct sockaddr_storage *addr, socklen_t *len)
73
{
74
75
goto socket_failed;
76
}
77
78
- follower->socket = pw_loop_add_io(impl->data_loop->loop, fd,
79
+ follower->socket = pw_loop_add_io(impl->data_loop, fd,
80
0, false, on_data_io, follower);
81
if (follower->socket == NULL) {
82
res = -errno;
83
84
{
85
struct pw_context *context = pw_impl_module_get_context(module);
86
struct pw_properties *props = NULL;
87
+ struct pw_data_loop *data_loop;
88
struct impl *impl;
89
const char *str;
90
int res;
91
92
goto error;
93
}
94
impl->props = props;
95
- impl->data_loop = pw_context_get_data_loop(context);
96
+ data_loop = pw_context_get_data_loop(context);
97
+ impl->data_loop = pw_data_loop_get_loop(data_loop);
98
99
impl->sink_props = pw_properties_new(NULL, NULL);
100
impl->source_props = pw_properties_new(NULL, NULL);
101
pipewire-0.3.72.tar.gz/src/modules/module-profiler.c -> pipewire-0.3.74.tar.gz/src/modules/module-profiler.c
Changed
76
1
2
3
#include "config.h"
4
5
+#include <spa/pod/builder.h>
6
#include <spa/utils/result.h>
7
#include <spa/utils/ringbuffer.h>
8
#include <spa/param/profiler.h>
9
10
struct pw_context *context;
11
struct pw_properties *properties;
12
13
+ struct pw_loop *main_loop;
14
struct pw_loop *data_loop;
15
16
struct spa_hook context_listener;
17
18
value.tv_nsec = 1;
19
interval.tv_sec = DEFAULT_INTERVAL;
20
interval.tv_nsec = 0;
21
- pw_loop_update_timer(impl->context->main_loop,
22
+ pw_loop_update_timer(impl->main_loop,
23
impl->flush_timeout, &value, &interval, false);
24
impl->flushing = true;
25
}
26
27
value.tv_nsec = 0;
28
interval.tv_sec = 0;
29
interval.tv_nsec = 0;
30
- pw_loop_update_timer(impl->context->main_loop,
31
+ pw_loop_update_timer(impl->main_loop,
32
impl->flush_timeout, &value, &interval, false);
33
impl->flushing = false;
34
}
35
36
37
pw_properties_free(impl->properties);
38
39
- pw_loop_destroy_source(pw_context_get_main_loop(impl->context), impl->flush_timeout);
40
+ pw_loop_destroy_source(impl->main_loop, impl->flush_timeout);
41
42
free(impl);
43
}
44
45
struct pw_context *context = pw_impl_module_get_context(module);
46
struct pw_properties *props;
47
struct impl *impl;
48
- struct pw_loop *main_loop = pw_context_get_main_loop(context);
49
static const char * const keys = {
50
PW_KEY_OBJECT_SERIAL,
51
NULL
52
53
54
impl->context = context;
55
impl->properties = props;
56
- impl->data_loop = pw_context_get_data_loop(impl->context)->loop;
57
+ impl->main_loop = pw_context_get_main_loop(impl->context);
58
+ impl->data_loop = pw_data_loop_get_loop(pw_context_get_data_loop(impl->context));
59
60
spa_ringbuffer_init(&impl->buffer);
61
62
63
free(impl);
64
return -errno;
65
}
66
- pw_properties_setf(impl->properties, PW_KEY_OBJECT_ID, "%d", impl->global->id);
67
+ pw_properties_setf(impl->properties, PW_KEY_OBJECT_ID, "%d", pw_global_get_id(impl->global));
68
pw_properties_setf(impl->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64,
69
pw_global_get_serial(impl->global));
70
71
- impl->flush_timeout = pw_loop_add_timer(main_loop, flush_timeout, impl);
72
+ impl->flush_timeout = pw_loop_add_timer(impl->main_loop, flush_timeout, impl);
73
74
pw_global_update_keys(impl->global, &impl->properties->dict, keys);
75
76
pipewire-0.3.72.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-native.c
Changed
44
1
2
#endif
3
4
#include <spa/pod/iter.h>
5
+#include <spa/pod/parser.h>
6
+#include <spa/pod/builder.h>
7
#include <spa/utils/result.h>
8
#include <spa/utils/string.h>
9
10
11
{
12
struct pw_context *context = pw_impl_module_get_context(module);
13
struct pw_protocol *this;
14
+ struct pw_impl_core *core = context->core;
15
struct protocol_data *d;
16
const struct pw_properties *props;
17
int res;
18
19
PW_LOG_TOPIC_INIT(mod_topic);
20
PW_LOG_TOPIC_INIT(mod_topic_connection);
21
22
- if (pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native) != NULL)
23
- return 0;
24
+ if (pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native) != NULL) {
25
+ pw_log_error("protocol %s is already loaded", PW_TYPE_INFO_PROTOCOL_Native);
26
+ return -EEXIST;
27
+ }
28
29
this = pw_protocol_new(context, PW_TYPE_INFO_PROTOCOL_Native, sizeof(struct protocol_data));
30
if (this == NULL)
31
32
d->module = module;
33
34
props = pw_context_get_properties(context);
35
- d->local = create_server(this, context->core, &props->dict);
36
+ d->local = create_server(this, core, &props->dict);
37
38
if (need_server(context, &props->dict)) {
39
- if (impl_add_server(this, context->core, &props->dict) == NULL) {
40
+ if (impl_add_server(this, core, &props->dict) == NULL) {
41
res = -errno;
42
goto error_cleanup;
43
}
44
pipewire-0.3.72.tar.gz/src/modules/module-protocol-native/defs.h -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-native/defs.h
Changed
11
1
2
return NULL;
3
return pod;
4
}
5
+
6
+struct protocol_compat_v2 {
7
+ /* v2 typemap */
8
+ struct pw_map types;
9
+ unsigned int send_types:1;
10
+};
11
pipewire-0.3.72.tar.gz/src/modules/module-protocol-native/protocol-footer.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-native/protocol-footer.c
Changed
19
1
2
end_footer(&fb);
3
}
4
5
-int demarshal_core_generation(void *object, struct spa_pod_parser *parser)
6
+static int demarshal_core_generation(void *object, struct spa_pod_parser *parser)
7
{
8
struct pw_core *core = object;
9
int64_t generation;
10
11
return 0;
12
}
13
14
-int demarshal_client_generation(void *object, struct spa_pod_parser *parser)
15
+static int demarshal_client_generation(void *object, struct spa_pod_parser *parser)
16
{
17
struct pw_impl_client *client = object;
18
int64_t generation;
19
pipewire-0.3.72.tar.gz/src/modules/module-protocol-native/v0/protocol-native.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-native/v0/protocol-native.c
Changed
9
1
2
#include "interfaces.h"
3
#include "typemap.h"
4
5
+#include "../defs.h"
6
#include "../connection.h"
7
8
PW_LOG_TOPIC_EXTERN(mod_topic);
9
pipewire-0.3.72.tar.gz/src/modules/module-protocol-native/v0/typemap.h -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-native/v0/typemap.h
Changed
15
1
2
+enum spa_node0_event {
3
+ SPA_NODE0_EVENT_START = SPA_TYPE_VENDOR_PipeWire,
4
+ SPA_NODE0_EVENT_RequestClockUpdate,
5
+};
6
+
7
+enum spa_node0_command {
8
+ SPA_NODE0_COMMAND_START = SPA_TYPE_VENDOR_PipeWire,
9
+ SPA_NODE0_COMMAND_ClockUpdate,
10
+};
11
+
12
static const struct type_info {
13
const char *type;
14
const char *name;
15
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse.c
Changed
34
1
2
* VMs usually can't support the low latency settings that are possible on real
3
* hardware.
4
*
5
+ * ### Quirk options
6
+ *
7
+ *\code{.unparsed}
8
+ * pulse.fix.format = "S16LE"
9
+ *\endcode
10
+ *
11
+ * When a stream uses the FIX_FORMAT flag, fixate the format to this value.
12
+ * Normally the format would be fixed to the sink/source that the stream connects
13
+ * to. When an invalid format (null or "") is set, the FIX_FORMAT flag is ignored.
14
+ *
15
+ *\code{.unparsed}
16
+ * pulse.fix.rate = 48000
17
+ *\endcode
18
+ *
19
+ * When a stream uses the FIX_RATE flag, fixate the sample rate to this value.
20
+ * Normally the rate would be fixed to the sink/source that the stream connects
21
+ * to. When a 0 rate is set, the FIX_RATE flag is ignored.
22
+ *
23
+ *\code{.unparsed}
24
+ * pulse.fix.position = " FL FR "
25
+ *\endcode
26
+ *
27
+ * When a stream uses the FIX_CHANNELS flag, fixate the channels to this value.
28
+ * Normally the channels would be fixed to the sink/source that the stream connects
29
+ * to. When an invalid position (null or "") is set, the FIX_CHANNELS flag is ignored.
30
+ *
31
* ## Command execution
32
*
33
* As part of the server startup sequence, a set of commands can be executed.
34
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/cmd.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/cmd.c
Changed
38
1
2
3
#include <spa/utils/json.h>
4
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/utils.h>
7
8
#include "module.h"
9
10
{
11
struct impl *impl = user_data;
12
struct spa_json it3;
13
- char key512, *s;
14
+ char key512;
15
int res = 0;
16
17
- s = strndup(str, len);
18
+ spa_autofree char *s = strndup(str, len);
19
spa_json_init(&it0, s, len);
20
if (spa_json_enter_array(&it0, &it1) < 0) {
21
pw_log_error("config file error: pulse.cmd is not an array");
22
- res = -EINVAL;
23
- goto exit;
24
+ return -EINVAL;
25
}
26
27
while (spa_json_enter_object(&it1, &it2) > 0) {
28
29
if (res < 0)
30
break;
31
}
32
-exit:
33
- free(s);
34
+
35
return res;
36
}
37
38
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c
Changed
16
1
2
#include <stdlib.h>
3
#include <string.h>
4
5
+#include <spa/pod/builder.h>
6
#include <spa/utils/defs.h>
7
#include <spa/utils/dict.h>
8
#include <spa/utils/string.h>
9
#include <spa/utils/json.h>
10
+#include <spa/param/audio/format.h>
11
+#include <spa/param/props.h>
12
+
13
#include <pipewire/log.h>
14
#include <pipewire/properties.h>
15
16
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/format.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/format.c
Changed
51
1
2
{
3
const char *str;
4
if (fix_ss->format != 0) {
5
- if ((str = spa_dict_lookup(props, "pulse.fix.format")) != NULL)
6
- ss->format = format_name2id(str);
7
+ if ((str = spa_dict_lookup(props, "pulse.fix.format")) != NULL) {
8
+ uint32_t val = format_name2id(str);
9
+ if (val != SPA_AUDIO_FORMAT_UNKNOWN)
10
+ ss->format = val;
11
+ }
12
else
13
ss->format = fix_ss->format;
14
/* convert back and forth to convert potential planar to packed */
15
ss->format = format_pa2id(format_id2pa(ss->format));
16
}
17
if (fix_ss->rate != 0) {
18
- if ((str = spa_dict_lookup(props, "pulse.fix.rate")) != NULL)
19
- ss->rate = atoi(str);
20
+ if ((str = spa_dict_lookup(props, "pulse.fix.rate")) != NULL) {
21
+ uint32_t val = atoi(str);
22
+ if (val != 0)
23
+ ss->rate = val;
24
+ }
25
else
26
ss->rate = fix_ss->rate;
27
ss->rate = SPA_CLAMP(ss->rate, 0u, RATE_MAX);
28
}
29
if (fix_ss->channels != 0) {
30
if ((str = spa_dict_lookup(props, "pulse.fix.position")) != NULL) {
31
- channel_map_parse_position(str, map);
32
- ss->channels = map->channels;
33
+ struct channel_map val;
34
+ channel_map_parse_position(str, &val);
35
+ if (val.channels > 0) {
36
+ ss->channels = val.channels;
37
+ *map = val;
38
+ }
39
} else {
40
ss->channels = fix_ss->channels;
41
*map = *fix_map;
42
43
if (ss != NULL)
44
*ss = *def_ss;
45
} else {
46
+ if (info.info.raw.rate == 0)
47
+ info.info.raw.rate = 48000;
48
if (info.info.raw.format == 0 ||
49
info.info.raw.rate == 0 ||
50
info.info.raw.channels == 0 ||
51
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/format.h -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/format.h
Changed
10
1
2
const struct spa_pod *format_info_build_param(struct spa_pod_builder *b, uint32_t id,
3
const struct format_info *info, uint32_t *rate);
4
5
-int format_info_from_spec(struct format_info *info, const struct sample_spec *ss,
6
- const struct channel_map *map);
7
int format_info_to_spec(const struct format_info *info, struct sample_spec *ss,
8
struct channel_map *map);
9
10
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/internal.h -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/internal.h
Changed
24
1
2
#include <stdbool.h>
3
#include <stdint.h>
4
5
+#include <spa/utils/result.h>
6
#include <spa/utils/defs.h>
7
+#include <spa/utils/ratelimit.h>
8
#include <spa/utils/ringbuffer.h>
9
-#include <pipewire/map.h>
10
-#include <pipewire/private.h>
11
+#include <pipewire/impl.h>
12
13
#include "format.h"
14
#include "server.h"
15
16
struct pw_properties *props;
17
void *dbus_name;
18
19
- struct ratelimit rate_limit;
20
+ struct spa_ratelimit rate_limit;
21
22
struct spa_hook_list hooks;
23
struct spa_list servers;
24
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/module.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/module.c
Changed
27
1
2
#include <spa/utils/list.h>
3
#include <spa/utils/hook.h>
4
#include <spa/utils/string.h>
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/log.h>
7
#include <pipewire/map.h>
8
#include <pipewire/properties.h>
9
10
/** utils */
11
void module_args_add_props(struct pw_properties *props, const char *str)
12
{
13
- char *s = strdup(str), *p = s, *e, f;
14
+ spa_autofree char *s = strdup(str);
15
+ char *p = s, *e, f;
16
const char *k, *v;
17
const struct str_map *map;
18
19
20
}
21
pw_properties_set(props, k, v);
22
}
23
- free(s);
24
}
25
26
int module_args_to_audioinfo_keys(struct impl *impl, struct pw_properties *props,
27
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c
Changed
18
1
2
3
struct spa_source *sinks_timeout;
4
5
- struct spa_audio_info_raw info;
6
-
7
unsigned int sinks_pending;
8
unsigned int load_emitted:1;
9
unsigned int start_error:1;
10
11
audioinfo_to_properties(&info, global_props);
12
13
d->module = module;
14
- d->info = info;
15
d->sink_names = sink_names;
16
d->sinks_pending = (sink_names == NULL) ? 0 : num_sinks;
17
d->stream_props = stream_props;
18
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/modules/module-raop-discover.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/modules/module-raop-discover.c
Changed
50
1
2
3
struct spa_hook mod_listener;
4
struct pw_impl_module *mod;
5
+
6
+ uint32_t latency_msec;
7
};
8
9
static void module_destroy(void *data)
10
11
static int module_raop_discover_load(struct module *module)
12
{
13
struct module_raop_discover_data *data = module->user_data;
14
+ FILE *f;
15
+ char *args;
16
+ size_t size;
17
+
18
+ if ((f = open_memstream(&args, &size)) == NULL)
19
+ return -errno;
20
+
21
+ fprintf(f, "{");
22
+ if (data->latency_msec > 0)
23
+ fprintf(f, " raop.latency.ms = %u ", data->latency_msec);
24
+ fprintf(f, "}");
25
+ fclose(f);
26
27
data->mod = pw_context_load_module(module->impl->context,
28
"libpipewire-module-raop-discover",
29
- NULL, NULL);
30
+ args, NULL);
31
+
32
+ free(args);
33
+
34
if (data->mod == NULL)
35
return -errno;
36
37
38
{
39
PW_LOG_TOPIC_INIT(mod_topic);
40
41
+ struct pw_properties * const props = module->props;
42
struct module_raop_discover_data * const data = module->user_data;
43
data->module = module;
44
45
+ pw_properties_fetch_uint32(props, "latency_msec", &data->latency_msec);
46
+
47
return 0;
48
}
49
50
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
417
1
2
#include <spa/utils/ringbuffer.h>
3
#include <spa/utils/json.h>
4
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/pipewire.h>
7
#include <pipewire/extensions/metadata.h>
8
9
10
int res;
11
struct sample_spec ss, fix_ss;
12
struct channel_map map, fix_map;
13
- uint32_t sink_index, syncid, rate = 0;
14
+ uint32_t sink_index, syncid, ss_rate = 0, rate = 0;
15
const char *sink_name;
16
struct buffer_attr attr = { 0 };
17
bool corked = false,
18
19
n_params++;
20
n_valid_formats++;
21
if (r > rate)
22
- rate = r;
23
+ ss_rate = rate = r;
24
} else {
25
log_format_info(impl, SPA_LOG_LEVEL_WARN, &format);
26
}
27
28
struct sample_spec sfix = ss;
29
struct channel_map mfix = map;
30
31
- rate = ss.rate;
32
-
33
+ ss_rate = ss.rate;
34
sample_spec_fix(&sfix, &mfix, &fix_ss, &fix_map, &props->dict);
35
+ rate = sfix.rate;
36
37
if (n_params < MAX_FORMATS &&
38
(paramsn_params = format_build_param(&b,
39
40
n_valid_formats++;
41
} else {
42
pw_log_warn("%p: unsupported format:%s rate:%d channels:%u",
43
- impl, format_id2name(ss.format), ss.rate,
44
- ss.channels);
45
+ impl, format_id2name(sfix.format), sfix.rate,
46
+ sfix.channels);
47
}
48
}
49
50
51
52
if (rate != 0) {
53
struct spa_fraction lat;
54
- fix_playback_buffer_attr(stream, &attr, rate, &lat);
55
+ fix_playback_buffer_attr(stream, &attr, ss_rate, &lat);
56
pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", rate);
57
pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%u",
58
lat.num, lat.denom);
59
60
struct pw_properties *props = NULL;
61
uint8_t n_formats = 0;
62
struct stream *stream = NULL;
63
- uint32_t n_params = 0, n_valid_formats = 0, flags, id, rate = 0;
64
+ uint32_t n_params = 0, n_valid_formats = 0, flags, id, ss_rate = 0, rate = 0;
65
const struct spa_pod *paramsMAX_FORMATS;
66
uint8_t buffer4096;
67
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
68
69
n_params++;
70
n_valid_formats++;
71
if (r > rate)
72
- rate = r;
73
+ ss_rate = rate = r;
74
} else {
75
log_format_info(impl, SPA_LOG_LEVEL_WARN, &format);
76
}
77
78
struct sample_spec sfix = ss;
79
struct channel_map mfix = map;
80
81
- rate = ss.rate;
82
-
83
+ ss_rate = ss.rate;
84
sample_spec_fix(&sfix, &mfix, &fix_ss, &fix_map, &props->dict);
85
+ rate = sfix.rate;
86
87
if (n_params < MAX_FORMATS &&
88
(paramsn_params = format_build_param(&b,
89
90
n_valid_formats++;
91
} else {
92
pw_log_warn("%p: unsupported format:%s rate:%d channels:%u",
93
- impl, format_id2name(ss.format), ss.rate,
94
- ss.channels);
95
+ impl, format_id2name(sfix.format), sfix.rate,
96
+ sfix.channels);
97
}
98
}
99
if (m->offset != m->length)
100
101
102
if (rate != 0) {
103
struct spa_fraction lat;
104
- fix_record_buffer_attr(stream, &attr, rate, &lat);
105
+ fix_record_buffer_attr(stream, &attr, ss_rate, &lat);
106
pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", rate);
107
pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%u",
108
lat.num, lat.denom);
109
110
uint32_t sink_index, volume;
111
struct sample *sample;
112
const char *sink_name, *name;
113
- struct pw_properties *props = NULL;
114
+ spa_autoptr(pw_properties) props = NULL;
115
struct pw_manager_object *o;
116
int res;
117
118
if ((props = pw_properties_new(NULL, NULL)) == NULL)
119
- goto error_errno;
120
+ return -errno;
121
122
if ((res = message_get(m,
123
TAG_U32, &sink_index,
124
125
TAG_U32, &volume,
126
TAG_STRING, &name,
127
TAG_INVALID)) < 0)
128
- goto error_proto;
129
+ return -EPROTO;
130
131
if (client->version >= 13) {
132
if ((res = message_get(m,
133
TAG_PROPLIST, props,
134
TAG_INVALID)) < 0)
135
- goto error_proto;
136
+ return -EPROTO;
137
138
}
139
pw_log_info("%s %s tag:%u sink_index:%u sink_name:%s name:%s",
140
141
pw_properties_update(props, &client->props->dict);
142
143
if (sink_index != SPA_ID_INVALID && sink_name != NULL)
144
- goto error_inval;
145
+ return -EINVAL;
146
147
o = find_device(client, sink_index, sink_name, PW_DIRECTION_OUTPUT, NULL);
148
if (o == NULL)
149
- goto error_noent;
150
+ return -ENOENT;
151
152
sample = find_sample(impl, SPA_ID_INVALID, name);
153
if (sample == NULL)
154
- goto error_noent;
155
+ return -ENOENT;
156
157
pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%"PRIu64, o->serial);
158
159
- return pending_sample_new(client, sample, props, tag);
160
-
161
-error_errno:
162
- res = -errno;
163
- goto error;
164
-error_proto:
165
- res = -EPROTO;
166
- goto error;
167
-error_inval:
168
- res = -EINVAL;
169
- goto error;
170
-error_noent:
171
- res = -ENOENT;
172
- goto error;
173
-error:
174
- pw_properties_free(props);
175
- return res;
176
+ return pending_sample_new(client, sample, spa_steal_ptr(props), tag);
177
}
178
179
static int do_remove_sample(struct client *client, uint32_t command, uint32_t tag, struct message *m)
180
181
static int do_update_proplist(struct client *client, uint32_t command, uint32_t tag, struct message *m)
182
{
183
uint32_t channel, mode;
184
- struct stream *stream;
185
- struct pw_properties *props;
186
- int res;
187
188
- props = pw_properties_new(NULL, NULL);
189
+ spa_autoptr(pw_properties) props = pw_properties_new(NULL, NULL);
190
if (props == NULL)
191
return -errno;
192
193
194
if (message_get(m,
195
TAG_U32, &channel,
196
TAG_INVALID) < 0)
197
- goto error_protocol;
198
+ return -EPROTO;
199
} else {
200
channel = SPA_ID_INVALID;
201
}
202
203
TAG_U32, &mode,
204
TAG_PROPLIST, props,
205
TAG_INVALID) < 0)
206
- goto error_protocol;
207
+ return -EPROTO;
208
209
if (command != COMMAND_UPDATE_CLIENT_PROPLIST) {
210
- stream = pw_map_lookup(&client->streams, channel);
211
+ struct stream *stream = pw_map_lookup(&client->streams, channel);
212
if (stream == NULL || stream->type == STREAM_TYPE_UPLOAD)
213
- goto error_noentity;
214
+ return -ENOENT;
215
216
pw_stream_update_properties(stream->stream, &props->dict);
217
} else {
218
219
pw_core_update_properties(client->core, &client->props->dict);
220
}
221
}
222
- res = reply_simple_ack(client, tag);
223
-exit:
224
- pw_properties_free(props);
225
- return res;
226
227
-error_protocol:
228
- res = -EPROTO;
229
- goto exit;
230
-error_noentity:
231
- res = -ENOENT;
232
- goto exit;
233
+ return reply_simple_ack(client, tag);
234
}
235
236
static int do_remove_proplist(struct client *client, uint32_t command, uint32_t tag, struct message *m)
237
{
238
uint32_t i, channel;
239
- struct stream *stream;
240
- struct pw_properties *props;
241
struct spa_dict dict;
242
struct spa_dict_item *items;
243
- int res;
244
245
- props = pw_properties_new(NULL, NULL);
246
+ spa_autoptr(pw_properties) props = pw_properties_new(NULL, NULL);
247
if (props == NULL)
248
return -errno;
249
250
251
if (message_get(m,
252
TAG_U32, &channel,
253
TAG_INVALID) < 0)
254
- goto error_protocol;
255
+ return -EPROTO;
256
} else {
257
channel = SPA_ID_INVALID;
258
}
259
260
if (message_get(m,
261
TAG_STRING, &key,
262
TAG_INVALID) < 0)
263
- goto error_protocol;
264
+ return -EPROTO;
265
if (key == NULL)
266
break;
267
pw_properties_set(props, key, key);
268
269
itemsi.value = NULL;
270
}
271
272
- if (command != COMMAND_UPDATE_CLIENT_PROPLIST) {
273
- stream = pw_map_lookup(&client->streams, channel);
274
+ if (command != COMMAND_REMOVE_CLIENT_PROPLIST) {
275
+ struct stream *stream = pw_map_lookup(&client->streams, channel);
276
if (stream == NULL || stream->type == STREAM_TYPE_UPLOAD)
277
- goto error_noentity;
278
+ return -ENOENT;
279
280
pw_stream_update_properties(stream->stream, &dict);
281
} else {
282
pw_core_update_properties(client->core, &dict);
283
}
284
- res = reply_simple_ack(client, tag);
285
-exit:
286
- pw_properties_free(props);
287
- return res;
288
289
-error_protocol:
290
- res = -EPROTO;
291
- goto exit;
292
-error_noentity:
293
- res = -ENOENT;
294
- goto exit;
295
+ return reply_simple_ack(client, tag);
296
}
297
298
299
300
{
301
struct pw_manager *manager = client->manager;
302
struct pw_device_info *info = o->info;
303
- const char *str, *drv_name;
304
+ const char *str, *drv_name, *card_name;
305
uint32_t module_id = SPA_ID_INVALID, n_profiles, n;
306
struct card_info card_info = CARD_INFO_INIT;
307
struct profile_info *profile_info;
308
+ char name128;
309
310
if (!pw_manager_object_is_card(o) || info == NULL || info->props == NULL)
311
return -ENOENT;
312
313
if (drv_name && spa_streq("bluez5", drv_name))
314
drv_name = "module-bluez5-device.c"; /* blueman needs this */
315
316
+ card_name = spa_dict_lookup(info->props, PW_KEY_DEVICE_NAME);
317
+ if (card_name == NULL)
318
+ card_name = spa_dict_lookup(info->props, "api.alsa.card.name");
319
+ if (card_name == NULL) {
320
+ snprintf(name, sizeof(name), "card_%u", o->index);
321
+ card_name = name;
322
+ }
323
+
324
message_put(m,
325
TAG_U32, o->index, /* card index */
326
- TAG_STRING, spa_dict_lookup(info->props, PW_KEY_DEVICE_NAME),
327
+ TAG_STRING, card_name,
328
TAG_U32, id_to_index(manager, module_id),
329
TAG_STRING, drv_name,
330
TAG_INVALID);
331
332
const struct pw_manager_object *card)
333
{
334
struct pw_device_info *card_info = card ? card->info : NULL;
335
- struct pw_properties *props = NULL;
336
+ spa_autoptr(pw_properties) props = NULL;
337
338
if (card_info && card_info->props) {
339
props = pw_properties_new_dict(sink_props);
340
341
pw_properties_add(props, card_info->props);
342
sink_props = &props->dict;
343
}
344
- message_put(m, TAG_PROPLIST, sink_props, TAG_INVALID);
345
346
- pw_properties_free(props);
347
+ message_put(m, TAG_PROPLIST, sink_props, TAG_INVALID);
348
349
return 0;
350
}
351
352
const struct pw_manager_object *card, const bool is_monitor)
353
{
354
struct pw_device_info *card_info = card ? card->info : NULL;
355
- struct pw_properties *props = NULL;
356
+ spa_autoptr(pw_properties) props = NULL;
357
358
if ((card_info && card_info->props) || is_monitor) {
359
props = pw_properties_new_dict(source_props);
360
361
362
source_props = &props->dict;
363
}
364
- message_put(m, TAG_PROPLIST, source_props, TAG_INVALID);
365
366
- pw_properties_free(props);
367
+ message_put(m, TAG_PROPLIST, source_props, TAG_INVALID);
368
369
return 0;
370
}
371
372
const char *object_path = NULL;
373
const char *message = NULL;
374
const char *params = NULL;
375
- char *response = NULL;
376
- char *path = NULL;
377
struct message *reply;
378
struct pw_manager_object *o;
379
int len = 0;
380
- int res;
381
382
if (message_get(m,
383
TAG_STRING, &object_path,
384
385
len = strlen(object_path);
386
if (len > 0 && object_pathlen - 1 == '/')
387
--len;
388
- path = strndup(object_path, len);
389
+
390
+ spa_autofree char *path = strndup(object_path, len);
391
if (path == NULL)
392
return -ENOMEM;
393
394
- res = -ENOENT;
395
+ spa_autofree char *response = NULL;
396
+ int res = -ENOENT;
397
398
spa_list_for_each(o, &manager->object_list, link) {
399
if (o->message_object_path && spa_streq(o->message_object_path, path)) {
400
401
}
402
}
403
404
- free(path);
405
if (res < 0)
406
return res;
407
408
409
410
reply = reply_new(client, tag);
411
message_put(reply, TAG_STRING, response, TAG_INVALID);
412
- free(response);
413
+
414
return client_queue_message(client, reply);
415
}
416
417
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/reply.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/reply.c
Changed
9
1
2
#include "commands.h"
3
#include "message.h"
4
#include "log.h"
5
+#include "reply.h"
6
7
struct message *reply_new(const struct client *client, uint32_t tag)
8
{
9
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
27
1
2
#include <spa/utils/defs.h>
3
#include <spa/utils/json.h>
4
#include <spa/utils/result.h>
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/pipewire.h>
7
8
#include "client.h"
9
10
client_access = server->client_access;
11
12
if (server->addr.ss_family == AF_UNIX) {
13
- char *app_id = NULL, *devices = NULL;
14
+ spa_autofree char *app_id = NULL, *devices = NULL;
15
16
#ifdef SO_PRIORITY
17
val = 6;
18
19
else
20
pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, NULL);
21
}
22
- free(devices);
23
- free(app_id);
24
}
25
else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) {
26
27
pipewire-0.3.72.tar.gz/src/modules/module-protocol-pulse/stream.c -> pipewire-0.3.74.tar.gz/src/modules/module-protocol-pulse/stream.c
Changed
16
1
2
struct client *client = stream->client;
3
struct impl *impl = client->impl;
4
struct message *reply;
5
+ int missed;
6
7
- if (ratelimit_test(&impl->rate_limit, stream->timestamp, SPA_LOG_LEVEL_INFO)) {
8
- pw_log_info("%s: UNDERFLOW channel:%u offset:%" PRIi64,
9
- client->name, stream->channel, offset);
10
+ if ((missed = spa_ratelimit_test(&impl->rate_limit, stream->timestamp)) >= 0) {
11
+ pw_log_info("%s: UNDERFLOW channel:%u offset:%" PRIi64" (%d missed)",
12
+ client->name, stream->channel, offset, missed);
13
}
14
15
reply = message_alloc(impl, -1, 0);
16
pipewire-0.3.72.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.74.tar.gz/src/modules/module-pulse-tunnel.c
Changed
62
1
2
#include <spa/utils/json.h>
3
#include <spa/utils/ringbuffer.h>
4
#include <spa/utils/dll.h>
5
+#include <spa/utils/ratelimit.h>
6
#include <spa/debug/types.h>
7
#include <spa/pod/builder.h>
8
#include <spa/param/audio/format-utils.h>
9
10
11
#include <pipewire/impl.h>
12
#include <pipewire/i18n.h>
13
-#include <pipewire/private.h>
14
15
#include <pulse/pulseaudio.h>
16
#include "module-protocol-pulse/defs.h"
17
18
pa_stream *pa_stream;
19
uint32_t pa_index;
20
21
- struct ratelimit rate_limit;
22
+ struct spa_ratelimit rate_limit;
23
24
uint32_t target_latency;
25
uint32_t current_latency;
26
27
return 0;
28
}
29
30
-void module_schedule_destroy(struct impl *impl)
31
+static void module_schedule_destroy(struct impl *impl)
32
{
33
pw_loop_invoke(impl->main_loop, do_schedule_destroy, 1, NULL, 0, false, impl);
34
}
35
36
{
37
struct impl *impl = userdata;
38
struct timespec ts;
39
+ int missed;
40
41
clock_gettime(CLOCK_MONOTONIC, &ts);
42
- if (ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts), SPA_LOG_LEVEL_WARN))
43
- pw_log_warn("underflow");
44
+ if ((missed = spa_ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts))) >= 0)
45
+ pw_log_warn("underflow (%d missed)", missed);
46
impl->resync = true;
47
}
48
static void stream_overflow_cb(pa_stream *s, void *userdata)
49
{
50
struct impl *impl = userdata;
51
struct timespec ts;
52
+ int missed;
53
+
54
clock_gettime(CLOCK_MONOTONIC, &ts);
55
- if (ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts), SPA_LOG_LEVEL_WARN))
56
- pw_log_warn("overflow");
57
+ if ((missed = spa_ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts))) >= 0)
58
+ pw_log_warn("overflow (%d missed)", missed);
59
impl->resync = true;
60
}
61
62
pipewire-0.3.72.tar.gz/src/modules/module-raop-discover.c -> pipewire-0.3.74.tar.gz/src/modules/module-raop-discover.c
Changed
28
1
2
*
3
* Options specific to the behavior of this module
4
*
5
+ * - `raop.latency.ms` = latency for all streams in microseconds. This
6
+ * can be overwritten in the stream rules.
7
* - `stream.rules` = <rules>: match rules, use create-stream actions. See
8
* \ref page_module_raop_sink for module properties.
9
*
10
11
* context.modules =
12
* { name = libpipewire-raop-discover
13
* args = {
14
+ * #raop.latency.ms = 1000
15
* stream.rules =
16
* { matches =
17
* { raop.ip = "~.*"
18
19
avahi_free(value);
20
}
21
22
+ if ((str = pw_properties_get(impl->properties, "raop.latency.ms")) != NULL)
23
+ pw_properties_set(props, "raop.latency.ms", str);
24
+
25
if ((str = pw_properties_get(impl->properties, "stream.rules")) == NULL)
26
str = DEFAULT_CREATE_RULES;
27
if (str != NULL) {
28
pipewire-0.3.72.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.74.tar.gz/src/modules/module-raop-sink.c
Changed
154
1
2
#include <spa/param/audio/raw.h>
3
#include <spa/param/latency-utils.h>
4
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/impl.h>
7
#include <pipewire/i18n.h>
8
9
10
pkt0 |= htonl(0x10000000);
11
pkt1 = htonl(rtptime - latency);
12
transmitted = ntp_now();
13
- pkt2 = htonl(transmitted >> 32);
14
+ pkt2 = htonl((transmitted >> 32) & 0x0000ffff);
15
pkt3 = htonl(transmitted & 0xffffffff);
16
pkt4 = htonl(rtptime);
17
18
19
size_t len;
20
uint64_t ntp;
21
uint16_t control_port, timing_port;
22
+ int res;
23
24
pw_log_info("reply %d", status);
25
26
27
return 0;
28
}
29
30
- if (pw_getrandom(&impl->seq, sizeof(impl->seq), 0) < 0 ||
31
- pw_getrandom(&impl->rtptime, sizeof(impl->rtptime), 0) < 0) {
32
- pw_log_error("error generating random seq and rtptime: %m");
33
+ if ((res = pw_getrandom(&impl->seq, sizeof(impl->seq), 0)) < 0 ||
34
+ (res = pw_getrandom(&impl->rtptime, sizeof(impl->rtptime), 0)) < 0) {
35
+ pw_log_error("error generating random seq and rtptime: %s", spa_strerror(res));
36
return 0;
37
}
38
39
40
char key512*2;
41
char iv16*2;
42
int res, frames, rsa_len, ip_version;
43
- char *sdp;
44
+ spa_autofree char *sdp = NULL;
45
char local_ip256;
46
host = pw_properties_get(impl->props, "raop.ip");
47
48
49
break;
50
51
case CRYPTO_RSA:
52
- if (pw_getrandom(impl->key, sizeof(impl->key), 0) < 0 ||
53
- pw_getrandom(impl->iv, sizeof(impl->iv), 0) < 0)
54
- return -errno;
55
+ if ((res = pw_getrandom(impl->key, sizeof(impl->key), 0)) < 0 ||
56
+ (res = pw_getrandom(impl->iv, sizeof(impl->iv), 0)) < 0)
57
+ return res;
58
59
rsa_len = rsa_encrypt(impl->key, 16, rsakey);
60
if (rsa_len < 0)
61
62
default:
63
return -ENOTSUP;
64
}
65
- res = rtsp_send(impl, "ANNOUNCE", "application/sdp", sdp, rtsp_announce_reply);
66
- free(sdp);
67
68
- return res;
69
+ return rtsp_send(impl, "ANNOUNCE", "application/sdp", sdp, rtsp_announce_reply);
70
}
71
72
static int rtsp_auth_setup_reply(void *data, int status, const struct spa_dict *headers)
73
74
static int rtsp_do_auth(struct impl *impl, const struct spa_dict *headers)
75
{
76
const char *str, *realm, *nonce;
77
- char **tokens;
78
int n_tokens;
79
80
if ((str = spa_dict_lookup(headers, "WWW-Authenticate")) == NULL)
81
82
83
pw_log_info("Auth: %s", str);
84
85
- tokens = pw_split_strv(str, " ", INT_MAX, &n_tokens);
86
+ spa_auto(pw_strv) tokens = pw_split_strv(str, " ", INT_MAX, &n_tokens);
87
if (tokens == NULL || tokens0 == NULL)
88
- goto error;
89
+ return -EINVAL;
90
91
impl->auth_method = strdup(tokens0);
92
93
94
realm = find_attr(tokens, "realm");
95
nonce = find_attr(tokens, "nonce");
96
if (realm == NULL || nonce == NULL)
97
- goto error;
98
+ return -EINVAL;
99
100
impl->realm = strdup(realm);
101
impl->nonce = strdup(nonce);
102
}
103
104
- pw_free_strv(tokens);
105
-
106
- rtsp_send(impl, "OPTIONS", NULL, NULL, rtsp_auth_reply);
107
- return 0;
108
-
109
-error:
110
- pw_free_strv(tokens);
111
- return -EINVAL;
112
+ return rtsp_send(impl, "OPTIONS", NULL, NULL, rtsp_auth_reply);
113
}
114
115
static int rtsp_options_reply(void *data, int status, const struct spa_dict *headers)
116
117
uint32_t sci2;
118
uint8_t rac16;
119
char sac16*4;
120
+ int res;
121
122
pw_log_info("connected");
123
124
impl->connected = true;
125
126
- if (pw_getrandom(sci, sizeof(sci), 0) < 0 ||
127
- pw_getrandom(rac, sizeof(rac), 0) < 0) {
128
- pw_log_error("error generating random data: %m");
129
+ if ((res = pw_getrandom(sci, sizeof(sci), 0)) < 0 ||
130
+ (res = pw_getrandom(rac, sizeof(rac), 0)) < 0) {
131
+ pw_log_error("error generating random data: %s", spa_strerror(res));
132
return;
133
}
134
135
136
{
137
const char *hostname, *port;
138
uint32_t session_id;
139
+ int res;
140
141
if (impl->connected) {
142
if (!impl->ready)
143
144
if (hostname == NULL || port == NULL)
145
return -EINVAL;
146
147
- if (pw_getrandom(&session_id, sizeof(session_id), 0) < 0)
148
- return -errno;
149
+ if ((res = pw_getrandom(&session_id, sizeof(session_id), 0)) < 0)
150
+ return res;
151
152
spa_scnprintf(impl->session_id, sizeof(impl->session_id), "%u", session_id);
153
154
pipewire-0.3.72.tar.gz/src/modules/module-rt.c -> pipewire-0.3.74.tar.gz/src/modules/module-rt.c
Changed
212
1
2
* This requires `RLIMIT_RTPRIO` to be set to a value that's equal to this
3
* module's `rt.prio` parameter or higher. Most distros will come with some
4
* package that configures this for certain groups or users. If this is not set
5
- * up and DBus is available, then this module will fall back to using RTKit.
6
+ * up and DBus is available, then this module will fall back to using the Portal
7
+ * Realtime DBus API or RTKit.
8
*
9
* ## Module Options
10
*
11
12
* consume without doing any blocking calls before the kernel kills
13
* the thread. This is a safety measure to avoid lockups of the complete
14
* system when some thread consumes 100%.
15
+ * - `rlimits.enabled`: enable the use of rtlimits, default true.
16
+ * - `rtportal.enabled`: enable the use of realtime portal, default true
17
+ * - `rtkit.enabled`: enable the use of rtkit, default true
18
19
* The nice level is by default set to an invalid value so that clients don't
20
* automatically have the nice level raised.
21
22
* #rt.prio = 88
23
* #rt.time.soft = -1
24
* #rt.time.hard = -1
25
+ * #rlimits.enabled = true
26
+ * #rtportal.enabled = true
27
+ * #rtkit.enabled = true
28
* }
29
* flags = ifexists nofail
30
* }
31
32
#define MAX_NICE_LEVEL 19
33
#define IS_VALID_NICE_LEVEL(l) ((l)>=MIN_NICE_LEVEL && (l)<=MAX_NICE_LEVEL)
34
35
-#define DEFAULT_NICE_LEVEL 20
36
+#define DEFAULT_NICE_LEVEL 20 /* invalid value by default, see above */
37
#define DEFAULT_RT_PRIO_MIN 11
38
#define DEFAULT_RT_PRIO 88
39
#define DEFAULT_RT_TIME_SOFT -1
40
41
42
#define MODULE_USAGE "( nice.level=<priority: default "SPA_STRINGIFY(DEFAULT_NICE_LEVEL)"(don't change)> ) " \
43
"( rt.prio=<priority: default "SPA_STRINGIFY(DEFAULT_RT_PRIO)"> ) " \
44
- "( rt.time.soft=<in usec: default "SPA_STRINGIFY(DEFAULT_RT_TIME_SOFT)" ) " \
45
- "( rt.time.hard=<in usec: default "SPA_STRINGIFY(DEFAULT_RT_TIME_HARD)" ) "
46
+ "( rt.time.soft=<in usec: default "SPA_STRINGIFY(DEFAULT_RT_TIME_SOFT)"> ) " \
47
+ "( rt.time.hard=<in usec: default "SPA_STRINGIFY(DEFAULT_RT_TIME_HARD)"> ) " \
48
+ "( rlimits.enabled=<default true> ) " \
49
+ "( rtportal.enabled=<default true> ) " \
50
+ "( rtkit.enabled=<default true> ) "
51
52
static const struct spa_dict_item module_props = {
53
{ PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
54
55
56
struct spa_hook module_listener;
57
58
+ unsigned rlimits_enabled:1;
59
+ unsigned rtportal_enabled:1;
60
+ unsigned rtkit_enabled:1;
61
+
62
#ifdef HAVE_DBUS
63
bool use_rtkit;
64
/* For D-Bus. These are const static. */
65
66
}
67
68
#ifdef HAVE_DBUS
69
-struct pw_rtkit_bus *pw_rtkit_bus_get(DBusBusType bus_type)
70
+static struct pw_rtkit_bus *pw_rtkit_bus_get(DBusBusType bus_type)
71
{
72
struct pw_rtkit_bus *bus;
73
DBusError error;
74
75
return NULL;
76
}
77
78
-struct pw_rtkit_bus *pw_rtkit_bus_get_system(void)
79
+static struct pw_rtkit_bus *pw_rtkit_bus_get_system(void)
80
{
81
return pw_rtkit_bus_get(DBUS_BUS_SYSTEM);
82
}
83
84
-struct pw_rtkit_bus *pw_rtkit_bus_get_session(void)
85
+static struct pw_rtkit_bus *pw_rtkit_bus_get_session(void)
86
{
87
return pw_rtkit_bus_get(DBUS_BUS_SESSION);
88
}
89
90
-bool pw_rtkit_check_xdg_portal(struct pw_rtkit_bus *system_bus)
91
+static bool pw_rtkit_check_xdg_portal(struct pw_rtkit_bus *system_bus)
92
{
93
if (!dbus_bus_name_has_owner(system_bus->bus, XDG_PORTAL_SERVICE_NAME, NULL)) {
94
pw_log_info("Can't find %s. Is xdg-desktop-portal running?", XDG_PORTAL_SERVICE_NAME);
95
96
return true;
97
}
98
99
-void pw_rtkit_bus_free(struct pw_rtkit_bus *system_bus)
100
+static void pw_rtkit_bus_free(struct pw_rtkit_bus *system_bus)
101
{
102
dbus_connection_close(system_bus->bus);
103
dbus_connection_unref(system_bus->bus);
104
105
return ret;
106
}
107
108
-int pw_rtkit_get_max_realtime_priority(struct impl *impl)
109
+static int pw_rtkit_get_max_realtime_priority(struct impl *impl)
110
{
111
long long retval;
112
int err;
113
114
return err < 0 ? err : retval;
115
}
116
117
-int pw_rtkit_get_min_nice_level(struct impl *impl, int *min_nice_level)
118
+static int pw_rtkit_get_min_nice_level(struct impl *impl, int *min_nice_level)
119
{
120
long long retval;
121
int err;
122
123
return err;
124
}
125
126
-long long pw_rtkit_get_rttime_usec_max(struct impl *impl)
127
+static long long pw_rtkit_get_rttime_usec_max(struct impl *impl)
128
{
129
long long retval;
130
int err;
131
132
return err < 0 ? err : retval;
133
}
134
135
-int pw_rtkit_make_realtime(struct impl *impl, pid_t thread, int priority)
136
+static int pw_rtkit_make_realtime(struct impl *impl, pid_t thread, int priority)
137
{
138
DBusMessage *m = NULL, *r = NULL;
139
dbus_uint64_t pid;
140
141
return ret;
142
}
143
144
-int pw_rtkit_make_high_priority(struct impl *impl, pid_t thread, int nice_level)
145
+static int pw_rtkit_make_high_priority(struct impl *impl, pid_t thread, int nice_level)
146
{
147
DBusMessage *m = NULL, *r = NULL;
148
dbus_uint64_t pid;
149
150
struct sched_param new_sched_params;
151
int try = 0;
152
153
+ if (!impl->rlimits_enabled)
154
+ return false;
155
+
156
while (try++ < 2) {
157
/* We could check `RLIMIT_RTPRIO`, but the BSDs generally don't have
158
* that available, and there are also other ways to use realtime
159
160
}
161
res = pw_rtkit_make_high_priority(impl, 0, nice_level);
162
}
163
- else
164
+ else if (impl->rlimits_enabled)
165
res = sched_set_nice(nice_level);
166
+ else
167
+ res = -ENOTSUP;
168
#else
169
- res = sched_set_nice(nice_level);
170
+ if (impl->rlimits_enabled)
171
+ res = sched_set_nice(nice_level);
172
+ else
173
+ res = -ENOTSUP;
174
#endif
175
176
if (res < 0) {
177
178
impl->rt_prio = pw_properties_get_int32(props, "rt.prio", DEFAULT_RT_PRIO);
179
impl->rt_time_soft = pw_properties_get_int32(props, "rt.time.soft", DEFAULT_RT_TIME_SOFT);
180
impl->rt_time_hard = pw_properties_get_int32(props, "rt.time.hard", DEFAULT_RT_TIME_HARD);
181
+ impl->rlimits_enabled = pw_properties_get_bool(props, "rlimits.enabled", true);
182
+ impl->rtportal_enabled = pw_properties_get_bool(props, "rtportal.enabled", true);
183
+ impl->rtkit_enabled = pw_properties_get_bool(props, "rtkit.enabled", true);
184
185
bool can_use_rtkit = false, use_rtkit = false;
186
187
188
impl->use_rtkit = use_rtkit;
189
if (impl->use_rtkit) {
190
/* Checking xdg-desktop-portal. It works fine in all situations. */
191
- impl->rtkit_bus = pw_rtkit_bus_get_session();
192
+ if (impl->rtportal_enabled)
193
+ impl->rtkit_bus = pw_rtkit_bus_get_session();
194
+ else
195
+ pw_log_info("Portal Realtime disabled");
196
if (impl->rtkit_bus != NULL) {
197
if (pw_rtkit_check_xdg_portal(impl->rtkit_bus)) {
198
impl->service_name = XDG_PORTAL_SERVICE_NAME;
199
200
}
201
/* Failed to get xdg-desktop-portal, try to use rtkit. */
202
if (impl->rtkit_bus == NULL) {
203
- impl->rtkit_bus = pw_rtkit_bus_get_system();
204
+ if (impl->rtkit_enabled)
205
+ impl->rtkit_bus = pw_rtkit_bus_get_system();
206
+ else
207
+ pw_log_info("RTkit disabled");
208
+
209
if (impl->rtkit_bus != NULL) {
210
impl->service_name = RTKIT_SERVICE_NAME;
211
impl->object_path = RTKIT_OBJECT_PATH;
212
pipewire-0.3.72.tar.gz/src/modules/module-rtp-sap.c -> pipewire-0.3.74.tar.gz/src/modules/module-rtp-sap.c
Changed
19
1
2
#define ifr_ifindex ifr_index
3
#endif
4
5
-/** \page page_module_rtp_sap PipeWire Module: Announce and create RTP streams
6
+/** \page page_module_rtp_sap PipeWire Module: SAP Announce and create RTP streams
7
*
8
* The `rtp-sap` module announces RTP streams that match the rules with the
9
* announce-stream action.
10
11
}
12
}
13
}
14
- if ((res = parse_address(str, port, &impl->src_addr, &impl->src_len)) < 0) {
15
+ if ((res = parse_address(str, 0, &impl->src_addr, &impl->src_len)) < 0) {
16
pw_log_error("invalid source.ip %s: %s", str, spa_strerror(res));
17
goto out;
18
}
19
pipewire-0.3.72.tar.gz/src/modules/module-rtp-source.c -> pipewire-0.3.74.tar.gz/src/modules/module-rtp-source.c
Changed
48
1
2
* The `rtp-source` module creates a PipeWire source that receives audio
3
* and midi RTP packets.
4
*
5
+ * This module is usually loaded from the \page page_module_rtp_sap so that the
6
+ * source.ip and source.port and format parameters matches that of the sender.
7
+ *
8
* ## Module Options
9
*
10
* Options specific to the behavior of this module
11
*
12
* - `local.ifname = <str>`: interface name to use
13
+ * - `source.ip = <str>`: the source ip address, default 224.0.0.56
14
+ * - `source.port = <int>`: the source port
15
* - `node.always-process = <bool>`: true to receive even when not running
16
* - `sess.latency.msec = <str>`: target network latency in milliseconds, default 100
17
+ * - `sess.ignore-ssrc = <bool>`: ignore SSRC, default false
18
* - `sess.media = <string>`: the media type audio|midi|opus, default audio
19
* - `stream.props = {}`: properties to be passed to the stream
20
*
21
22
* { name = libpipewire-module-rtp-source
23
* args = {
24
* #local.ifname = eth0
25
+ * #source.ip = 224.0.0.56
26
+ * #source.port = 0
27
* sess.latency.msec = 100
28
+ * #sess.ignore-ssrc = false
29
* #node.always-process = false
30
* #sess.media = "audio"
31
* #audio.format = "S16BE"
32
33
"( source.ip=<source IP address, default:"DEFAULT_SOURCE_IP"> ) " \
34
"source.port=<int, source port> " \
35
"( sess.latency.msec=<target network latency, default "SPA_STRINGIFY(DEFAULT_SESS_LATENCY)"> ) "\
36
+ "( sess.ignore-ssrc=<to ignore SSRC, default false> ) "\
37
"( sess.media=<string, the media type audio|midi|opus, default audio> ) " \
38
"( audio.format=<format, default:"DEFAULT_FORMAT"> ) " \
39
"( audio.rate=<sample rate, default:"SPA_STRINGIFY(DEFAULT_RATE)"> ) " \
40
41
copy_props(impl, props, "sess.max-ptime");
42
copy_props(impl, props, "sess.latency.msec");
43
copy_props(impl, props, "sess.ts-direct");
44
+ copy_props(impl, props, "sess.ignore-ssrc");
45
46
str = pw_properties_get(props, "local.ifname");
47
impl->ifname = str ? strdup(str) : NULL;
48
pipewire-0.3.72.tar.gz/src/modules/module-rtp/audio.c -> pipewire-0.3.74.tar.gz/src/modules/module-rtp/audio.c
Changed
10
1
2
if (impl->have_ssrc && impl->ssrc != hdr->ssrc)
3
goto unexpected_ssrc;
4
impl->ssrc = hdr->ssrc;
5
- impl->have_ssrc = true;
6
+ impl->have_ssrc = !impl->ignore_ssrc;
7
8
seq = ntohs(hdr->sequence_number);
9
if (impl->have_seq && impl->seq != seq) {
10
pipewire-0.3.72.tar.gz/src/modules/module-rtp/midi.c -> pipewire-0.3.74.tar.gz/src/modules/module-rtp/midi.c
Changed
10
1
2
if (impl->have_ssrc && impl->ssrc != hdr->ssrc)
3
goto unexpected_ssrc;
4
impl->ssrc = hdr->ssrc;
5
- impl->have_ssrc = true;
6
+ impl->have_ssrc = !impl->ignore_ssrc;
7
8
seq = ntohs(hdr->sequence_number);
9
if (impl->have_seq && impl->seq != seq) {
10
pipewire-0.3.72.tar.gz/src/modules/module-rtp/opus.c -> pipewire-0.3.74.tar.gz/src/modules/module-rtp/opus.c
Changed
10
1
2
if (impl->have_ssrc && impl->ssrc != hdr->ssrc)
3
goto unexpected_ssrc;
4
impl->ssrc = hdr->ssrc;
5
- impl->have_ssrc = true;
6
+ impl->have_ssrc = !impl->ignore_ssrc;
7
8
seq = ntohs(hdr->sequence_number);
9
if (impl->have_seq && impl->seq != seq) {
10
pipewire-0.3.72.tar.gz/src/modules/module-rtp/stream.c -> pipewire-0.3.74.tar.gz/src/modules/module-rtp/stream.c
Changed
17
1
2
uint32_t ssrc;
3
uint16_t seq;
4
unsigned have_ssrc:1;
5
+ unsigned ignore_ssrc:1;
6
unsigned have_seq:1;
7
uint32_t ts_offset;
8
uint32_t psamples;
9
10
if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL)
11
pw_properties_set(props, PW_KEY_NODE_NETWORK, "true");
12
13
+ impl->ignore_ssrc = pw_properties_get_bool(props, "sess.ignore-ssrc", false);
14
impl->direct_timestamp = pw_properties_get_bool(props, "sess.ts-direct", false);
15
16
if (direction == PW_DIRECTION_INPUT) {
17
pipewire-0.3.72.tar.gz/src/modules/spa/module-device.c -> pipewire-0.3.74.tar.gz/src/modules/spa/module-device.c
Changed
63
1
2
#include <getopt.h>
3
#include <limits.h>
4
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/impl.h>
7
8
#include "spa-device.h"
9
10
int pipewire__module_init(struct pw_impl_module *module, const char *args)
11
{
12
struct pw_properties *props = NULL;
13
- char **argv = NULL;
14
+ spa_auto(pw_strv) argv = NULL;
15
int n_tokens;
16
struct pw_context *context = pw_impl_module_get_context(module);
17
struct pw_impl_device *device;
18
struct device_data *data;
19
- int res;
20
21
PW_LOG_TOPIC_INIT(mod_topic);
22
23
24
25
if (n_tokens == 2) {
26
props = pw_properties_new_string(argv1);
27
- if (props == NULL) {
28
- res = -errno;
29
- goto error_exit_cleanup;
30
- }
31
+ if (props == NULL)
32
+ return -errno;
33
}
34
35
device = pw_spa_device_load(context,
36
37
0,
38
props,
39
sizeof(struct device_data));
40
- if (device == NULL) {
41
- res = -errno;
42
- goto error_exit_cleanup;
43
- }
44
-
45
- pw_free_strv(argv);
46
+ if (device == NULL)
47
+ return -errno;
48
49
data = pw_spa_device_get_user_data(device);
50
data->this = device;
51
52
return 0;
53
54
error_arguments:
55
- res = -EINVAL;
56
pw_log_error("usage: module-spa-device " MODULE_USAGE);
57
- goto error_exit_cleanup;
58
-error_exit_cleanup:
59
- pw_free_strv(argv);
60
- return res;
61
+ return -EINVAL;
62
}
63
pipewire-0.3.72.tar.gz/src/modules/spa/module-node.c -> pipewire-0.3.74.tar.gz/src/modules/spa/module-node.c
Changed
60
1
2
#include <getopt.h>
3
#include <limits.h>
4
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/impl.h>
7
8
#include "spa-node.h"
9
10
int pipewire__module_init(struct pw_impl_module *module, const char *args)
11
{
12
struct pw_properties *props = NULL;
13
- char **argv = NULL;
14
- int n_tokens, res;
15
+ spa_auto(pw_strv) argv = NULL;
16
+ int n_tokens;
17
struct pw_context *context = pw_impl_module_get_context(module);
18
struct pw_impl_node *node;
19
struct node_data *data;
20
21
22
if (n_tokens == 2) {
23
props = pw_properties_new_string(argv1);
24
- if (props == NULL) {
25
- res = -errno;
26
- goto error_exit_cleanup;
27
- }
28
+ if (props == NULL)
29
+ return -errno;
30
}
31
32
node = pw_spa_node_load(context,
33
34
props,
35
sizeof(struct node_data));
36
37
- if (node == NULL) {
38
- res = -errno;
39
- goto error_exit_cleanup;
40
- }
41
-
42
- pw_free_strv(argv);
43
+ if (node == NULL)
44
+ return -errno;
45
46
data = pw_spa_node_get_user_data(node);
47
data->this = node;
48
49
return 0;
50
51
error_arguments:
52
- res = -EINVAL;
53
pw_log_error("usage: module-spa-node " MODULE_USAGE);
54
- goto error_exit_cleanup;
55
-error_exit_cleanup:
56
- pw_free_strv(argv);
57
- return res;
58
+ return -EINVAL;
59
}
60
pipewire-0.3.74.tar.gz/src/pipewire/cleanup.h
Added
23
1
2
+/* PipeWire */
3
+/* SPDX-FileCopyrightText: Copyright © 2023 PipeWire authors */
4
+/* SPDX-License-Identifier: MIT */
5
+
6
+#ifndef PIPEWIRE_CLEANUP_H
7
+#define PIPEWIRE_CLEANUP_H
8
+
9
+#include <spa/utils/cleanup.h>
10
+
11
+#include <pipewire/properties.h>
12
+#include <pipewire/utils.h>
13
+
14
+SPA_DEFINE_AUTOPTR_CLEANUP(pw_properties, struct pw_properties, {
15
+ spa_clear_ptr(*thing, pw_properties_free);
16
+})
17
+
18
+SPA_DEFINE_AUTO_CLEANUP(pw_strv, char **, {
19
+ spa_clear_ptr(*thing, pw_free_strv);
20
+})
21
+
22
+#endif /* PIPEWIRE_CLEANUP_H */
23
pipewire-0.3.72.tar.gz/src/pipewire/conf.c -> pipewire-0.3.74.tar.gz/src/pipewire/conf.c
Changed
193
1
2
#include <spa/utils/string.h>
3
#include <spa/utils/json.h>
4
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/impl.h>
7
#include <pipewire/private.h>
8
9
10
{
11
char pathPATH_MAX;
12
char *tmp_name;
13
- int res, sfd, fd, count = 0;
14
+ spa_autoclose int sfd = -1;
15
+ int res, fd, count = 0;
16
FILE *f;
17
18
if ((sfd = open_write_dir(path, sizeof(path), prefix)) < 0)
19
20
tmp_name = alloca(strlen(name)+5);
21
sprintf(tmp_name, "%s.tmp", name);
22
if ((fd = openat(sfd, tmp_name, O_CLOEXEC | O_CREAT | O_WRONLY | O_TRUNC, 0600)) < 0) {
23
- pw_log_error("can't open file '%s': %m", tmp_name);
24
res = -errno;
25
- goto error;
26
+ pw_log_error("can't open file '%s': %m", tmp_name);
27
+ return res;
28
}
29
30
f = fdopen(fd, "w");
31
32
fclose(f);
33
34
if (renameat(sfd, tmp_name, sfd, name) < 0) {
35
- pw_log_error("can't rename temp file '%s': %m", tmp_name);
36
res = -errno;
37
- goto error;
38
+ pw_log_error("can't rename temp file '%s': %m", tmp_name);
39
+ return res;
40
}
41
- res = 0;
42
+
43
pw_log_info("%p: saved state '%s%s'", conf, path, name);
44
-error:
45
- close(sfd);
46
- return res;
47
+
48
+ return 0;
49
}
50
51
static int conf_load(const char *path, struct pw_properties *conf)
52
{
53
char *data;
54
struct stat sbuf;
55
- int fd, count;
56
+ int count;
57
58
- if ((fd = open(path, O_CLOEXEC | O_RDONLY)) < 0)
59
+ spa_autoclose int fd = open(path, O_CLOEXEC | O_RDONLY);
60
+ if (fd < 0)
61
goto error;
62
63
if (fstat(fd, &sbuf) < 0)
64
- goto error_close;
65
+ goto error;
66
67
if (sbuf.st_size > 0) {
68
if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
69
- goto error_close;
70
+ goto error;
71
72
count = pw_properties_update_string(conf, data, sbuf.st_size);
73
munmap(data, sbuf.st_size);
74
} else {
75
count = 0;
76
}
77
- close(fd);
78
79
pw_log_info("%p: loaded config '%s' with %d items", conf, path, count);
80
81
return 0;
82
83
-error_close:
84
- close(fd);
85
error:
86
pw_log_warn("%p: error loading config '%s': %m", conf, path);
87
return -errno;
88
89
char pathPATH_MAX;
90
char fnamePATH_MAX + 256;
91
int i, res, level = 0;
92
- struct pw_properties *override = NULL;
93
+ spa_autoptr(pw_properties) override = NULL;
94
const char *dname;
95
96
if (name == NULL) {
97
98
}
99
free(entries);
100
}
101
- pw_properties_free(override);
102
+
103
return 0;
104
}
105
106
107
struct data *d = user_data;
108
struct pw_context *context = d->context;
109
struct spa_json it4;
110
- char key512, *s;
111
+ char key512;
112
int res = 0;
113
114
- s = strndup(str, len);
115
+ spa_autofree char *s = strndup(str, len);
116
spa_json_init(&it0, s, len);
117
if (spa_json_enter_array(&it0, &it1) < 0) {
118
pw_log_error("config file error: context.modules is not an array");
119
- res = -EINVAL;
120
- goto exit;
121
+ return -EINVAL;
122
}
123
124
while (spa_json_enter_object(&it1, &it2) > 0) {
125
126
127
d->count++;
128
}
129
-exit:
130
- free(s);
131
+
132
return res;
133
}
134
135
136
struct data *d = user_data;
137
struct pw_context *context = d->context;
138
struct spa_json it4;
139
- char key512, *s;
140
+ char key512;
141
int res = 0;
142
143
- s = strndup(str, len);
144
+ spa_autofree char *s = strndup(str, len);
145
spa_json_init(&it0, s, len);
146
if (spa_json_enter_array(&it0, &it1) < 0) {
147
pw_log_error("config file error: context.objects is not an array");
148
- res = -EINVAL;
149
- goto exit;
150
+ return -EINVAL;
151
}
152
153
while (spa_json_enter_object(&it1, &it2) > 0) {
154
155
break;
156
d->count++;
157
}
158
-exit:
159
- free(s);
160
+
161
return res;
162
}
163
164
165
struct data *d = user_data;
166
struct pw_context *context = d->context;
167
struct spa_json it4;
168
- char key512, *s;
169
+ char key512;
170
int res = 0;
171
172
- s = strndup(str, len);
173
+ spa_autofree char *s = strndup(str, len);
174
spa_json_init(&it0, s, len);
175
if (spa_json_enter_array(&it0, &it1) < 0) {
176
pw_log_error("config file error: context.exec is not an array");
177
- res = -EINVAL;
178
- goto exit;
179
+ return -EINVAL;
180
}
181
182
while (spa_json_enter_object(&it1, &it2) > 0) {
183
184
185
d->count++;
186
}
187
-exit:
188
- free(s);
189
+
190
return res;
191
}
192
193
pipewire-0.3.72.tar.gz/src/pipewire/conf.h -> pipewire-0.3.74.tar.gz/src/pipewire/conf.h
Changed
17
1
2
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */
3
/* SPDX-License-Identifier: MIT */
4
5
+#ifndef PIPEWIRE_CONF_H
6
+#define PIPEWIRE_CONF_H
7
+
8
#include <pipewire/context.h>
9
10
/** \defgroup pw_conf Configuration
11
12
/**
13
* \}
14
*/
15
+
16
+#endif /* PIPEWIRE_CONF_H */
17
pipewire-0.3.72.tar.gz/src/pipewire/context.c -> pipewire-0.3.74.tar.gz/src/pipewire/context.c
Changed
44
1
2
}
3
4
SPA_EXPORT
5
+struct pw_mempool *pw_context_get_mempool(struct pw_context *context)
6
+{
7
+ return context->pool;
8
+}
9
+
10
+SPA_EXPORT
11
const struct pw_properties *pw_context_get_properties(struct pw_context *context)
12
{
13
return context->properties;
14
15
* 8000 and 44100 192000 -> 44100
16
* 11025 and 44100 48000 -> 44100
17
* 44100 and 48000 176400 -> 48000
18
+ * 144 and 44100 48000 88200 96000 -> 48000
19
*/
20
spa_zero(best);
21
/* Don't try to do excessive upsampling by limiting the max rate
22
* for desired < default to default*2. For other rates allow
23
- * a x3 upsample rate max */
24
- limit = rate < def ? def*2 : rate*3;
25
+ * a x3 upsample rate max. For values lower than half of the default,
26
+ * limit to the default. */
27
+ limit = rate < def/2 ? def : rate < def ? def*2 : rate*3;
28
for (i = 0; i < n_rates; i++) {
29
if (infoi.rate >= rate && infoi.rate <= limit)
30
update_nearest_gcd(&best, &infoi);
31
32
if ((t->want_driver && t->active && t->runnable) ||
33
t->always_process) {
34
driver = target;
35
- driver->runnable = true;
36
break;
37
}
38
}
39
if (driver != NULL) {
40
+ driver->runnable = true;
41
/* driver needed for this group */
42
move_to_driver(context, &collect, driver);
43
} else {
44
pipewire-0.3.72.tar.gz/src/pipewire/context.h -> pipewire-0.3.74.tar.gz/src/pipewire/context.h
Changed
11
1
2
/** Get the work queue from the context: Since 0.3.26 */
3
struct pw_work_queue *pw_context_get_work_queue(struct pw_context *context);
4
5
+/** Get the memmory pool from the context: Since 0.3.74 */
6
+struct pw_mempool *pw_context_get_mempool(struct pw_context *context);
7
+
8
/** Iterate the globals of the context. The callback should return
9
* 0 to fetch the next item, any other value stops the iteration and returns
10
* the value. When all callbacks return 0, this function returns 0 when all
11
pipewire-0.3.72.tar.gz/src/pipewire/core.c -> pipewire-0.3.74.tar.gz/src/pipewire/core.c
Changed
44
1
2
{
3
struct pw_core *this = data;
4
pw_log_debug("%p: object %u ping %u", this, id, seq);
5
- pw_core_pong(this->core, id, seq);
6
+ pw_core_pong(this, id, seq);
7
}
8
9
static void core_event_done(void *data, uint32_t id, int seq)
10
11
12
pw_properties_add(properties, &context->properties->dict);
13
14
- p->proxy.core = p;
15
p->context = context;
16
p->properties = properties;
17
p->pool = pw_mempool_new(NULL);
18
- p->core = p;
19
if (user_data_size > 0)
20
p->user_data = SPA_PTROFF(p, sizeof(struct pw_core), void);
21
p->proxy.user_data = p->user_data;
22
23
if (p->conn == NULL)
24
goto error_connection;
25
26
- if ((res = pw_proxy_init(&p->proxy, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE)) < 0)
27
+ if ((res = pw_proxy_init(&p->proxy, p, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE)) < 0)
28
goto error_proxy;
29
30
p->client = (struct pw_client*)pw_proxy_new(&p->proxy,
31
32
SPA_EXPORT
33
int pw_core_disconnect(struct pw_core *core)
34
{
35
+ /*
36
+ * the `proxy` member must be the first because the whole pw_core object is
37
+ * freed via the free() call in pw_proxy_destroy() -> pw_proxy_unref()
38
+ */
39
+ SPA_STATIC_ASSERT(offsetof(struct pw_core, proxy) == 0, "`proxy` member must be first");
40
+
41
pw_log_debug("%p: disconnect", core);
42
if (!core->removed)
43
pw_proxy_remove(&core->proxy);
44
pipewire-0.3.72.tar.gz/src/pipewire/filter.c -> pipewire-0.3.74.tar.gz/src/pipewire/filter.c
Changed
39
1
2
#include <spa/pod/dynamic.h>
3
#include <spa/debug/types.h>
4
5
+#include <pipewire/cleanup.h>
6
#include "pipewire/pipewire.h"
7
#include "pipewire/filter.h"
8
#include "pipewire/private.h"
9
10
impl->info = SPA_NODE_INFO_INIT();
11
impl->info.max_input_ports = UINT32_MAX;
12
impl->info.max_output_ports = UINT32_MAX;
13
- impl->info.flags = impl->process_rt ? SPA_NODE_FLAG_RT : 0;
14
+ impl->info.flags = SPA_NODE_FLAG_RT;
15
+ if (!impl->process_rt || SPA_FLAG_IS_SET(flags, PW_FILTER_FLAG_ASYNC))
16
+ impl->info.flags |= SPA_NODE_FLAG_ASYNC;
17
impl->info.props = &filter->properties->dict;
18
impl->paramsNODE_PropInfo = SPA_PARAM_INFO(SPA_PARAM_PropInfo, 0);
19
impl->paramsNODE_Props = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_WRITE);
20
21
ensure_loop(impl->main_loop, return -EIO);
22
23
if (res < 0) {
24
+ spa_autofree char *value = NULL;
25
va_list args;
26
- char *value;
27
int r;
28
29
va_start(args, error);
30
31
if (filter->proxy)
32
pw_proxy_error(filter->proxy, res, value);
33
filter_set_state(filter, PW_FILTER_STATE_ERROR, res, value);
34
-
35
- free(value);
36
}
37
return res;
38
}
39
pipewire-0.3.72.tar.gz/src/pipewire/filter.h -> pipewire-0.3.74.tar.gz/src/pipewire/filter.h
Changed
15
1
2
* needs to be called. This can be used
3
* when the filter depends on processing
4
* of other filters. */
5
+ PW_FILTER_FLAG_ASYNC = (1 << 5), /**< Buffers will not be dequeued/queued from
6
+ * the realtime process() function. This is
7
+ * assumed when RT_PROCESS is unset but can
8
+ * also be the case when the process() function
9
+ * does a trigger_process() that will then
10
+ * dequeue/queue a buffer from another process()
11
+ * function. since 0.3.73 */
12
};
13
14
enum pw_filter_port_flags {
15
pipewire-0.3.72.tar.gz/src/pipewire/impl-client.c -> pipewire-0.3.74.tar.gz/src/pipewire/impl-client.c
Changed
14
1
2
}
3
4
SPA_EXPORT
5
+struct pw_mempool *pw_impl_client_get_mempool(struct pw_impl_client *client)
6
+{
7
+ return client->pool;
8
+}
9
+
10
+SPA_EXPORT
11
const struct pw_properties *pw_impl_client_get_properties(struct pw_impl_client *client)
12
{
13
return client->properties;
14
pipewire-0.3.72.tar.gz/src/pipewire/impl-client.h -> pipewire-0.3.74.tar.gz/src/pipewire/impl-client.h
Changed
11
1
2
/** Get the global associated with this client */
3
struct pw_global *pw_impl_client_get_global(struct pw_impl_client *client);
4
5
+/** Get the mempool associated with this client, Since 0.3.74 */
6
+struct pw_mempool *pw_impl_client_get_mempool(struct pw_impl_client *client);
7
+
8
/** listen to events from this client */
9
void pw_impl_client_add_listener(struct pw_impl_client *client,
10
struct spa_hook *listener,
11
pipewire-0.3.72.tar.gz/src/pipewire/impl-metadata.c -> pipewire-0.3.74.tar.gz/src/pipewire/impl-metadata.c
Changed
47
1
2
#include <spa/debug/types.h>
3
#include <spa/utils/string.h>
4
5
+#include <pipewire/cleanup.h>
6
#include "pipewire/impl.h"
7
#include "pipewire/private.h"
8
9
10
uint32_t subject, const char *key, const char *type,
11
const char *fmt, ...)
12
{
13
+ spa_autofree char *value = NULL;
14
va_list args;
15
- int n = 0, res;
16
- size_t size = 0;
17
- char *p = NULL;
18
-
19
- va_start(args, fmt);
20
- n = vsnprintf(p, size, fmt, args);
21
- va_end(args);
22
- if (n < 0)
23
- return -errno;
24
-
25
- size = (size_t) n + 1;
26
- p = malloc(size);
27
- if (p == NULL)
28
- return -errno;
29
+ int res;
30
31
va_start(args, fmt);
32
- n = vsnprintf(p, size, fmt, args);
33
+ res = vasprintf(&value, fmt, args);
34
va_end(args);
35
-
36
- if (n < 0) {
37
- free(p);
38
+ if (res < 0)
39
return -errno;
40
- }
41
- res = pw_impl_metadata_set_property(metadata, subject, key, type, p);
42
- free(p);
43
44
- return res;
45
+ return pw_impl_metadata_set_property(metadata, subject, key, type, value);
46
}
47
pipewire-0.3.72.tar.gz/src/pipewire/impl-module.c -> pipewire-0.3.74.tar.gz/src/pipewire/impl-module.c
Changed
61
1
2
3
#include <spa/utils/string.h>
4
5
+#include <pipewire/cleanup.h>
6
#include "pipewire/impl.h"
7
#include "pipewire/private.h"
8
9
10
char *filename;
11
struct dirent *entry;
12
struct stat s;
13
- DIR *dir;
14
int res;
15
16
filename = spa_aprintf("%s/%s.so", path, name);
17
18
if (level <= 0)
19
return NULL;
20
21
- dir = opendir(path);
22
+ spa_autoptr(DIR) dir = opendir(path);
23
if (dir == NULL) {
24
res = -errno;
25
pw_log_warn("could not open %s: %m", path);
26
27
}
28
29
while ((entry = readdir(dir))) {
30
- char *newpath;
31
-
32
if (spa_streq(entry->d_name, ".") || spa_streq(entry->d_name, ".."))
33
continue;
34
35
- newpath = spa_aprintf("%s/%s", path, entry->d_name);
36
+ spa_autofree char *newpath = spa_aprintf("%s/%s", path, entry->d_name);
37
if (newpath == NULL)
38
break;
39
40
- if (stat(newpath, &s) == 0 && S_ISDIR(s.st_mode))
41
+ if (entry->d_type == DT_DIR ||
42
+ (entry->d_type == DT_UNKNOWN && stat(newpath, &s) == 0 && S_ISDIR(s.st_mode))) {
43
filename = find_module(newpath, name, level - 1);
44
-
45
- free(newpath);
46
-
47
- if (filename != NULL)
48
- break;
49
+ if (filename)
50
+ return filename;
51
+ }
52
}
53
54
- closedir(dir);
55
-
56
- return filename;
57
+ return NULL;
58
}
59
60
static int
61
pipewire-0.3.72.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.74.tar.gz/src/pipewire/impl-node.c
Changed
77
1
2
3
pw_impl_node_emit_driver_changed(node, old, driver);
4
5
- pw_impl_node_emit_peer_added(driver, node);
6
pw_impl_node_emit_peer_removed(old, node);
7
+ pw_impl_node_emit_peer_added(driver, node);
8
9
return 0;
10
}
11
12
struct pw_node_activation *na = driver->rt.target.activation;
13
struct spa_io_clock *cl = &na->position.clock;
14
enum spa_log_level level = SPA_LOG_LEVEL_DEBUG;
15
+ int missed;
16
17
- if (ratelimit_test(&driver->rt.rate_limit, nsec, SPA_LOG_LEVEL_DEBUG))
18
+ if ((missed = spa_ratelimit_test(&driver->rt.rate_limit, nsec)) >= 0)
19
level = SPA_LOG_LEVEL_INFO;
20
21
spa_list_for_each(t, &driver->rt.target_list, link) {
22
struct pw_node_activation *a = t->activation;
23
struct pw_node_activation_state *state = &a->state0;
24
25
+ if (t->id == driver->info.id)
26
+ continue;
27
+
28
if (a->status == PW_NODE_ACTIVATION_TRIGGERED ||
29
a->status == PW_NODE_ACTIVATION_AWAKE) {
30
update_xrun_stats(a, nsec / 1000, 0);
31
32
- pw_log(level, "(%s-%u) client too slow! rate:%u/%u pos:%"PRIu64" status:%s",
33
+ pw_log(level, "(%s-%u) client too slow! rate:%u/%u pos:%"PRIu64" status:%s (%u missed)",
34
t->name, t->id,
35
(uint32_t)(cl->rate.num * cl->duration), cl->rate.denom,
36
- cl->position, str_status(a->status));
37
+ cl->position, str_status(a->status),
38
+ missed);
39
}
40
pw_log_debug("(%s-%u) state:%p pending:%d/%d s:%"PRIu64" a:%"PRIu64" f:%"PRIu64
41
" waiting:%"PRIu64" process:%"PRIu64" status:%s sync:%d",
42
43
struct pw_node_activation *da = this->rt.driver_target.activation;
44
struct spa_system *data_system = this->data_system;
45
uint64_t nsec = get_time_ns(data_system);
46
+ int missed;
47
48
update_xrun_stats(a, trigger, delay);
49
50
- if (ratelimit_test(&this->rt.rate_limit, nsec, SPA_LOG_LEVEL_INFO)) {
51
+ if ((missed = spa_ratelimit_test(&this->rt.rate_limit, nsec)) >= 0) {
52
struct spa_fraction rate;
53
if (da) {
54
struct spa_io_clock *cl = &da->position.clock;
55
56
rate = SPA_FRACTION(0,0);
57
}
58
pw_log_info("(%s-%d) XRun! rate:%u/%u count:%u time:%"PRIu64
59
- " delay:%"PRIu64" max:%"PRIu64,
60
+ " delay:%"PRIu64" max:%"PRIu64" (%d missed)",
61
this->name, this->info.id,
62
rate.num, rate.denom, a->xrun_count,
63
- trigger, delay, a->max_delay);
64
+ trigger, delay, a->max_delay,
65
+ missed);
66
}
67
68
pw_context_driver_emit_xrun(this->context, this);
69
70
71
/* remove ourself as a follower from the driver node */
72
spa_list_remove(&node->follower_link);
73
+ pw_impl_node_emit_peer_removed(node->driver_node, node);
74
remove_segment_owner(node->driver_node, node->info.id);
75
76
spa_list_consume(follower, &node->follower_list, follower_link) {
77
pipewire-0.3.72.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.74.tar.gz/src/pipewire/impl-port.c
Changed
33
1
2
spa_list_append(&port->mix_list, &mix->link);
3
port->n_mix++;
4
5
- pw_log_debug("%p: init mix n_mix:%d %d.%d io:%p: (%s)", port,
6
+ pw_log_debug("%p: init mix n_mix:%d %d.%d id:%d peer:%d io:%p: (%s)", port,
7
port->n_mix, port->port_id, mix->port.port_id,
8
- mix->io, spa_strerror(res));
9
+ mix->id, mix->peer_id, mix->io, spa_strerror(res));
10
11
if (port->n_mix == 1) {
12
pw_log_debug("%p: setting port io", port);
13
14
spa_list_remove(&mix->link);
15
port->n_mix--;
16
17
+ pw_log_debug("%p: release mix %d %d.%d", port,
18
+ port->n_mix, port->port_id, mix->port.port_id);
19
+
20
res = pw_impl_port_call_release_mix(port, mix);
21
22
if (port->destroying)
23
24
res != -ENOTSUP)
25
pw_log_warn("can't remove mix port %d: %s", port_id, spa_strerror(res));
26
27
- pw_log_debug("%p: release mix %d %d.%d", port,
28
- port->n_mix, port->port_id, mix->port.port_id);
29
-
30
if (port->n_mix == 0) {
31
pw_log_debug("%p: clearing port io", port);
32
spa_node_port_set_io(node->node,
33
pipewire-0.3.72.tar.gz/src/pipewire/log.h -> pipewire-0.3.74.tar.gz/src/pipewire/log.h
Changed
19
1
2
*/
3
#define PW_LOG_TOPIC_STATIC(var, topic) \
4
static struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \
5
- static struct spa_log_topic *(var) = &(var##__LINE__)
6
+ static struct spa_log_topic *var = &(var##__LINE__)
7
8
/**
9
* Declare a static log topic named \a var.
10
11
*/
12
#define PW_LOG_TOPIC(var, topic) \
13
struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \
14
- struct spa_log_topic *(var) = &(var##__LINE__)
15
+ struct spa_log_topic *var = &(var##__LINE__)
16
17
#define PW_LOG_TOPIC_INIT(var) \
18
spa_log_topic_init(pw_log_get(), var);
19
pipewire-0.3.72.tar.gz/src/pipewire/pipewire.c -> pipewire-0.3.74.tar.gz/src/pipewire/pipewire.c
Changed
66
1
2
#include <spa/support/cpu.h>
3
#include <spa/support/i18n.h>
4
5
+#include <pipewire/cleanup.h>
6
#include "pipewire.h"
7
#include "private.h"
8
+#include "i18n.h"
9
10
#define MAX_SUPPORT 32
11
12
13
parse_pw_debug_env(void)
14
{
15
const char *str;
16
- char **tokens;
17
int n_tokens;
18
- size_t slen;
19
char json1024 = {0};
20
char *pos = json;
21
char *end = pos + sizeof(json) - 1;
22
23
24
str = getenv("PIPEWIRE_DEBUG");
25
26
- if (!str || (slen = strlen(str)) == 0)
27
+ if (!str || !*str)
28
return NULL;
29
30
/* String format is PIPEWIRE_DEBUG=<glob>:<level>,...,
31
32
*/
33
pos += spa_scnprintf(pos, end - pos, " { conn.* = %d },", SPA_LOG_LEVEL_NONE);
34
35
- tokens = pw_split_strv(str, ",", INT_MAX, &n_tokens);
36
+ spa_auto(pw_strv) tokens = pw_split_strv(str, ",", INT_MAX, &n_tokens);
37
if (n_tokens > 0) {
38
int i;
39
for (i = 0; i < n_tokens; i++) {
40
int n_tok;
41
- char **tok;
42
- char *pattern;
43
+ char *tok2;
44
45
- tok = pw_split_strv(tokensi, ":", 2, &n_tok);
46
+ n_tok = pw_split_ip(tokensi, ":", SPA_N_ELEMENTS(tok), tok);
47
if (n_tok == 2 && parse_log_level(tok1, &lvl)) {
48
- pattern = tok0;
49
+ char *pattern = tok0;
50
pos += spa_scnprintf(pos, end - pos, "{ %s = %d },",
51
pattern, lvl);
52
} else if (n_tok == 1 && parse_log_level(tok0, &lvl)) {
53
54
pw_log_warn("Ignoring invalid format in PIPEWIRE_DEBUG: '%s'",
55
tokensi);
56
}
57
-
58
- pw_free_strv(tok);
59
}
60
}
61
- pw_free_strv(tokens);
62
+
63
pos += spa_scnprintf(pos, end - pos, "");
64
return strdup(json);
65
}
66
pipewire-0.3.72.tar.gz/src/pipewire/private.h -> pipewire-0.3.74.tar.gz/src/pipewire/private.h
Changed
99
1
2
#include <spa/support/plugin.h>
3
#include <spa/pod/builder.h>
4
#include <spa/param/latency-utils.h>
5
+#include <spa/utils/ratelimit.h>
6
#include <spa/utils/result.h>
7
#include <spa/utils/type-info.h>
8
9
10
uint32_t clock_force_quantum; /* force a quantum */
11
};
12
13
-struct ratelimit {
14
- uint64_t interval;
15
- uint64_t begin;
16
- unsigned burst;
17
- unsigned n_printed, n_missed;
18
-};
19
-
20
-static inline bool ratelimit_test(struct ratelimit *r, uint64_t now, enum spa_log_level level)
21
-{
22
- if (r->begin + r->interval < now) {
23
- if (r->n_missed)
24
- pw_log(level, "%u events suppressed", r->n_missed);
25
- r->begin = now;
26
- r->n_printed = 0;
27
- r->n_missed = 0;
28
- } else if (r->n_printed >= r->burst) {
29
- r->n_missed++;
30
- return false;
31
- }
32
- r->n_printed++;
33
- return true;
34
-}
35
-
36
#define MAX_PARAMS 32
37
38
struct pw_param {
39
40
#define pw_impl_client_emit_resource_removed(o,r) pw_impl_client_emit(o, resource_removed, 0, r)
41
#define pw_impl_client_emit_busy_changed(o,b) pw_impl_client_emit(o, busy_changed, 0, b)
42
43
-enum spa_node0_event {
44
- SPA_NODE0_EVENT_START = SPA_TYPE_VENDOR_PipeWire,
45
- SPA_NODE0_EVENT_RequestClockUpdate,
46
-};
47
-
48
-enum spa_node0_command {
49
- SPA_NODE0_COMMAND_START = SPA_TYPE_VENDOR_PipeWire,
50
- SPA_NODE0_COMMAND_ClockUpdate,
51
-};
52
-
53
-struct protocol_compat_v2 {
54
- /* v2 typemap */
55
- struct pw_map types;
56
- unsigned int send_types:1;
57
-};
58
-
59
#define pw_impl_core_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct pw_impl_core_events, m, v, ##__VA_ARGS__)
60
61
#define pw_impl_core_emit_destroy(s) pw_impl_core_emit(s, destroy, 0)
62
63
driver */
64
struct spa_list driver_link; /* our link in driver */
65
66
- struct ratelimit rate_limit;
67
+ struct spa_ratelimit rate_limit;
68
} rt;
69
struct spa_fraction target_rate;
70
uint64_t target_quantum;
71
72
struct pw_properties *properties; /**< extra properties */
73
74
struct pw_mempool *pool; /**< memory pool */
75
- struct pw_core *core; /**< proxy for the core object */
76
struct spa_hook core_listener;
77
struct spa_hook proxy_core_listener;
78
79
80
struct spa_node *node, enum spa_direction direction,
81
uint32_t port_id, uint32_t id, int err, const char *debug, ...);
82
83
-const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, const char *type);
84
-
85
-int pw_proxy_init(struct pw_proxy *proxy, const char *type, uint32_t version);
86
+int pw_proxy_init(struct pw_proxy *proxy, struct pw_core *core, const char *type, uint32_t version);
87
88
void pw_proxy_remove(struct pw_proxy *proxy);
89
90
91
void pw_log_init(void);
92
void pw_log_deinit(void);
93
94
-void pw_random_init();
95
+void pw_random_init(void);
96
97
void pw_settings_init(struct pw_context *context);
98
int pw_settings_expose(struct pw_context *context);
99
pipewire-0.3.72.tar.gz/src/pipewire/proxy.c -> pipewire-0.3.74.tar.gz/src/pipewire/proxy.c
Changed
38
1
2
};
3
/** \endcond */
4
5
-int pw_proxy_init(struct pw_proxy *proxy, const char *type, uint32_t version)
6
+int pw_proxy_init(struct pw_proxy *proxy, struct pw_core *core, const char *type, uint32_t version)
7
{
8
int res;
9
10
+ proxy->core = core;
11
proxy->refcount = 1;
12
proxy->type = type;
13
proxy->version = version;
14
15
return NULL;
16
17
this = &impl->this;
18
- this->core = factory->core;
19
20
- if ((res = pw_proxy_init(this, type, version)) < 0)
21
+ if ((res = pw_proxy_init(this, factory->core, type, version)) < 0)
22
goto error_init;
23
24
if (user_data_size > 0)
25
26
}
27
28
SPA_EXPORT
29
-struct pw_core *pw_proxy_get_core(struct pw_proxy *proxy)
30
-{
31
- return proxy->core;
32
-}
33
-
34
-SPA_EXPORT
35
struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy)
36
{
37
if (proxy->core == NULL || proxy->core->conn == NULL)
38
pipewire-0.3.72.tar.gz/src/pipewire/stream.c -> pipewire-0.3.74.tar.gz/src/pipewire/stream.c
Changed
47
1
2
3
#define PW_ENABLE_DEPRECATED
4
5
+#include <pipewire/cleanup.h>
6
#include "pipewire/pipewire.h"
7
#include "pipewire/stream.h"
8
#include "pipewire/private.h"
9
10
struct stream *impl = user_data;
11
struct pw_stream *stream = &impl->this;
12
pw_log_trace_fp("%p: do process", stream);
13
- pw_stream_emit_process(stream);
14
+ if (!impl->disconnecting)
15
+ pw_stream_emit_process(stream);
16
return 0;
17
}
18
19
20
impl->info.flags = SPA_NODE_FLAG_RT;
21
/* if the callback was not marked RT_PROCESS, we will offload
22
* the process callback in the main thread and we are ASYNC */
23
- if (!impl->process_rt)
24
+ if (!impl->process_rt || SPA_FLAG_IS_SET(flags, PW_STREAM_FLAG_ASYNC))
25
impl->info.flags |= SPA_NODE_FLAG_ASYNC;
26
impl->info.props = &stream->properties->dict;
27
impl->paramsNODE_PropInfo = SPA_PARAM_INFO(SPA_PARAM_PropInfo, 0);
28
29
ensure_loop(impl->main_loop, return -EIO);
30
31
if (res < 0) {
32
+ spa_autofree char *value = NULL;
33
va_list args;
34
- char *value;
35
int r;
36
37
va_start(args, error);
38
39
if (stream->proxy)
40
pw_proxy_error(stream->proxy, res, value);
41
stream_set_state(stream, PW_STREAM_STATE_ERROR, res, value);
42
-
43
- free(value);
44
}
45
return res;
46
}
47
pipewire-0.3.72.tar.gz/src/pipewire/stream.h -> pipewire-0.3.74.tar.gz/src/pipewire/stream.h
Changed
15
1
2
* needs to be called. This can be used
3
* when the output of the stream depends
4
* on input from other streams. */
5
+ PW_STREAM_FLAG_ASYNC = (1 << 10), /**< Buffers will not be dequeued/queued from
6
+ * the realtime process() function. This is
7
+ * assumed when RT_PROCESS is unset but can
8
+ * also be the case when the process() function
9
+ * does a trigger_process() that will then
10
+ * dequeue/queue a buffer from another process()
11
+ * function. since 0.3.73 */
12
};
13
14
/** Create a new unconneced \ref pw_stream
15
pipewire-0.3.72.tar.gz/src/pipewire/thread.c -> pipewire-0.3.74.tar.gz/src/pipewire/thread.c
Changed
12
1
2
#include <spa/utils/list.h>
3
4
#include <pipewire/log.h>
5
-
6
-#include "thread.h"
7
+#include <pipewire/private.h>
8
+#include <pipewire/thread.h>
9
10
#define CHECK(expression,label) \
11
do { \
12
pipewire-0.3.72.tar.gz/src/pipewire/utils.c -> pipewire-0.3.74.tar.gz/src/pipewire/utils.c
Changed
62
1
2
#include <pipewire/array.h>
3
#include <pipewire/log.h>
4
#include <pipewire/utils.h>
5
+#include <pipewire/private.h>
6
7
/** Split a string based on delimiters
8
* \param str a string to split
9
10
static inline ssize_t make_random(void *buf, size_t buflen, unsigned int flags)
11
{
12
ssize_t bytes;
13
- int read_errno;
14
15
#ifdef HAVE_GETRANDOM
16
bytes = getrandom(buf, buflen, flags);
17
- if (!(bytes == -1 && errno == ENOSYS))
18
+ if (bytes < 0)
19
+ bytes = -errno;
20
+ if (bytes != -ENOSYS)
21
return bytes;
22
#endif
23
24
int fd = open("/dev/urandom", O_CLOEXEC);
25
if (fd < 0)
26
- return -1;
27
+ return -errno;
28
+
29
bytes = read(fd, buf, buflen);
30
- read_errno = errno;
31
+ if (bytes < 0)
32
+ bytes = -errno;
33
+
34
close(fd);
35
- errno = read_errno;
36
+
37
return bytes;
38
}
39
40
41
ssize_t res;
42
do {
43
res = make_random(buf, buflen, flags);
44
- } while ((res == -1) && (errno == EINTR));
45
- if (res == -1)
46
- return -errno;
47
+ } while (res == -EINTR);
48
+ if (res < 0)
49
+ return res;
50
if ((size_t)res != buflen)
51
return -ENODATA;
52
return res;
53
54
}
55
}
56
57
-void pw_random_init()
58
+void pw_random_init(void)
59
{
60
unsigned int seed;
61
if (pw_getrandom(&seed, sizeof(seed), 0) < 0) {
62
pipewire-0.3.72.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.74.tar.gz/src/tools/pw-cat.c
Changed
111
1
2
#include <spa/utils/json.h>
3
#include <spa/debug/types.h>
4
5
+#include <pipewire/cleanup.h>
6
#include <pipewire/pipewire.h>
7
#include <pipewire/i18n.h>
8
#include <pipewire/extensions/metadata.h>
9
10
static int parse_channelmap(const char *channel_map, struct channelmap *map)
11
{
12
int i, nch;
13
- char **ch;
14
15
SPA_FOR_EACH_ELEMENT_VAR(maps, m) {
16
if (spa_streq(m->name, channel_map)) {
17
18
}
19
}
20
21
- ch = pw_split_strv(channel_map, ",", SPA_AUDIO_MAX_CHANNELS, &nch);
22
+ spa_auto(pw_strv) ch = pw_split_strv(channel_map, ",", SPA_AUDIO_MAX_CHANNELS, &nch);
23
if (ch == NULL)
24
return -1;
25
26
27
int c = find_channel(chi);
28
map->channelsi = c;
29
}
30
- pw_free_strv(ch);
31
+
32
return 0;
33
}
34
35
36
*s == '\0')
37
continue;
38
39
- pw_properties_set(data->props, tablec, s);
40
+ if (pw_properties_get(data->props, tablec) == NULL)
41
+ pw_properties_set(data->props, tablec, s);
42
}
43
44
spa_zero(sfi);
45
46
spa_zero(fi);
47
fi.format = sfi.format;
48
if (sf_command(data->file, SFC_GET_FORMAT_INFO, &fi, sizeof(fi)) == 0 && fi.name)
49
- pw_properties_set(data->props, PW_KEY_MEDIA_FORMAT, fi.name);
50
+ if (pw_properties_get(data->props, PW_KEY_MEDIA_FORMAT) == NULL)
51
+ pw_properties_set(data->props, PW_KEY_MEDIA_FORMAT, fi.name);
52
53
s = pw_properties_get(data->props, PW_KEY_MEDIA_TITLE);
54
t = pw_properties_get(data->props, PW_KEY_MEDIA_ARTIST);
55
if (s && t)
56
- pw_properties_setf(data->props, PW_KEY_MEDIA_NAME,
57
- "'%s' / '%s'", s, t);
58
+ if (pw_properties_get(data->props, PW_KEY_MEDIA_NAME) == NULL)
59
+ pw_properties_setf(data->props, PW_KEY_MEDIA_NAME,
60
+ "'%s' / '%s'", s, t);
61
62
return 0;
63
}
64
65
const char *s;
66
unsigned int nom = 0;
67
68
- if (data->quality >= 0)
69
+ if (data->quality >= 0 && pw_properties_get(data->props, "resample.quality") == NULL)
70
pw_properties_setf(data->props, "resample.quality", "%d", data->quality);
71
72
- if (data->rate)
73
+ if (data->rate && pw_properties_get(data->props, PW_KEY_NODE_RATE) == NULL)
74
pw_properties_setf(data->props, PW_KEY_NODE_RATE, "1/%u", data->rate);
75
76
data->latency_unit = unit_none;
77
78
if (data->verbose)
79
printf("rate:%d latency:%u (%.3fs)\n",
80
data->rate, nom, data->rate ? (double)nom/data->rate : 0.0f);
81
- if (nom)
82
+ if (nom && pw_properties_get(data->props, PW_KEY_NODE_LATENCY) == NULL)
83
pw_properties_setf(data->props, PW_KEY_NODE_LATENCY, "%u/%u", nom, data->rate);
84
85
return 0;
86
87
}
88
data.filename = argvoptind++;
89
90
- pw_properties_set(data.props, PW_KEY_MEDIA_TYPE, data.media_type);
91
- pw_properties_set(data.props, PW_KEY_MEDIA_CATEGORY, data.media_category);
92
- pw_properties_set(data.props, PW_KEY_MEDIA_ROLE, data.media_role);
93
- pw_properties_set(data.props, PW_KEY_MEDIA_FILENAME, data.filename);
94
- pw_properties_set(data.props, PW_KEY_MEDIA_NAME, data.filename);
95
- pw_properties_set(data.props, PW_KEY_TARGET_OBJECT, data.target);
96
+ if (pw_properties_get(data.props, PW_KEY_MEDIA_TYPE) == NULL)
97
+ pw_properties_set(data.props, PW_KEY_MEDIA_TYPE, data.media_type);
98
+ if (pw_properties_get(data.props, PW_KEY_MEDIA_CATEGORY) == NULL)
99
+ pw_properties_set(data.props, PW_KEY_MEDIA_CATEGORY, data.media_category);
100
+ if (pw_properties_get(data.props, PW_KEY_MEDIA_ROLE) == NULL)
101
+ pw_properties_set(data.props, PW_KEY_MEDIA_ROLE, data.media_role);
102
+ if (pw_properties_get(data.props, PW_KEY_MEDIA_FILENAME) == NULL)
103
+ pw_properties_set(data.props, PW_KEY_MEDIA_FILENAME, data.filename);
104
+ if (pw_properties_get(data.props, PW_KEY_MEDIA_NAME) == NULL)
105
+ pw_properties_set(data.props, PW_KEY_MEDIA_NAME, data.filename);
106
+ if (pw_properties_get(data.props, PW_KEY_TARGET_OBJECT) == NULL)
107
+ pw_properties_set(data.props, PW_KEY_TARGET_OBJECT, data.target);
108
109
/* make a main loop. If you already have another main loop, you can add
110
* the fd of this pipewire mainloop to it. */
111
Refresh
No build results available
Refresh
No rpmlint results available
Login required, please
login
or
signup
in order to comment
Request History
zaitor created request almost 2 years ago
New upstream release
zaitor accepted request almost 2 years ago
Xin