Changes of Revision 4
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Fri Feb 18 14:59:46 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.47
6
+
7
+-------------------------------------------------------------------
8
+Thu Feb 17 13:55:01 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
9
+
10
+- Update to version 0.3.46
11
+
12
+-------------------------------------------------------------------
13
Fri Feb 4 06:41:51 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
14
15
- Update to version 0.3.45
16
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.45
6
+Version: 0.3.47
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.45.tar.gz/pipewire-jack/src/match-rules.c
Deleted
143
1
2
-/* PipeWire
3
- *
4
- * Copyright © 2021 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include <string.h>
27
-#include <stdio.h>
28
-#include <errno.h>
29
-#include <math.h>
30
-#include <time.h>
31
-#include <regex.h>
32
-
33
-#include "config.h"
34
-
35
-#include <spa/utils/json.h>
36
-#include <spa/utils/string.h>
37
-
38
-#include <pipewire/pipewire.h>
39
-
40
-static bool find_match(struct spa_json *arr, const struct spa_dict *props)
41
-{
42
- struct spa_json it[1];
43
-
44
- while (spa_json_enter_object(arr, &it[0]) > 0) {
45
- char key[256], val[1024];
46
- const char *str, *value;
47
- int match = 0, fail = 0;
48
- int len;
49
-
50
- while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
51
- bool success = false;
52
-
53
- if ((len = spa_json_next(&it[0], &value)) <= 0)
54
- break;
55
-
56
- str = spa_dict_lookup(props, key);
57
-
58
- if (spa_json_is_null(value, len)) {
59
- success = str == NULL;
60
- } else {
61
- if (spa_json_parse_stringn(value, len, val, sizeof(val)) < 0)
62
- continue;
63
- value = val;
64
- len = strlen(val);
65
- }
66
- if (str != NULL) {
67
- if (value[0] == '~') {
68
- regex_t preg;
69
- if (regcomp(&preg, value+1, REG_EXTENDED | REG_NOSUB) == 0) {
70
- if (regexec(&preg, str, 0, NULL, 0) == 0)
71
- success = true;
72
- regfree(&preg);
73
- }
74
- } else if (strncmp(str, value, len) == 0 &&
75
- strlen(str) == (size_t)len) {
76
- success = true;
77
- }
78
- }
79
- if (success) {
80
- match++;
81
- pw_log_debug("'%s' match '%s' < > '%.*s'", key, str, len, value);
82
- }
83
- else
84
- fail++;
85
- }
86
- if (match > 0 && fail == 0)
87
- return true;
88
- }
89
- return false;
90
-}
91
-
92
-int pw_jack_match_rules(const char *rules, size_t size, const struct spa_dict *props,
93
- int (*matched) (void *data, const char *action, const char *val, size_t len),
94
- void *data)
95
-{
96
- const char *val;
97
- struct spa_json it[4], actions;
98
- int count = 0;
99
-
100
- spa_json_init(&it[0], rules, size);
101
- if (spa_json_enter_array(&it[0], &it[1]) < 0)
102
- return 0;
103
-
104
- while (spa_json_enter_object(&it[1], &it[2]) > 0) {
105
- char key[64];
106
- bool have_match = false, have_actions = false;
107
-
108
- while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
109
- if (spa_streq(key, "matches")) {
110
- if (spa_json_enter_array(&it[2], &it[3]) < 0)
111
- break;
112
-
113
- have_match = find_match(&it[3], props);
114
- }
115
- else if (spa_streq(key, "actions")) {
116
- if (spa_json_enter_object(&it[2], &actions) > 0)
117
- have_actions = true;
118
- }
119
- else if (spa_json_next(&it[2], &val) <= 0)
120
- break;
121
- }
122
- if (!have_match || !have_actions)
123
- continue;
124
-
125
- while (spa_json_get_string(&actions, key, sizeof(key)) > 0) {
126
- int res, len;
127
- pw_log_debug("action %s", key);
128
-
129
- if ((len = spa_json_next(&actions, &val)) <= 0)
130
- break;
131
-
132
- if (spa_json_is_container(val, len))
133
- len = spa_json_container_len(&actions, val, len);
134
-
135
- if ((res = matched(data, key, val, len)) < 0)
136
- return res;
137
-
138
- count += res;
139
- }
140
- }
141
- return count;
142
-}
143
pipewire-0.3.45.tar.gz/src/modules/module-echo-cancel
Deleted
2
1
-(directory)
2
pipewire-0.3.45.tar.gz/src/modules/module-echo-cancel/aec-null.c
Deleted
66
1
2
-/* PipeWire
3
- *
4
- * Copyright © 2021 Wim Taymans <wim.taymans@gmail.com>
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include "echo-cancel.h"
27
-
28
-struct impl {
29
- uint32_t channels;
30
-};
31
-
32
-static void *null_create(const struct pw_properties *args, const struct spa_audio_info_raw *info)
33
-{
34
- struct impl *impl;
35
- impl = calloc(1, sizeof(struct impl));
36
- impl->channels = info->channels;
37
- return impl;
38
-}
39
-
40
-static void null_destroy(void *ec)
41
-{
42
- free(ec);
43
-}
44
-
45
-static int null_run(void *ec, const float *rec[], const float *play[], float *out[], uint32_t n_samples)
46
-{
47
- struct impl *impl = ec;
48
- uint32_t i;
49
- for (i = 0; i < impl->channels; i++)
50
- memcpy(out[i], rec[i], n_samples * sizeof(float));
51
- return 0;
52
-}
53
-
54
-static const struct echo_cancel_info echo_cancel_null_impl = {
55
- .name = "null",
56
- .info = SPA_DICT_INIT(NULL, 0),
57
- .latency = NULL,
58
-
59
- .create = null_create,
60
- .destroy = null_destroy,
61
-
62
- .run = null_run,
63
-};
64
-
65
-const struct echo_cancel_info *echo_cancel_null = &echo_cancel_null_impl;
66
pipewire-0.3.45.tar.gz/src/modules/module-echo-cancel/aec-webrtc.cpp
Deleted
165
1
2
-/* PipeWire
3
- *
4
- * Copyright © 2021 Wim Taymans <wim.taymans@gmail.com>
5
- * © 2021 Arun Raghavan <arun@asymptotic.io>
6
- *
7
- * Permission is hereby granted, free of charge, to any person obtaining a
8
- * copy of this software and associated documentation files (the "Software"),
9
- * to deal in the Software without restriction, including without limitation
10
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
- * and/or sell copies of the Software, and to permit persons to whom the
12
- * Software is furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice (including the next
15
- * paragraph) shall be included in all copies or substantial portions of the
16
- * Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
- * DEALINGS IN THE SOFTWARE.
25
- */
26
-
27
-#include <memory>
28
-#include <utility>
29
-
30
-#include "echo-cancel.h"
31
-
32
-#include <pipewire/pipewire.h>
33
-
34
-#include <webrtc/modules/audio_processing/include/audio_processing.h>
35
-#include <webrtc/modules/interface/module_common_types.h>
36
-#include <webrtc/system_wrappers/include/trace.h>
37
-
38
-struct impl {
39
- std::unique_ptr<webrtc::AudioProcessing> apm;
40
- spa_audio_info_raw info;
41
- std::unique_ptr<float *[]> play_buffer, rec_buffer, out_buffer;
42
-
43
- impl(std::unique_ptr<webrtc::AudioProcessing> apm, const spa_audio_info_raw& info)
44
- : apm(std::move(apm)),
45
- info(info),
46
- play_buffer(std::make_unique<float *[]>(info.channels)),
47
- rec_buffer(std::make_unique<float *[]>(info.channels)),
48
- out_buffer(std::make_unique<float *[]>(info.channels))
49
- { }
50
-};
51
-
52
-static void *webrtc_create(const struct pw_properties *args, const spa_audio_info_raw *info)
53
-{
54
- bool extended_filter = pw_properties_get_bool(args, "webrtc.extended_filter", true);
55
- bool delay_agnostic = pw_properties_get_bool(args, "webrtc.delay_agnostic", true);
56
- bool high_pass_filter = pw_properties_get_bool(args, "webrtc.high_pass_filter", true);
57
- bool noise_suppression = pw_properties_get_bool(args, "webrtc.noise_suppression", true);
58
- bool voice_detection = pw_properties_get_bool(args, "webrtc.voice_detection", true);
59
-
60
- // Note: AGC seems to mess up with Agnostic Delay Detection, especially with speech,
61
- // result in very poor performance, disable by default
62
- bool gain_control = pw_properties_get_bool(args, "webrtc.gain_control", false);
63
-
64
- // Disable experimental flags by default
65
- bool experimental_agc = pw_properties_get_bool(args, "webrtc.experimental_agc", false);
66
- bool experimental_ns = pw_properties_get_bool(args, "webrtc.experimental_ns", false);
67
-
68
- // FIXME: Intelligibility enhancer is not currently supported
69
- // This filter will modify playback buffer (when calling ProcessReverseStream), but now
70
- // playback buffer modifications are discarded.
71
-
72
- webrtc::Config config;
73
- config.Set<webrtc::ExtendedFilter>(new webrtc::ExtendedFilter(extended_filter));
74
- config.Set<webrtc::DelayAgnostic>(new webrtc::DelayAgnostic(delay_agnostic));
75
- config.Set<webrtc::ExperimentalAgc>(new webrtc::ExperimentalAgc(experimental_agc));
76
- config.Set<webrtc::ExperimentalNs>(new webrtc::ExperimentalNs(experimental_ns));
77
-
78
- webrtc::ProcessingConfig pconfig = {{
79
- webrtc::StreamConfig(info->rate, info->channels, false), /* input stream */
80
- webrtc::StreamConfig(info->rate, info->channels, false), /* output stream */
81
- webrtc::StreamConfig(info->rate, info->channels, false), /* reverse input stream */
82
- webrtc::StreamConfig(info->rate, info->channels, false), /* reverse output stream */
83
- }};
84
-
85
- auto apm = std::unique_ptr<webrtc::AudioProcessing>(webrtc::AudioProcessing::Create(config));
86
- if (apm->Initialize(pconfig) != webrtc::AudioProcessing::kNoError) {
87
- pw_log_error("Error initialising webrtc audio processing module");
88
- return nullptr;
89
- }
90
-
91
- apm->high_pass_filter()->Enable(high_pass_filter);
92
- // Always disable drift compensation since it requires drift sampling
93
- apm->echo_cancellation()->enable_drift_compensation(false);
94
- apm->echo_cancellation()->Enable(true);
95
- // TODO: wire up supression levels to args
96
- apm->echo_cancellation()->set_suppression_level(webrtc::EchoCancellation::kHighSuppression);
97
- apm->noise_suppression()->set_level(webrtc::NoiseSuppression::kHigh);
98
- apm->noise_suppression()->Enable(noise_suppression);
99
- apm->voice_detection()->Enable(voice_detection);
100
- // TODO: wire up AGC parameters to args
101
- apm->gain_control()->set_analog_level_limits(0, 255);
102
- apm->gain_control()->set_mode(webrtc::GainControl::kAdaptiveDigital);
103
- apm->gain_control()->Enable(gain_control);
104
-
105
- return new impl(std::move(apm), *info);
106
-}
107
-
108
-static void webrtc_destroy(void *ec)
109
-{
110
- auto impl = static_cast<struct impl *>(ec);
111
-
112
- delete impl;
113
-}
114
-
115
-static int webrtc_run(void *ec, const float *rec[], const float *play[], float *out[], uint32_t n_samples)
116
-{
117
- auto impl = static_cast<struct impl *>(ec);
118
- webrtc::StreamConfig config =
119
- webrtc::StreamConfig(impl->info.rate, impl->info.channels, false);
120
- unsigned int num_blocks = n_samples * 1000 / impl->info.rate / 10;
121
-
122
- if (n_samples * 1000 / impl->info.rate % 10 != 0) {
123
- pw_log_error("Buffers must be multiples of 10ms in length (currently %u samples)", n_samples);
124
- return -1;
125
- }
126
-
127
- for (size_t i = 0; i < num_blocks; i ++) {
128
- for (size_t j = 0; j < impl->info.channels; j++) {
129
- impl->play_buffer[j] = const_cast<float *>(play[j]) + config.num_frames() * i;
130
- impl->rec_buffer[j] = const_cast<float *>(rec[j]) + config.num_frames() * i;
131
- impl->out_buffer[j] = out[j] + config.num_frames() * i;
132
- }
133
- /* FIXME: ProcessReverseStream may change the playback buffer, in which
134
- * case we should use that, if we ever expose the intelligibility
135
- * enhancer */
136
- if (impl->apm->ProcessReverseStream(impl->play_buffer.get(), config, config, impl->play_buffer.get()) !=
137
- webrtc::AudioProcessing::kNoError) {
138
- pw_log_error("Processing reverse stream failed");
139
- }
140
-
141
- // Extra delay introduced by multiple frames
142
- impl->apm->set_stream_delay_ms((num_blocks - 1) * 10);
143
-
144
- if (impl->apm->ProcessStream(impl->rec_buffer.get(), config, config, impl->out_buffer.get()) !=
145
- webrtc::AudioProcessing::kNoError) {
146
- pw_log_error("Processing stream failed");
147
- }
148
- }
149
-
150
- return 0;
151
-}
152
-
153
-static const struct echo_cancel_info echo_cancel_webrtc_impl = {
154
- .name = "webrtc",
155
- .info = SPA_DICT_INIT(NULL, 0),
156
- .latency = "480/48000",
157
-
158
- .create = webrtc_create,
159
- .destroy = webrtc_destroy,
160
-
161
- .run = webrtc_run,
162
-};
163
-
164
-const struct echo_cancel_info *echo_cancel_webrtc = &echo_cancel_webrtc_impl;
165
pipewire-0.3.45.tar.gz/src/modules/module-echo-cancel/echo-cancel.h
Deleted
52
1
2
-/* PipeWire
3
- *
4
- * Copyright © 2021 Wim Taymans <wim.taymans@gmail.com>
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include "config.h"
27
-
28
-#include <spa/utils/dict.h>
29
-#include <spa/param/audio/raw.h>
30
-
31
-#include <pipewire/properties.h>
32
-
33
-struct echo_cancel_info {
34
- const char *name;
35
- const struct spa_dict info;
36
- const char *latency;
37
-
38
- void *(*create) (const struct pw_properties *args, const struct spa_audio_info_raw *info);
39
- void (*destroy) (void *ec);
40
-
41
- int (*run) (void *ec, const float *rec[], const float *play[], float *out[], uint32_t n_samples);
42
-};
43
-
44
-#define echo_cancel_create(i,...) (i)->create(__VA_ARGS__)
45
-#define echo_cancel_destroy(i,...) (i)->destroy(__VA_ARGS__)
46
-#define echo_cancel_run(i,...) (i)->run(__VA_ARGS__)
47
-
48
-#ifdef HAVE_WEBRTC
49
-extern const struct echo_cancel_info *echo_cancel_webrtc;
50
-#endif
51
-extern const struct echo_cancel_info *echo_cancel_null;
52
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/media-roles.c
Deleted
42
1
2
-/* PipeWire
3
- *
4
- * Copyright © 2020 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#include <stddef.h>
27
-
28
-#include "media-roles.h"
29
-
30
-const struct str_map media_role_map[] = {
31
- { "Movie", "video", },
32
- { "Music", "music", },
33
- { "Game", "game", },
34
- { "Notification", "event", },
35
- { "Communication", "phone", },
36
- { "Movie", "animation", },
37
- { "Production", "production", },
38
- { "Accessibility", "a11y", },
39
- { "Test", "test", },
40
- { NULL, NULL },
41
-};
42
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/media-roles.h
Deleted
52
1
2
-/* PipeWire
3
- *
4
- * Copyright © 2020 Wim Taymans
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a
7
- * copy of this software and associated documentation files (the "Software"),
8
- * to deal in the Software without restriction, including without limitation
9
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- * and/or sell copies of the Software, and to permit persons to whom the
11
- * Software is furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice (including the next
14
- * paragraph) shall be included in all copies or substantial portions of the
15
- * Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
- * DEALINGS IN THE SOFTWARE.
24
- */
25
-
26
-#ifndef PULSE_SERVER_MEDIA_ROLES_H
27
-#define PULSE_SERVER_MEDIA_ROLES_H
28
-
29
-#include <stddef.h>
30
-
31
-#include <spa/utils/string.h>
32
-
33
-struct str_map {
34
- const char *pw_str;
35
- const char *pa_str;
36
- const struct str_map *child;
37
-};
38
-
39
-extern const struct str_map media_role_map[];
40
-
41
-static inline const struct str_map *str_map_find(const struct str_map *map, const char *pw, const char *pa)
42
-{
43
- size_t i;
44
- for (i = 0; map[i].pw_str; i++)
45
- if ((pw && spa_streq(map[i].pw_str, pw)) ||
46
- (pa && spa_streq(map[i].pa_str, pa)))
47
- return &map[i];
48
- return NULL;
49
-}
50
-
51
-#endif /* PULSE_SERVER_MEDIA_ROLES_H */
52
pipewire-0.3.45.tar.gz/.gitlab-ci.yml -> pipewire-0.3.47.tar.gz/.gitlab-ci.yml
Changed
19
1
2
.fedora:
3
variables:
4
# Update this tag when you want to trigger a rebuild
5
- FDO_DISTRIBUTION_TAG: '2022-01-28.0'
6
+ FDO_DISTRIBUTION_TAG: '2022-02-16.0'
7
FDO_DISTRIBUTION_VERSION: '35'
8
FDO_DISTRIBUTION_PACKAGES: >-
9
alsa-lib-devel
10
11
FDO_DISTRIBUTION_EXEC: >-
12
mkdir -p /opt ;
13
cd /opt ;
14
- curl -o /tmp/cov-analysis-linux64.tgz https://scan.coverity.com/download/linux64
15
+ curl -o /tmp/cov-analysis-linux64.tgz https://scan.coverity.com/download/cxx/linux64
16
--form project=$COVERITY_SCAN_PROJECT_NAME --form token=$COVERITY_SCAN_TOKEN ;
17
tar xf /tmp/cov-analysis-linux64.tgz ;
18
mv cov-analysis-linux64-* coverity ;
19
pipewire-0.3.45.tar.gz/NEWS -> pipewire-0.3.47.tar.gz/NEWS
Changed
122
1
2
+# PipeWire 0.3.47 (2022-02-18)
3
+
4
+This is a bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+This is a quick emergency release to fix some severe
8
+problems with the previous release.
9
+
10
+## Highlights
11
+ - Fixes a bug in pulse-server that caused cached notifications
12
+ to play multiple times. (#2142)
13
+ - Removed check and warnings to catch leaked listeners on the
14
+ proxy. This might access invalid memory and cause infinite
15
+ loops in older wireplumber.
16
+
17
+Older versions:
18
+
19
+# PipeWire 0.3.46 (2022-02-17)
20
+
21
+This is a bugfix release that is API and ABI compatible with previous
22
+0.3.x releases.
23
+
24
+## Highlights
25
+ - Fix a critical bug in pipewire-pulse buffer size handling that made some
26
+ apps (MuseScore, ... ) stutter.
27
+ - Fix a critical bug where devices would not show when the kernel was
28
+ compiled without VERBOSE_PROCSFS.
29
+ - JACK clients will now use lock-quantum by default. This makes sure that
30
+ all dynamic quantum changes are disabled while a JACK app is running.
31
+ The only way to force a quantum chance is through a JACK app or with
32
+ the metadata.
33
+ - Almost all limits on number of ports, clients and nodes are removed.
34
+ - A Dummy fallback sink is now automatically created when there are no
35
+ other sinks. This avoids stalling browsers.
36
+ - Sound sharing with Zoom should work better. A new WirePlumber release
37
+ might be required.
38
+ - Many more fixes and improvements.
39
+
40
+
41
+## PipeWire
42
+ - Update docs with new config overrides.
43
+ - The rule matching logic was moved to config and code is now shared with
44
+ pulse-server and JACK.
45
+ - Add new Romanian translation.
46
+ - When a quantum is forced with metadata, any node that asked to lock-quantum
47
+ is ignored so that the quantum change can happen.
48
+ - Fix a bug where a mixer was removed twice, leading to potential memory
49
+ corruption.
50
+ - The port limits on nodes and filters are now removed. Some code was
51
+ simplified.
52
+ - Fix a potential leak because listeners where removed while they could be
53
+ emitted.
54
+ - Improve context.exec and avoid zombie processes.
55
+
56
+## Modules
57
+ - The RAOP module now has a default latency of 2 seconds, like PulseAudio.
58
+ - The echo-cancel module now uses the plugin loader to load the backends.
59
+ This makes it possible to add custom, out of tree, echo cancel plugins.
60
+
61
+## Tools
62
+ - Improve help of pw-link.
63
+ - Output to stdout and error to stderr. Use setlinebuf for stdout to improve
64
+ piping between apps. (#2110)
65
+
66
+## SPA
67
+ - Improve removing sources when dispatching. Also improve performance now
68
+ that a destroy loop can be removed. (#2114)
69
+ - Fix an fd leak in the logger when logging to a file.
70
+ - Improve loop enter/leave checks and support recursive loops.
71
+
72
+## pulse-server
73
+ - Clamp various buffer attributes to the max length. Fixes some issues
74
+ with various applications. (#2100)
75
+ - Module properties are now remapped correctly from their pulseaudio variant
76
+ to the PipeWire ones.
77
+ - Fix module index in introspect. Use the right index when loaded from our
78
+ internal modules. (#2101)
79
+ - Improve argument parsing and node.description. (#2086)
80
+ - The sink-index should now be filled in correctly when playing a sample.
81
+ (#2129)
82
+ - module-always-sink is now implemented and loaded by default. (#1838)
83
+ - Add support for loading some modules only once.
84
+ - Module load and unload now does extra sync to make it appear synchronous,
85
+ like in PulseAudio. This improves sounds sharing in Zoom.
86
+
87
+## ALSA
88
+ - Fix critial bug where alsa devices would not show when the kernel was
89
+ compiled without VERBOSE_PROCFS.
90
+ - Some corner cases were fixed in the ALSA timing code. When the capture node
91
+ is follower, it will now not try to read too much data and xrun but it will
92
+ instead produce a cycle of silence.
93
+ - Various fixes and improvements to make ALSA devices resync to the driver
94
+ more quickly and accurately.
95
+
96
+## JACK
97
+ - Add an option to name the defauld device as `system` to improve
98
+ compatibility with some applications,
99
+ - Use lock-quantum by default. This makes sure that all dynamic quantum
100
+ changes are disabled while a JACK app is running. The only way to force
101
+ a quantum chance is through a JACK app or with the metadata.
102
+ - It is now possible to do IPC calls from the data thread. Note that this
103
+ is a very bad idea but required for compatibility with JACK2.
104
+
105
+## GStreamer
106
+ - GStreamer sink will now set a default channelmap to make it possible to
107
+ remap to the channel layout of the device.
108
+
109
# PipeWire 0.3.45 (2022-02-03)
110
111
This is a bugfix release that is API and ABI compatible with previous
112
113
switch quantum and ensure it can't change for the lifetime of the JACK
114
app. (#2079)
115
116
-Older versions:
117
-
118
-
119
# PipeWire 0.3.44 (2022-01-27)
120
121
This is a bugfix release that is API and ABI compatible with previous
122
pipewire-0.3.45.tar.gz/doc/pipewire-daemon.dox -> pipewire-0.3.47.tar.gz/doc/pipewire-daemon.dox
Changed
22
1
2
- `$sysconfdir/pipewire/pipewire.conf` (usually `/etc/pipewire/pipewire.conf`)
3
- `$datadir/pipewire/pipewire.conf` (usually `/usr/share/pipewire/pipewire.conf`)
4
5
-The first configuration file found is loaded, the PipeWire daemon does not
6
-currently combine configuration files.
7
+The first configuration file found is loaded as the base configuration.
8
+
9
+Next, configuration sections are collected in the directories in this
10
+order:
11
+
12
+- `$datadir/pipewire/pipewire.conf.d/` (usually `/usr/share/pipewire/pipewire.conf.d/`)
13
+- `$sysconfdir/pipewire/pipewire.conf.d/` (usually `/etc/pipewire/pipewire.conf.d/`)
14
+- `$XDG_CONFIG_HOME/pipewire/pipewire.conf.d/` (usually `$HOME/.config/pipewire/pipewire.conf.d/`)
15
+
16
+They are applied to the global configuration file. Properties are overwritten
17
+and array elements are appended. This makes it possible to make small custom customizations
18
+or additions to the main configuration file.
19
20
The environment variables `PIPEWIRE_CONFIG_DIR`, `PIPEWIRE_CONFIG_PREFIX`
21
and `PIPEWIRE_CONFIG_NAME` can be used to specify an alternative config
22
pipewire-0.3.45.tar.gz/doc/pipewire-modules.dox -> pipewire-0.3.47.tar.gz/doc/pipewire-modules.dox
Changed
9
1
2
- \subpage page_module_echo_cancel
3
- \subpage page_module_example_sink
4
- \subpage page_module_example_source
5
+- \subpage page_module_fallback_sink
6
- \subpage page_module_filter_chain
7
- \subpage page_module_link_factory
8
- \subpage page_module_loopback
9
pipewire-0.3.45.tar.gz/man/meson.build -> pipewire-0.3.47.tar.gz/man/meson.build
Changed
10
1
2
'pw-profiler.1.rst.in',
3
]
4
5
-if not get_option('pipewire-jack').disabled()
6
+if get_option('pipewire-jack').allowed()
7
manpages += 'pw-jack.1.rst.in'
8
endif
9
10
pipewire-0.3.45.tar.gz/man/pipewire.conf.5.rst.in -> pipewire-0.3.47.tar.gz/man/pipewire.conf.5.rst.in
Changed
54
1
2
3
*@PIPEWIRE_CONFDATADIR@/pipewire.conf*
4
5
+*@PIPEWIRE_CONFDATADIR@/pipewire.conf.d/*
6
+
7
+*@PIPEWIRE_CONFIG_DIR@/pipewire.conf.d/*
8
+
9
+*$XDG_CONFIG_HOME/pipewire/pipewire.conf.d/*
10
+
11
DESCRIPTION
12
===========
13
14
PipeWire is a service that facilitates sharing of multimedia content
15
between devices and applications.
16
17
-On startup, the daemon reads a configuration file to configure
18
+On startup, the daemon reads a main configuration file to configure
19
itself. It executes a series of commands listed in the config
20
file.
21
22
23
and ``PIPEWIRE_CONFIG_NAME`` can be used to specify an alternative config
24
directory, subdirectory and file respectively.
25
26
+Next to the configuration file can be a directory with the same name as
27
+the file with a ``.d/`` suffix. All directories in the SYNOPSIS_ directory
28
+search paths are traversed in the listed order and the contents of the
29
+``*.conf`` files inside them are appended to the main configuration file
30
+as overrides. Object sections are merged and array sections are appended.
31
+
32
+
33
CONFIGURATION FILE FORMAT
34
=========================
35
36
37
38
name = [ { k = v1 } { k = v2 } ] # an array of dictionaries
39
40
+
41
+The configuration files can be expressed in full JSON syntax but for ease
42
+of use, a relaxed format may be used where:
43
+
44
+ * ``:`` to delimit keys and values can be substuted by ``=`` or a space.
45
+ * ``"`` around keys and string can be omited as long as no special characters
46
+ are used in the strings.
47
+ * ``,`` to separate objects can be replaced with a whitespace character.
48
+ * ``#`` can be used to start a comment until the line end
49
+
50
+
51
CONFIGURATION FILE SECTIONS
52
===========================
53
54
pipewire-0.3.45.tar.gz/meson.build -> pipewire-0.3.47.tar.gz/meson.build
Changed
240
1
2
project('pipewire', ['c' ],
3
- version : '0.3.45',
4
+ version : '0.3.47',
5
license : [ 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ],
6
meson_version : '>= 0.59.0',
7
default_options : [ 'warning_level=3',
8
9
cdata.set_quoted('PIPEWIRE_CONFIG_DIR', pipewire_configdir)
10
cdata.set_quoted('PLUGINDIR', spa_plugindir)
11
cdata.set_quoted('SPADATADIR', spa_datadir)
12
-# FIXME: --with-memory-alignment],[8,N,malloc,pagesize (default is 32)]) option
13
-cdata.set('MEMORY_ALIGNMENT_MALLOC', 1)
14
cdata.set_quoted('PA_ALSA_PATHS_DIR', alsadatadir / 'paths')
15
cdata.set_quoted('PA_ALSA_PROFILE_SETS_DIR', alsadatadir / 'profile-sets')
16
17
18
cdata.set('WORDS_BIGENDIAN', 1)
19
endif
20
21
-check_headers = [['dlfcn.h','HAVE_DLFCN_H'],
22
- ['inttypes.h', 'HAVE_INTTYPES_H'],
23
- ['memory.h', 'HAVE_MEMORY_H'],
24
- ['poll.h', 'HAVE_POLL_H'],
25
- ['stddef.h', 'HAVE_STDDEF_H'],
26
- ['stdint.h', 'HAVE_STDINT_H'],
27
- ['stdio_ext.h', 'HAVE_STDIO_EXT_H'],
28
- ['strings.h', 'HAVE_STRINGS_H'],
29
- ['string.h', 'HAVE_STRING_H'],
30
+check_headers = [
31
['sys/mount.h', 'HAVE_SYS_MOUNT_H'],
32
['sys/param.h', 'HAVE_SYS_PARAM_H'],
33
- ['sys/poll.h', 'HAVE_SYS_POLL_H'],
34
- ['sys/prctl.h', 'HAVE_SYS_PRCTL_H'],
35
['sys/random.h', 'HAVE_SYS_RANDOM_H'],
36
- ['sys/socket.h', 'HAVE_SYS_SOCKET_H'],
37
- ['sys/stat.h', 'HAVE_SYS_STAT_H'],
38
- ['sys/times.h', 'HAVE_SYS_TIMES_H'],
39
- ['sys/time.h', 'HAVE_SYS_TIME_H'],
40
- ['sys/types.h', 'HAVE_SYS_TYPES_H'],
41
- ['sys/utsname.h', 'HAVE_SYS_UTSNAME_H'],
42
['sys/vfs.h', 'HAVE_SYS_VFS_H'],
43
- ['sys/wait.h', 'HAVE_SYS_WAIT_H'],
44
['pwd.h', 'HAVE_PWD_H'],
45
- ['ucontext.h', 'HAVE_UCONTEXT_H'],
46
- ['unistd.h', 'HAVE_UNISTD_H'],
47
]
48
49
foreach h : check_headers
50
- if cc.has_header(h.get(0))
51
- cdata.set(h.get(1), 1)
52
- endif
53
+ cdata.set(h.get(1), cc.has_header(h.get(0)))
54
endforeach
55
56
-if cc.has_function('poll', prefix : '#include<poll.h>')
57
- cdata.set('HAVE_POLL', 1)
58
-endif
59
-if cc.has_function('pselect', prefix : '#include<sys/select.h>')
60
- cdata.set('HAVE_PSELECT', 1)
61
-endif
62
-cdata.set('HAVE_MMAP', 1)
63
-
64
-if cc.has_function('posix_memalign', prefix : '#include<stdlib.h>')
65
- cdata.set('HAVE_POSIX_MEMALIGN', 1)
66
-endif
67
-if cc.has_function('getpagesize', prefix : '#include<unistd.h>')
68
- cdata.set('HAVE_GETPAGESIZE', 1)
69
-endif
70
-if cc.has_function('gettid', prefix : '#include<unistd.h>', args: [ '-D_GNU_SOURCE' ])
71
- cdata.set('HAVE_GETTID', 1)
72
-endif
73
-if cc.has_function('clock_gettime', prefix : '#include <time.h>')
74
- cdata.set('HAVE_CLOCK_GETTIME', 1)
75
-endif
76
-
77
-if cc.has_type('ptrdiff_t', prefix : '#include <stddef.h>')
78
- cdata.set('HAVE_PTRDIFF_T', 1)
79
-endif
80
-
81
-if cc.has_header_symbol('string.h', 'strndupa', args : [ '-D_GNU_SOURCE' ])
82
- cdata.set('HAVE_STRNDUPA', 1)
83
-endif
84
-
85
-if cc.has_function('mkstemp', prefix : '#include <stdlib.h>')
86
- cdata.set('HAVE_MKSTEMP', 1)
87
-endif
88
-
89
-if cc.has_function('memfd_create', prefix : '#include <sys/mman.h>', args : [ '-D_GNU_SOURCE' ])
90
- cdata.set('HAVE_MEMFD_CREATE', 1)
91
-endif
92
-
93
-if cc.has_function('getrandom', prefix : '#include <stddef.h>\n#include <sys/random.h>', args : [ '-D_GNU_SOURCE' ])
94
- cdata.set('HAVE_GETRANDOM', 1)
95
-endif
96
+check_functions = [
97
+ ['gettid', '#include <unistd.h>', ['-D_GNU_SOURCE']],
98
+ ['memfd_create', '#include <sys/mman.h>', ['-D_GNU_SOURCE']],
99
+ ['getrandom', '#include <stddef.h>\n#include <sys/random.h>', ['-D_GNU_SOURCE']],
100
+ ['sigabbrev_np', '#include <string.h>', ['-D_GNU_SOURCE']],
101
+]
102
103
-if cc.has_function('sigabbrev_np', prefix : '#include <string.h>', args : [ '-D_GNU_SOURCE' ])
104
- cdata.set('HAVE_SIGABBREV_NP', 1)
105
-endif
106
+foreach f : check_functions
107
+ cdata.set('HAVE_' + f.get(0).to_upper(),
108
+ cc.has_function(f.get(0), prefix: f.get(1), args: f.get(2)))
109
+endforeach
110
111
-if cc.get_define('SYS_pidfd_open', prefix : '#include <sys/syscall.h>') != ''
112
- cdata.set('HAVE_PIDFD_OPEN', 1)
113
-endif
114
+cdata.set('HAVE_PIDFD_OPEN',
115
+ cc.get_define('SYS_pidfd_open', prefix: '#include <sys/syscall.h>') != '')
116
117
systemd = dependency('systemd', required: get_option('systemd'))
118
systemd_dep = dependency('libsystemd',required: get_option('systemd'))
119
summary({'systemd conf data': systemd.found()}, bool_yn: true)
120
summary({'libsystemd': systemd_dep.found()}, bool_yn: true)
121
-if systemd.found() and systemd_dep.found()
122
- cdata.set('HAVE_SYSTEMD', 1)
123
-endif
124
+cdata.set('HAVE_SYSTEMD', systemd.found() and systemd_dep.found())
125
126
configinc = include_directories('.')
127
includes_inc = include_directories('include')
128
129
pthread_lib = dependency('threads')
130
dbus_dep = dependency('dbus-1', required : get_option('dbus'))
131
summary({'dbus (Bluetooth, rt, portal, pw-reserve)': dbus_dep.found()}, bool_yn: true, section: 'Misc dependencies')
132
-if dbus_dep.found()
133
- cdata.set('HAVE_DBUS', 1)
134
-endif
135
+cdata.set('HAVE_DBUS', dbus_dep.found())
136
sdl_dep = dependency('sdl2', required : get_option('sdl2'))
137
summary({'SDL2 (video examples)': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies')
138
drm_dep = dependency('libdrm', required : false)
139
140
ncurses_dep = dependency('ncursesw', required : false)
141
sndfile_dep = dependency('sndfile', version : '>= 1.0.20', required : get_option('sndfile'))
142
summary({'sndfile': sndfile_dep.found()}, bool_yn: true, section: 'pw-cat/pw-play/pw-dump/filter-chain')
143
-if sndfile_dep.found()
144
- cdata.set('HAVE_SNDFILE', 1)
145
-endif
146
+cdata.set('HAVE_SNDFILE', sndfile_dep.found())
147
pulseaudio_dep = dependency('libpulse', required : get_option('libpulse'))
148
summary({'libpulse': pulseaudio_dep.found()}, bool_yn: true, section: 'Streaming between daemons')
149
avahi_dep = dependency('avahi-client', required : get_option('avahi'))
150
151
152
libusb_dep = dependency('libusb-1.0', required : get_option('libusb'))
153
summary({'libusb (Bluetooth quirks)': libusb_dep.found()}, bool_yn: true, section: 'Backend')
154
-if libusb_dep.found()
155
- cdata.set('HAVE_LIBUSB', 1)
156
-endif
157
+cdata.set('HAVE_LIBUSB', libusb_dep.found())
158
159
cap_lib = dependency('libcap', required : false)
160
-if cap_lib.found()
161
- cdata.set('HAVE_LIBCAP', 1)
162
-endif
163
+cdata.set('HAVE_LIBCAP', cap_lib.found())
164
165
gst_option = get_option('gstreamer')
166
gst_deps_def = {
167
168
gst_dp_found = gst_dep.length() > 0
169
summary({'gstreamer-device-provider': gst_dp_found}, bool_yn: true, section: 'Backend')
170
171
-if not get_option('gstreamer-device-provider').disabled()
172
- cdata.set('HAVE_GSTREAMER_DEVICE_PROVIDER', 1)
173
-endif
174
+cdata.set('HAVE_GSTREAMER_DEVICE_PROVIDER', get_option('gstreamer-device-provider').allowed())
175
176
webrtc_dep = dependency('webrtc-audio-processing',
177
version : ['>= 0.2', '< 1.0'],
178
required : get_option('echo-cancel-webrtc'))
179
summary({'WebRTC Echo Canceling': webrtc_dep.found()}, bool_yn: true, section: 'Misc dependencies')
180
-
181
-if webrtc_dep.found()
182
- cdata.set('HAVE_WEBRTC', 1)
183
-endif
184
+cdata.set('HAVE_WEBRTC', webrtc_dep.found())
185
186
# On FreeBSD, epoll-shim library is required for eventfd() and timerfd()
187
epoll_shim_dep = (build_machine.system() == 'freebsd'
188
189
190
lilv_lib = dependency('lilv-0', required: get_option('lv2'))
191
summary({'lilv (for lv2 plugins)': lilv_lib.found()}, bool_yn: true)
192
-if lilv_lib.found()
193
- cdata.set('HAVE_LILV', 1)
194
-endif
195
+cdata.set('HAVE_LILV', lilv_lib.found())
196
197
installed_tests_metadir = pipewire_datadir / 'installed-tests' / pipewire_name
198
installed_tests_execdir = pipewire_libexecdir / 'installed-tests' / pipewire_name
199
-installed_tests_enabled = not get_option('installed_tests').disabled()
200
+installed_tests_enabled = get_option('installed_tests').allowed()
201
installed_tests_template = files('template.test.in')
202
203
-if not get_option('tests').disabled()
204
+if get_option('tests').allowed()
205
gstack = find_program('gstack', required : false)
206
- cdata.set10('HAVE_GSTACK', gstack.found())
207
+ cdata.set('HAVE_GSTACK', gstack.found())
208
endif
209
210
subdir('po')
211
subdir('spa')
212
subdir('src')
213
214
-if not get_option('tests').disabled()
215
+if get_option('tests').allowed()
216
subdir('test')
217
endif
218
219
configure_file(output : 'config.h',
220
configuration : cdata)
221
222
-if not get_option('pipewire-jack').disabled()
223
+if get_option('pipewire-jack').allowed()
224
subdir('pipewire-jack')
225
endif
226
-if not get_option('pipewire-v4l2').disabled()
227
+if get_option('pipewire-v4l2').allowed()
228
subdir('pipewire-v4l2')
229
endif
230
231
232
endif
233
234
generate_manpages = false
235
-if not get_option('man').disabled()
236
+if get_option('man').allowed()
237
rst2man = find_program('rst2man', required: false)
238
if not rst2man.found()
239
rst2man = find_program('rst2man.py', required: get_option('man'))
240
pipewire-0.3.45.tar.gz/pipewire-jack/src/meson.build -> pipewire-0.3.47.tar.gz/pipewire-jack/src/meson.build
Changed
9
1
2
pipewire_jack_sources = [
3
'export.c',
4
'pipewire-jack.c',
5
- 'match-rules.c',
6
'ringbuffer.c',
7
'uuid.c',
8
]
9
pipewire-0.3.45.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.47.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
337
1
2
3
#define JACK_CLIENT_NAME_SIZE 128
4
#define JACK_PORT_NAME_SIZE 256
5
-#define JACK_PORT_MAX 4096
6
#define JACK_PORT_TYPE_SIZE 32
7
-#define CONNECTION_NUM_FOR_PORT 1024
8
#define MONITOR_EXT " Monitor"
9
10
+#define MAX_MIDI_MIX 1024
11
#define MAX_BUFFER_FRAMES 8192
12
13
#define MAX_ALIGN 16
14
-#define MAX_PORTS 1024
15
#define MAX_BUFFERS 2
16
#define MAX_BUFFER_DATAS 1u
17
18
19
} rt;
20
21
pthread_mutex_t rt_lock;
22
+ unsigned int rt_locked:1;
23
24
unsigned int started:1;
25
unsigned int active:1;
26
27
unsigned int filter_name:1;
28
unsigned int freewheeling:1;
29
unsigned int locked_process:1;
30
+ unsigned int default_as_system:1;
31
int self_connect_mode;
32
int rt_max;
33
34
35
int res = 0; \
36
if (c->callback) { \
37
if (pthread_mutex_trylock(&c->rt_lock) == 0) { \
38
+ c->rt_locked = true; \
39
res = c->callback(__VA_ARGS__); \
40
+ c->rt_locked = false; \
41
pthread_mutex_unlock(&c->rt_lock); \
42
} \
43
} \
44
45
46
static int do_sync(struct client *client)
47
{
48
+ bool in_data_thread = pw_data_loop_in_thread(client->loop);
49
+
50
if (pw_thread_loop_in_thread(client->context.loop)) {
51
pw_log_warn("sync requested from callback");
52
return 0;
53
54
client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync);
55
56
while (true) {
57
+ if (in_data_thread && client->rt_locked)
58
+ pthread_mutex_unlock(&client->rt_lock);
59
+
60
pw_thread_loop_wait(client->context.loop);
61
62
+ if (in_data_thread && client->rt_locked)
63
+ pthread_mutex_lock(&client->rt_lock);
64
+
65
if (client->error)
66
return client->last_res;
67
68
69
struct client *client = data;
70
client->node = NULL;
71
spa_hook_remove(&client->proxy_listener);
72
+ spa_hook_remove(&client->node_listener);
73
}
74
75
static void on_node_bound(void *data, uint32_t global_id)
76
77
}
78
79
80
-static int execute_match(void *data, const char *action, const char *val, int len)
81
+static int execute_match(void *data, const char *location, const char *action,
82
+ const char *val, size_t len)
83
{
84
struct client *client = data;
85
if (spa_streq(action, "update-props"))
86
87
return 1;
88
}
89
90
-static int apply_jack_rules(void *data, const char *location, const char *section,
91
- const char *str, size_t len)
92
-{
93
- struct client *client = data;
94
- const struct pw_properties *p =
95
- pw_context_get_properties(client->context.context);
96
-
97
- if (p != NULL)
98
- pw_jack_match_rules(str, len, &p->dict, execute_match, client);
99
-
100
- return 0;
101
-}
102
-
103
SPA_EXPORT
104
jack_client_t * jack_client_open (const char *client_name,
105
jack_options_t options,
106
107
if ((str = getenv("PIPEWIRE_PROPS")) != NULL)
108
pw_properties_update_string(client->props, str, strlen(str));
109
110
-
111
- pw_context_conf_section_for_each(client->context.context, "jack.rules",
112
- apply_jack_rules, client);
113
+ pw_context_conf_section_match_rules(client->context.context, "jack.rules",
114
+ &client->props->dict, execute_match, client);
115
116
client->show_monitor = pw_properties_get_bool(client->props, "jack.show-monitor", true);
117
client->merge_monitor = pw_properties_get_bool(client->props, "jack.merge-monitor", false);
118
client->short_name = pw_properties_get_bool(client->props, "jack.short-name", false);
119
client->filter_name = pw_properties_get_bool(client->props, "jack.filter-name", false);
120
client->locked_process = pw_properties_get_bool(client->props, "jack.locked-process", true);
121
+ client->default_as_system = pw_properties_get_bool(client->props, "jack.default-as-system", false);
122
123
client->self_connect_mode = SELF_CONNECT_ALLOW;
124
if ((str = pw_properties_get(client->props, "jack.self-connect-mode")) != NULL) {
125
126
spa_list_init(&client->mix);
127
spa_list_init(&client->free_mix);
128
129
- pw_map_init(&client->ports[SPA_DIRECTION_INPUT], MAX_PORTS, 32);
130
- pw_map_init(&client->ports[SPA_DIRECTION_OUTPUT], MAX_PORTS, 32);
131
+ pw_map_init(&client->ports[SPA_DIRECTION_INPUT], 32, 32);
132
+ pw_map_init(&client->ports[SPA_DIRECTION_OUTPUT], 32, 32);
133
spa_list_init(&client->free_ports);
134
135
pw_thread_loop_start(client->context.loop);
136
137
pw_properties_set(client->props, PW_KEY_MEDIA_ROLE, "DSP");
138
if (pw_properties_get(client->props, PW_KEY_NODE_ALWAYS_PROCESS) == NULL)
139
pw_properties_set(client->props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
140
+ if (pw_properties_get(client->props, PW_KEY_NODE_LOCK_QUANTUM) == NULL)
141
+ pw_properties_set(client->props, PW_KEY_NODE_LOCK_QUANTUM, "true");
142
pw_properties_set(client->props, PW_KEY_NODE_TRANSPORT_SYNC, "true");
143
144
client->node = pw_core_create_object(client->core,
145
146
&client->proxy_listener, &node_proxy_events, client);
147
148
client->info = SPA_NODE_INFO_INIT();
149
- client->info.max_input_ports = MAX_PORTS;
150
- client->info.max_output_ports = MAX_PORTS;
151
+ client->info.max_input_ports = UINT32_MAX;
152
+ client->info.max_output_ports = UINT32_MAX;
153
client->info.change_mask = SPA_NODE_CHANGE_MASK_FLAGS |
154
SPA_NODE_CHANGE_MASK_PROPS;
155
client->info.flags = SPA_NODE_FLAG_RT;
156
157
158
pw_thread_loop_stop(c->context.loop);
159
160
- if (c->registry)
161
+ if (c->registry) {
162
+ spa_hook_remove(&c->registry_listener);
163
pw_proxy_destroy((struct pw_proxy*)c->registry);
164
+ }
165
if (c->metadata && c->metadata->proxy) {
166
pw_proxy_destroy((struct pw_proxy*)c->metadata->proxy);
167
}
168
+ spa_hook_remove(&c->core_listener);
169
pw_core_disconnect(c->core);
170
pw_context_destroy(c->context.context);
171
172
173
int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
174
{
175
struct client *c = (struct client *) client;
176
- char latency[128];
177
178
spa_return_val_if_fail(c != NULL, -EINVAL);
179
180
- snprintf(latency, sizeof(latency), "%d/%d", nframes, jack_get_sample_rate(client));
181
- pw_log_info("%p: buffer-size %s", client, latency);
182
+ pw_log_info("%p: buffer-size %u", client, nframes);
183
184
pw_thread_loop_lock(c->context.loop);
185
- pw_properties_set(c->props, PW_KEY_NODE_LATENCY, latency);
186
pw_properties_setf(c->props, PW_KEY_NODE_FORCE_QUANTUM, "%u", nframes);
187
188
c->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
189
190
{
191
struct mix *mix;
192
void *ptr = p->emptyptr;
193
- struct spa_pod_sequence *seq[CONNECTION_NUM_FOR_PORT];
194
+ struct spa_pod_sequence *seq[MAX_MIDI_MIX];
195
uint32_t n_seq = 0;
196
197
jack_midi_clear_buffer(ptr);
198
199
continue;
200
201
seq[n_seq++] = pod;
202
+ if (n_seq == MAX_MIDI_MIX)
203
+ break;
204
}
205
convert_to_midi(seq, n_seq, ptr);
206
207
208
return jack_port_uuid_generate(o->serial);
209
}
210
211
+static const char *port_name(struct object *o)
212
+{
213
+ const char *name;
214
+ struct client *c = o->client;
215
+ if (c->default_as_system && is_port_default(c, o))
216
+ name = o->port.system;
217
+ else
218
+ name = o->port.name;
219
+ return name;
220
+}
221
+
222
SPA_EXPORT
223
const char * jack_port_name (const jack_port_t *port)
224
{
225
struct object *o = (struct object *) port;
226
spa_return_val_if_fail(o != NULL, NULL);
227
- return o->port.name;
228
+ return port_name(o);
229
}
230
231
SPA_EXPORT
232
233
{
234
struct object *o = (struct object *) port;
235
spa_return_val_if_fail(o != NULL, NULL);
236
- return strchr(o->port.name, ':') + 1;
237
+ return strchr(port_name(o), ':') + 1;
238
}
239
240
SPA_EXPORT
241
242
struct object *p, *l;
243
const char **res;
244
int count = 0;
245
+ struct pw_array tmp;
246
247
spa_return_val_if_fail(c != NULL, NULL);
248
spa_return_val_if_fail(o != NULL, NULL);
249
250
- res = malloc(sizeof(char*) * (CONNECTION_NUM_FOR_PORT + 1));
251
+ pw_array_init(&tmp, sizeof(void*) * 32);
252
253
pthread_mutex_lock(&c->context.lock);
254
spa_list_for_each(l, &c->context.objects, link) {
255
256
if (p == NULL)
257
continue;
258
259
- res[count++] = p->port.name;
260
- if (count == CONNECTION_NUM_FOR_PORT)
261
- break;
262
+ pw_array_add_ptr(&tmp, (void*)port_name(p));
263
+ count++;
264
}
265
pthread_mutex_unlock(&c->context.lock);
266
267
if (count == 0) {
268
- free(res);
269
+ pw_array_clear(&tmp);
270
res = NULL;
271
- } else
272
- res[count] = NULL;
273
-
274
+ } else {
275
+ pw_array_add_ptr(&tmp, NULL);
276
+ res = tmp.data;
277
+ }
278
return res;
279
}
280
281
282
struct client *c = (struct client *) client;
283
const char **res;
284
struct object *o;
285
- struct object *tmp[JACK_PORT_MAX];
286
+ struct pw_array tmp;
287
const char *str;
288
uint32_t i, count, id;
289
int r;
290
291
port_name_pattern, type_name_pattern, flags);
292
293
pthread_mutex_lock(&c->context.lock);
294
+ pw_array_init(&tmp, sizeof(void*) * 32);
295
count = 0;
296
+
297
spa_list_for_each(o, &c->context.objects, link) {
298
if (o->type != INTERFACE_Port || o->removed)
299
continue;
300
pw_log_debug("%p: check port type:%d flags:%08lx name:\"%s\"", c,
301
o->port.type_id, o->port.flags, o->port.name);
302
- if (count == JACK_PORT_MAX)
303
- break;
304
if (o->port.type_id > TYPE_ID_VIDEO)
305
continue;
306
if (!SPA_FLAG_IS_SET(o->port.flags, flags))
307
308
0, NULL, 0) == REG_NOMATCH)
309
continue;
310
}
311
-
312
pw_log_debug("%p: port \"%s\" prio:%d matches (%d)",
313
c, o->port.name, o->port.priority, count);
314
- tmp[count++] = o;
315
+
316
+ pw_array_add_ptr(&tmp, o);
317
+ count++;
318
}
319
pthread_mutex_unlock(&c->context.lock);
320
321
if (count > 0) {
322
- qsort(tmp, count, sizeof(struct object *), port_compare_func);
323
-
324
- res = malloc(sizeof(char*) * (count + 1));
325
+ qsort(tmp.data, count, sizeof(struct object *), port_compare_func);
326
+ pw_array_add_ptr(&tmp, NULL);
327
+ res = tmp.data;
328
for (i = 0; i < count; i++)
329
- res[i] = tmp[i]->port.name;
330
- res[count] = NULL;
331
+ res[i] = port_name((struct object*)res[i]);
332
} else {
333
+ pw_array_clear(&tmp);
334
res = NULL;
335
}
336
337
pipewire-0.3.45.tar.gz/po/LINGUAS -> pipewire-0.3.47.tar.gz/po/LINGUAS
Changed
9
1
2
pl
3
pt_BR
4
pt
5
+ro
6
ru
7
sk
8
sr@latin
9
pipewire-0.3.45.tar.gz/po/POTFILES.in -> pipewire-0.3.47.tar.gz/po/POTFILES.in
Changed
9
1
2
src/daemon/pipewire.desktop.in
3
src/modules/module-protocol-pulse/modules/module-tunnel-sink.c
4
src/modules/module-protocol-pulse/modules/module-tunnel-source.c
5
+src/modules/module-fallback-sink.c
6
src/modules/module-pulse-tunnel.c
7
src/modules/module-zeroconf-discover.c
8
src/tools/pw-cat.c
9
pipewire-0.3.47.tar.gz/po/ro.po
Added
681
1
2
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
+# This file is distributed under the same license as the pipewire package.
4
+#
5
+# Sergiu Bivol <sergiu@cip.md>, 2022.
6
+msgid ""
7
+msgstr ""
8
+"Project-Id-Version: pipewire\n"
9
+"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/issues/"
10
+"new\n"
11
+"POT-Creation-Date: 2021-11-17 15:06+0100\n"
12
+"PO-Revision-Date: 2022-02-05 12:06+0000\n"
13
+"Last-Translator: Sergiu Bivol <sergiu@cip.md>\n"
14
+"Language-Team: Romanian\n"
15
+"Language: ro\n"
16
+"MIME-Version: 1.0\n"
17
+"Content-Type: text/plain; charset=UTF-8\n"
18
+"Content-Transfer-Encoding: 8bit\n"
19
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 <"
20
+" 20)) ? 1 : 2;\n"
21
+"X-Generator: Lokalize 21.12.2\n"
22
+
23
+#: src/daemon/pipewire.c:45
24
+#, c-format
25
+msgid ""
26
+"%s [options]\n"
27
+" -h, --help Show this help\n"
28
+" --version Show version\n"
29
+" -c, --config Load config (Default %s)\n"
30
+msgstr ""
31
+"%s [opțiuni]\n"
32
+" -h, --help Arată acest ajutor\n"
33
+" --version Arată versiunea\n"
34
+" -c, --config Încarcă configurare (implicit %s)\n"
35
+
36
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:185
37
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:185
38
+#, c-format
39
+msgid "Tunnel to %s/%s"
40
+msgstr "Tunelează spre %s/%s"
41
+
42
+#: src/modules/module-pulse-tunnel.c:536
43
+#, c-format
44
+msgid "Tunnel for %s@%s"
45
+msgstr "Tunelează pentru %s@%s"
46
+
47
+#: src/modules/module-zeroconf-discover.c:332
48
+msgid "Unknown device"
49
+msgstr "Dispozitiv necunoscut"
50
+
51
+#: src/modules/module-zeroconf-discover.c:344
52
+#, c-format
53
+msgid "%s on %s@%s"
54
+msgstr "%s pe %s@%s"
55
+
56
+#: src/modules/module-zeroconf-discover.c:348
57
+#, c-format
58
+msgid "%s on %s"
59
+msgstr "%s pe %s"
60
+
61
+#: src/tools/pw-cat.c:1058
62
+#, c-format
63
+msgid ""
64
+"%s [options] <file>\n"
65
+" -h, --help Show this help\n"
66
+" --version Show version\n"
67
+" -v, --verbose Enable verbose operations\n"
68
+"\n"
69
+msgstr ""
70
+"%s [opțiuni] <fișier>\n"
71
+" -h, --help Arată acest ajutor\n"
72
+" --version Arată versiunea\n"
73
+" -v, --verbose Activează operații verboase\n"
74
+"\n"
75
+
76
+#: src/tools/pw-cat.c:1065
77
+#, c-format
78
+msgid ""
79
+" -R, --remote Remote daemon name\n"
80
+" --media-type Set media type (default %s)\n"
81
+" --media-category Set media category (default %s)\n"
82
+" --media-role Set media role (default %s)\n"
83
+" --target Set node target (default %s)\n"
84
+" 0 means don't link\n"
85
+" --latency Set node latency (default %s)\n"
86
+" Xunit (unit = s, ms, us, ns)\n"
87
+" or direct samples (256)\n"
88
+" the rate is the one of the source "
89
+"file\n"
90
+" --list-targets List available targets for --target\n"
91
+"\n"
92
+msgstr ""
93
+" -R, --remote Denumirea demonului distant\n"
94
+" --media-type Stabilește tipul mediului (implicit "
95
+"%s)\n"
96
+" --media-category Stabilește categoria mediului"
97
+" (implicit %s)\n"
98
+" --media-role Stabilește rolul mediului (implicit "
99
+"%s)\n"
100
+" --target Stabilește ținta nodului (implicit "
101
+"%s)\n"
102
+" 0 înseamnă „nu lega”\n"
103
+" --latency Stabilește latența nodului (implicit "
104
+"%s)\n"
105
+" Xunit (unitate = s, ms, us, ns)\n"
106
+" sau mostre directe (256)\n"
107
+" rata este cea a fișierului sursă\n"
108
+" --list-targets Enumeră țintele disponibile pentru"
109
+" --target\n"
110
+"\n"
111
+
112
+#: src/tools/pw-cat.c:1083
113
+#, c-format
114
+msgid ""
115
+" --rate Sample rate (req. for rec) (default "
116
+"%u)\n"
117
+" --channels Number of channels (req. for rec) "
118
+"(default %u)\n"
119
+" --channel-map Channel map\n"
120
+" one of: \"stereo\", "
121
+"\"surround-51\",... or\n"
122
+" comma separated list of channel "
123
+"names: eg. \"FL,FR\"\n"
124
+" --format Sample format %s (req. for rec) "
125
+"(default %s)\n"
126
+" --volume Stream volume 0-1.0 (default %.3f)\n"
127
+" -q --quality Resampler quality (0 - 15) (default "
128
+"%d)\n"
129
+"\n"
130
+msgstr ""
131
+" --rate Rată de eșantionare (nec. pt."
132
+" înregistrare) (implicit %u)\n"
133
+" --channels Număr de canale (nec. pt."
134
+" înregistrare) (implicit %u)\n"
135
+" --channel-map Hartă canale\n"
136
+" una dintre: \"stereo\","
137
+" \"surround-51\",... sau listă\n"
138
+" separată prin virgulă cu denumiri"
139
+" de canale: de ex. \"FL,FR\"\n"
140
+" --format Format de eșantionare %s (nec. pt."
141
+" înregistrare) (implicit %s)\n"
142
+" --volume Volum flux 0-1.0 (implicit %.3f)\n"
143
+" -q --quality Calitate de re-eșantionare (0 - 15)"
144
+" (implicit %d)\n"
145
+"\n"
146
+
147
+#: src/tools/pw-cat.c:1100
148
+msgid ""
149
+" -p, --playback Playback mode\n"
150
+" -r, --record Recording mode\n"
151
+" -m, --midi Midi mode\n"
152
+" -d, --dsd DSD mode\n"
153
+"\n"
154
+msgstr ""
155
+" -p, --playback Regim de redare\n"
156
+" -r, --record Regim de înregistrare\n"
157
+" -m, --midi Regim MIDI\n"
158
+" -d, --dsd regim DSD\n"
159
+"\n"
160
+
161
+#: src/tools/pw-cli.c:3018
162
+#, c-format
163
+msgid ""
164
+"%s [options] [command]\n"
165
+" -h, --help Show this help\n"
166
+" --version Show version\n"
167
+" -d, --daemon Start as daemon (Default false)\n"
168
+" -r, --remote Remote daemon name\n"
169
+"\n"
170
+msgstr ""
171
+"%s [opțiuni] [comandă]\n"
172
+" -h, --help Arată acest ajutor\n"
173
+" --version Arată versiunea\n"
174
+" -d, --daemon Pornește ca demon (implicit fals)\n"
175
+" -r, --remote Denumire demon distant\n"
176
+"\n"
177
+
178
+#: spa/plugins/alsa/acp/acp.c:321
179
+msgid "Pro Audio"
180
+msgstr "Pro Audio"
181
+
182
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
183
+#: spa/plugins/bluez5/bluez5-device.c:1145
184
+msgid "Off"
185
+msgstr "Oprit"
186
+
187
+#: spa/plugins/alsa/acp/alsa-mixer.c:2652
188
+msgid "Input"
189
+msgstr "Intrare"
190
+
191
+#: spa/plugins/alsa/acp/alsa-mixer.c:2653
192
+msgid "Docking Station Input"
193
+msgstr "Intrare stație de andocare"
194
+
195
+#: spa/plugins/alsa/acp/alsa-mixer.c:2654
196
+msgid "Docking Station Microphone"
197
+msgstr "Microfon stație de andocare"
198
+
199
+#: spa/plugins/alsa/acp/alsa-mixer.c:2655
200
+msgid "Docking Station Line In"
201
+msgstr "Linie de intrare stație de andocare"
202
+
203
+#: spa/plugins/alsa/acp/alsa-mixer.c:2656
204
+#: spa/plugins/alsa/acp/alsa-mixer.c:2747
205
+msgid "Line In"
206
+msgstr "Linie de intrare"
207
+
208
+#: spa/plugins/alsa/acp/alsa-mixer.c:2657
209
+#: spa/plugins/alsa/acp/alsa-mixer.c:2741
210
+#: spa/plugins/bluez5/bluez5-device.c:1302
211
+msgid "Microphone"
212
+msgstr "Microfon"
213
+
214
+#: spa/plugins/alsa/acp/alsa-mixer.c:2658
215
+#: spa/plugins/alsa/acp/alsa-mixer.c:2742
216
+msgid "Front Microphone"
217
+msgstr "Microfon frontal"
218
+
219
+#: spa/plugins/alsa/acp/alsa-mixer.c:2659
220
+#: spa/plugins/alsa/acp/alsa-mixer.c:2743
221
+msgid "Rear Microphone"
222
+msgstr "Microfon spate"
223
+
224
+#: spa/plugins/alsa/acp/alsa-mixer.c:2660
225
+msgid "External Microphone"
226
+msgstr "Microfon extern"
227
+
228
+#: spa/plugins/alsa/acp/alsa-mixer.c:2661
229
+#: spa/plugins/alsa/acp/alsa-mixer.c:2745
230
+msgid "Internal Microphone"
231
+msgstr "Microfon intern"
232
+
233
+#: spa/plugins/alsa/acp/alsa-mixer.c:2662
234
+#: spa/plugins/alsa/acp/alsa-mixer.c:2748
235
+msgid "Radio"
236
+msgstr "Radio"
237
+
238
+#: spa/plugins/alsa/acp/alsa-mixer.c:2663
239
+#: spa/plugins/alsa/acp/alsa-mixer.c:2749
240
+msgid "Video"
241
+msgstr "Video"
242
+
243
+#: spa/plugins/alsa/acp/alsa-mixer.c:2664
244
+msgid "Automatic Gain Control"
245
+msgstr "Control automat al nivelului de intrare"
246
+
247
+#: spa/plugins/alsa/acp/alsa-mixer.c:2665
248
+msgid "No Automatic Gain Control"
249
+msgstr "Fără control automat al nivelului de intrare"
250
+
251
+#: spa/plugins/alsa/acp/alsa-mixer.c:2666
252
+msgid "Boost"
253
+msgstr "Stimulare"
254
+
255
+#: spa/plugins/alsa/acp/alsa-mixer.c:2667
256
+msgid "No Boost"
257
+msgstr "Fără stimulare"
258
+
259
+#: spa/plugins/alsa/acp/alsa-mixer.c:2668
260
+msgid "Amplifier"
261
+msgstr "Amplificator"
262
+
263
+#: spa/plugins/alsa/acp/alsa-mixer.c:2669
264
+msgid "No Amplifier"
265
+msgstr "Fără amplificator"
266
+
267
+#: spa/plugins/alsa/acp/alsa-mixer.c:2670
268
+msgid "Bass Boost"
269
+msgstr "Stimulare bas"
270
+
271
+#: spa/plugins/alsa/acp/alsa-mixer.c:2671
272
+msgid "No Bass Boost"
273
+msgstr "Fără stimulare bas"
274
+
275
+#: spa/plugins/alsa/acp/alsa-mixer.c:2672
276
+#: spa/plugins/bluez5/bluez5-device.c:1307
277
+msgid "Speaker"
278
+msgstr "Difuzor"
279
+
280
+#: spa/plugins/alsa/acp/alsa-mixer.c:2673
281
+#: spa/plugins/alsa/acp/alsa-mixer.c:2751
282
+msgid "Headphones"
283
+msgstr "Căști"
284
+
285
+#: spa/plugins/alsa/acp/alsa-mixer.c:2740
286
+msgid "Analog Input"
287
+msgstr "Intrare analogică"
288
+
289
+#: spa/plugins/alsa/acp/alsa-mixer.c:2744
290
+msgid "Dock Microphone"
291
+msgstr "Microfon andocare"
292
+
293
+#: spa/plugins/alsa/acp/alsa-mixer.c:2746
294
+msgid "Headset Microphone"
295
+msgstr "Microfon căști"
296
+
297
+#: spa/plugins/alsa/acp/alsa-mixer.c:2750
298
+msgid "Analog Output"
299
+msgstr "Ieșire analogică"
300
+
301
+#: spa/plugins/alsa/acp/alsa-mixer.c:2752
302
+msgid "Headphones 2"
303
+msgstr "Căști 2"
304
+
305
+#: spa/plugins/alsa/acp/alsa-mixer.c:2753
306
+msgid "Headphones Mono Output"
307
+msgstr "Ieșire mono căști"
308
+
309
+#: spa/plugins/alsa/acp/alsa-mixer.c:2754
310
+msgid "Line Out"
311
+msgstr "Linie de ieșire"
312
+
313
+#: spa/plugins/alsa/acp/alsa-mixer.c:2755
314
+msgid "Analog Mono Output"
315
+msgstr "Ieșire mono analogic"
316
+
317
+#: spa/plugins/alsa/acp/alsa-mixer.c:2756
318
+msgid "Speakers"
319
+msgstr "Difuzoare"
320
+
321
+#: spa/plugins/alsa/acp/alsa-mixer.c:2757
322
+msgid "HDMI / DisplayPort"
323
+msgstr "HDMI / DisplayPort"
324
+
325
+#: spa/plugins/alsa/acp/alsa-mixer.c:2758
326
+msgid "Digital Output (S/PDIF)"
327
+msgstr "Ieșire digitală (S/PDIF)"
328
+
329
+#: spa/plugins/alsa/acp/alsa-mixer.c:2759
330
+msgid "Digital Input (S/PDIF)"
331
+msgstr "Intrare digitală (S/PDIF)"
332
+
333
+#: spa/plugins/alsa/acp/alsa-mixer.c:2760
334
+msgid "Multichannel Input"
335
+msgstr "Intrare multicanal"
336
+
337
+#: spa/plugins/alsa/acp/alsa-mixer.c:2761
338
+msgid "Multichannel Output"
339
+msgstr "Ieșire multicanal"
340
+
341
+#: spa/plugins/alsa/acp/alsa-mixer.c:2762
342
+msgid "Game Output"
343
+msgstr "Ieșire joc"
344
+
345
+#: spa/plugins/alsa/acp/alsa-mixer.c:2763
346
+#: spa/plugins/alsa/acp/alsa-mixer.c:2764
347
+msgid "Chat Output"
348
+msgstr "Ieșire discuție"
349
+
350
+#: spa/plugins/alsa/acp/alsa-mixer.c:2765
351
+msgid "Chat Input"
352
+msgstr "Intrare discuție"
353
+
354
+#: spa/plugins/alsa/acp/alsa-mixer.c:2766
355
+msgid "Virtual Surround 7.1"
356
+msgstr "surround virtual 7.1"
357
+
358
+#: spa/plugins/alsa/acp/alsa-mixer.c:4471
359
+msgid "Analog Mono"
360
+msgstr "mono analogic"
361
+
362
+#: spa/plugins/alsa/acp/alsa-mixer.c:4472
363
+msgid "Analog Mono (Left)"
364
+msgstr "mono analogic (stânga)"
365
+
366
+#: spa/plugins/alsa/acp/alsa-mixer.c:4473
367
+msgid "Analog Mono (Right)"
368
+msgstr "mono analogic (dreapta)"
369
+
370
+#. Note: Not translated to "Analog Stereo Input", because the source
371
+#. * name gets "Input" appended to it automatically, so adding "Input"
372
+#. * here would lead to the source name to become "Analog Stereo Input
373
+#. * Input". The same logic applies to analog-stereo-output,
374
+#. * multichannel-input and multichannel-output.
375
+#: spa/plugins/alsa/acp/alsa-mixer.c:4474
376
+#: spa/plugins/alsa/acp/alsa-mixer.c:4482
377
+#: spa/plugins/alsa/acp/alsa-mixer.c:4483
378
+msgid "Analog Stereo"
379
+msgstr "stereo analogic"
380
+
381
+#: spa/plugins/alsa/acp/alsa-mixer.c:4475
382
+msgid "Mono"
383
+msgstr "Mono"
384
+
385
+#: spa/plugins/alsa/acp/alsa-mixer.c:4476
386
+msgid "Stereo"
387
+msgstr "Stereo"
388
+
389
+#: spa/plugins/alsa/acp/alsa-mixer.c:4484
390
+#: spa/plugins/alsa/acp/alsa-mixer.c:4642
391
+#: spa/plugins/bluez5/bluez5-device.c:1292
392
+msgid "Headset"
393
+msgstr "Set cu cască"
394
+
395
+#: spa/plugins/alsa/acp/alsa-mixer.c:4485
396
+#: spa/plugins/alsa/acp/alsa-mixer.c:4643
397
+msgid "Speakerphone"
398
+msgstr "Difuzor"
399
+
400
+#: spa/plugins/alsa/acp/alsa-mixer.c:4486
401
+#: spa/plugins/alsa/acp/alsa-mixer.c:4487
402
+msgid "Multichannel"
403
+msgstr "multicanal"
404
+
405
+#: spa/plugins/alsa/acp/alsa-mixer.c:4488
406
+msgid "Analog Surround 2.1"
407
+msgstr "surround analogic 2.1"
408
+
409
+#: spa/plugins/alsa/acp/alsa-mixer.c:4489
410
+msgid "Analog Surround 3.0"
411
+msgstr "surround analogic 3.0"
412
+
413
+#: spa/plugins/alsa/acp/alsa-mixer.c:4490
414
+msgid "Analog Surround 3.1"
415
+msgstr "surround analogic 3.1"
416
+
417
+#: spa/plugins/alsa/acp/alsa-mixer.c:4491
418
+msgid "Analog Surround 4.0"
419
+msgstr "surround analogic 4.0"
420
+
421
+#: spa/plugins/alsa/acp/alsa-mixer.c:4492
422
+msgid "Analog Surround 4.1"
423
+msgstr "surround analogic 4.1"
424
+
425
+#: spa/plugins/alsa/acp/alsa-mixer.c:4493
426
+msgid "Analog Surround 5.0"
427
+msgstr "surround analogic 5.0"
428
+
429
+#: spa/plugins/alsa/acp/alsa-mixer.c:4494
430
+msgid "Analog Surround 5.1"
431
+msgstr "surround analogic 5.1"
432
+
433
+#: spa/plugins/alsa/acp/alsa-mixer.c:4495
434
+msgid "Analog Surround 6.0"
435
+msgstr "surround analogic 6.0"
436
+
437
+#: spa/plugins/alsa/acp/alsa-mixer.c:4496
438
+msgid "Analog Surround 6.1"
439
+msgstr "surround analogic 6.1"
440
+
441
+#: spa/plugins/alsa/acp/alsa-mixer.c:4497
442
+msgid "Analog Surround 7.0"
443
+msgstr "surround analogic 7.0"
444
+
445
+#: spa/plugins/alsa/acp/alsa-mixer.c:4498
446
+msgid "Analog Surround 7.1"
447
+msgstr "surround analogic 7.1"
448
+
449
+#: spa/plugins/alsa/acp/alsa-mixer.c:4499
450
+msgid "Digital Stereo (IEC958)"
451
+msgstr "stereo digital (IEC958)"
452
+
453
+#: spa/plugins/alsa/acp/alsa-mixer.c:4500
454
+msgid "Digital Surround 4.0 (IEC958/AC3)"
455
+msgstr "surround digital 4.0 (IEC958/AC3)"
456
+
457
+#: spa/plugins/alsa/acp/alsa-mixer.c:4501
458
+msgid "Digital Surround 5.1 (IEC958/AC3)"
459
+msgstr "surround digital 5.1 (IEC958/AC3)"
460
+
461
+#: spa/plugins/alsa/acp/alsa-mixer.c:4502
462
+msgid "Digital Surround 5.1 (IEC958/DTS)"
463
+msgstr "surround digital 5.1 (IEC958/DTS)"
464
+
465
+#: spa/plugins/alsa/acp/alsa-mixer.c:4503
466
+msgid "Digital Stereo (HDMI)"
467
+msgstr "stereo digital (HDMI)"
468
+
469
+#: spa/plugins/alsa/acp/alsa-mixer.c:4504
470
+msgid "Digital Surround 5.1 (HDMI)"
471
+msgstr "surround digital 5.1 (HDMI)"
472
+
473
+#: spa/plugins/alsa/acp/alsa-mixer.c:4505
474
+msgid "Chat"
475
+msgstr "Discuție"
476
+
477
+#: spa/plugins/alsa/acp/alsa-mixer.c:4506
478
+msgid "Game"
479
+msgstr "joc"
480
+
481
+#: spa/plugins/alsa/acp/alsa-mixer.c:4640
482
+msgid "Analog Mono Duplex"
483
+msgstr "Duplex mono analogic"
484
+
485
+#: spa/plugins/alsa/acp/alsa-mixer.c:4641
486
+msgid "Analog Stereo Duplex"
487
+msgstr "Duplex stereo analogic"
488
+
489
+#: spa/plugins/alsa/acp/alsa-mixer.c:4644
490
+msgid "Digital Stereo Duplex (IEC958)"
491
+msgstr "Duplex stereo digital (IEC958)"
492
+
493
+#: spa/plugins/alsa/acp/alsa-mixer.c:4645
494
+msgid "Multichannel Duplex"
495
+msgstr "Duplex multicanal"
496
+
497
+#: spa/plugins/alsa/acp/alsa-mixer.c:4646
498
+msgid "Stereo Duplex"
499
+msgstr "Duplex stereo"
500
+
501
+#: spa/plugins/alsa/acp/alsa-mixer.c:4647
502
+msgid "Mono Chat + 7.1 Surround"
503
+msgstr "Discuție mono + Surround 7.1"
504
+
505
+#: spa/plugins/alsa/acp/alsa-mixer.c:4750
506
+#, c-format
507
+msgid "%s Output"
508
+msgstr "Ieșire %s"
509
+
510
+#: spa/plugins/alsa/acp/alsa-mixer.c:4757
511
+#, c-format
512
+msgid "%s Input"
513
+msgstr "Intrare %s"
514
+
515
+#: spa/plugins/alsa/acp/alsa-util.c:1173
516
+#: spa/plugins/alsa/acp/alsa-util.c:1267
517
+#, c-format
518
+msgid ""
519
+"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
520
+"ms).\n"
521
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
522
+"to the ALSA developers."
523
+msgid_plural ""
524
+"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
525
+"ms).\n"
526
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
527
+"to the ALSA developers."
528
+msgstr[0] ""
529
+"snd_pcm_avail() a întors o valoare excepțional de mare: %lu octet (%lu ms).\n"
530
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
531
+" această problemă dezvoltatorilor ALSA."
532
+msgstr[1] ""
533
+"snd_pcm_avail() a întors o valoare excepțional de mare: %lu octeți (%lu ms).\n"
534
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
535
+" această problemă dezvoltatorilor ALSA."
536
+msgstr[2] ""
537
+"snd_pcm_avail() a întors o valoare excepțional de mare: %lu de octeți (%lu"
538
+" ms).\n"
539
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
540
+" această problemă dezvoltatorilor ALSA."
541
+
542
+#: spa/plugins/alsa/acp/alsa-util.c:1239
543
+#, c-format
544
+msgid ""
545
+"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
546
+"%lu ms).\n"
547
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
548
+"to the ALSA developers."
549
+msgid_plural ""
550
+"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
551
+"%lu ms).\n"
552
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
553
+"to the ALSA developers."
554
+msgstr[0] ""
555
+"snd_pcm_delay() a întors o valoare excepțional de mare: %li octet (%s%lu"
556
+" ms).\n"
557
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
558
+" această problemă dezvoltatorilor ALSA."
559
+msgstr[1] ""
560
+"snd_pcm_delay() a întors o valoare excepțional de mare: %li octeți (%s%lu"
561
+" ms).\n"
562
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
563
+" această problemă dezvoltatorilor ALSA."
564
+msgstr[2] ""
565
+"snd_pcm_delay() a întors o valoare excepțional de mare: %li de octeți (%s%lu"
566
+" ms).\n"
567
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
568
+" această problemă dezvoltatorilor ALSA."
569
+
570
+#: spa/plugins/alsa/acp/alsa-util.c:1286
571
+#, c-format
572
+msgid ""
573
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
574
+"%lu.\n"
575
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
576
+"to the ALSA developers."
577
+msgstr ""
578
+"snd_pcm_avail_delay() a întors valori stranii: întârzierea %lu e mai mică"
579
+" decât disponibilul %lu.\n"
580
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
581
+" această problemă dezvoltatorilor ALSA."
582
+
583
+#: spa/plugins/alsa/acp/alsa-util.c:1329
584
+#, c-format
585
+msgid ""
586
+"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
587
+"(%lu ms).\n"
588
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
589
+"to the ALSA developers."
590
+msgid_plural ""
591
+"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
592
+"(%lu ms).\n"
593
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
594
+"to the ALSA developers."
595
+msgstr[0] ""
596
+"snd_pcm_mmap_begin() a întors o valoare excepțional de mare: %lu octet (%lu"
597
+" ms).\n"
598
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
599
+" această problemă dezvoltatorilor ALSA."
600
+msgstr[1] ""
601
+"snd_pcm_mmap_begin() a întors o valoare excepțional de mare: %lu octeți (%lu"
602
+" ms).\n"
603
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
604
+" această problemă dezvoltatorilor ALSA."
605
+msgstr[2] ""
606
+"snd_pcm_mmap_begin() a întors o valoare excepțional de mare: %lu de octeți ("
607
+"%lu ms).\n"
608
+"Cel mai probabil, acesta e un defect în driver-ul ALSA „%s”. Raportați"
609
+" această problemă dezvoltatorilor ALSA."
610
+
611
+#: spa/plugins/alsa/acp/channelmap.h:464
612
+msgid "(invalid)"
613
+msgstr "(nevalid)"
614
+
615
+#: spa/plugins/alsa/acp/compat.c:189
616
+msgid "Built-in Audio"
617
+msgstr "Audio încorporat"
618
+
619
+#: spa/plugins/alsa/acp/compat.c:194
620
+msgid "Modem"
621
+msgstr "Modem"
622
+
623
+#: spa/plugins/bluez5/bluez5-device.c:1155
624
+msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
625
+msgstr "Poartă de acces audio (sursă A2DP și HSP/HFP AG)"
626
+
627
+#: spa/plugins/bluez5/bluez5-device.c:1178
628
+#, c-format
629
+msgid "High Fidelity Playback (A2DP Sink, codec %s)"
630
+msgstr "Redare de fidelitate înaltă (chiuvetă A2DP, codec %s)"
631
+
632
+#: spa/plugins/bluez5/bluez5-device.c:1181
633
+#, c-format
634
+msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
635
+msgstr "Duplex de fidelitate înaltă (sursă/chiuvetă A2DP, codec %s)"
636
+
637
+#: spa/plugins/bluez5/bluez5-device.c:1188
638
+msgid "High Fidelity Playback (A2DP Sink)"
639
+msgstr "Redare de fidelitate înaltă (chiuvetă A2DP)"
640
+
641
+#: spa/plugins/bluez5/bluez5-device.c:1190
642
+msgid "High Fidelity Duplex (A2DP Source/Sink)"
643
+msgstr "Duplex de fidelitate înaltă (sursă/chiuvetă A2DP)"
644
+
645
+#: spa/plugins/bluez5/bluez5-device.c:1217
646
+#, c-format
647
+msgid "Headset Head Unit (HSP/HFP, codec %s)"
648
+msgstr "Bază pentru set cu cască (HSP/HFP, codec %s)"
649
+
650
+#: spa/plugins/bluez5/bluez5-device.c:1221
651
+msgid "Headset Head Unit (HSP/HFP)"
652
+msgstr "Bază pentru set cu cască (HSP/HFP)"
653
+
654
+#: spa/plugins/bluez5/bluez5-device.c:1297
655
+msgid "Handsfree"
656
+msgstr "Mâini libere"
657
+
658
+#: spa/plugins/bluez5/bluez5-device.c:1312
659
+msgid "Headphone"
660
+msgstr "Cască"
661
+
662
+#: spa/plugins/bluez5/bluez5-device.c:1317
663
+msgid "Portable"
664
+msgstr "Portabil"
665
+
666
+#: spa/plugins/bluez5/bluez5-device.c:1322
667
+msgid "Car"
668
+msgstr "Mașină"
669
+
670
+#: spa/plugins/bluez5/bluez5-device.c:1327
671
+msgid "HiFi"
672
+msgstr "HiFi"
673
+
674
+#: spa/plugins/bluez5/bluez5-device.c:1332
675
+msgid "Phone"
676
+msgstr "Telefon"
677
+
678
+#: spa/plugins/bluez5/bluez5-device.c:1338
679
+msgid "Bluetooth"
680
+msgstr "Bluetooth"
681
pipewire-0.3.45.tar.gz/po/sv.po -> pipewire-0.3.47.tar.gz/po/sv.po
Changed
277
1
2
# Swedish translation for pipewire.
3
-# Copyright © 2008-2021 Free Software Foundation, Inc.
4
+# Copyright © 2008-2022 Free Software Foundation, Inc.
5
# This file is distributed under the same license as the pipewire package.
6
# Daniel Nylander <po@danielnylander.se>, 2008, 2012.
7
# Josef Andersson <josef.andersson@fripost.org>, 2014, 2017.
8
-# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2021.
9
+# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2021, 2022.
10
#
11
# Termer:
12
# input/output: ingång/utgång (det handlar om ljud)
13
14
"Project-Id-Version: pipewire\n"
15
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
16
"issues\n"
17
-"POT-Creation-Date: 2021-09-21 15:31+0000\n"
18
-"PO-Revision-Date: 2021-09-21 21:51+0200\n"
19
+"POT-Creation-Date: 2022-02-13 15:33+0000\n"
20
+"PO-Revision-Date: 2022-02-14 22:57+0100\n"
21
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
22
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
23
"Language: sv\n"
24
25
"Content-Type: text/plain; charset=UTF-8\n"
26
"Content-Transfer-Encoding: 8bit\n"
27
"Plural-Forms: nplurals=2; plural=n != 1;\n"
28
-"X-Generator: Poedit 3.0\n"
29
+"X-Generator: Poedit 3.0.1\n"
30
31
#: src/daemon/pipewire.c:45
32
#, c-format
33
34
msgid "Start the PipeWire Media System"
35
msgstr "Starta mediasystemet PipeWire"
36
37
-#: src/examples/media-session/alsa-monitor.c:656
38
-#: spa/plugins/alsa/acp/compat.c:189
39
-msgid "Built-in Audio"
40
-msgstr "Inbyggt ljud"
41
-
42
-#: src/examples/media-session/alsa-monitor.c:660
43
-#: spa/plugins/alsa/acp/compat.c:194
44
-msgid "Modem"
45
-msgstr "Modem"
46
-
47
-#: src/examples/media-session/alsa-monitor.c:669
48
-#: src/modules/module-zeroconf-discover.c:296
49
-msgid "Unknown device"
50
-msgstr "Okänd enhet"
51
-
52
-#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:173
53
-#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:173
54
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:188
55
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:188
56
#, c-format
57
msgid "Tunnel to %s/%s"
58
msgstr "Tunnel till %s/%s"
59
60
-#: src/modules/module-pulse-tunnel.c:534
61
+#: src/modules/module-fallback-sink.c:51
62
+msgid "Dummy Output"
63
+msgstr "Attrapputgång"
64
+
65
+#: src/modules/module-pulse-tunnel.c:536
66
#, c-format
67
msgid "Tunnel for %s@%s"
68
msgstr "Tunnel för %s@%s"
69
70
-#: src/modules/module-zeroconf-discover.c:308
71
+#: src/modules/module-zeroconf-discover.c:332
72
+msgid "Unknown device"
73
+msgstr "Okänd enhet"
74
+
75
+#: src/modules/module-zeroconf-discover.c:344
76
#, c-format
77
msgid "%s on %s@%s"
78
msgstr "%s på %s@%s"
79
80
-#: src/modules/module-zeroconf-discover.c:312
81
+#: src/modules/module-zeroconf-discover.c:348
82
#, c-format
83
msgid "%s on %s"
84
msgstr "%s på %s"
85
86
-#: src/tools/pw-cat.c:1055
87
+#: src/tools/pw-cat.c:1075
88
#, c-format
89
msgid ""
90
"%s [options] <file>\n"
91
92
" -v, --verbose Aktivera utförliga operationer\n"
93
"\n"
94
95
-#: src/tools/pw-cat.c:1062
96
+#: src/tools/pw-cat.c:1082
97
#, c-format
98
msgid ""
99
" -R, --remote Remote daemon name\n"
100
101
" --list-targets Lista tillgängliga mål för --target\n"
102
"\n"
103
104
-#: src/tools/pw-cat.c:1080
105
+#: src/tools/pw-cat.c:1100
106
#, c-format
107
msgid ""
108
" --rate Sample rate (req. for rec) (default "
109
110
"%d)\n"
111
"\n"
112
113
-#: src/tools/pw-cat.c:1097
114
+#: src/tools/pw-cat.c:1117
115
msgid ""
116
" -p, --playback Playback mode\n"
117
" -r, --record Recording mode\n"
118
119
" -d, --dsd DSD-läge\n"
120
"\n"
121
122
-#: src/tools/pw-cli.c:2954
123
+#: src/tools/pw-cli.c:3050
124
#, c-format
125
msgid ""
126
"%s [options] [command]\n"
127
128
" -r, --remote Fjärrdemonnamn\n"
129
"\n"
130
131
-#: spa/plugins/alsa/acp/acp.c:310
132
+#: spa/plugins/alsa/acp/acp.c:321
133
msgid "Pro Audio"
134
msgstr "Professionellt ljud"
135
136
-#: spa/plugins/alsa/acp/acp.c:433 spa/plugins/alsa/acp/alsa-mixer.c:4648
137
-#: spa/plugins/bluez5/bluez5-device.c:1135
138
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
139
+#: spa/plugins/bluez5/bluez5-device.c:1159
140
msgid "Off"
141
msgstr "Av"
142
143
144
145
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
146
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
147
-#: spa/plugins/bluez5/bluez5-device.c:1292
148
+#: spa/plugins/bluez5/bluez5-device.c:1328
149
msgid "Microphone"
150
msgstr "Mikrofon"
151
152
153
msgstr "Ingen basökning"
154
155
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
156
-#: spa/plugins/bluez5/bluez5-device.c:1297
157
+#: spa/plugins/bluez5/bluez5-device.c:1333
158
msgid "Speaker"
159
msgstr "Högtalare"
160
161
162
163
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
164
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
165
-#: spa/plugins/bluez5/bluez5-device.c:1282
166
+#: spa/plugins/bluez5/bluez5-device.c:1318
167
msgid "Headset"
168
msgstr "Headset"
169
170
171
#: spa/plugins/alsa/acp/alsa-util.c:1239
172
#, c-format
173
msgid ""
174
-"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
175
-"%lu ms).\n"
176
+"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
177
+"(%s%lu ms).\n"
178
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
179
"to the ALSA developers."
180
msgid_plural ""
181
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
182
-"%lu ms).\n"
183
+"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
184
+"(%s%lu ms).\n"
185
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
186
"to the ALSA developers."
187
msgstr[0] ""
188
189
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
190
"problemet till ALSA-utvecklarna."
191
192
-#: spa/plugins/alsa/acp/channelmap.h:466
193
+#: spa/plugins/alsa/acp/channelmap.h:464
194
msgid "(invalid)"
195
msgstr "(ogiltig)"
196
197
-#: spa/plugins/bluez5/bluez5-device.c:1145
198
+#: spa/plugins/alsa/acp/compat.c:189
199
+msgid "Built-in Audio"
200
+msgstr "Inbyggt ljud"
201
+
202
+#: spa/plugins/alsa/acp/compat.c:194
203
+msgid "Modem"
204
+msgstr "Modem"
205
+
206
+#: spa/plugins/bluez5/bluez5-device.c:1170
207
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
208
msgstr "Audio gateway (A2DP-källa & HSP/HFP AG)"
209
210
-#: spa/plugins/bluez5/bluez5-device.c:1168
211
+#: spa/plugins/bluez5/bluez5-device.c:1195
212
#, c-format
213
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
214
msgstr "High fidelity-uppspelning (A2DP-utgång, kodek %s)"
215
216
-#: spa/plugins/bluez5/bluez5-device.c:1171
217
+#: spa/plugins/bluez5/bluez5-device.c:1198
218
#, c-format
219
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
220
msgstr "High fidelity duplex (A2DP-källa/utgång, kodek %s)"
221
222
-#: spa/plugins/bluez5/bluez5-device.c:1178
223
+#: spa/plugins/bluez5/bluez5-device.c:1206
224
msgid "High Fidelity Playback (A2DP Sink)"
225
msgstr "High fidelity-uppspelning (A2DP-utgång)"
226
227
-#: spa/plugins/bluez5/bluez5-device.c:1180
228
+#: spa/plugins/bluez5/bluez5-device.c:1208
229
msgid "High Fidelity Duplex (A2DP Source/Sink)"
230
msgstr "High fidelity duplex (A2DP-källa/utgång)"
231
232
-#: spa/plugins/bluez5/bluez5-device.c:1207
233
+#: spa/plugins/bluez5/bluez5-device.c:1236
234
#, c-format
235
msgid "Headset Head Unit (HSP/HFP, codec %s)"
236
msgstr "Headset-huvudenhet (HSP/HFP, kodek %s)"
237
238
-#: spa/plugins/bluez5/bluez5-device.c:1211
239
+#: spa/plugins/bluez5/bluez5-device.c:1241
240
msgid "Headset Head Unit (HSP/HFP)"
241
msgstr "Headset-huvudenhet (HSP/HFP)"
242
243
-#: spa/plugins/bluez5/bluez5-device.c:1287
244
+#: spa/plugins/bluez5/bluez5-device.c:1323
245
msgid "Handsfree"
246
msgstr "Handsfree"
247
248
-#: spa/plugins/bluez5/bluez5-device.c:1302
249
+#: spa/plugins/bluez5/bluez5-device.c:1338
250
msgid "Headphone"
251
msgstr "Hörlurar"
252
253
-#: spa/plugins/bluez5/bluez5-device.c:1307
254
+#: spa/plugins/bluez5/bluez5-device.c:1343
255
msgid "Portable"
256
msgstr "Bärbar"
257
258
-#: spa/plugins/bluez5/bluez5-device.c:1312
259
+#: spa/plugins/bluez5/bluez5-device.c:1348
260
msgid "Car"
261
msgstr "Bil"
262
263
-#: spa/plugins/bluez5/bluez5-device.c:1317
264
+#: spa/plugins/bluez5/bluez5-device.c:1353
265
msgid "HiFi"
266
msgstr "HiFi"
267
268
-#: spa/plugins/bluez5/bluez5-device.c:1322
269
+#: spa/plugins/bluez5/bluez5-device.c:1358
270
msgid "Phone"
271
msgstr "Telefon"
272
273
-#: spa/plugins/bluez5/bluez5-device.c:1328
274
+#: spa/plugins/bluez5/bluez5-device.c:1364
275
msgid "Bluetooth"
276
msgstr "Bluetooth"
277
pipewire-0.3.45.tar.gz/spa/include/meson.build -> pipewire-0.3.47.tar.gz/spa/include/meson.build
Changed
9
1
2
'control',
3
'debug',
4
'graph',
5
+ 'interfaces',
6
'monitor',
7
'node',
8
'param',
9
pipewire-0.3.45.tar.gz/spa/include/spa/debug/buffer.h -> pipewire-0.3.47.tar.gz/spa/include/spa/debug/buffer.h
Changed
17
1
2
* \{
3
*/
4
5
+#include <spa/debug/log.h>
6
#include <spa/debug/mem.h>
7
#include <spa/debug/types.h>
8
#include <spa/buffer/type-info.h>
9
10
-#ifndef spa_debug
11
-#define spa_debug(...) ({ fprintf(stderr, __VA_ARGS__);fputc('\n', stderr); })
12
-#endif
13
-
14
static inline int spa_debug_buffer(int indent, const struct spa_buffer *buffer)
15
{
16
uint32_t i;
17
pipewire-0.3.45.tar.gz/spa/include/spa/debug/dict.h -> pipewire-0.3.47.tar.gz/spa/include/spa/debug/dict.h
Changed
15
1
2
* \{
3
*/
4
5
+#include <spa/debug/log.h>
6
#include <spa/utils/dict.h>
7
8
-#ifndef spa_debug
9
-#define spa_debug(...) ({ fprintf(stderr, __VA_ARGS__);fputc('\n', stderr); })
10
-#endif
11
-
12
static inline int spa_debug_dict(int indent, const struct spa_dict *dict)
13
{
14
const struct spa_dict_item *item;
15
pipewire-0.3.45.tar.gz/spa/include/spa/debug/format.h -> pipewire-0.3.47.tar.gz/spa/include/spa/debug/format.h
Changed
132
1
2
*/
3
4
#include <spa/pod/parser.h>
5
+#include <spa/debug/log.h>
6
#include <spa/debug/types.h>
7
#include <spa/param/type-info.h>
8
#include <spa/param/format-utils.h>
9
10
{
11
switch (type) {
12
case SPA_TYPE_Bool:
13
- fprintf(stderr, "%s", *(int32_t *) body ? "true" : "false");
14
+ spa_debugn("%s", *(int32_t *) body ? "true" : "false");
15
break;
16
case SPA_TYPE_Id:
17
{
18
19
snprintf(tmp, sizeof(tmp), "%d", *(int32_t*)body);
20
str = tmp;
21
}
22
- fprintf(stderr, "%s", str);
23
+ spa_debugn("%s", str);
24
break;
25
}
26
case SPA_TYPE_Int:
27
- fprintf(stderr, "%d", *(int32_t *) body);
28
+ spa_debugn("%d", *(int32_t *) body);
29
break;
30
case SPA_TYPE_Long:
31
- fprintf(stderr, "%" PRIi64, *(int64_t *) body);
32
+ spa_debugn("%" PRIi64, *(int64_t *) body);
33
break;
34
case SPA_TYPE_Float:
35
- fprintf(stderr, "%f", *(float *) body);
36
+ spa_debugn("%f", *(float *) body);
37
break;
38
case SPA_TYPE_Double:
39
- fprintf(stderr, "%g", *(double *) body);
40
+ spa_debugn("%g", *(double *) body);
41
break;
42
case SPA_TYPE_String:
43
- fprintf(stderr, "%s", (char *) body);
44
+ spa_debugn("%s", (char *) body);
45
break;
46
case SPA_TYPE_Rectangle:
47
{
48
struct spa_rectangle *r = (struct spa_rectangle *)body;
49
- fprintf(stderr, "%" PRIu32 "x%" PRIu32, r->width, r->height);
50
+ spa_debugn("%" PRIu32 "x%" PRIu32, r->width, r->height);
51
break;
52
}
53
case SPA_TYPE_Fraction:
54
{
55
struct spa_fraction *f = (struct spa_fraction *)body;
56
- fprintf(stderr, "%" PRIu32 "/%" PRIu32, f->num, f->denom);
57
+ spa_debugn("%" PRIu32 "/%" PRIu32, f->num, f->denom);
58
break;
59
}
60
case SPA_TYPE_Bitmap:
61
- fprintf(stderr, "Bitmap");
62
+ spa_debugn("Bitmap");
63
break;
64
case SPA_TYPE_Bytes:
65
- fprintf(stderr, "Bytes");
66
+ spa_debugn("Bytes");
67
break;
68
case SPA_TYPE_Array:
69
{
70
71
struct spa_pod_array_body *b = (struct spa_pod_array_body *)body;
72
int i = 0;
73
info = info && info->values ? info->values : info;
74
- fprintf(stderr, "< ");
75
+ spa_debugn("< ");
76
SPA_POD_ARRAY_BODY_FOREACH(b, size, p) {
77
if (i++ > 0)
78
- fprintf(stderr, ", ");
79
+ spa_debugn(", ");
80
spa_debug_format_value(info, b->child.type, p, b->child.size);
81
}
82
- fprintf(stderr, " >");
83
+ spa_debugn(" >");
84
break;
85
}
86
default:
87
- fprintf(stderr, "INVALID type %d", type);
88
+ spa_debugn("INVALID type %d", type);
89
break;
90
}
91
return 0;
92
93
media_type = spa_debug_type_find_name(spa_type_media_type, mtype);
94
media_subtype = spa_debug_type_find_name(spa_type_media_subtype, mstype);
95
96
- fprintf(stderr, "%*s %s/%s\n", indent, "",
97
+ spa_debug("%*s %s/%s", indent, "",
98
media_type ? spa_debug_type_short_name(media_type) : "unknown",
99
media_subtype ? spa_debug_type_short_name(media_subtype) : "unknown");
100
101
102
ti = spa_debug_type_find(info, prop->key);
103
key = ti ? ti->name : NULL;
104
105
- fprintf(stderr, "%*s %16s : (%s) ", indent, "",
106
+ spa_debugn("%*s %16s : (%s) ", indent, "",
107
key ? spa_debug_type_short_name(key) : "unknown",
108
spa_debug_type_short_name(spa_types[type].name));
109
110
111
break;
112
}
113
114
- fprintf(stderr, "%s", ssep);
115
+ spa_debugn("%s", ssep);
116
117
for (i = 1; i < n_vals; i++) {
118
vals = SPA_PTROFF(vals, size, void);
119
if (i > 1)
120
- fprintf(stderr, "%s", sep);
121
+ spa_debugn("%s", sep);
122
spa_debug_format_value(ti ? ti->values : NULL, type, vals, size);
123
}
124
- fprintf(stderr, "%s", esep);
125
+ spa_debugn("%s", esep);
126
}
127
- fprintf(stderr, "\n");
128
+ spa_debugn("\n");
129
}
130
return 0;
131
}
132
pipewire-0.3.47.tar.gz/spa/include/spa/debug/log.h
Added
55
1
2
+/* Simple Plugin API
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#ifndef SPA_DEBUG_LOG_H
27
+#define SPA_DEBUG_LOG_H
28
+
29
+#ifdef __cplusplus
30
+extern "C" {
31
+#endif
32
+
33
+#include <stdio.h>
34
+/**
35
+ * \addtogroup spa_debug
36
+ * \{
37
+ */
38
+
39
+#ifndef spa_debug
40
+#define spa_debug(fmt,...) ({ printf(fmt"\n", ## __VA_ARGS__); })
41
+#endif
42
+#ifndef spa_debugn
43
+#define spa_debugn(fmt,...) ({ printf(fmt, ## __VA_ARGS__); })
44
+#endif
45
+
46
+/**
47
+ * \}
48
+ */
49
+
50
+#ifdef __cplusplus
51
+} /* extern "C" */
52
+#endif
53
+
54
+#endif /* SPA_DEBUG_LOGH */
55
pipewire-0.3.45.tar.gz/spa/include/spa/debug/mem.h -> pipewire-0.3.47.tar.gz/spa/include/spa/debug/mem.h
Changed
21
1
2
extern "C" {
3
#endif
4
5
+#include <inttypes.h>
6
+
7
/**
8
* \addtogroup spa_debug
9
* \{
10
*/
11
12
-#include <spa/utils/dict.h>
13
-
14
-#ifndef spa_debug
15
-#define spa_debug(...) ({ fprintf(stderr, __VA_ARGS__);fputc('\n', stderr); })
16
-#endif
17
+#include <spa/debug/log.h>
18
19
static inline int spa_debug_mem(int indent, const void *data, size_t size)
20
{
21
pipewire-0.3.45.tar.gz/spa/include/spa/debug/node.h -> pipewire-0.3.47.tar.gz/spa/include/spa/debug/node.h
Changed
15
1
2
*/
3
4
#include <spa/node/node.h>
5
+#include <spa/debug/log.h>
6
#include <spa/debug/dict.h>
7
8
-#ifndef spa_debug
9
-#define spa_debug(...) ({ fprintf(stderr, __VA_ARGS__);fputc('\n', stderr); })
10
-#endif
11
-
12
static inline int spa_debug_port_info(int indent, const struct spa_port_info *info)
13
{
14
spa_debug("%*s" "struct spa_port_info %p:", indent, "", info);
15
pipewire-0.3.45.tar.gz/spa/include/spa/debug/pod.h -> pipewire-0.3.47.tar.gz/spa/include/spa/debug/pod.h
Changed
18
1
2
* \{
3
*/
4
5
+#include <spa/debug/log.h>
6
#include <spa/debug/mem.h>
7
#include <spa/debug/types.h>
8
#include <spa/pod/pod.h>
9
#include <spa/pod/iter.h>
10
11
-#ifndef spa_debug
12
-#define spa_debug(...) ({ fprintf(stderr, __VA_ARGS__);fputc('\n', stderr); })
13
-#endif
14
-
15
static inline int
16
spa_debug_pod_value(int indent, const struct spa_type_info *info,
17
uint32_t type, void *body, uint32_t size)
18
pipewire-0.3.47.tar.gz/spa/include/spa/interfaces
Added
2
1
+(directory)
2
pipewire-0.3.47.tar.gz/spa/include/spa/interfaces/audio
Added
2
1
+(directory)
2
pipewire-0.3.47.tar.gz/spa/include/spa/interfaces/audio/aec.h
Added
97
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2021 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+
27
+#include <spa/utils/dict.h>
28
+#include <spa/utils/hook.h>
29
+#include <spa/param/audio/raw.h>
30
+
31
+#ifndef SPA_AUDIO_AEC_H
32
+#define SPA_AUDIO_AEC_H
33
+
34
+#ifdef __cplusplus
35
+extern "C" {
36
+#endif
37
+
38
+#define SPA_TYPE_INTERFACE_AUDIO_AEC SPA_TYPE_INFO_INTERFACE_BASE "Audio:AEC"
39
+
40
+#define SPA_VERSION_AUDIO_AEC 0
41
+struct spa_audio_aec {
42
+ struct spa_interface iface;
43
+ const char *name;
44
+ const struct spa_dict *info;
45
+ const char *latency;
46
+};
47
+
48
+struct spa_audio_aec_info {
49
+#define SPA_AUDIO_AEC_CHANGE_MASK_PROPS (1u<<0)
50
+ uint64_t change_mask;
51
+
52
+ const struct spa_dict *props;
53
+};
54
+
55
+struct spa_audio_aec_events {
56
+#define SPA_VERSION_AUDIO_AEC_EVENTS 0
57
+ uint32_t version; /**< version of this structure */
58
+
59
+ /** Emitted when info changes */
60
+ void (*info) (void *data, const struct spa_audio_aec_info *info);
61
+};
62
+
63
+struct spa_audio_aec_methods {
64
+#define SPA_VERSION_AUDIO_AEC_METHODS 0
65
+ uint32_t version;
66
+
67
+ int (*add_listener) (void *object,
68
+ struct spa_hook *listener,
69
+ const struct spa_audio_aec_events *events,
70
+ void *data);
71
+
72
+ int (*init) (void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info);
73
+ int (*run) (void *data, const float *rec[], const float *play[], float *out[], uint32_t n_samples);
74
+ int (*set_props) (void *data, const struct spa_dict *args);
75
+};
76
+
77
+#define spa_audio_aec_method(o,method,version,...) \
78
+({ \
79
+ int _res = -ENOTSUP; \
80
+ struct spa_audio_aec *_o = o; \
81
+ spa_interface_call_res(&_o->iface, \
82
+ struct spa_audio_aec_methods, _res, \
83
+ method, version, ##__VA_ARGS__); \
84
+ _res; \
85
+})
86
+
87
+#define spa_audio_aec_add_listener(o,...) spa_audio_aec_method(o, add_listener, 0, __VA_ARGS__)
88
+#define spa_audio_aec_init(o,...) spa_audio_aec_method(o, init, 0, __VA_ARGS__)
89
+#define spa_audio_aec_run(o,...) spa_audio_aec_method(o, run, 0, __VA_ARGS__)
90
+#define spa_audio_aec_set_props(o,...) spa_audio_aec_method(o, set_props, 0, __VA_ARGS__)
91
+
92
+#ifdef __cplusplus
93
+} /* extern "C" */
94
+#endif
95
+
96
+#endif /* SPA_AUDIO_AEC_H */
97
pipewire-0.3.45.tar.gz/spa/include/spa/support/loop.h -> pipewire-0.3.47.tar.gz/spa/include/spa/support/loop.h
Changed
10
1
2
int fd;
3
uint32_t mask;
4
uint32_t rmask;
5
+ /* private data for the loop implementer */
6
+ void *priv;
7
};
8
9
typedef int (*spa_invoke_func_t) (struct spa_loop *loop,
10
pipewire-0.3.45.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.47.tar.gz/spa/include/spa/utils/defs.h
Changed
11
1
2
#define SPA_RESTRICT
3
#endif
4
5
+#define SPA_ROUND_DOWN(num,value) ((num) - ((num) % (value)))
6
+#define SPA_ROUND_UP(num,value) ((((num) + (value) - 1) / (value)) * (value))
7
+
8
#define SPA_ROUND_DOWN_N(num,align) ((num) & ~((align) - 1))
9
#define SPA_ROUND_UP_N(num,align) SPA_ROUND_DOWN_N((num) + ((align) - 1),align)
10
11
pipewire-0.3.45.tar.gz/spa/include/spa/utils/names.h -> pipewire-0.3.47.tar.gz/spa/include/spa/utils/names.h
Changed
10
1
2
#define SPA_NAME_AUDIO_ADAPT "audio.adapt" /**< combination of a node and an
3
* audio.convert. Does clock slaving */
4
5
+#define SPA_NAME_AEC "audio.aec" /**< Echo canceling */
6
+
7
/** video processing */
8
#define SPA_NAME_VIDEO_PROCESS_FORMAT "video.process.format" /**< processes raw video from one format
9
* to another */
10
pipewire-0.3.45.tar.gz/spa/meson.build -> pipewire-0.3.47.tar.gz/spa/meson.build
Changed
18
1
2
3
subdir('include')
4
5
-if not get_option('spa-plugins').disabled()
6
+if get_option('spa-plugins').allowed()
7
udevrulesdir = get_option('udevrulesdir')
8
if udevrulesdir == ''
9
# absolute path, otherwise meson prepends the prefix
10
11
12
subdir('tools')
13
subdir('tests')
14
-if not get_option('examples').disabled()
15
+if get_option('examples').allowed()
16
subdir('examples')
17
endif
18
pipewire-0.3.47.tar.gz/spa/plugins/aec
Added
2
1
+(directory)
2
pipewire-0.3.47.tar.gz/spa/plugins/aec/aec-null.c
Added
181
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2021 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <spa/interfaces/audio/aec.h>
27
+#include <spa/support/log.h>
28
+#include <spa/utils/string.h>
29
+#include <spa/utils/names.h>
30
+#include <spa/support/plugin.h>
31
+
32
+struct impl {
33
+ struct spa_handle handle;
34
+ struct spa_audio_aec aec;
35
+ struct spa_log *log;
36
+
37
+ struct spa_hook_list hooks_list;
38
+
39
+ uint32_t channels;
40
+};
41
+
42
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.aec.null");
43
+#undef SPA_LOG_TOPIC_DEFAULT
44
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
45
+
46
+static int null_init(void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info)
47
+{
48
+ struct impl *impl = data;
49
+ impl->channels = info->channels;
50
+ return 0;
51
+}
52
+
53
+static int null_run(void *data, const float *rec[], const float *play[], float *out[], uint32_t n_samples)
54
+{
55
+ struct impl *impl = data;
56
+ uint32_t i;
57
+ for (i = 0; i < impl->channels; i++)
58
+ memcpy(out[i], rec[i], n_samples * sizeof(float));
59
+ return 0;
60
+}
61
+
62
+static struct spa_audio_aec_methods impl_aec = {
63
+ .init = null_init,
64
+ .run = null_run,
65
+};
66
+
67
+static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
68
+{
69
+ struct impl *impl;
70
+
71
+ spa_return_val_if_fail(handle != NULL, -EINVAL);
72
+ spa_return_val_if_fail(interface != NULL, -EINVAL);
73
+
74
+ impl = (struct impl *) handle;
75
+
76
+ if (spa_streq(type, SPA_TYPE_INTERFACE_AUDIO_AEC))
77
+ *interface = &impl->aec;
78
+ else
79
+ return -ENOENT;
80
+
81
+ return 0;
82
+}
83
+
84
+static int impl_clear(struct spa_handle *handle)
85
+{
86
+ spa_return_val_if_fail(handle != NULL, -EINVAL);
87
+
88
+ return 0;
89
+}
90
+
91
+static size_t
92
+impl_get_size(const struct spa_handle_factory *factory,
93
+ const struct spa_dict *params)
94
+{
95
+ return sizeof(struct impl);
96
+}
97
+
98
+static int
99
+impl_init(const struct spa_handle_factory *factory,
100
+ struct spa_handle *handle,
101
+ const struct spa_dict *info,
102
+ const struct spa_support *support,
103
+ uint32_t n_support)
104
+{
105
+ struct impl *impl;
106
+
107
+ spa_return_val_if_fail(factory != NULL, -EINVAL);
108
+ spa_return_val_if_fail(handle != NULL, -EINVAL);
109
+
110
+ handle->get_interface = impl_get_interface;
111
+ handle->clear = impl_clear;
112
+
113
+ impl = (struct impl *) handle;
114
+
115
+ impl->aec.iface = SPA_INTERFACE_INIT(
116
+ SPA_TYPE_INTERFACE_AUDIO_AEC,
117
+ SPA_VERSION_AUDIO_AEC,
118
+ &impl_aec, impl);
119
+ impl->aec.name = "null";
120
+ impl->aec.info = NULL;
121
+ impl->aec.latency = NULL;
122
+
123
+ impl->log = (struct spa_log*)spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
124
+ spa_log_topic_init(impl->log, &log_topic);
125
+
126
+ spa_hook_list_init(&impl->hooks_list);
127
+
128
+ return 0;
129
+}
130
+
131
+static const struct spa_interface_info impl_interfaces[] = {
132
+ {SPA_TYPE_INTERFACE_AUDIO_AEC,},
133
+};
134
+
135
+static int
136
+impl_enum_interface_info(const struct spa_handle_factory *factory,
137
+ const struct spa_interface_info **info,
138
+ uint32_t *index)
139
+{
140
+ spa_return_val_if_fail(factory != NULL, -EINVAL);
141
+ spa_return_val_if_fail(info != NULL, -EINVAL);
142
+ spa_return_val_if_fail(index != NULL, -EINVAL);
143
+
144
+ switch (*index) {
145
+ case 0:
146
+ *info = &impl_interfaces[*index];
147
+ break;
148
+ default:
149
+ return 0;
150
+ }
151
+ (*index)++;
152
+ return 1;
153
+}
154
+
155
+const struct spa_handle_factory spa_aec_exaudio_factory = {
156
+ SPA_VERSION_HANDLE_FACTORY,
157
+ SPA_NAME_AEC,
158
+ NULL,
159
+ impl_get_size,
160
+ impl_init,
161
+ impl_enum_interface_info,
162
+};
163
+
164
+
165
+SPA_EXPORT
166
+int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
167
+{
168
+ spa_return_val_if_fail(factory != NULL, -EINVAL);
169
+ spa_return_val_if_fail(index != NULL, -EINVAL);
170
+
171
+ switch (*index) {
172
+ case 0:
173
+ *factory = &spa_aec_exaudio_factory;
174
+ break;
175
+ default:
176
+ return 0;
177
+ }
178
+ (*index)++;
179
+ return 1;
180
+}
181
pipewire-0.3.47.tar.gz/spa/plugins/aec/aec-webrtc.cpp
Added
280
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2021 Wim Taymans <wim.taymans@gmail.com>
5
+ * © 2021 Arun Raghavan <arun@asymptotic.io>
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a
8
+ * copy of this software and associated documentation files (the "Software"),
9
+ * to deal in the Software without restriction, including without limitation
10
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ * and/or sell copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice (including the next
15
+ * paragraph) shall be included in all copies or substantial portions of the
16
+ * Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ * DEALINGS IN THE SOFTWARE.
25
+ */
26
+
27
+#include <memory>
28
+#include <utility>
29
+
30
+#include <spa/interfaces/audio/aec.h>
31
+#include <spa/support/log.h>
32
+#include <spa/utils/string.h>
33
+#include <spa/utils/names.h>
34
+#include <spa/support/plugin.h>
35
+
36
+#include <webrtc/modules/audio_processing/include/audio_processing.h>
37
+#include <webrtc/modules/interface/module_common_types.h>
38
+#include <webrtc/system_wrappers/include/trace.h>
39
+
40
+struct impl_data {
41
+ struct spa_handle handle;
42
+ struct spa_audio_aec aec;
43
+
44
+ struct spa_log *log;
45
+ std::unique_ptr<webrtc::AudioProcessing> apm;
46
+ spa_audio_info_raw info;
47
+ std::unique_ptr<float *[]> play_buffer, rec_buffer, out_buffer;
48
+};
49
+
50
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.eac.webrtc");
51
+#undef SPA_LOG_TOPIC_DEFAULT
52
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
53
+
54
+static bool webrtc_get_spa_bool(const struct spa_dict *args, const char *key, bool default_value) {
55
+ const char *str_val;
56
+ bool value = default_value;
57
+ str_val = spa_dict_lookup(args, key);
58
+ if (str_val != NULL)
59
+ value =spa_atob(str_val);
60
+
61
+ return value;
62
+}
63
+
64
+static int webrtc_init(void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info)
65
+{
66
+ auto impl = reinterpret_cast<struct impl_data*>(data);
67
+
68
+ bool extended_filter = webrtc_get_spa_bool(args, "webrtc.extended_filter", true);
69
+ bool delay_agnostic = webrtc_get_spa_bool(args, "webrtc.delay_agnostic", true);
70
+ bool high_pass_filter = webrtc_get_spa_bool(args, "webrtc.high_pass_filter", true);
71
+ bool noise_suppression = webrtc_get_spa_bool(args, "webrtc.noise_suppression", true);
72
+ bool voice_detection = webrtc_get_spa_bool(args, "webrtc.voice_detection", true);
73
+
74
+ // Note: AGC seems to mess up with Agnostic Delay Detection, especially with speech,
75
+ // result in very poor performance, disable by default
76
+ bool gain_control = webrtc_get_spa_bool(args, "webrtc.gain_control", false);
77
+
78
+ // Disable experimental flags by default
79
+ bool experimental_agc = webrtc_get_spa_bool(args, "webrtc.experimental_agc", false);
80
+ bool experimental_ns = webrtc_get_spa_bool(args, "webrtc.experimental_ns", false);
81
+
82
+ // FIXME: Intelligibility enhancer is not currently supported
83
+ // This filter will modify playback buffer (when calling ProcessReverseStream), but now
84
+ // playback buffer modifications are discarded.
85
+
86
+ webrtc::Config config;
87
+ config.Set<webrtc::ExtendedFilter>(new webrtc::ExtendedFilter(extended_filter));
88
+ config.Set<webrtc::DelayAgnostic>(new webrtc::DelayAgnostic(delay_agnostic));
89
+ config.Set<webrtc::ExperimentalAgc>(new webrtc::ExperimentalAgc(experimental_agc));
90
+ config.Set<webrtc::ExperimentalNs>(new webrtc::ExperimentalNs(experimental_ns));
91
+
92
+ webrtc::ProcessingConfig pconfig = {{
93
+ webrtc::StreamConfig(info->rate, info->channels, false), /* input stream */
94
+ webrtc::StreamConfig(info->rate, info->channels, false), /* output stream */
95
+ webrtc::StreamConfig(info->rate, info->channels, false), /* reverse input stream */
96
+ webrtc::StreamConfig(info->rate, info->channels, false), /* reverse output stream */
97
+ }};
98
+
99
+ auto apm = std::unique_ptr<webrtc::AudioProcessing>(webrtc::AudioProcessing::Create(config));
100
+ if (apm->Initialize(pconfig) != webrtc::AudioProcessing::kNoError) {
101
+ spa_log_error(impl->log, "Error initialising webrtc audio processing module");
102
+ return -1;
103
+ }
104
+
105
+ apm->high_pass_filter()->Enable(high_pass_filter);
106
+ // Always disable drift compensation since it requires drift sampling
107
+ apm->echo_cancellation()->enable_drift_compensation(false);
108
+ apm->echo_cancellation()->Enable(true);
109
+ // TODO: wire up supression levels to args
110
+ apm->echo_cancellation()->set_suppression_level(webrtc::EchoCancellation::kHighSuppression);
111
+ apm->noise_suppression()->set_level(webrtc::NoiseSuppression::kHigh);
112
+ apm->noise_suppression()->Enable(noise_suppression);
113
+ apm->voice_detection()->Enable(voice_detection);
114
+ // TODO: wire up AGC parameters to args
115
+ apm->gain_control()->set_analog_level_limits(0, 255);
116
+ apm->gain_control()->set_mode(webrtc::GainControl::kAdaptiveDigital);
117
+ apm->gain_control()->Enable(gain_control);
118
+ impl->apm = std::move(apm);
119
+ impl->info = *info;
120
+ impl->play_buffer = std::make_unique<float *[]>(info->channels);
121
+ impl->rec_buffer = std::make_unique<float *[]>(info->channels);
122
+ impl->out_buffer = std::make_unique<float *[]>(info->channels);
123
+ return 0;
124
+}
125
+
126
+static int webrtc_run(void *data, const float *rec[], const float *play[], float *out[], uint32_t n_samples)
127
+{
128
+ auto impl = reinterpret_cast<struct impl_data*>(data);
129
+ webrtc::StreamConfig config =
130
+ webrtc::StreamConfig(impl->info.rate, impl->info.channels, false);
131
+ unsigned int num_blocks = n_samples * 1000 / impl->info.rate / 10;
132
+
133
+ if (n_samples * 1000 / impl->info.rate % 10 != 0) {
134
+ spa_log_error(impl->log, "Buffers must be multiples of 10ms in length (currently %u samples)", n_samples);
135
+ return -1;
136
+ }
137
+
138
+ for (size_t i = 0; i < num_blocks; i ++) {
139
+ for (size_t j = 0; j < impl->info.channels; j++) {
140
+ impl->play_buffer[j] = const_cast<float *>(play[j]) + config.num_frames() * i;
141
+ impl->rec_buffer[j] = const_cast<float *>(rec[j]) + config.num_frames() * i;
142
+ impl->out_buffer[j] = out[j] + config.num_frames() * i;
143
+ }
144
+ /* FIXME: ProcessReverseStream may change the playback buffer, in which
145
+ * case we should use that, if we ever expose the intelligibility
146
+ * enhancer */
147
+ if (impl->apm->ProcessReverseStream(impl->play_buffer.get(), config, config, impl->play_buffer.get()) !=
148
+ webrtc::AudioProcessing::kNoError) {
149
+ spa_log_error(impl->log, "Processing reverse stream failed");
150
+ }
151
+
152
+ // Extra delay introduced by multiple frames
153
+ impl->apm->set_stream_delay_ms((num_blocks - 1) * 10);
154
+
155
+ if (impl->apm->ProcessStream(impl->rec_buffer.get(), config, config, impl->out_buffer.get()) !=
156
+ webrtc::AudioProcessing::kNoError) {
157
+ spa_log_error(impl->log, "Processing stream failed");
158
+ }
159
+ }
160
+
161
+ return 0;
162
+}
163
+
164
+static struct spa_audio_aec_methods impl_aec = {
165
+ SPA_VERSION_AUDIO_AEC_METHODS,
166
+ .add_listener = NULL,
167
+ .init = webrtc_init,
168
+ .run = webrtc_run,
169
+};
170
+
171
+static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
172
+{
173
+ auto impl = reinterpret_cast<struct impl_data*>(handle);
174
+
175
+ spa_return_val_if_fail(handle != NULL, -EINVAL);
176
+ spa_return_val_if_fail(interface != NULL, -EINVAL);
177
+
178
+ if (spa_streq(type, SPA_TYPE_INTERFACE_AUDIO_AEC))
179
+ *interface = &impl->aec;
180
+ else
181
+ return -ENOENT;
182
+
183
+ return 0;
184
+}
185
+
186
+static int impl_clear(struct spa_handle *handle)
187
+{
188
+ spa_return_val_if_fail(handle != NULL, -EINVAL);
189
+ auto impl = reinterpret_cast<struct impl_data*>(handle);
190
+ impl->~impl_data();
191
+ return 0;
192
+}
193
+
194
+static size_t
195
+impl_get_size(const struct spa_handle_factory *factory,
196
+ const struct spa_dict *params)
197
+{
198
+ return sizeof(struct impl_data);
199
+}
200
+
201
+static int
202
+impl_init(const struct spa_handle_factory *factory,
203
+ struct spa_handle *handle,
204
+ const struct spa_dict *info,
205
+ const struct spa_support *support,
206
+ uint32_t n_support)
207
+{
208
+ spa_return_val_if_fail(factory != NULL, -EINVAL);
209
+ spa_return_val_if_fail(handle != NULL, -EINVAL);
210
+
211
+ auto impl = new (handle) impl_data();
212
+
213
+ impl->handle.get_interface = impl_get_interface;
214
+ impl->handle.clear = impl_clear;
215
+
216
+ impl->aec.iface = SPA_INTERFACE_INIT(
217
+ SPA_TYPE_INTERFACE_AUDIO_AEC,
218
+ SPA_VERSION_AUDIO_AEC,
219
+ &impl_aec, impl);
220
+ impl->aec.name = "webrtc",
221
+ impl->aec.info = NULL;
222
+ impl->aec.latency = "480/48000",
223
+
224
+ impl->log = (struct spa_log*)spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
225
+ spa_log_topic_init(impl->log, &log_topic);
226
+
227
+ return 0;
228
+}
229
+
230
+static const struct spa_interface_info impl_interfaces[] = {
231
+ {SPA_TYPE_INTERFACE_AUDIO_AEC,},
232
+};
233
+
234
+static int
235
+impl_enum_interface_info(const struct spa_handle_factory *factory,
236
+ const struct spa_interface_info **info,
237
+ uint32_t *index)
238
+{
239
+ spa_return_val_if_fail(factory != NULL, -EINVAL);
240
+ spa_return_val_if_fail(info != NULL, -EINVAL);
241
+ spa_return_val_if_fail(index != NULL, -EINVAL);
242
+
243
+ switch (*index) {
244
+ case 0:
245
+ *info = &impl_interfaces[*index];
246
+ break;
247
+ default:
248
+ return 0;
249
+ }
250
+ (*index)++;
251
+ return 1;
252
+}
253
+
254
+const struct spa_handle_factory spa_aec_exaudio_factory = {
255
+ SPA_VERSION_HANDLE_FACTORY,
256
+ SPA_NAME_AEC,
257
+ NULL,
258
+ impl_get_size,
259
+ impl_init,
260
+ impl_enum_interface_info,
261
+};
262
+
263
+
264
+SPA_EXPORT
265
+int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
266
+{
267
+ spa_return_val_if_fail(factory != NULL, -EINVAL);
268
+ spa_return_val_if_fail(index != NULL, -EINVAL);
269
+
270
+ switch (*index) {
271
+ case 0:
272
+ *factory = &spa_aec_exaudio_factory;
273
+ break;
274
+ default:
275
+ return 0;
276
+ }
277
+ (*index)++;
278
+ return 1;
279
+}
280
pipewire-0.3.47.tar.gz/spa/plugins/aec/meson.build
Added
18
1
2
+aec_null = shared_library('spa-aec-null',
3
+ [ 'aec-null.c' ],
4
+ include_directories : [ configinc ],
5
+ dependencies : [ spa_dep ],
6
+ install : true,
7
+ install_dir : spa_plugindir / 'aec')
8
+
9
+if webrtc_dep.found()
10
+ aec_webrtc = shared_library('spa-aec-webrtc',
11
+ [ 'aec-webrtc.cpp' ],
12
+ include_directories : [ configinc ],
13
+ dependencies : [ spa_dep, webrtc_dep ],
14
+ install : true,
15
+ install_dir : spa_plugindir / 'aec')
16
+endif
17
+
18
pipewire-0.3.45.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.47.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
460
1
2
/* get the current params */
3
CHECK(snd_pcm_sw_params_current(hndl, params), "sw_params_current");
4
5
- CHECK(snd_pcm_sw_params_set_tstamp_mode(hndl, params, SND_PCM_TSTAMP_ENABLE), "sw_params_set_tstamp_mode");
6
-
7
+ CHECK(snd_pcm_sw_params_set_tstamp_mode(hndl, params, SND_PCM_TSTAMP_ENABLE),
8
+ "sw_params_set_tstamp_mode");
9
+ CHECK(snd_pcm_sw_params_set_tstamp_type(hndl, params, SND_PCM_TSTAMP_TYPE_MONOTONIC),
10
+ "sw_params_set_tstamp_type");
11
#if 0
12
snd_pcm_uframes_t boundary;
13
CHECK(snd_pcm_sw_params_get_boundary(params, &boundary), "get_boundary");
14
15
case SND_PCM_STATE_SUSPENDED:
16
spa_log_info(state->log, "%s: recover from state %s",
17
state->props.device, snd_pcm_state_name(st));
18
+ res = snd_pcm_resume(state->hndl);
19
+ if (res >= 0)
20
+ return res;
21
err = -ESTRPIPE;
22
break;
23
default:
24
25
return do_start(state);
26
}
27
28
-static int get_status(struct state *state, snd_pcm_uframes_t *delay, snd_pcm_uframes_t *target)
29
+static int get_avail(struct state *state, uint64_t current_time)
30
{
31
- snd_pcm_sframes_t avail;
32
int res;
33
+ snd_pcm_sframes_t avail;
34
35
if (SPA_UNLIKELY((avail = snd_pcm_avail(state->hndl)) < 0)) {
36
if ((res = alsa_recover(state, avail)) < 0)
37
38
} else {
39
state->alsa_recovering = false;
40
}
41
+ return avail;
42
+}
43
+
44
+#if 0
45
+static int get_avail_htimestamp(struct state *state, uint64_t current_time)
46
+{
47
+ int res;
48
+ snd_pcm_uframes_t avail;
49
+ snd_htimestamp_t tstamp;
50
+ uint64_t then;
51
+
52
+ if ((res = snd_pcm_htimestamp(state->hndl, &avail, &tstamp)) < 0) {
53
+ if ((res = alsa_recover(state, avail)) < 0)
54
+ return res;
55
+ if ((res = snd_pcm_htimestamp(state->hndl, &avail, &tstamp)) < 0) {
56
+ spa_log_warn(state->log, "%s: snd_pcm_htimestamp error: %s",
57
+ state->props.device, snd_strerror(res));
58
+ avail = state->threshold * 2;
59
+ }
60
+ } else {
61
+ state->alsa_recovering = false;
62
+ }
63
+
64
+ if ((then = SPA_TIMESPEC_TO_NSEC(&tstamp)) != 0) {
65
+ if (then < current_time)
66
+ avail += (current_time - then) * state->rate / SPA_NSEC_PER_SEC;
67
+ else
68
+ avail -= (then - current_time) * state->rate / SPA_NSEC_PER_SEC;
69
+ }
70
+ return SPA_MIN(avail, state->buffer_frames);
71
+}
72
+#endif
73
+
74
+static int get_status(struct state *state, uint64_t current_time,
75
+ snd_pcm_uframes_t *delay, snd_pcm_uframes_t *target)
76
+{
77
+ int avail;
78
+
79
+ if ((avail = get_avail(state, current_time)) < 0)
80
+ return avail;
81
+
82
+ avail = SPA_MIN(avail, (int)state->buffer_frames);
83
84
*target = state->threshold + state->headroom;
85
86
87
return 0;
88
}
89
90
-static int update_time(struct state *state, uint64_t nsec, snd_pcm_sframes_t delay,
91
+static int update_time(struct state *state, uint64_t current_time, snd_pcm_sframes_t delay,
92
snd_pcm_sframes_t target, bool follower)
93
{
94
double err, corr;
95
96
97
if (SPA_UNLIKELY(state->dll.bw == 0.0)) {
98
spa_dll_set_bw(&state->dll, SPA_DLL_BW_MAX, state->threshold, state->rate);
99
- state->next_time = nsec;
100
- state->base_time = nsec;
101
+ state->next_time = current_time;
102
+ state->base_time = current_time;
103
}
104
diff = (int32_t) (state->last_threshold - state->threshold);
105
106
107
spa_log_trace(state->log, "%p: follower:%d quantum change %d -> %d (%d) %f",
108
state, follower, state->last_threshold, state->threshold, diff, err);
109
state->last_threshold = state->threshold;
110
+ state->alsa_sync = true;
111
}
112
- err = SPA_CLAMP(err, -state->max_error, state->max_error);
113
- corr = spa_dll_update(&state->dll, err);
114
+ if (err > state->max_error) {
115
+ err = state->max_error;
116
+ state->alsa_sync = true;
117
+ } else if (err < -state->max_error) {
118
+ err = -state->max_error;
119
+ state->alsa_sync = true;
120
+ }
121
+
122
+ if (!follower || state->matching)
123
+ corr = spa_dll_update(&state->dll, err);
124
+ else
125
+ corr = 1.0;
126
127
if (diff < 0)
128
state->next_time += diff / corr * 1e9 / state->rate;
129
130
if (SPA_UNLIKELY((state->next_time - state->base_time) > BW_PERIOD)) {
131
state->base_time = state->next_time;
132
133
- spa_log_debug(state->log, "%p: follower:%d match:%d rate:%f "
134
- "bw:%f thr:%u del:%ld target:%ld err:%f",
135
- state, follower, state->matching, corr, state->dll.bw,
136
- state->threshold, delay, target,
137
- err);
138
+ spa_log_debug(state->log, "%s: follower:%d match:%d rate:%f "
139
+ "bw:%f thr:%u del:%ld target:%ld err:%f max:%f",
140
+ state->props.device, follower, state->matching,
141
+ corr, state->dll.bw, state->threshold, delay, target,
142
+ err, state->max_error);
143
}
144
145
if (state->rate_match) {
146
147
state->next_time += state->threshold / corr * 1e9 / state->rate;
148
149
if (SPA_LIKELY(!follower && state->clock)) {
150
- state->clock->nsec = nsec;
151
+ state->clock->nsec = current_time;
152
state->clock->position += state->duration;
153
state->clock->duration = state->duration;
154
state->clock->delay = delay + state->delay;
155
156
}
157
158
spa_log_trace_fp(state->log, "%p: follower:%d %"PRIu64" %f %ld %f %f %u",
159
- state, follower, nsec, corr, delay, err, state->threshold * corr,
160
+ state, follower, current_time, corr, delay, err, state->threshold * corr,
161
state->threshold);
162
163
return 0;
164
165
state->rate_denom = state->position->clock.rate.denom;
166
state->threshold = (state->duration * state->rate + state->rate_denom-1) / state->rate_denom;
167
state->resample = ((uint32_t)state->rate != state->rate_denom) || state->matching;
168
+ state->alsa_sync = true;
169
}
170
}
171
172
173
{
174
snd_pcm_t *hndl = state->hndl;
175
const snd_pcm_channel_area_t *my_areas;
176
- snd_pcm_uframes_t written, frames, offset, off, to_write, total_written;
177
+ snd_pcm_uframes_t written, frames, offset, off, to_write, total_written, max_write;
178
snd_pcm_sframes_t commitres;
179
int res = 0;
180
181
check_position_config(state);
182
183
+ max_write = state->buffer_frames;
184
+
185
if (state->following && state->alsa_started) {
186
- uint64_t nsec;
187
+ uint64_t current_time;
188
snd_pcm_uframes_t delay, target;
189
190
- if (SPA_UNLIKELY((res = get_status(state, &delay, &target)) < 0))
191
+ current_time = state->position->clock.nsec;
192
+
193
+ if (SPA_UNLIKELY((res = get_status(state, current_time, &delay, &target)) < 0))
194
return res;
195
196
- if (SPA_UNLIKELY(!state->alsa_recovering && delay > target + state->threshold)) {
197
+ if (SPA_UNLIKELY(state->alsa_sync)) {
198
spa_log_warn(state->log, "%s: follower delay:%ld target:%ld thr:%u, resync",
199
state->props.device, delay, target, state->threshold);
200
- spa_dll_init(&state->dll);
201
- state->alsa_sync = true;
202
- }
203
- if (SPA_UNLIKELY(state->alsa_sync)) {
204
if (delay > target)
205
snd_pcm_rewind(state->hndl, delay - target);
206
- else
207
- snd_pcm_forward(state->hndl, target - delay);
208
-
209
+ else if (delay < target)
210
+ spa_alsa_silence(state, target - delay);
211
delay = target;
212
state->alsa_sync = false;
213
}
214
-
215
- nsec = state->position->clock.nsec;
216
- if (SPA_UNLIKELY((res = update_time(state, nsec, delay, target, true)) < 0))
217
+ if (SPA_UNLIKELY((res = update_time(state, current_time, delay, target, true)) < 0))
218
return res;
219
}
220
221
total_written = 0;
222
again:
223
224
- frames = state->buffer_frames;
225
- if (state->use_mmap) {
226
+ frames = max_write;
227
+ if (state->use_mmap && frames > 0) {
228
if (SPA_UNLIKELY((res = snd_pcm_mmap_begin(hndl, &my_areas, &offset, &frames)) < 0)) {
229
spa_log_error(state->log, "%s: snd_pcm_mmap_begin error: %s",
230
state->props.device, snd_strerror(res));
231
232
state, offset, written, state->sample_count);
233
total_written += written;
234
235
- if (state->use_mmap) {
236
+ if (state->use_mmap && written > 0) {
237
if (SPA_UNLIKELY((commitres = snd_pcm_mmap_commit(hndl, offset, written)) < 0)) {
238
spa_log_error(state->log, "%s: snd_pcm_mmap_commit error: %s",
239
state->props.device, snd_strerror(commitres));
240
if (commitres != -EPIPE && commitres != -ESTRPIPE)
241
return res;
242
}
243
-
244
if (commitres > 0 && written != (snd_pcm_uframes_t) commitres) {
245
spa_log_warn(state->log, "%s: mmap_commit wrote %ld instead of %ld",
246
state->props.device, commitres, written);
247
248
int spa_alsa_read(struct state *state)
249
{
250
snd_pcm_t *hndl = state->hndl;
251
- snd_pcm_uframes_t total_read = 0, to_read;
252
+ snd_pcm_uframes_t total_read = 0, to_read, max_read;
253
const snd_pcm_channel_area_t *my_areas;
254
snd_pcm_uframes_t read, frames, offset;
255
snd_pcm_sframes_t commitres;
256
int res = 0;
257
258
- if (state->position) {
259
- check_position_config(state);
260
+ check_position_config(state);
261
262
- if (!state->following) {
263
- uint64_t position;
264
-
265
- position = state->position->clock.position;
266
- if (state->last_position && state->last_position + state->last_duration != position) {
267
- state->alsa_sync = true;
268
- spa_log_info(state->log, "%s: discont, resync %"PRIu64" %"PRIu64" %d",
269
- state->props.device, state->last_position,
270
- position, state->last_duration);
271
- }
272
- state->last_position = position;
273
- state->last_duration = state->duration;
274
- }
275
- }
276
+ max_read = state->buffer_frames;
277
278
if (state->following && state->alsa_started) {
279
- uint64_t nsec;
280
- snd_pcm_uframes_t delay, target;
281
+ uint64_t current_time;
282
+ snd_pcm_uframes_t avail, delay, target;
283
uint32_t threshold = state->threshold;
284
285
- if ((res = get_status(state, &delay, &target)) < 0)
286
+ current_time = state->position->clock.nsec;
287
+
288
+ if ((res = get_status(state, current_time, &delay, &target)) < 0)
289
return res;
290
291
- if (!state->alsa_recovering && (delay < target / 2 || delay > target * 2)) {
292
- spa_log_warn(state->log, "%s: follower delay:%lu target:%lu thr:%u, resync",
293
- state->props.device, delay, target, threshold);
294
- spa_dll_init(&state->dll);
295
- state->alsa_sync = true;
296
- }
297
+ avail = delay;
298
+
299
if (state->alsa_sync) {
300
- spa_log_warn(state->log, "%s: follower resync delay:%ld target:%ld thr:%u",
301
+ spa_log_warn(state->log, "%s: follower delay:%lu target:%lu thr:%u, resync",
302
state->props.device, delay, target, threshold);
303
if (delay < target)
304
- snd_pcm_rewind(state->hndl, target - delay);
305
+ max_read = target - delay;
306
else if (delay > target)
307
snd_pcm_forward(state->hndl, delay - target);
308
-
309
delay = target;
310
state->alsa_sync = false;
311
}
312
313
- nsec = state->position->clock.nsec;
314
- if ((res = update_time(state, nsec, delay, target, true)) < 0)
315
+ if ((res = update_time(state, current_time, delay, target, true)) < 0)
316
return res;
317
+
318
+ if (avail < state->read_size)
319
+ max_read = 0;
320
}
321
322
- frames = state->read_size;
323
+ frames = SPA_MIN(max_read, state->read_size);
324
325
if (state->use_mmap) {
326
to_read = state->buffer_frames;
327
328
offset = 0;
329
}
330
331
- read = push_frames(state, my_areas, offset, frames);
332
-
333
- total_read += read;
334
+ if (frames > 0) {
335
+ read = push_frames(state, my_areas, offset, frames);
336
+ total_read += read;
337
+ } else {
338
+ spa_alsa_skip(state);
339
+ total_read += state->read_size;
340
+ read = 0;
341
+ }
342
343
- if (state->use_mmap) {
344
+ if (state->use_mmap && read > 0) {
345
spa_log_trace_fp(state->log, "%p: commit offs:%ld read:%ld count:%"PRIi64, state,
346
offset, read, state->sample_count);
347
if ((commitres = snd_pcm_mmap_commit(hndl, offset, read)) < 0) {
348
- spa_log_error(state->log, "%s: snd_pcm_mmap_commit error: %s",
349
- state->props.device, snd_strerror(commitres));
350
+ spa_log_error(state->log, "%s: snd_pcm_mmap_commit error %lu %lu: %s",
351
+ state->props.device, frames, read, snd_strerror(commitres));
352
if (commitres != -EPIPE && commitres != -ESTRPIPE)
353
return res;
354
}
355
-
356
if (commitres > 0 && read != (snd_pcm_uframes_t) commitres) {
357
spa_log_warn(state->log, "%s: mmap_commit read %ld instead of %ld",
358
state->props.device, commitres, read);
359
360
}
361
362
363
-static int handle_play(struct state *state, uint64_t nsec,
364
+static int handle_play(struct state *state, uint64_t current_time,
365
snd_pcm_uframes_t delay, snd_pcm_uframes_t target)
366
{
367
int res;
368
369
spa_log_trace(state->log, "%p: early wakeup %lu %lu", state, delay, target);
370
if (delay > target * 3)
371
delay = target * 3;
372
- state->next_time = nsec + (delay - target) * SPA_NSEC_PER_SEC / state->rate;
373
+ state->next_time = current_time + (delay - target) * SPA_NSEC_PER_SEC / state->rate;
374
return -EAGAIN;
375
}
376
377
- if (SPA_UNLIKELY((res = update_time(state, nsec, delay, target, false)) < 0))
378
+ if (SPA_UNLIKELY((res = update_time(state, current_time, delay, target, false)) < 0))
379
return res;
380
381
if (spa_list_is_empty(&state->ready)) {
382
383
return res;
384
}
385
386
-static int handle_capture(struct state *state, uint64_t nsec,
387
+static int handle_capture(struct state *state, uint64_t current_time,
388
snd_pcm_uframes_t delay, snd_pcm_uframes_t target)
389
{
390
int res;
391
392
393
if (SPA_UNLIKELY(delay < target)) {
394
spa_log_trace(state->log, "%p: early wakeup %ld %ld", state, delay, target);
395
- state->next_time = nsec + (target - delay) * SPA_NSEC_PER_SEC /
396
+ state->next_time = current_time + (target - delay) * SPA_NSEC_PER_SEC /
397
state->rate;
398
return -EAGAIN;
399
}
400
401
- if (SPA_UNLIKELY(res = update_time(state, nsec, delay, target, false)) < 0)
402
+ if (SPA_UNLIKELY(res = update_time(state, current_time, delay, target, false)) < 0)
403
return res;
404
405
if ((res = spa_alsa_read(state)) < 0)
406
407
{
408
struct state *state = source->data;
409
snd_pcm_uframes_t delay, target;
410
- uint64_t expire;
411
+ uint64_t expire, current_time;
412
413
if (SPA_UNLIKELY(state->started && spa_system_timerfd_read(state->data_system, state->timerfd, &expire) < 0))
414
spa_log_warn(state->log, "%p: error reading timerfd: %m", state);
415
416
check_position_config(state);
417
418
- if (SPA_UNLIKELY(get_status(state, &delay, &target) < 0))
419
- return;
420
+ current_time = state->next_time;
421
422
- state->current_time = state->next_time;
423
+ if (SPA_UNLIKELY(get_status(state, current_time, &delay, &target) < 0)) {
424
+ spa_log_error(state->log, "get_status error");
425
+ state->next_time += state->threshold * 1e9 / state->rate;
426
+ goto done;
427
+ }
428
429
#ifndef FASTPATH
430
if (SPA_UNLIKELY(spa_log_level_enabled(state->log, SPA_LOG_LEVEL_TRACE))) {
431
432
return;
433
nsec = SPA_TIMESPEC_TO_NSEC(&now);
434
spa_log_trace_fp(state->log, "%p: timeout %lu %lu %"PRIu64" %"PRIu64" %"PRIi64
435
- " %d %"PRIi64, state, delay, target, nsec, state->current_time,
436
- nsec - state->current_time, state->threshold, state->sample_count);
437
+ " %d %"PRIi64, state, delay, target, nsec, nsec,
438
+ nsec - current_time, state->threshold, state->sample_count);
439
}
440
#endif
441
442
if (state->stream == SND_PCM_STREAM_PLAYBACK)
443
- handle_play(state, state->current_time, delay, target);
444
+ handle_play(state, current_time, delay, target);
445
else
446
- handle_capture(state, state->current_time, delay, target);
447
+ handle_capture(state, current_time, delay, target);
448
449
+done:
450
+ if (state->next_time > current_time + SPA_NSEC_PER_SEC ||
451
+ current_time > state->next_time + SPA_NSEC_PER_SEC) {
452
+ spa_log_error(state->log, "%s: impossible timeout %lu %lu %"PRIu64" %"PRIu64" %"PRIi64
453
+ " %d %"PRIi64, state->props.device, delay, target, current_time, state->next_time,
454
+ state->next_time - current_time, state->threshold, state->sample_count);
455
+ state->next_time = current_time + state->threshold * 1e9 / state->rate;
456
+ }
457
set_timeout(state, state->next_time);
458
}
459
460
pipewire-0.3.45.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.47.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
18
1
2
uint32_t start_delay;
3
4
uint32_t duration;
5
- uint32_t last_duration;
6
- uint64_t last_position;
7
unsigned int alsa_started:1;
8
unsigned int alsa_sync:1;
9
unsigned int alsa_recovering:1;
10
11
int64_t sample_count;
12
13
int64_t sample_time;
14
- uint64_t current_time;
15
uint64_t next_time;
16
uint64_t base_time;
17
18
pipewire-0.3.45.tar.gz/spa/plugins/alsa/alsa-udev.c -> pipewire-0.3.47.tar.gz/spa/plugins/alsa/alsa-udev.c
Changed
159
1
2
*d = 0;
3
}
4
5
+static int check_device_pcm_class(const char *devname)
6
+{
7
+ FILE *f;
8
+ char path[PATH_MAX];
9
+ char buf[16];
10
+ size_t sz;
11
+
12
+ /* Check device class */
13
+ spa_scnprintf(path, sizeof(path), "/sys/class/sound/%s/pcm_class",
14
+ devname);
15
+ f = fopen(path, "r");
16
+ if (f == NULL)
17
+ return -errno;
18
+ sz = fread(buf, 1, sizeof(buf) - 1, f);
19
+ buf[sz] = '\0';
20
+ fclose(f);
21
+ return spa_strstartswith(buf, "modem") ? -ENXIO : 0;
22
+}
23
+
24
+static int get_num_pcm_devices(unsigned int card_id)
25
+{
26
+ char prefix[32];
27
+ DIR *snd = NULL;
28
+ struct dirent *entry;
29
+ int num_dev = 0;
30
+ int res;
31
+
32
+ /* Check if card has PCM devices, without opening them */
33
+
34
+ spa_scnprintf(prefix, sizeof(prefix), "pcmC%uD", card_id);
35
+
36
+ if ((snd = opendir("/dev/snd")) == NULL)
37
+ return -errno;
38
+
39
+ while ((errno = 0, entry = readdir(snd)) != NULL) {
40
+ if (!(entry->d_type == DT_CHR &&
41
+ spa_strstartswith(entry->d_name, prefix)))
42
+ continue;
43
+
44
+ res = check_device_pcm_class(entry->d_name);
45
+ if (res != -ENXIO) {
46
+ /* count device also if sysfs status file not accessible */
47
+ ++num_dev;
48
+ }
49
+ }
50
+ if (errno != 0)
51
+ res = -errno;
52
+ else
53
+ res = num_dev;
54
+
55
+ closedir(snd);
56
+ return res;
57
+}
58
+
59
static int check_device_available(struct impl *this, struct device *device, int *num_pcm)
60
{
61
char path[PATH_MAX];
62
63
struct dirent *entry, *entry_pcm;
64
int res;
65
66
+ res = get_num_pcm_devices(device->id);
67
+ if (res < 0) {
68
+ spa_log_error(this->log, "Error finding PCM devices for ALSA card %u: %s",
69
+ (unsigned int)device->id, spa_strerror(res));
70
+ return res;
71
+ }
72
+ *num_pcm = res;
73
+
74
+ spa_log_debug(this->log, "card %u has %d pcm device(s)", (unsigned int)device->id, *num_pcm);
75
+
76
/*
77
* Check if some pcm devices of the card are busy. Check it via /proc, as we
78
* don't want to actually open any devices using alsa-lib (generates uncontrolled
79
* number of inotify events), or replicate its subdevice logic.
80
+ *
81
+ * The /proc/asound directory might not exist if kernel is compiled with
82
+ * CONFIG_SND_PROCFS=n, and the pcmXX directories may be missing if compiled
83
+ * with CONFIG_SND_VERBOSE_PROCFS=n. In those cases, the busy check always succeeds.
84
*/
85
86
- *num_pcm = 0;
87
+ res = 0;
88
89
spa_scnprintf(path, sizeof(path), "/proc/asound/card%u", (unsigned int)device->id);
90
91
92
spa_strstartswith(entry->d_name, "pcm")))
93
continue;
94
95
- /* Check device class */
96
- spa_scnprintf(path, sizeof(path), "/sys/class/sound/pcmC%uD%s/pcm_class",
97
+ spa_scnprintf(path, sizeof(path), "pcmC%uD%s",
98
(unsigned int)device->id, entry->d_name+3);
99
- f = fopen(path, "r");
100
- if (f == NULL)
101
- goto done;
102
- sz = fread(buf, 1, sizeof(buf) - 1, f);
103
- buf[sz] = '\0';
104
- fclose(f);
105
- if (spa_strstartswith(buf, "modem"))
106
+ if (check_device_pcm_class(path) < 0)
107
continue;
108
109
/* Check busy status */
110
111
if (!spa_strstartswith(buf, "closed")) {
112
spa_log_debug(this->log, "card %u pcm device %s busy",
113
(unsigned int)device->id, entry->d_name);
114
- errno = EBUSY;
115
+ res = -EBUSY;
116
goto done;
117
}
118
spa_log_debug(this->log, "card %u pcm device %s free",
119
120
if (errno != 0)
121
goto done;
122
123
- ++*num_pcm;
124
-
125
closedir(pcm);
126
pcm = NULL;
127
}
128
129
goto done;
130
131
done:
132
- res = -errno;
133
+ if (errno != 0) {
134
+ spa_log_info(this->log, "card %u: failed to find busy status (%s)",
135
+ (unsigned int)device->id, spa_strerror(-errno));
136
+ }
137
if (card)
138
closedir(card);
139
if (pcm)
140
141
* device->emitted to true. alsalib functions can be used after that.
142
*/
143
144
+ snprintf(path, sizeof(path), "hw:%u", id);
145
+
146
if ((res = check_device_available(this, device, &pcm)) < 0)
147
return res;
148
if (pcm == 0) {
149
spa_log_debug(this->log, "no pcm devices for %s", path);
150
device->ignored = true;
151
- return 0;
152
+ return -ENODEV;
153
}
154
155
- snprintf(path, sizeof(path), "hw:%u", id);
156
spa_log_debug(this->log, "emitting card %s", path);
157
device->emitted = true;
158
159
pipewire-0.3.45.tar.gz/spa/plugins/alsa/mixer/profile-sets/texas-instruments-pcm2902.conf -> pipewire-0.3.47.tar.gz/spa/plugins/alsa/mixer/profile-sets/texas-instruments-pcm2902.conf
Changed
18
1
2
; Texas Instruments PCM2902
3
;
4
; This is a generic chip used in multiple products, including at least
5
-; Behringer U-Phoria UMC22, Behringer Xenyx 302USB, Intopic Jazz-UB700 and
6
-; some unbranded "usb mini microphone".
7
+; Behringer U-Phoria UMC22, Behringer U-Phoria UM2, Behringer Xenyx 302USB,
8
+; Intopic Jazz-UB700 and some unbranded "usb mini microphone".
9
;
10
; Behringer UMC22 has stereo input (representing two physical mono inputs),
11
; others have mono input.
12
;
13
+; (Behringer UMC22 and UM2 are "the same device" with different controls)
14
+;
15
; Some devices have a mic input path, but at least Behringer Xenyx 302USB
16
; doesn't have any input mixer controls.
17
;
18
pipewire-0.3.45.tar.gz/spa/plugins/alsa/test-timer.c -> pipewire-0.3.47.tar.gz/spa/plugins/alsa/test-timer.c
Changed
102
1
2
unsigned int rate;
3
unsigned int channels;
4
snd_pcm_uframes_t period;
5
+ snd_pcm_uframes_t buffer_frames;
6
7
snd_pcm_t *hndl;
8
int timerfd;
9
10
+ double max_error;
11
float accumulator;
12
13
uint64_t next_time;
14
15
16
static int on_timer_wakeup(struct state *state)
17
{
18
- snd_pcm_sframes_t avail, delay;
19
+ snd_pcm_sframes_t delay;
20
double error, corr;
21
-
22
- /* check the delay in the device */
23
- CHECK(snd_pcm_avail_delay(state->hndl, &avail, &delay), "delay");
24
+#if 1
25
+ snd_pcm_sframes_t avail;
26
+ CHECK(snd_pcm_avail_delay(state->hndl, &avail, &delay), "delay");
27
+#else
28
+ snd_pcm_uframes_t avail;
29
+ snd_htimestamp_t tstamp;
30
+ uint64_t then;
31
+
32
+ CHECK(snd_pcm_htimestamp(state->hndl, &avail, &tstamp), "htimestamp");
33
+ delay = state->buffer_frames - avail;
34
+
35
+ then = TIMESPEC_TO_NSEC(&tstamp);
36
+ if (then != 0) {
37
+ if (then < state->next_time) {
38
+ delay -= (state->next_time - then) * state->rate / NSEC_PER_SEC;
39
+ } else {
40
+ delay += (then - state->next_time) * state->rate / NSEC_PER_SEC;
41
+ }
42
+ }
43
+#endif
44
45
/* calculate the error, we want to have exactly 1 period of
46
* samples remaining in the device when we wakeup. */
47
error = (double)delay - (double)state->period;
48
+ if (error > state->max_error)
49
+ error = state->max_error;
50
+ else if (error < -state->max_error)
51
+ error = -state->max_error;
52
53
/* update the dll with the error, this gives a rate correction */
54
corr = spa_dll_update(&state->dll, error);
55
56
57
if (state->next_time - state->prev_time > BW_PERIOD) {
58
state->prev_time = state->next_time;
59
-
60
- /* reduce bandwidth and show some stats */
61
- if (state->dll.bw > SPA_DLL_BW_MIN)
62
- spa_dll_set_bw(&state->dll, state->dll.bw / 2.0,
63
- state->period, state->rate);
64
-
65
fprintf(stdout, "corr:%f error:%f bw:%f\n",
66
corr, error, state->dll.bw);
67
}
68
69
struct state state = { 0, };
70
const char *device = DEFAULT_DEVICE;
71
snd_pcm_hw_params_t *hparams;
72
+ snd_pcm_sw_params_t *sparams;
73
struct timespec now;
74
75
CHECK(snd_pcm_open(&state.hndl, device, SND_PCM_STREAM_PLAYBACK, 0), "open %s failed", device);
76
77
&state.rate, 0), "set rate");
78
CHECK(snd_pcm_hw_params(state.hndl, hparams), "hw_params");
79
80
+ CHECK(snd_pcm_hw_params_get_buffer_size(hparams, &state.buffer_frames), "get_buffer_size_max");
81
+
82
fprintf(stdout, "opened format:%s rate:%u channels:%u\n",
83
snd_pcm_format_name(SND_PCM_FORMAT_S32_LE),
84
state.rate, state.channels);
85
86
+ snd_pcm_sw_params_alloca(&sparams);
87
+#if 0
88
+ CHECK(snd_pcm_sw_params_current(state.hndl, sparams), "sw_params_current");
89
+ CHECK(snd_pcm_sw_params_set_tstamp_mode(state.hndl, sparams, SND_PCM_TSTAMP_ENABLE),
90
+ "sw_params_set_tstamp_type");
91
+ CHECK(snd_pcm_sw_params_set_tstamp_type(state.hndl, sparams, SND_PCM_TSTAMP_TYPE_MONOTONIC),
92
+ "sw_params_set_tstamp_type");
93
+ CHECK(snd_pcm_sw_params(state.hndl, sparams), "sw_params");
94
+#endif
95
+
96
spa_dll_init(&state.dll);
97
spa_dll_set_bw(&state.dll, SPA_DLL_BW_MAX, state.period, state.rate);
98
+ state.max_error = 256.0;
99
100
if ((state.timerfd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0)
101
perror("timerfd");
102
pipewire-0.3.45.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.47.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
10
1
2
3
/* Check if USB ALT6 is really available on the device */
4
if (device->adapter->bus_type == BUS_TYPE_USB && !msbc_alt1_ok && msbc_ok) {
5
-#if HAVE_LIBUSB
6
+#ifdef HAVE_LIBUSB
7
if (device->adapter->source_id == SOURCE_ID_USB) {
8
msbc_ok = check_usb_altsetting_6(backend, device->adapter->vendor_id,
9
device->adapter->product_id);
10
pipewire-0.3.45.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.47.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
14
1
2
}
3
}
4
5
-static inline void add_dict(struct spa_pod_builder *builder, const char *key, const char *val)
6
-{
7
- spa_pod_builder_string(builder, key);
8
- spa_pod_builder_string(builder, val);
9
-}
10
-
11
static int a2dp_codec_to_endpoint(const struct a2dp_codec *codec,
12
const char * endpoint,
13
char** object_path)
14
pipewire-0.3.45.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.47.tar.gz/spa/plugins/bluez5/meson.build
Changed
56
1
2
endif
3
endforeach
4
5
-if not get_option('bluez5-backend-hsp-native').disabled()
6
- cdata.set('HAVE_BLUEZ_5_BACKEND_HSP_NATIVE', 1)
7
- cdata.set('HAVE_BLUEZ_5_BACKEND_NATIVE', 1)
8
-endif
9
-if not get_option('bluez5-backend-hfp-native').disabled()
10
- cdata.set('HAVE_BLUEZ_5_BACKEND_HFP_NATIVE', 1)
11
- cdata.set('HAVE_BLUEZ_5_BACKEND_NATIVE', 1)
12
-endif
13
-if not get_option('bluez5-backend-ofono').disabled()
14
- cdata.set('HAVE_BLUEZ_5_BACKEND_OFONO', 1)
15
-endif
16
-if not get_option('bluez5-backend-hsphfpd').disabled()
17
- cdata.set('HAVE_BLUEZ_5_BACKEND_HSPHFPD', 1)
18
-endif
19
-
20
-if dependency('bluez', version: '< 6', required: false).found()
21
- cdata.set('HAVE_BLUEZ_5_HCI', 1)
22
-endif
23
+cdata.set('HAVE_BLUEZ_5_BACKEND_NATIVE',
24
+ get_option('bluez5-backend-hsp-native').allowed() or
25
+ get_option('bluez5-backend-hfp-native').allowed())
26
+cdata.set('HAVE_BLUEZ_5_BACKEND_HSP_NATIVE', get_option('bluez5-backend-hsp-native').allowed())
27
+cdata.set('HAVE_BLUEZ_5_BACKEND_HFP_NATIVE', get_option('bluez5-backend-hfp-native').allowed())
28
+cdata.set('HAVE_BLUEZ_5_BACKEND_OFONO', get_option('bluez5-backend-ofono').allowed())
29
+cdata.set('HAVE_BLUEZ_5_BACKEND_HSPHFPD', get_option('bluez5-backend-hsphfpd').allowed())
30
+cdata.set('HAVE_BLUEZ_5_HCI', dependency('bluez', version: '< 6', required: false).found())
31
32
bluez5_sources = [
33
'plugin.c',
34
35
36
install_data(bluez5_data, install_dir : spa_datadir / 'bluez5')
37
38
-if not get_option('bluez5-backend-hsp-native').disabled() or not get_option('bluez5-backend-hfp-native').disabled()
39
+if get_option('bluez5-backend-hsp-native').allowed() or get_option('bluez5-backend-hfp-native').allowed()
40
if libusb_dep.found()
41
bluez5_deps += libusb_dep
42
endif
43
bluez5_sources += ['backend-native.c']
44
endif
45
46
-if not get_option('bluez5-backend-ofono').disabled()
47
+if get_option('bluez5-backend-ofono').allowed()
48
bluez5_sources += ['backend-ofono.c']
49
endif
50
51
-if not get_option('bluez5-backend-hsphfpd').disabled()
52
+if get_option('bluez5-backend-hsphfpd').allowed()
53
bluez5_sources += ['backend-hsphfpd.c']
54
endif
55
56
pipewire-0.3.45.tar.gz/spa/plugins/meson.build -> pipewire-0.3.47.tar.gz/spa/plugins/meson.build
Changed
54
1
2
if alsa_dep.found()
3
subdir('alsa')
4
endif
5
-if not get_option('audioconvert').disabled()
6
+if get_option('audioconvert').allowed()
7
subdir('audioconvert')
8
endif
9
-if not get_option('audiomixer').disabled()
10
+if get_option('audiomixer').allowed()
11
subdir('audiomixer')
12
endif
13
-if not get_option('control').disabled()
14
+if get_option('control').allowed()
15
subdir('control')
16
endif
17
-if not get_option('audiotestsrc').disabled()
18
+if get_option('audiotestsrc').allowed()
19
subdir('audiotestsrc')
20
endif
21
if bluez_dep.found()
22
23
if jack_dep.found()
24
subdir('jack')
25
endif
26
-if not get_option('support').disabled()
27
+if get_option('support').allowed()
28
subdir('support')
29
endif
30
-if not get_option('test').disabled()
31
+if get_option('test').allowed()
32
subdir('test')
33
endif
34
-if not get_option('videoconvert').disabled()
35
+if get_option('videoconvert').allowed()
36
subdir('videoconvert')
37
endif
38
-if not get_option('videotestsrc').disabled()
39
+if get_option('videotestsrc').allowed()
40
subdir('videotestsrc')
41
endif
42
-if not get_option('volume').disabled()
43
+if get_option('volume').allowed()
44
subdir('volume')
45
endif
46
if vulkan_headers
47
48
if libcamera_dep.found()
49
subdir('libcamera')
50
endif
51
+
52
+subdir('aec')
53
\ No newline at end of file
54
pipewire-0.3.45.tar.gz/spa/plugins/support/logger.c -> pipewire-0.3.47.tar.gz/spa/plugins/support/logger.c
Changed
28
1
2
struct spa_log log;
3
4
FILE *file;
5
+ bool close_file;
6
7
struct spa_system *system;
8
struct spa_source source;
9
10
11
support_log_free_patterns(&this->patterns);
12
13
+ if (this->close_file && this->file != NULL)
14
+ fclose(this->file);
15
+
16
if (this->have_source) {
17
spa_loop_remove_source(this->source.loop, &this->source);
18
spa_system_close(this->system, this->source.fd);
19
20
this->file = fopen(str, "w");
21
if (this->file == NULL)
22
fprintf(stderr, "Warning: failed to open file %s: (%m)", str);
23
+ else
24
+ this->close_file = true;
25
}
26
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_PATTERNS)) != NULL)
27
support_log_parse_patterns(&this->patterns, str);
28
pipewire-0.3.45.tar.gz/spa/plugins/support/loop.c -> pipewire-0.3.47.tar.gz/spa/plugins/support/loop.c
Changed
156
1
2
#define MAX_ALIGN 8
3
#define ITEM_ALIGN 8
4
#define DATAS_SIZE (4096*8)
5
+#define MAX_EP 32
6
7
/** \cond */
8
9
10
struct spa_system *system;
11
12
struct spa_list source_list;
13
- struct spa_list destroy_list;
14
struct spa_hook_list hooks_list;
15
16
int poll_fd;
17
pthread_t thread;
18
+ int enter_count;
19
20
struct spa_source *wakeup;
21
int ack_fd;
22
23
{
24
struct impl *impl = object;
25
source->loop = &impl->loop;
26
+ source->priv = NULL;
27
return spa_system_pollfd_add(impl->system, impl->poll_fd, source->fd, source->mask, source);
28
}
29
30
31
static int loop_remove_source(void *object, struct spa_source *source)
32
{
33
struct impl *impl = object;
34
+ struct spa_poll_event *e;
35
+ if ((e = source->priv)) {
36
+ /* active in an iteration of the loop, remove it from there */
37
+ e->data = NULL;
38
+ source->priv = NULL;
39
+ }
40
source->loop = NULL;
41
return spa_system_pollfd_del(impl->system, impl->poll_fd, source->fd);
42
}
43
44
static void loop_enter(void *object)
45
{
46
struct impl *impl = object;
47
- impl->thread = pthread_self();
48
+ pthread_t thread_id = pthread_self();
49
+
50
+ if (impl->enter_count == 0) {
51
+ spa_return_if_fail(impl->thread == 0);
52
+ impl->thread = thread_id;
53
+ impl->enter_count = 1;
54
+ } else {
55
+ spa_return_if_fail(impl->enter_count > 0);
56
+ spa_return_if_fail(impl->thread == thread_id);
57
+ impl->enter_count++;
58
+ }
59
spa_log_trace(impl->log, "%p: enter %lu", impl, impl->thread);
60
}
61
62
static void loop_leave(void *object)
63
{
64
struct impl *impl = object;
65
+ pthread_t thread_id = pthread_self();
66
+
67
+ spa_return_if_fail(impl->enter_count > 0);
68
+ spa_return_if_fail(impl->thread == thread_id);
69
+
70
spa_log_trace(impl->log, "%p: leave %lu", impl, impl->thread);
71
- impl->thread = 0;
72
-}
73
74
-static inline void process_destroy(struct impl *impl)
75
-{
76
- struct source_impl *source, *tmp;
77
- spa_list_for_each_safe(source, tmp, &impl->destroy_list, link)
78
- free(source);
79
- spa_list_init(&impl->destroy_list);
80
+ if (--impl->enter_count == 0)
81
+ impl->thread = 0;
82
}
83
84
static int loop_iterate(void *object, int timeout)
85
{
86
struct impl *impl = object;
87
- struct spa_loop *loop = &impl->loop;
88
- struct spa_poll_event ep[32];
89
+ struct spa_poll_event ep[MAX_EP], *e;
90
int i, nfds;
91
92
spa_loop_control_hook_before(&impl->hooks_list);
93
94
- nfds = spa_system_pollfd_wait(impl->system, impl->poll_fd, ep, SPA_N_ELEMENTS(ep), timeout);
95
+ nfds = spa_system_pollfd_wait(impl->system, impl->poll_fd, ep, MAX_EP, timeout);
96
97
spa_loop_control_hook_after(&impl->hooks_list);
98
99
100
for (i = 0; i < nfds; i++) {
101
struct spa_source *s = ep[i].data;
102
s->rmask = ep[i].events;
103
+ /* already active in another iteration of the loop,
104
+ * remove it from that iteration */
105
+ if (SPA_UNLIKELY(e = s->priv))
106
+ e->data = NULL;
107
+ s->priv = &ep[i];
108
}
109
for (i = 0; i < nfds; i++) {
110
struct spa_source *s = ep[i].data;
111
- if (SPA_LIKELY(s->rmask && s->fd != -1 && s->loop == loop))
112
+ if (SPA_LIKELY(s && s->rmask)) {
113
+ s->priv = NULL;
114
s->func(s);
115
+ }
116
}
117
- if (SPA_UNLIKELY(!spa_list_is_empty(&impl->destroy_list)))
118
- process_destroy(impl);
119
-
120
return nfds;
121
}
122
123
124
spa_system_close(impl->impl->system, source->fd);
125
source->fd = -1;
126
}
127
- spa_list_insert(&impl->impl->destroy_list, &impl->link);
128
+ free(source);
129
}
130
131
static const struct spa_loop_methods impl_loop = {
132
133
134
impl = (struct impl *) handle;
135
136
+ if (impl->enter_count != 0)
137
+ spa_log_warn(impl->log, "%p: loop is entered %d times",
138
+ impl, impl->enter_count);
139
+
140
spa_list_consume(source, &impl->source_list, link)
141
loop_destroy_source(impl, &source->source);
142
143
- process_destroy(impl);
144
-
145
spa_system_close(impl->system, impl->ack_fd);
146
spa_system_close(impl->system, impl->poll_fd);
147
148
149
impl->poll_fd = res;
150
151
spa_list_init(&impl->source_list);
152
- spa_list_init(&impl->destroy_list);
153
spa_hook_list_init(&impl->hooks_list);
154
155
impl->buffer_data = SPA_PTR_ALIGN(impl->buffer_mem, MAX_ALIGN, uint8_t);
156
pipewire-0.3.45.tar.gz/spa/plugins/support/meson.build -> pipewire-0.3.47.tar.gz/spa/plugins/support/meson.build
Changed
10
1
2
install_dir : spa_plugindir / 'support')
3
spa_support_dep = declare_dependency(link_with: spa_support_lib)
4
5
-if not get_option('evl').disabled()
6
+if get_option('evl').allowed()
7
evl_inc = include_directories('/usr/evl/include')
8
evl_lib = cc.find_library('evl',
9
dirs: ['/usr/evl/lib/'],
10
pipewire-0.3.45.tar.gz/src/daemon/client-rt.conf.in -> pipewire-0.3.47.tar.gz/src/daemon/client-rt.conf.in
Changed
13
1
2
#
3
# Copy and edit this file in @PIPEWIRE_CONFIG_DIR@ for system-wide changes
4
# or in ~/.config/pipewire for local changes.
5
+#
6
+# It is also possible to place a file with an updated section in
7
+# @PIPEWIRE_CONFIG_DIR@/client-rt.conf.d/ for system-wide changes or in
8
+# ~/.config/pipewire/client-rt.conf.d/ for local changes.
9
+#
10
11
context.properties = {
12
## Configure properties in the system.
13
pipewire-0.3.45.tar.gz/src/daemon/client.conf.in -> pipewire-0.3.47.tar.gz/src/daemon/client.conf.in
Changed
14
1
2
#
3
# Copy and edit this file in @PIPEWIRE_CONFIG_DIR@ for system-wide changes
4
# or in ~/.config/pipewire for local changes.
5
-
6
+#
7
+# It is also possible to place a file with an updated section in
8
+# @PIPEWIRE_CONFIG_DIR@/client.conf.d/ for system-wide changes or in
9
+# ~/.config/pipewire/client.conf.d/ for local changes.
10
+#
11
context.properties = {
12
## Configure properties in the system.
13
#mem.warn-mlock = false
14
pipewire-0.3.45.tar.gz/src/daemon/jack.conf.in -> pipewire-0.3.47.tar.gz/src/daemon/jack.conf.in
Changed
33
1
2
#
3
# Copy and edit this file in @PIPEWIRE_CONFIG_DIR@ for system-wide changes
4
# or in ~/.config/pipewire for local changes.
5
+#
6
+# It is also possible to place a file with an updated section in
7
+# @PIPEWIRE_CONFIG_DIR@/jack.conf.d/ for system-wide changes or in
8
+# ~/.config/pipewire/jack.conf.d/ for local changes.
9
+#
10
11
context.properties = {
12
## Configure properties in the system.
13
14
# global properties for all jack clients
15
jack.properties = {
16
#node.latency = 1024/48000
17
- #node.lock-quantum = false
18
+ #node.rate = 1/48000
19
+ #node.quantum = 1024/48000
20
+ #node.lock-quantum = true
21
+ #node.force-quantum = 0
22
#jack.show-monitor = true
23
#jack.merge-monitor = false
24
#jack.short-name = false
25
26
# ignore-all: Ignore all self connect requests
27
#jack.self-connect-mode = allow
28
#jack.locked-process = true
29
+ #jack.default-as-system = false
30
}
31
32
# client specific properties
33
pipewire-0.3.45.tar.gz/src/daemon/minimal.conf.in -> pipewire-0.3.47.tar.gz/src/daemon/minimal.conf.in
Changed
13
1
2
#
3
# Copy and edit this file in @PIPEWIRE_CONFIG_DIR@ for system-wide changes
4
# or in ~/.config/pipewire for local changes.
5
+#
6
+# It is also possible to place a file with an updated section in
7
+# @PIPEWIRE_CONFIG_DIR@/minimal.conf.d/ for system-wide changes or in
8
+# ~/.config/pipewire/minimal.conf.d/ for local changes.
9
+#
10
11
context.properties = {
12
## Configure properties in the system.
13
pipewire-0.3.45.tar.gz/src/daemon/pipewire-pulse.conf.in -> pipewire-0.3.47.tar.gz/src/daemon/pipewire-pulse.conf.in
Changed
21
1
2
#
3
# Copy and edit this file in @PIPEWIRE_CONFIG_DIR@ for system-wide changes
4
# or in ~/.config/pipewire for local changes.
5
+#
6
+# It is also possible to place a file with an updated section in
7
+# @PIPEWIRE_CONFIG_DIR@/pipewire-pulse.conf.d/ for system-wide changes or in
8
+# ~/.config/pipewire/pipewire-pulse.conf.d/ for local changes.
9
+#
10
11
context.properties = {
12
## Configure properties in the system.
13
14
15
# Extra modules can be loaded here. Setup in default.pa can be moved here
16
context.exec = [
17
+ { path = "pactl" args = "load-module module-always-sink" }
18
#{ path = "pactl" args = "load-module module-switch-on-connect" }
19
#{ path = "/usr/bin/sh" args = "~/.config/pipewire/default.pw" }
20
]
21
pipewire-0.3.45.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.47.tar.gz/src/daemon/pipewire.conf.in
Changed
22
1
2
#
3
# Copy and edit this file in @PIPEWIRE_CONFIG_DIR@ for system-wide changes
4
# or in ~/.config/pipewire for local changes.
5
+#
6
+# It is also possible to place a file with an updated section in
7
+# @PIPEWIRE_CONFIG_DIR@/pipewire.conf.d/ for system-wide changes or in
8
+# ~/.config/pipewire/pipewire.conf.d/ for local changes.
9
+#
10
11
context.properties = {
12
## Configure properties in the system.
13
14
#default.clock.rate = 48000
15
#default.clock.allowed-rates = [ 48000 ]
16
#default.clock.quantum = 1024
17
- #default.clock.min-quantum = 32
18
+ default.clock.min-quantum = 16
19
#default.clock.max-quantum = 2048
20
#default.clock.quantum-limit = 8192
21
#default.video.width = 640
22
pipewire-0.3.45.tar.gz/src/daemon/systemd/meson.build -> pipewire-0.3.47.tar.gz/src/daemon/systemd/meson.build
Changed
10
1
2
-if not get_option('systemd-system-service').disabled()
3
+if get_option('systemd-system-service').allowed()
4
subdir('system')
5
endif
6
-if not get_option('systemd-user-service').disabled()
7
+if get_option('systemd-user-service').allowed()
8
subdir('user')
9
endif
10
pipewire-0.3.45.tar.gz/src/gst/gstpipewire.c -> pipewire-0.3.47.tar.gz/src/gst/gstpipewire.c
Changed
10
1
2
gst_element_register (plugin, "pipewiresink", GST_RANK_NONE,
3
GST_TYPE_PIPEWIRE_SINK);
4
5
-#if HAVE_GSTREAMER_DEVICE_PROVIDER
6
+#ifdef HAVE_GSTREAMER_DEVICE_PROVIDER
7
if (!gst_device_provider_register (plugin, "pipewiredeviceprovider",
8
GST_RANK_PRIMARY + 1, GST_TYPE_PIPEWIRE_DEVICE_PROVIDER))
9
return FALSE;
10
pipewire-0.3.45.tar.gz/src/gst/gstpipewireformat.c -> pipewire-0.3.47.tar.gz/src/gst/gstpipewireformat.c
Changed
58
1
2
return TRUE;
3
}
4
5
+static void
6
+set_default_channels (struct spa_pod_builder *b, uint32_t channels)
7
+{
8
+ uint32_t position[SPA_AUDIO_MAX_CHANNELS] = {0};
9
+ gboolean ok = TRUE;
10
+
11
+ switch (channels) {
12
+ case 8:
13
+ position[6] = SPA_AUDIO_CHANNEL_SL;
14
+ position[7] = SPA_AUDIO_CHANNEL_SR;
15
+ SPA_FALLTHROUGH
16
+ case 6:
17
+ position[5] = SPA_AUDIO_CHANNEL_LFE;
18
+ SPA_FALLTHROUGH
19
+ case 5:
20
+ position[4] = SPA_AUDIO_CHANNEL_FC;
21
+ SPA_FALLTHROUGH
22
+ case 4:
23
+ position[2] = SPA_AUDIO_CHANNEL_RL;
24
+ position[3] = SPA_AUDIO_CHANNEL_RR;
25
+ SPA_FALLTHROUGH
26
+ case 2:
27
+ position[0] = SPA_AUDIO_CHANNEL_FL;
28
+ position[1] = SPA_AUDIO_CHANNEL_FR;
29
+ break;
30
+ case 1:
31
+ position[0] = SPA_AUDIO_CHANNEL_MONO;
32
+ break;
33
+ default:
34
+ ok = FALSE;
35
+ break;
36
+ }
37
+
38
+ if (ok)
39
+ spa_pod_builder_add (b, SPA_FORMAT_AUDIO_position,
40
+ SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, channels, position), 0);
41
+}
42
+
43
static gboolean
44
handle_audio_fields (ConvertData *d)
45
{
46
47
}
48
if (i > 0) {
49
choice = spa_pod_builder_pop(&d->b, &f);
50
- if (i == 1)
51
+ if (i == 1) {
52
choice->body.type = SPA_CHOICE_None;
53
+ set_default_channels (&d->b, v);
54
+ }
55
}
56
}
57
return TRUE;
58
pipewire-0.3.45.tar.gz/src/gst/meson.build -> pipewire-0.3.47.tar.gz/src/gst/meson.build
Changed
10
1
2
'gstpipewiresrc.c',
3
]
4
5
-if not get_option('gstreamer-device-provider').disabled()
6
+if get_option('gstreamer-device-provider').allowed()
7
pipewire_gst_sources += [ 'gstpipewiredeviceprovider.c' ]
8
endif
9
10
pipewire-0.3.45.tar.gz/src/meson.build -> pipewire-0.3.47.tar.gz/src/meson.build
Changed
14
1
2
subdir('daemon')
3
subdir('tools')
4
subdir('modules')
5
-if not get_option('examples').disabled()
6
+if get_option('examples').allowed()
7
subdir('examples')
8
endif
9
-if not get_option('tests').disabled()
10
+if get_option('tests').allowed()
11
subdir('tests')
12
endif
13
14
pipewire-0.3.45.tar.gz/src/modules/meson.build -> pipewire-0.3.47.tar.gz/src/modules/meson.build
Changed
87
1
2
'module-echo-cancel.c',
3
'module-example-sink.c',
4
'module-example-source.c',
5
+ 'module-fallback-sink.c',
6
'module-filter-chain.c',
7
'module-link-factory.c',
8
'module-loopback.c',
9
10
11
pipewire_module_echo_cancel_sources = [
12
'module-echo-cancel.c',
13
- 'module-echo-cancel/aec-null.c',
14
]
15
16
-if webrtc_dep.found()
17
- pipewire_module_echo_cancel_sources += [
18
- 'module-echo-cancel/aec-webrtc.cpp'
19
- ]
20
-endif
21
-
22
pipewire_module_echo_cancel = shared_library('pipewire-module-echo-cancel',
23
pipewire_module_echo_cancel_sources,
24
include_directories : [configinc],
25
install : true,
26
install_dir : modules_install_dir,
27
install_rpath: modules_install_dir,
28
- dependencies : [mathlib, dl_lib, pipewire_dep, webrtc_dep],
29
+ dependencies : [mathlib, dl_lib, pipewire_dep],
30
)
31
32
pipewire_module_profiler = shared_library('pipewire-module-profiler',
33
34
'module-protocol-pulse/extensions/ext-stream-restore.c',
35
'module-protocol-pulse/format.c',
36
'module-protocol-pulse/manager.c',
37
- 'module-protocol-pulse/media-roles.c',
38
'module-protocol-pulse/message.c',
39
'module-protocol-pulse/message-handler.c',
40
'module-protocol-pulse/module.c',
41
42
'module-protocol-pulse/pending-sample.c',
43
'module-protocol-pulse/pulse-server.c',
44
'module-protocol-pulse/quirks.c',
45
+ 'module-protocol-pulse/remap.c',
46
'module-protocol-pulse/reply.c',
47
'module-protocol-pulse/sample.c',
48
'module-protocol-pulse/sample-play.c',
49
50
'module-protocol-pulse/stream.c',
51
'module-protocol-pulse/utils.c',
52
'module-protocol-pulse/volume.c',
53
+ 'module-protocol-pulse/modules/module-always-sink.c',
54
'module-protocol-pulse/modules/module-combine-sink.c',
55
'module-protocol-pulse/modules/module-echo-cancel.c',
56
'module-protocol-pulse/modules/module-ladspa-sink.c',
57
58
'module-protocol-pulse/dbus-name.c',
59
]
60
pipewire_module_protocol_pulse_deps += dbus_dep
61
- cdata.set('HAVE_DBUS', 1)
62
endif
63
64
if avahi_dep.found()
65
66
'module-zeroconf-discover/avahi-poll.c',
67
]
68
pipewire_module_protocol_pulse_deps += avahi_dep
69
- cdata.set('HAVE_AVAHI', 1)
70
+ cdata.set('HAVE_AVAHI', true)
71
endif
72
73
pipewire_module_protocol_pulse = shared_library('pipewire-module-protocol-pulse',
74
75
)
76
endif
77
summary({'x11-bell': build_module_x11_bell}, bool_yn: true, section: 'Optional Modules')
78
+
79
+pipewire_module_fallback_sink = shared_library('pipewire-module-fallback-sink',
80
+ [ 'module-fallback-sink.c' ],
81
+ include_directories : [configinc],
82
+ install : true,
83
+ install_dir : modules_install_dir,
84
+ install_rpath: modules_install_dir,
85
+ dependencies : [mathlib, dl_lib, rt_lib, pipewire_dep],
86
+)
87
pipewire-0.3.45.tar.gz/src/modules/module-access.c -> pipewire-0.3.47.tar.gz/src/modules/module-access.c
Changed
14
1
2
3
#include "config.h"
4
5
-#if HAVE_SYS_VFS_H
6
+#ifdef HAVE_SYS_VFS_H
7
#include <sys/vfs.h>
8
#endif
9
-#if HAVE_SYS_MOUNT_H
10
+#ifdef HAVE_SYS_MOUNT_H
11
#include <sys/mount.h>
12
#endif
13
14
pipewire-0.3.45.tar.gz/src/modules/module-client-node/client-node.c -> pipewire-0.3.47.tar.gz/src/modules/module-client-node/client-node.c
Changed
235
1
2
3
/** \cond */
4
5
-#define MAX_INPUTS 1024
6
-#define MAX_OUTPUTS 1024
7
-
8
#define MAX_BUFFERS 64
9
#define MAX_METAS 16u
10
#define MAX_DATAS 64u
11
#define MAX_AREAS 2048
12
-#define MAX_MIX 128
13
-
14
-#define CHECK_IN_PORT_ID(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_INPUTS)
15
-#define CHECK_OUT_PORT_ID(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_OUTPUTS)
16
-#define CHECK_PORT_ID(this,d,p) (CHECK_IN_PORT_ID(this,d,p) || CHECK_OUT_PORT_ID(this,d,p))
17
-#define CHECK_FREE_IN_PORT(this,d,p) (CHECK_IN_PORT_ID(this,d,p) && (this)->in_ports[p] == NULL)
18
-#define CHECK_FREE_OUT_PORT(this,d,p) (CHECK_OUT_PORT_ID(this,d,p) && (this)->out_ports[p] == NULL)
19
-#define CHECK_FREE_PORT(this,d,p) (CHECK_FREE_IN_PORT (this,d,p) || CHECK_FREE_OUT_PORT (this,d,p))
20
-#define CHECK_IN_PORT(this,d,p) (CHECK_IN_PORT_ID(this,d,p) && (this)->in_ports[p])
21
-#define CHECK_OUT_PORT(this,d,p) (CHECK_OUT_PORT_ID(this,d,p) && (this)->out_ports[p])
22
-#define CHECK_PORT(this,d,p) (CHECK_IN_PORT (this,d,p) || CHECK_OUT_PORT (this,d,p))
23
-
24
-#define GET_IN_PORT(this,p) (this->in_ports[p])
25
-#define GET_OUT_PORT(this,p) (this->out_ports[p])
26
-#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
27
+
28
+#define CHECK_FREE_PORT(this,d,p) (p <= pw_map_get_size(&this->ports[d]) && !CHECK_PORT(this,d,p))
29
+#define CHECK_PORT(this,d,p) (pw_map_lookup(&this->ports[d], p) != NULL)
30
+#define GET_PORT(this,d,p) (pw_map_lookup(&this->ports[d], p))
31
32
#define CHECK_PORT_BUFFER(this,b,p) (b < p->n_buffers)
33
34
35
struct spa_source data_source;
36
int writefd;
37
38
- uint32_t n_inputs;
39
- uint32_t n_outputs;
40
- struct port *in_ports[MAX_INPUTS];
41
- struct port *out_ports[MAX_OUTPUTS];
42
+ struct pw_map ports[2];
43
44
struct port dummy;
45
46
47
mix_id = 0;
48
else
49
mix_id++;
50
- if (mix_id >= MAX_MIX)
51
- return NULL;
52
+
53
len = pw_array_get_len(&p->mix, struct mix);
54
if (mix_id >= len) {
55
size_t need = sizeof(struct mix) * (mix_id + 1 - len);
56
57
{
58
struct node *this = object;
59
struct spa_hook_list save;
60
- uint32_t i;
61
+ union pw_map_item *item;
62
63
spa_return_val_if_fail(this != NULL, -EINVAL);
64
65
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
66
67
- for (i = 0; i < MAX_INPUTS; i++) {
68
- if (this->in_ports[i])
69
- emit_port_info(this, this->in_ports[i]);
70
+ pw_array_for_each(item, &this->ports[SPA_DIRECTION_INPUT].items) {
71
+ if (item->data)
72
+ emit_port_info(this, item->data);
73
}
74
- for (i = 0; i < MAX_OUTPUTS; i++) {
75
- if (this->out_ports[i])
76
- emit_port_info(this, this->out_ports[i]);
77
+ pw_array_for_each(item, &this->ports[SPA_DIRECTION_OUTPUT].items) {
78
+ if (item->data)
79
+ emit_port_info(this, item->data);
80
}
81
spa_hook_list_join(&this->hooks, &save);
82
83
84
pw_array_clear(&port->mix);
85
pw_array_init(&port->mix, sizeof(struct mix) * 2);
86
87
- if (port->direction == SPA_DIRECTION_INPUT) {
88
- if (this->in_ports[port->id] == port) {
89
- this->in_ports[port->id] = NULL;
90
- this->n_inputs--;
91
- }
92
- }
93
- else {
94
- if (this->out_ports[port->id] == port) {
95
- this->out_ports[port->id] = NULL;
96
- this->n_outputs--;
97
- }
98
- }
99
+ pw_map_insert_at(&this->ports[port->direction], port->id, NULL);
100
+
101
if (!port->removed)
102
spa_node_emit_port_info(&this->hooks, port->direction, port->id, NULL);
103
}
104
105
106
spa_return_val_if_fail(this != NULL, -EINVAL);
107
spa_return_val_if_fail(num != 0, -EINVAL);
108
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
109
110
port = GET_PORT(this, direction, port_id);
111
+ spa_return_val_if_fail(port != NULL, -EINVAL);
112
113
pw_log_debug("%p: seq:%d port %d.%d id:%u start:%u num:%u n_params:%d",
114
this, seq, direction, port_id, id, start, num, port->n_params);
115
116
struct mix *mix;
117
118
spa_return_val_if_fail(this != NULL, -EINVAL);
119
- if(!CHECK_PORT(this, direction, port_id))
120
+
121
+ port = GET_PORT(this, direction, port_id);
122
+ if(port == NULL)
123
return param == NULL ? 0 : -EINVAL;
124
125
pw_log_debug("%p: port %d.%d set param %s %d", this,
126
direction, port_id,
127
spa_debug_type_find_name(spa_type_param, id), id);
128
129
- port = GET_PORT(this, direction, port_id);
130
-
131
if (id == SPA_PARAM_Format) {
132
pw_array_for_each(mix, &port->mix)
133
clear_buffers(this, mix);
134
135
direction == SPA_DIRECTION_INPUT ? "input" : "output",
136
port_id, mix_id, data, size);
137
138
- if (!CHECK_PORT(this, direction, port_id))
139
- return data == NULL ? 0 : -EINVAL;
140
-
141
port = GET_PORT(this, direction, port_id);
142
+ if (port == NULL)
143
+ return data == NULL ? 0 : -EINVAL;
144
145
if ((mix = find_mix(port, mix_id)) == NULL || !mix->valid)
146
return -EINVAL;
147
148
uint32_t i, j, peer_id;
149
struct pw_client_node_buffer *mb;
150
151
- if (!CHECK_PORT(this, direction, port_id))
152
+ p = GET_PORT(this, direction, port_id);
153
+ if (p == NULL)
154
return n_buffers == 0 ? 0 : -EINVAL;
155
156
if (n_buffers > MAX_BUFFERS)
157
return -ENOSPC;
158
159
- p = GET_PORT(this, direction, port_id);
160
161
spa_log_debug(this->log, "%p: %s port %d.%d use buffers %p %u flags:%08x", this,
162
direction == SPA_DIRECTION_INPUT ? "input" : "output",
163
164
struct node *this = object;
165
166
spa_return_val_if_fail(this != NULL, -EINVAL);
167
- spa_return_val_if_fail(CHECK_OUT_PORT(this, SPA_DIRECTION_OUTPUT, port_id), -EINVAL);
168
+ spa_return_val_if_fail(CHECK_PORT(this, SPA_DIRECTION_OUTPUT, port_id), -EINVAL);
169
170
spa_log_trace_fp(this->log, "reuse buffer %d", buffer_id);
171
172
173
174
spa_log_debug(this->log, "%p: got port update change:%08x params:%d",
175
this, change_mask, n_params);
176
- if (!CHECK_PORT_ID(this, direction, port_id))
177
- return -EINVAL;
178
179
remove = (change_mask == 0);
180
181
182
struct port *target;
183
184
if (port == NULL) {
185
+ if (!CHECK_FREE_PORT(this, direction, port_id))
186
+ return -EINVAL;
187
+
188
target = &this->dummy;
189
spa_zero(this->dummy);
190
target->direction = direction;
191
192
direction == SPA_DIRECTION_INPUT ? "input" : "output",
193
port_id, mix_id, buffers, n_buffers);
194
195
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
196
-
197
p = GET_PORT(this, direction, port_id);
198
+ spa_return_val_if_fail(p != NULL, -EINVAL);
199
200
if (direction == SPA_DIRECTION_OUTPUT)
201
mix_id = SPA_ID_INVALID;
202
203
if (impl->io_areas)
204
pw_memblock_unref(impl->io_areas);
205
206
+ pw_map_clear(&impl->node.ports[0]);
207
+ pw_map_clear(&impl->node.ports[1]);
208
pw_map_clear(&impl->io_map);
209
210
if (impl->fds[0] != -1)
211
212
&impl_port_mix, p);
213
ensure_mix(impl, p, SPA_ID_INVALID);
214
215
- if (p->direction == SPA_DIRECTION_INPUT) {
216
- this->in_ports[p->id] = p;
217
- this->n_inputs++;
218
- } else {
219
- this->out_ports[p->id] = p;
220
- this->n_outputs++;
221
- }
222
+ pw_map_insert_at(&this->ports[p->direction], p->id, p);
223
return;
224
}
225
226
227
impl->node.client = client;
228
this->flags = do_register ? 0 : 1;
229
230
+ pw_map_init(&impl->node.ports[0], 64, 64);
231
+ pw_map_init(&impl->node.ports[1], 64, 64);
232
pw_map_init(&impl->io_map, 64, 64);
233
234
this->resource = resource;
235
pipewire-0.3.45.tar.gz/src/modules/module-client-node/remote-node.c -> pipewire-0.3.47.tar.gz/src/modules/module-client-node/remote-node.c
Changed
94
1
2
#include "pipewire/extensions/client-node.h"
3
4
#define MAX_BUFFERS 64
5
-#define MAX_MIX 4096
6
7
PW_LOG_TOPIC_EXTERN(mod_topic);
8
#define PW_LOG_TOPIC_DEFAULT mod_topic
9
10
int rtwritefd;
11
struct pw_memmap *activation;
12
13
- struct mix mix_pool[MAX_MIX];
14
struct spa_list mix[2];
15
struct spa_list free_mix;
16
17
18
if ((mix = find_mix(data, direction, port_id, mix_id)))
19
return mix;
20
21
- if (spa_list_is_empty(&data->free_mix))
22
- return NULL;
23
-
24
port = pw_impl_node_find_port(data->node, direction, port_id);
25
if (port == NULL)
26
return NULL;
27
28
- mix = spa_list_first(&data->free_mix, struct mix, link);
29
- spa_list_remove(&mix->link);
30
+ if (spa_list_is_empty(&data->free_mix)) {
31
+ if ((mix = calloc(1, sizeof(*mix))) == NULL)
32
+ return NULL;
33
+ } else {
34
+ mix = spa_list_first(&data->free_mix, struct mix, link);
35
+ spa_list_remove(&mix->link);
36
+ }
37
38
mix_init(mix, port, mix_id);
39
spa_list_append(&data->mix[direction], &mix->link);
40
41
clear_buffers(data, mix);
42
pw_array_clear(&mix->buffers);
43
44
- spa_list_remove(&mix->mix.link);
45
spa_list_append(&data->free_mix, &mix->link);
46
pw_impl_port_release_mix(mix->port, &mix->mix);
47
}
48
49
static void clean_node(struct node_data *d)
50
{
51
- struct mix *mix, *tmp;
52
+ struct mix *mix;
53
54
if (d->have_transport) {
55
- spa_list_for_each_safe(mix, tmp, &d->mix[SPA_DIRECTION_INPUT], link)
56
+ spa_list_consume(mix, &d->mix[SPA_DIRECTION_INPUT], link)
57
clear_mix(d, mix);
58
- spa_list_for_each_safe(mix, tmp, &d->mix[SPA_DIRECTION_OUTPUT], link)
59
+ spa_list_consume(mix, &d->mix[SPA_DIRECTION_OUTPUT], link)
60
clear_mix(d, mix);
61
}
62
+ spa_list_consume(mix, &d->free_mix, link) {
63
+ spa_list_remove(&mix->link);
64
+ free(mix);
65
+ }
66
clean_transport(d);
67
}
68
69
70
pw_log_debug("%p: removed", data);
71
72
spa_hook_remove(&data->proxy_client_node_listener);
73
+ spa_hook_remove(&data->client_node_listener);
74
75
if (data->node) {
76
spa_hook_remove(&data->node_listener);
77
78
struct pw_impl_node *node = object;
79
struct pw_proxy *client_node;
80
struct node_data *data;
81
- int i;
82
83
user_data_size = SPA_ROUND_UP_N(user_data_size, __alignof__(struct node_data));
84
85
86
spa_list_init(&data->free_mix);
87
spa_list_init(&data->mix[0]);
88
spa_list_init(&data->mix[1]);
89
- for (i = 0; i < MAX_MIX; i++)
90
- spa_list_append(&data->free_mix, &data->mix_pool[i].link);
91
92
spa_list_init(&data->links);
93
94
pipewire-0.3.45.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.47.tar.gz/src/modules/module-echo-cancel.c
Changed
217
1
2
#include <spa/param/audio/raw.h>
3
#include <spa/param/profiler.h>
4
#include <spa/pod/builder.h>
5
+#include <spa/support/plugin.h>
6
#include <spa/utils/json.h>
7
+#include <spa/utils/names.h>
8
#include <spa/utils/result.h>
9
#include <spa/utils/ringbuffer.h>
10
#include <spa/utils/string.h>
11
+#include <spa/support/plugin-loader.h>
12
+#include <spa/interfaces/audio/aec.h>
13
14
#include <pipewire/private.h>
15
#include <pipewire/impl.h>
16
17
18
#include <pipewire/extensions/profiler.h>
19
20
-#include "module-echo-cancel/echo-cancel.h"
21
-
22
/** \page page_module_echo_cancel PipeWire Module: Echo Cancel
23
*
24
* The `echo-cancel` module performs echo cancellation. The module creates
25
26
*
27
* - `source.props = {}`: properties to be passed to the source stream
28
* - `sink.props = {}`: properties to be passed to the sink stream
29
- * - `aec.method = <str>`: the echo cancellation method. Currently supported:
30
- * `webrtc`. Leave unset to use the default method (`webrtc`).
31
+ * - `library.name = <str>`: the echo cancellation library Currently supported:
32
+ * `aec/libspa-aec-exaudio`. Leave unset to use the default method (`aec/libspa-aec-exaudio`).
33
* - `aec.args = <str>`: arguments to pass to the echo cancellation method
34
*
35
* ## General options
36
37
* context.modules = [
38
* { name = libpipewire-module-echo-cancel
39
* args = {
40
- * # aec.method = webrtc
41
+ * # library.name = aec/libspa-aec-exaudio
42
* # node.latency = 1024/48000
43
* source.props = {
44
* node.name = "Echo Cancellation Source"
45
46
"[ audio.position=<channel map> ] "
47
"[ buffer.max_size=<max buffer size in ms> ] "
48
"[ buffer.play_delay=<play delay in ms> ] "
49
- "[ aec.method=<aec method> ] "
50
+ "[ library.name =<library name> ] "
51
"[ aec.args=<aec arguments> ] "
52
"[ source.props=<properties> ] "
53
"[ sink.props=<properties> ] " },
54
55
uint32_t out_ringsize;
56
struct spa_ringbuffer out_ring;
57
58
- const struct echo_cancel_info *aec_info;
59
- void *aec;
60
+ struct spa_audio_aec *aec;
61
uint32_t aec_blocksize;
62
63
unsigned int capture_ready:1;
64
65
66
uint32_t max_buffer_size;
67
uint32_t buffer_delay;
68
+
69
+ struct spa_handle *spa_handle;
70
+ struct spa_plugin_loader *loader;
71
};
72
73
static void do_unload_module(void *obj, void *data, int res, uint32_t id)
74
75
pw_stream_queue_buffer(impl->playback, pout);
76
77
/* Now run the canceller */
78
- echo_cancel_run(impl->aec_info, impl->aec, rec, play_delayed, out, size / sizeof(float));
79
+ spa_audio_aec_run(impl->aec, rec, play_delayed, out, size / sizeof(float));
80
81
/* Next, copy over the output to the output ringbuffer */
82
avail = spa_ringbuffer_get_write_index(&impl->out_ring, &oindex);
83
84
pw_properties_set(props, PW_KEY_NODE_LINK_GROUP, str);
85
if ((str = pw_properties_get(impl->source_props, PW_KEY_NODE_LATENCY)) != NULL)
86
pw_properties_set(props, PW_KEY_NODE_LATENCY, str);
87
- else if (impl->aec_info->latency)
88
- pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec_info->latency);
89
+ else if (impl->aec->latency)
90
+ pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec->latency);
91
92
impl->capture = pw_stream_new(impl->core,
93
"Echo-Cancel Capture", props);
94
95
pw_properties_set(props, PW_KEY_NODE_LINK_GROUP, str);
96
if ((str = pw_properties_get(impl->sink_props, PW_KEY_NODE_LATENCY)) != NULL)
97
pw_properties_set(props, PW_KEY_NODE_LATENCY, str);
98
- else if (impl->aec_info->latency)
99
- pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec_info->latency);
100
+ else if (impl->aec->latency)
101
+ pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec->latency);
102
103
impl->playback = pw_stream_new(impl->core,
104
"Echo-Cancel Playback", props);
105
106
pw_stream_destroy(impl->sink);
107
if (impl->core && impl->do_disconnect)
108
pw_core_disconnect(impl->core);
109
- if (impl->aec)
110
- echo_cancel_destroy(impl->aec_info, impl->aec);
111
+ if (impl->spa_handle)
112
+ spa_plugin_loader_unload(impl->loader, impl->spa_handle);
113
pw_properties_free(impl->source_props);
114
pw_properties_free(impl->sink_props);
115
116
117
struct impl *impl;
118
uint32_t id = pw_global_get_id(pw_impl_module_get_global(module));
119
const char *str;
120
- int res;
121
+ const char *path;
122
+ int res = 0;
123
+ struct spa_handle *handle = NULL;
124
+ void *iface;
125
126
PW_LOG_TOPIC_INIT(mod_topic);
127
128
129
if (pw_properties_get(impl->sink_props, PW_KEY_MEDIA_CLASS) == NULL)
130
pw_properties_set(impl->sink_props, PW_KEY_MEDIA_CLASS, "Audio/Sink");
131
132
- if ((str = pw_properties_get(props, "aec.method")) == NULL)
133
- str = "webrtc";
134
+ if ((str = pw_properties_get(props, "aec.method")) != NULL)
135
+ pw_log_warn("aec.method is not supported anymore use library.name");
136
137
-#ifdef HAVE_WEBRTC
138
- if (spa_streq(str, "webrtc"))
139
- impl->aec_info = echo_cancel_webrtc;
140
- else
141
-#endif
142
- impl->aec_info = echo_cancel_null;
143
+ /* Use webrtc as default */
144
+ if ((path = pw_properties_get(props, "library.name")) == NULL)
145
+ path = "aec/libspa-aec-webrtc";
146
+
147
+ struct spa_dict_item info_items[] = {
148
+ { SPA_KEY_LIBRARY_NAME, path },
149
+ };
150
+ struct spa_dict info = SPA_DICT_INIT_ARRAY(info_items);
151
+
152
+ impl->loader = spa_support_find(context->support, context->n_support, SPA_TYPE_INTERFACE_PluginLoader);
153
+ if (impl->loader == NULL) {
154
+ pw_log_error("a plugin loader is needed");
155
+ return -EINVAL;
156
+ }
157
+
158
+ handle = spa_plugin_loader_load(impl->loader, SPA_NAME_AEC, &info);
159
+ if (handle == NULL) {
160
+ pw_log_error("AEC codec plugin %s not available library.name %s", SPA_NAME_AEC, path);
161
+ return -ENOENT;
162
+ }
163
+
164
+ if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_AUDIO_AEC, &iface)) < 0) {
165
+ pw_log_error("can't get %s interface %d", SPA_TYPE_INTERFACE_AUDIO_AEC, res);
166
+ return res;
167
+ }
168
+ impl->aec = iface;
169
+ impl->spa_handle = handle;
170
+ if (impl->aec->iface.version != SPA_VERSION_AUDIO_AEC) {
171
+ pw_log_error("codec plugin %s has incompatible ABI version (%d != %d)",
172
+ SPA_NAME_AEC, impl->aec->iface.version, SPA_VERSION_AUDIO_AEC);
173
+ res = -ENOENT;
174
+ goto error;
175
+ }
176
+
177
+ (void)SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_AUDIO_AEC, (struct spa_audio_aec *)impl->aec);
178
+
179
+ pw_log_info("Using plugin AEC %s", impl->aec->name);
180
181
if ((str = pw_properties_get(props, "aec.args")) != NULL)
182
aec_props = pw_properties_new_string(str);
183
else
184
aec_props = pw_properties_new(NULL, NULL);
185
186
- impl->aec = echo_cancel_create(impl->aec_info, aec_props, &impl->info);
187
+ if (spa_audio_aec_init(impl->aec, &aec_props->dict, &impl->info)) {
188
+ pw_log_error("codec plugin %s create failed", impl->aec->name);
189
+ res = -ENOENT;
190
+ goto error;
191
+ }
192
193
pw_properties_free(aec_props);
194
195
- if (impl->aec_info->latency) {
196
+ if (impl->aec->latency) {
197
unsigned int num, denom, req_num, req_denom;
198
unsigned int factor = 0;
199
unsigned int new_num = 0;
200
201
- spa_assert_se(sscanf(impl->aec_info->latency, "%u/%u", &num, &denom) == 2);
202
+ spa_assert_se(sscanf(impl->aec->latency, "%u/%u", &num, &denom) == 2);
203
204
if ((str = pw_properties_get(props, PW_KEY_NODE_LATENCY)) != NULL) {
205
sscanf(str, "%u/%u", &req_num, &req_denom);
206
207
}
208
209
if (factor == 0 || new_num == 0) {
210
- pw_log_info("Setting node latency to %s", impl->aec_info->latency);
211
- pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec_info->latency);
212
+ pw_log_info("Setting node latency to %s", impl->aec->latency);
213
+ pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec->latency);
214
impl->aec_blocksize = sizeof(float) * impl->info.rate * num / denom;
215
} else {
216
pw_log_info("Setting node latency to %u/%u", new_num, req_denom);
217
pipewire-0.3.47.tar.gz/src/modules/module-fallback-sink.c
Added
475
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2021 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <string.h>
27
+#include <stdio.h>
28
+#include <errno.h>
29
+#include <sys/types.h>
30
+#include <sys/stat.h>
31
+#include <fcntl.h>
32
+#include <unistd.h>
33
+
34
+#include "config.h"
35
+
36
+#include <spa/utils/result.h>
37
+#include <spa/utils/string.h>
38
+#include <spa/param/audio/raw.h>
39
+
40
+#include <pipewire/impl.h>
41
+#include <pipewire/i18n.h>
42
+
43
+/** \page page_module_fallback_sink PipeWire Module: Fallback Sink
44
+ *
45
+ * Fallback sink, which appear dynamically when no other sinks are
46
+ * present. This is only useful for Pulseaudio compatibility.
47
+ */
48
+
49
+#define NAME "fallback-sink"
50
+
51
+#define DEFAULT_SINK_NAME "auto_null"
52
+#define DEFAULT_SINK_DESCRIPTION _("Dummy Output")
53
+
54
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
55
+#define PW_LOG_TOPIC_DEFAULT mod_topic
56
+
57
+#define MODULE_USAGE ("[ sink.name=<str> ] " \
58
+ "[ sink.description=<str> ] ")
59
+
60
+static const struct spa_dict_item module_props[] = {
61
+ { PW_KEY_MODULE_AUTHOR, "Pauli Virtanen <pav@iki.fi>" },
62
+ { PW_KEY_MODULE_DESCRIPTION, "Dynamically appearing fallback sink" },
63
+ { PW_KEY_MODULE_USAGE, MODULE_USAGE },
64
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
65
+};
66
+
67
+struct bitmap {
68
+ uint8_t *data;
69
+ size_t size;
70
+ size_t items;
71
+};
72
+
73
+struct impl {
74
+ struct pw_context *context;
75
+
76
+ struct pw_impl_module *module;
77
+ struct spa_hook module_listener;
78
+
79
+ struct pw_core *core;
80
+ struct pw_registry *registry;
81
+ struct pw_proxy *sink;
82
+
83
+ struct spa_hook core_listener;
84
+ struct spa_hook core_proxy_listener;
85
+ struct spa_hook registry_listener;
86
+ struct spa_hook sink_listener;
87
+
88
+ struct pw_properties *properties;
89
+
90
+ struct bitmap sink_ids;
91
+ struct bitmap fallback_sink_ids;
92
+
93
+ int check_seq;
94
+
95
+ unsigned int do_disconnect:1;
96
+ unsigned int scheduled:1;
97
+};
98
+
99
+static int bitmap_add(struct bitmap *map, uint32_t i)
100
+{
101
+ const uint32_t pos = (i >> 3);
102
+ const uint8_t mask = 1 << (i & 0x7);
103
+
104
+ if (pos >= map->size) {
105
+ size_t new_size = map->size + pos + 16;
106
+ void *p;
107
+
108
+ p = realloc(map->data, new_size);
109
+ if (!p)
110
+ return -errno;
111
+
112
+ memset((uint8_t*)p + map->size, 0, new_size - map->size);
113
+ map->data = p;
114
+ map->size = new_size;
115
+ }
116
+
117
+ if (map->data[pos] & mask)
118
+ return 1;
119
+
120
+ map->data[pos] |= mask;
121
+ ++map->items;
122
+
123
+ return 0;
124
+}
125
+
126
+static bool bitmap_remove(struct bitmap *map, uint32_t i)
127
+{
128
+ const uint32_t pos = (i >> 3);
129
+ const uint8_t mask = 1 << (i & 0x7);
130
+
131
+ if (pos >= map->size)
132
+ return false;
133
+
134
+ if (!(map->data[pos] & mask))
135
+ return false;
136
+
137
+ map->data[pos] &= ~mask;
138
+ --map->items;
139
+
140
+ return true;
141
+}
142
+
143
+static void bitmap_free(struct bitmap *map)
144
+{
145
+ free(map->data);
146
+ spa_zero(*map);
147
+}
148
+
149
+static int add_id(struct bitmap *map, uint32_t id)
150
+{
151
+ int res;
152
+
153
+ if (id == SPA_ID_INVALID)
154
+ return -EINVAL;
155
+
156
+ if ((res = bitmap_add(map, id)) < 0)
157
+ pw_log_error("%s", spa_strerror(res));
158
+
159
+ return res;
160
+}
161
+
162
+static void reschedule_check(struct impl *impl)
163
+{
164
+ if (!impl->scheduled)
165
+ return;
166
+
167
+ impl->check_seq = pw_core_sync(impl->core, 0, impl->check_seq);
168
+}
169
+
170
+static void schedule_check(struct impl *impl)
171
+{
172
+ if (impl->scheduled)
173
+ return;
174
+
175
+ impl->scheduled = true;
176
+ impl->check_seq = pw_core_sync(impl->core, 0, impl->check_seq);
177
+}
178
+
179
+static void sink_proxy_removed(void *data)
180
+{
181
+ struct impl *impl = data;
182
+
183
+ pw_proxy_destroy(impl->sink);
184
+}
185
+
186
+static void sink_proxy_bound(void *data, uint32_t id)
187
+{
188
+ struct impl *impl = data;
189
+
190
+ add_id(&impl->sink_ids, id);
191
+ add_id(&impl->fallback_sink_ids, id);
192
+
193
+ reschedule_check(impl);
194
+ schedule_check(impl);
195
+}
196
+
197
+static void sink_proxy_destroy(void *data)
198
+{
199
+ struct impl *impl = data;
200
+
201
+ pw_log_debug("fallback dummy sink destroyed");
202
+
203
+ spa_hook_remove(&impl->sink_listener);
204
+ impl->sink = NULL;
205
+}
206
+
207
+static const struct pw_proxy_events sink_proxy_events = {
208
+ PW_VERSION_PROXY_EVENTS,
209
+ .removed = sink_proxy_removed,
210
+ .bound = sink_proxy_bound,
211
+ .destroy = sink_proxy_destroy,
212
+};
213
+
214
+static int sink_create(struct impl *impl)
215
+{
216
+ if (impl->sink)
217
+ return 0;
218
+
219
+ pw_log_info("creating fallback dummy sink");
220
+
221
+ impl->sink = pw_core_create_object(impl->core,
222
+ "adapter", PW_TYPE_INTERFACE_Node, PW_VERSION_NODE,
223
+ impl->properties ? &impl->properties->dict : NULL, 0);
224
+ if (impl->sink == NULL)
225
+ return -errno;
226
+
227
+ pw_proxy_add_listener(impl->sink, &impl->sink_listener, &sink_proxy_events, impl);
228
+
229
+ return 0;
230
+}
231
+
232
+static void sink_destroy(struct impl *impl)
233
+{
234
+ if (!impl->sink)
235
+ return;
236
+
237
+ pw_log_info("removing fallback dummy sink");
238
+ pw_proxy_destroy(impl->sink);
239
+}
240
+
241
+static void check_sinks(struct impl *impl)
242
+{
243
+ int res;
244
+
245
+ pw_log_debug("seeing %zu sink(s), %zu fallback sink(s)",
246
+ impl->sink_ids.items, impl->fallback_sink_ids.items);
247
+
248
+ if (impl->sink_ids.items > impl->fallback_sink_ids.items) {
249
+ sink_destroy(impl);
250
+ } else {
251
+ if ((res = sink_create(impl)) < 0)
252
+ pw_log_error("error creating sink: %s", spa_strerror(res));
253
+ }
254
+}
255
+
256
+static void registry_event_global(void *data, uint32_t id,
257
+ uint32_t permissions, const char *type, uint32_t version,
258
+ const struct spa_dict *props)
259
+{
260
+ struct impl *impl = data;
261
+ const char *str;
262
+
263
+ reschedule_check(impl);
264
+
265
+ if (!props)
266
+ return;
267
+
268
+ if (!spa_streq(type, PW_TYPE_INTERFACE_Node))
269
+ return;
270
+
271
+ str = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
272
+ if (!(spa_streq(str, "Audio/Sink") || spa_streq(str, "Audio/Sink/Virtual")))
273
+ return;
274
+
275
+ add_id(&impl->sink_ids, id);
276
+ schedule_check(impl);
277
+}
278
+
279
+static void registry_event_global_remove(void *data, uint32_t id)
280
+{
281
+ struct impl *impl = data;
282
+
283
+ reschedule_check(impl);
284
+
285
+ bitmap_remove(&impl->fallback_sink_ids, id);
286
+ if (bitmap_remove(&impl->sink_ids, id))
287
+ schedule_check(impl);
288
+}
289
+
290
+static const struct pw_registry_events registry_events = {
291
+ PW_VERSION_REGISTRY_EVENTS,
292
+ .global = registry_event_global,
293
+ .global_remove = registry_event_global_remove,
294
+};
295
+
296
+static void core_done(void *data, uint32_t id, int seq)
297
+{
298
+ struct impl *impl = data;
299
+
300
+ if (seq == impl->check_seq) {
301
+ impl->scheduled = false;
302
+ check_sinks(impl);
303
+ }
304
+}
305
+
306
+static const struct pw_core_events core_events = {
307
+ PW_VERSION_CORE_EVENTS,
308
+ .done = core_done,
309
+};
310
+
311
+static void core_proxy_removed(void *data)
312
+{
313
+ struct impl *impl = data;
314
+
315
+ if (impl->registry) {
316
+ spa_hook_remove(&impl->registry_listener);
317
+ pw_proxy_destroy((struct pw_proxy*)impl->registry);
318
+ impl->registry = NULL;
319
+ }
320
+}
321
+
322
+static void core_proxy_destroy(void *data)
323
+{
324
+ struct impl *impl = data;
325
+
326
+ spa_hook_remove(&impl->core_listener);
327
+ spa_hook_remove(&impl->core_proxy_listener);
328
+ impl->core = NULL;
329
+}
330
+
331
+static const struct pw_proxy_events core_proxy_events = {
332
+ PW_VERSION_PROXY_EVENTS,
333
+ .destroy = core_proxy_destroy,
334
+ .removed = core_proxy_removed,
335
+};
336
+
337
+static void impl_destroy(struct impl *impl)
338
+{
339
+ sink_destroy(impl);
340
+
341
+ if (impl->registry) {
342
+ spa_hook_remove(&impl->registry_listener);
343
+ pw_proxy_destroy((struct pw_proxy*)impl->registry);
344
+ impl->registry = NULL;
345
+ }
346
+
347
+ if (impl->core) {
348
+ spa_hook_remove(&impl->core_listener);
349
+ spa_hook_remove(&impl->core_proxy_listener);
350
+ if (impl->do_disconnect)
351
+ pw_core_disconnect(impl->core);
352
+ impl->core = NULL;
353
+ }
354
+
355
+ if (impl->properties) {
356
+ pw_properties_free(impl->properties);
357
+ impl->properties = NULL;
358
+ }
359
+
360
+ bitmap_free(&impl->sink_ids);
361
+ bitmap_free(&impl->fallback_sink_ids);
362
+
363
+ free(impl);
364
+}
365
+
366
+static void module_destroy(void *data)
367
+{
368
+ struct impl *impl = data;
369
+ spa_hook_remove(&impl->module_listener);
370
+ impl_destroy(impl);
371
+}
372
+
373
+static const struct pw_impl_module_events module_events = {
374
+ PW_VERSION_IMPL_MODULE_EVENTS,
375
+ .destroy = module_destroy,
376
+};
377
+
378
+SPA_EXPORT
379
+int pipewire__module_init(struct pw_impl_module *module, const char *args)
380
+{
381
+ struct pw_context *context = pw_impl_module_get_context(module);
382
+ struct pw_properties *props = NULL;
383
+ struct impl *impl = NULL;
384
+ const char *str;
385
+ int res;
386
+
387
+ PW_LOG_TOPIC_INIT(mod_topic);
388
+
389
+ impl = calloc(1, sizeof(struct impl));
390
+ if (impl == NULL)
391
+ goto error_errno;
392
+
393
+ pw_log_debug("module %p: new %s", impl, args);
394
+
395
+ if (args == NULL)
396
+ args = "";
397
+
398
+ impl->module = module;
399
+ impl->context = context;
400
+
401
+ props = pw_properties_new_string(args);
402
+ if (props == NULL)
403
+ goto error_errno;
404
+
405
+ impl->properties = pw_properties_new(NULL, NULL);
406
+ if (impl->properties == NULL)
407
+ goto error_errno;
408
+
409
+ if ((str = pw_properties_get(props, "sink.name")) == NULL)
410
+ str = DEFAULT_SINK_NAME;
411
+ pw_properties_set(impl->properties, PW_KEY_NODE_NAME, str);
412
+
413
+ if ((str = pw_properties_get(props, "sink.description")) == NULL)
414
+ str = DEFAULT_SINK_DESCRIPTION;
415
+ pw_properties_set(impl->properties, PW_KEY_NODE_DESCRIPTION, str);
416
+
417
+ pw_properties_setf(impl->properties, SPA_KEY_AUDIO_RATE, "%u", 48000);
418
+ pw_properties_setf(impl->properties, SPA_KEY_AUDIO_CHANNELS, "%u", 2);
419
+ pw_properties_set(impl->properties, SPA_KEY_AUDIO_POSITION, "FL,FR");
420
+
421
+ pw_properties_set(impl->properties, PW_KEY_MEDIA_CLASS, "Audio/Sink");
422
+ pw_properties_set(impl->properties, PW_KEY_FACTORY_NAME, "support.null-audio-sink");
423
+ pw_properties_set(impl->properties, PW_KEY_NODE_VIRTUAL, "true");
424
+ pw_properties_set(impl->properties, "monitor.channel-volumes", "true");
425
+
426
+ impl->core = pw_context_get_object(impl->context, PW_TYPE_INTERFACE_Core);
427
+ if (impl->core == NULL) {
428
+ str = pw_properties_get(props, PW_KEY_REMOTE_NAME);
429
+ impl->core = pw_context_connect(impl->context,
430
+ pw_properties_new(
431
+ PW_KEY_REMOTE_NAME, str,
432
+ NULL),
433
+ 0);
434
+ impl->do_disconnect = true;
435
+ }
436
+ if (impl->core == NULL) {
437
+ res = -errno;
438
+ pw_log_error("can't connect: %m");
439
+ goto error;
440
+ }
441
+
442
+ pw_proxy_add_listener((struct pw_proxy*)impl->core,
443
+ &impl->core_proxy_listener, &core_proxy_events,
444
+ impl);
445
+
446
+ pw_core_add_listener(impl->core, &impl->core_listener, &core_events, impl);
447
+
448
+ impl->registry = pw_core_get_registry(impl->core,
449
+ PW_VERSION_REGISTRY, 0);
450
+ if (impl->registry == NULL)
451
+ goto error_errno;
452
+
453
+ pw_registry_add_listener(impl->registry,
454
+ &impl->registry_listener,
455
+ ®istry_events, impl);
456
+
457
+ pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
458
+
459
+ pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
460
+
461
+ schedule_check(impl);
462
+
463
+ pw_properties_free(props);
464
+ return 0;
465
+
466
+error_errno:
467
+ res = -errno;
468
+error:
469
+ if (props)
470
+ pw_properties_free(props);
471
+ if (impl)
472
+ impl_destroy(impl);
473
+ return res;
474
+}
475
pipewire-0.3.45.tar.gz/src/modules/module-profiler.c -> pipewire-0.3.47.tar.gz/src/modules/module-profiler.c
Changed
28
1
2
spa_list_for_each(t, &node->rt.target_list, link) {
3
struct pw_impl_node *n = t->node;
4
struct pw_node_activation *na;
5
+ struct spa_fraction latency;
6
7
if (n == NULL || n == node)
8
continue;
9
10
+ latency = n->latency;
11
+ if (n->force_quantum != 0)
12
+ latency.num = n->force_quantum;
13
+ if (n->force_rate != 0)
14
+ latency.denom = n->force_rate;
15
+
16
na = n->rt.activation;
17
spa_pod_builder_prop(&b, SPA_PROFILER_followerBlock, 0);
18
spa_pod_builder_add_struct(&b,
19
20
SPA_POD_Long(na->awake_time),
21
SPA_POD_Long(na->finish_time),
22
SPA_POD_Int(na->status),
23
- SPA_POD_Fraction(&n->latency));
24
+ SPA_POD_Fraction(&latency));
25
}
26
spa_pod_builder_pop(&b, &f[0]);
27
28
pipewire-0.3.45.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-native.c
Changed
10
1
2
#include <fcntl.h>
3
#include <sys/file.h>
4
#include <ctype.h>
5
-#if HAVE_PWD_H
6
+#ifdef HAVE_PWD_H
7
#include <pwd.h>
8
#endif
9
#if defined(__FreeBSD__)
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-native/local-socket.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-native/local-socket.c
Changed
10
1
2
#include <sys/stat.h>
3
#include <fcntl.h>
4
#include <sys/file.h>
5
-#if HAVE_PWD_H
6
+#ifdef HAVE_PWD_H
7
#include <pwd.h>
8
#endif
9
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/client.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/client.c
Changed
19
1
2
}
3
4
/* returns true if an event with the (mask, event, index) triplet should be dropped because it is redundant */
5
-static bool client_prune_subscribe_events(struct client *client, uint32_t mask, uint32_t event, uint32_t index)
6
+static bool client_prune_subscribe_events(struct client *client, uint32_t event, uint32_t index)
7
{
8
struct message *m, *t;
9
10
11
12
pw_log_debug("client %p: SUBSCRIBE event:%08x index:%u", client, event, index);
13
14
- if (client_prune_subscribe_events(client, mask, event, index))
15
+ if (client_prune_subscribe_events(client, event, index))
16
return 0;
17
18
struct message *reply = message_alloc(client->impl, -1, 0);
19
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c
Changed
9
1
2
#include "../extension.h"
3
#include "../format.h"
4
#include "../manager.h"
5
-#include "../media-roles.h"
6
#include "../message.h"
7
#include "../reply.h"
8
#include "../volume.h"
9
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/extensions/ext-stream-restore.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/extensions/ext-stream-restore.c
Changed
11
1
2
#include "../extension.h"
3
#include "../format.h"
4
#include "../manager.h"
5
-#include "../media-roles.h"
6
#include "../message.h"
7
+#include "../remap.h"
8
#include "../reply.h"
9
#include "../volume.h"
10
#include "registry.h"
11
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/message.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/message.c
Changed
57
1
2
#include <spa/debug/buffer.h>
3
#include <spa/utils/defs.h>
4
#include <spa/utils/string.h>
5
-#include <pipewire/keys.h>
6
#include <pipewire/log.h>
7
8
#include "defs.h"
9
#include "format.h"
10
#include "internal.h"
11
#include "log.h"
12
-#include "media-roles.h"
13
#include "message.h"
14
+#include "remap.h"
15
#include "volume.h"
16
17
#define MAX_SIZE (256*1024)
18
19
return v * v * v;
20
}
21
22
-static const struct str_map key_table[] = {
23
- { PW_KEY_DEVICE_BUS_PATH, "device.bus_path" },
24
- { PW_KEY_DEVICE_FORM_FACTOR, "device.form_factor" },
25
- { PW_KEY_DEVICE_ICON_NAME, "device.icon_name" },
26
- { PW_KEY_DEVICE_INTENDED_ROLES, "device.intended_roles" },
27
- { PW_KEY_NODE_DESCRIPTION, "device.description" },
28
- { PW_KEY_MEDIA_ICON_NAME, "media.icon_name" },
29
- { PW_KEY_APP_ICON_NAME, "application.icon_name" },
30
- { PW_KEY_APP_PROCESS_MACHINE_ID, "application.process.machine_id" },
31
- { PW_KEY_APP_PROCESS_SESSION_ID, "application.process.session_id" },
32
- { PW_KEY_MEDIA_ROLE, "media.role", media_role_map },
33
- { NULL, NULL },
34
-};
35
-
36
static int read_u8(struct message *m, uint8_t *val)
37
{
38
if (m->offset + 1 > m->length)
39
40
TAG_INVALID)) < 0)
41
return res;
42
43
- if (remap && (map = str_map_find(key_table, NULL, key)) != NULL) {
44
+ if (remap && (map = str_map_find(props_key_map, NULL, key)) != NULL) {
45
key = map->pw_str;
46
if (map->child != NULL &&
47
(map = str_map_find(map->child, NULL, data)) != NULL)
48
49
int l;
50
const struct str_map *map;
51
52
- if (remap && (map = str_map_find(key_table, key, NULL)) != NULL) {
53
+ if (remap && (map = str_map_find(props_key_map, key, NULL)) != NULL) {
54
key = map->pa_str;
55
if (map->child != NULL &&
56
(map = str_map_find(map->child, val, NULL)) != NULL)
57
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/module.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/module.c
Changed
127
1
2
3
#include <stdlib.h>
4
#include <string.h>
5
+#include <ctype.h>
6
7
#include <spa/utils/defs.h>
8
#include <spa/utils/list.h>
9
10
#include "internal.h"
11
#include "log.h"
12
#include "module.h"
13
+#include "remap.h"
14
15
static void on_module_unload(void *obj, void *data, int res, uint32_t index)
16
{
17
18
{
19
char *s = strdup(str), *p = s, *e, f;
20
const char *k, *v;
21
+ const struct str_map *map;
22
23
while (*p) {
24
+ while (*p && isspace(*p))
25
+ p++;
26
e = strchr(p, '=');
27
if (e == NULL)
28
break;
29
30
if (*e != '\0')
31
p++;
32
*e = '\0';
33
+
34
+ if ((map = str_map_find(props_key_map, NULL, k)) != NULL) {
35
+ k = map->pw_str;
36
+ if (map->child != NULL &&
37
+ (map = str_map_find(map->child, NULL, v)) != NULL)
38
+ v = map->pw_str;
39
+ }
40
pw_properties_set(props, k, v);
41
}
42
free(s);
43
44
#include "modules/registry.h"
45
46
static const struct module_info module_list[] = {
47
- { "module-combine-sink", create_module_combine_sink, },
48
- { "module-echo-cancel", create_module_echo_cancel, },
49
- { "module-ladspa-sink", create_module_ladspa_sink, },
50
- { "module-ladspa-source", create_module_ladspa_source, },
51
- { "module-loopback", create_module_loopback, },
52
- { "module-null-sink", create_module_null_sink, },
53
- { "module-native-protocol-tcp", create_module_native_protocol_tcp, },
54
- { "module-pipe-source", create_module_pipe_source, },
55
- { "module-pipe-sink", create_module_pipe_sink, },
56
- { "module-raop-discover", create_module_raop_discover, },
57
- { "module-remap-sink", create_module_remap_sink, },
58
- { "module-remap-source", create_module_remap_source, },
59
- { "module-simple-protocol-tcp", create_module_simple_protocol_tcp, },
60
- { "module-switch-on-connect", create_module_switch_on_connect, },
61
- { "module-tunnel-sink", create_module_tunnel_sink, },
62
- { "module-tunnel-source", create_module_tunnel_source, },
63
- { "module-zeroconf-discover", create_module_zeroconf_discover, },
64
+ { "module-always-sink", 1, create_module_always_sink, },
65
+ { "module-combine-sink", 0, create_module_combine_sink, },
66
+ { "module-echo-cancel", 0, create_module_echo_cancel, },
67
+ { "module-ladspa-sink", 0, create_module_ladspa_sink, },
68
+ { "module-ladspa-source", 0, create_module_ladspa_source, },
69
+ { "module-loopback", 0, create_module_loopback, },
70
+ { "module-null-sink", 0, create_module_null_sink, },
71
+ { "module-native-protocol-tcp", 0, create_module_native_protocol_tcp, },
72
+ { "module-pipe-source", 0, create_module_pipe_source, },
73
+ { "module-pipe-sink", 0, create_module_pipe_sink, },
74
+ { "module-raop-discover", 1, create_module_raop_discover, },
75
+ { "module-remap-sink", 0, create_module_remap_sink, },
76
+ { "module-remap-source", 0, create_module_remap_source, },
77
+ { "module-simple-protocol-tcp", 0, create_module_simple_protocol_tcp, },
78
+ { "module-switch-on-connect", 1, create_module_switch_on_connect, },
79
+ { "module-tunnel-sink", 0, create_module_tunnel_sink, },
80
+ { "module-tunnel-source", 0, create_module_tunnel_source, },
81
+ { "module-zeroconf-discover", 1, create_module_zeroconf_discover, },
82
#ifdef HAVE_AVAHI
83
- { "module-zeroconf-publish", create_module_zeroconf_publish, },
84
+ { "module-zeroconf-publish", 0, create_module_zeroconf_publish, },
85
#endif
86
- { "module-roc-sink", create_module_roc_sink, },
87
- { "module-roc-source", create_module_roc_source, },
88
- { "module-x11-bell", create_module_x11_bell, },
89
+ { "module-roc-sink", 0, create_module_roc_sink, },
90
+ { "module-roc-source", 0, create_module_roc_source, },
91
+ { "module-x11-bell", 0, create_module_x11_bell, },
92
};
93
94
static const struct module_info *find_module_info(const char *name)
95
96
return NULL;
97
}
98
99
+static int find_module_by_name(void *item_data, void *data)
100
+{
101
+ const char *name = data;
102
+ const struct module *module = item_data;
103
+ return spa_streq(module->name, name) ? 1 : 0;
104
+}
105
+
106
struct module *module_create(struct client *client, const char *name, const char *args)
107
{
108
struct impl *impl = client->impl;
109
110
errno = ENOENT;
111
return NULL;
112
}
113
+
114
+ if (info->load_once) {
115
+ int exists;
116
+ exists = pw_map_for_each(&impl->modules, find_module_by_name,
117
+ (void *)name);
118
+ if (exists) {
119
+ errno = EEXIST;
120
+ return NULL;
121
+ }
122
+ }
123
+
124
module = info->create(impl, args);
125
if (module == NULL)
126
return NULL;
127
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/module.h -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/module.h
Changed
9
1
2
3
struct module_info {
4
const char *name;
5
+ unsigned int load_once:1;
6
struct module *(*create) (struct impl *impl, const char *args);
7
};
8
9
pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-always-sink.c
Added
138
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <pipewire/pipewire.h>
27
+
28
+#include "../module.h"
29
+
30
+#define NAME "always-sink"
31
+
32
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
33
+#define PW_LOG_TOPIC_DEFAULT mod_topic
34
+
35
+struct module_always_sink_data {
36
+ struct module *module;
37
+
38
+ struct pw_impl_module *mod;
39
+ struct spa_hook mod_listener;
40
+};
41
+
42
+static void module_destroy(void *data)
43
+{
44
+ struct module_always_sink_data *d = data;
45
+ spa_hook_remove(&d->mod_listener);
46
+ d->mod = NULL;
47
+ module_schedule_unload(d->module);
48
+}
49
+
50
+static const struct pw_impl_module_events module_events = {
51
+ PW_VERSION_IMPL_MODULE_EVENTS,
52
+ .destroy = module_destroy
53
+};
54
+
55
+static int module_always_sink_load(struct client *client, struct module *module)
56
+{
57
+ struct module_always_sink_data *data = module->user_data;
58
+ FILE *f;
59
+ char *args;
60
+ const char *str;
61
+ size_t size;
62
+
63
+ f = open_memstream(&args, &size);
64
+ fprintf(f, "{");
65
+ if ((str = pw_properties_get(module->props, "sink_name")) != NULL)
66
+ fprintf(f, " sink.name = \"%s\"", str);
67
+ fprintf(f, " }");
68
+ fclose(f);
69
+
70
+ data->mod = pw_context_load_module(module->impl->context,
71
+ "libpipewire-module-fallback-sink",
72
+ args, NULL);
73
+ free(args);
74
+
75
+ if (data->mod == NULL)
76
+ return -errno;
77
+
78
+ pw_impl_module_add_listener(data->mod,
79
+ &data->mod_listener,
80
+ &module_events, data);
81
+ return 0;
82
+}
83
+
84
+static int module_always_sink_unload(struct module *module)
85
+{
86
+ struct module_always_sink_data *d = module->user_data;
87
+
88
+ if (d->mod) {
89
+ spa_hook_remove(&d->mod_listener);
90
+ pw_impl_module_destroy(d->mod);
91
+ d->mod = NULL;
92
+ }
93
+ return 0;
94
+}
95
+
96
+static const struct module_methods module_always_sink_methods = {
97
+ VERSION_MODULE_METHODS,
98
+ .load = module_always_sink_load,
99
+ .unload = module_always_sink_unload,
100
+};
101
+
102
+static const struct spa_dict_item module_always_sink_info[] = {
103
+ { PW_KEY_MODULE_AUTHOR, "Pauli Virtanen <pav@iki.fi>" },
104
+ { PW_KEY_MODULE_DESCRIPTION, "Always keeps at least one sink loaded even if it's a null one" },
105
+ { PW_KEY_MODULE_USAGE, "sink_name=<name of sink>" },
106
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
107
+};
108
+
109
+struct module *create_module_always_sink(struct impl *impl, const char *argument)
110
+{
111
+ struct module *module;
112
+ struct pw_properties *props = NULL;
113
+ int res;
114
+
115
+ PW_LOG_TOPIC_INIT(mod_topic);
116
+
117
+ props = pw_properties_new_dict(&SPA_DICT_INIT_ARRAY(module_always_sink_info));
118
+ if (props == NULL) {
119
+ res = -EINVAL;
120
+ goto out;
121
+ }
122
+ if (argument)
123
+ module_args_add_props(props, argument);
124
+
125
+ module = module_new(impl, &module_always_sink_methods, sizeof(struct module_always_sink_data));
126
+ if (module == NULL) {
127
+ res = -errno;
128
+ goto out;
129
+ }
130
+ module->props = props;
131
+
132
+ return module;
133
+out:
134
+ pw_properties_free(props);
135
+ errno = -res;
136
+ return NULL;
137
+}
138
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c
Changed
210
1
2
3
#define MAX_SINKS 64 /* ... good enough for anyone */
4
5
+#define TIMEOUT_SINKS_MSEC 2000
6
+
7
static const struct spa_dict_item module_combine_sink_info[] = {
8
{ PW_KEY_MODULE_AUTHOR, "Arun Raghavan <arun@asymptotic.io>" },
9
{ PW_KEY_MODULE_DESCRIPTION, "Combine multiple sinks into a single sink" },
10
11
struct spa_hook stream_listener;
12
struct module_combine_sink_data *data;
13
bool cleanup;
14
+ bool started;
15
};
16
17
struct module_combine_sink_data {
18
19
struct combine_stream streams[MAX_SINKS];
20
21
struct spa_source *cleanup;
22
+ struct spa_source *sinks_timeout;
23
24
struct spa_audio_info_raw info;
25
+
26
+ unsigned int sinks_pending;
27
+ unsigned int source_started:1;
28
+ unsigned int load_emitted:1;
29
+ unsigned int start_error:1;
30
};
31
32
/* Core connection: mainly to unload the module if the connection errors out */
33
34
pw_stream_queue_buffer(data->sink, in);
35
}
36
37
+static void check_initialized(struct module_combine_sink_data *data)
38
+{
39
+ struct module *module = data->module;
40
+
41
+ if (data->load_emitted)
42
+ return;
43
+
44
+ if (data->start_error) {
45
+ pw_log_debug("module load error");
46
+ data->load_emitted = true;
47
+ module_emit_loaded(module, -EIO);
48
+ } else if (data->sinks_pending == 0 && data->source_started) {
49
+ pw_log_debug("module loaded");
50
+ data->load_emitted = true;
51
+ module_emit_loaded(module, 0);
52
+ }
53
+}
54
+
55
static void on_in_stream_state_changed(void *d, enum pw_stream_state old,
56
enum pw_stream_state state, const char *error)
57
{
58
59
struct module *module = data->module;
60
uint32_t i;
61
62
+ if (!data->source_started && state != PW_STREAM_STATE_CONNECTING) {
63
+ /* Input stream appears on server */
64
+ data->source_started = true;
65
+ if (state < PW_STREAM_STATE_PAUSED)
66
+ data->start_error = true;
67
+ check_initialized(data);
68
+ }
69
+
70
switch (state) {
71
case PW_STREAM_STATE_PAUSED:
72
pw_stream_flush(data->sink, false);
73
74
{
75
struct combine_stream *s = data;
76
77
+ if (!s->started && state != PW_STREAM_STATE_CONNECTING) {
78
+ /* Output stream appears on server */
79
+ s->started = true;
80
+ if (s->data->sinks_pending > 0)
81
+ --s->data->sinks_pending;
82
+ if (state < PW_STREAM_STATE_PAUSED)
83
+ s->data->start_error = true;
84
+ check_initialized(s->data);
85
+ }
86
+
87
if (state == PW_STREAM_STATE_UNCONNECTED) {
88
s->cleanup = true;
89
pw_loop_signal_event(s->data->module->impl->loop, s->data->cleanup);
90
91
pw_properties_set(props, PW_KEY_NODE_DONT_RECONNECT, "true");
92
pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
93
pw_properties_set(props, PW_KEY_NODE_PASSIVE, "true");
94
+ pw_properties_setf(props, "pulse.module.id", "%u", data->module->index);
95
96
cstream->data = data;
97
cstream->stream = pw_stream_new(data->core, NULL, props);
98
if (cstream->stream == NULL) {
99
pw_log_error("Could not create stream");
100
- return;
101
+ goto error;
102
}
103
104
pw_stream_add_listener(cstream->stream,
105
106
PW_STREAM_FLAG_RT_PROCESS,
107
params, n_params)) < 0) {
108
pw_log_error("Could not connect to sink '%s'", sink_name);
109
- return;
110
+ goto error;
111
}
112
+
113
+ return;
114
+
115
+error:
116
+ data->start_error = true;
117
+ check_initialized(data);
118
}
119
120
static const struct pw_manager_events manager_events = {
121
122
}
123
}
124
125
+static void on_sinks_timeout(void *d, uint64_t count)
126
+{
127
+ struct module_combine_sink_data *data = d;
128
+
129
+ if (data->load_emitted)
130
+ return;
131
+
132
+ data->start_error = true;
133
+ check_initialized(data);
134
+}
135
+
136
static int module_combine_sink_load(struct client *client, struct module *module)
137
{
138
struct module_combine_sink_data *data = module->user_data;
139
140
pw_properties_setf(props, PW_KEY_NODE_GROUP, "combine_sink-%u", data->module->index);
141
pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "combine_sink-%u", data->module->index);
142
pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
143
+ pw_properties_setf(props, "pulse.module.id", "%u", module->index);
144
145
if ((str = pw_properties_get(module->props, "sink_properties")) != NULL)
146
module_args_add_props(props, str);
147
148
return res;
149
150
data->manager = pw_manager_new(data->core);
151
- if (client->manager == NULL)
152
+ if (data->manager == NULL)
153
return -errno;
154
155
pw_manager_add_listener(data->manager, &data->manager_listener,
156
157
158
data->cleanup = pw_loop_add_event(module->impl->loop, on_cleanup, data);
159
160
- return 0;
161
+ data->sinks_timeout = pw_loop_add_timer(module->impl->loop, on_sinks_timeout, data);
162
+ if (data->sinks_timeout) {
163
+ struct timespec timeout = {0}, interval = {0};
164
+ timeout.tv_sec = TIMEOUT_SINKS_MSEC / 1000;
165
+ timeout.tv_nsec = (TIMEOUT_SINKS_MSEC % 1000) * SPA_NSEC_PER_MSEC;
166
+ pw_loop_update_timer(module->impl->loop, data->sinks_timeout, &timeout, &interval, false);
167
+ }
168
+
169
+ return data->load_emitted ? 0 : SPA_RESULT_RETURN_ASYNC(0);
170
}
171
172
static int module_combine_sink_unload(struct module *module)
173
174
if (d->cleanup != NULL)
175
pw_loop_destroy_source(module->impl->loop, d->cleanup);
176
177
+ if (d->sinks_timeout != NULL)
178
+ pw_loop_destroy_source(module->impl->loop, d->sinks_timeout);
179
+
180
/* Note that we explicitly disconnect the hooks to avoid having the
181
* cleanup triggered again in those callbacks */
182
if (d->sink != NULL) {
183
184
const char *str;
185
char *sink_name = NULL, **sink_names = NULL;
186
struct spa_audio_info_raw info = { 0 };
187
- int i, n, res;
188
+ int i, res;
189
+ int num_sinks = 0;
190
191
PW_LOG_TOPIC_INIT(mod_topic);
192
193
194
}
195
196
if ((str = pw_properties_get(props, "slaves")) != NULL) {
197
- sink_names = pw_split_strv(str, ",", MAX_SINKS, &n);
198
+ sink_names = pw_split_strv(str, ",", MAX_SINKS, &num_sinks);
199
pw_properties_set(props, "slaves", NULL);
200
}
201
202
203
d->info = info;
204
d->sink_name = sink_name;
205
d->sink_names = sink_names;
206
+ d->sinks_pending = (sink_names == NULL) ? 0 : num_sinks;
207
for (i = 0; i < MAX_SINKS; i++) {
208
d->streams[i].stream = NULL;
209
d->streams[i].cleanup = false;
210
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c
Changed
25
1
2
3
pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "ladspa-sink-%u", module->index);
4
pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "ladspa-sink-%u", module->index);
5
+ pw_properties_setf(data->capture_props, "pulse.module.id", "%u", module->index);
6
+ pw_properties_setf(data->playback_props, "pulse.module.id", "%u", module->index);
7
8
f = open_memstream(&args, &size);
9
fprintf(f, "{");
10
11
if (pw_properties_get(capture_props, PW_KEY_DEVICE_CLASS) == NULL)
12
pw_properties_set(capture_props, PW_KEY_DEVICE_CLASS, "filter");
13
14
+ if ((str = pw_properties_get(capture_props, PW_KEY_NODE_DESCRIPTION)) == NULL) {
15
+ str = pw_properties_get(capture_props, PW_KEY_NODE_NAME);
16
+ pw_properties_setf(props, PW_KEY_NODE_DESCRIPTION,
17
+ "%s Sink", str);
18
+ } else {
19
+ pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, str);
20
+ }
21
+
22
if ((str = pw_properties_get(props, "master")) != NULL ||
23
(str = pw_properties_get(props, "sink_master")) != NULL) {
24
pw_properties_set(playback_props, PW_KEY_NODE_TARGET, str);
25
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c
Changed
53
1
2
3
pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "ladspa-source-%u", module->index);
4
pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "ladspa-source-%u", module->index);
5
+ pw_properties_setf(data->capture_props, "pulse.module.id", "%u", module->index);
6
+ pw_properties_setf(data->playback_props, "pulse.module.id", "%u", module->index);
7
8
f = open_memstream(&args, &size);
9
fprintf(f, "{");
10
11
module_args_add_props(props, argument);
12
13
if ((str = pw_properties_get(props, "source_name")) != NULL) {
14
- pw_properties_set(capture_props, PW_KEY_NODE_NAME, str);
15
+ pw_properties_set(playback_props, PW_KEY_NODE_NAME, str);
16
pw_properties_set(props, "source_name", NULL);
17
}
18
if ((str = pw_properties_get(props, "source_properties")) != NULL) {
19
- module_args_add_props(capture_props, str);
20
+ module_args_add_props(playback_props, str);
21
pw_properties_set(props, "source_properties", NULL);
22
}
23
if (pw_properties_get(playback_props, PW_KEY_MEDIA_CLASS) == NULL)
24
25
if (pw_properties_get(playback_props, PW_KEY_DEVICE_CLASS) == NULL)
26
pw_properties_set(playback_props, PW_KEY_DEVICE_CLASS, "filter");
27
28
+ if ((str = pw_properties_get(playback_props, PW_KEY_NODE_DESCRIPTION)) == NULL) {
29
+ str = pw_properties_get(playback_props, PW_KEY_NODE_NAME);
30
+ pw_properties_setf(props, PW_KEY_NODE_DESCRIPTION,
31
+ "%s Source", str);
32
+ } else {
33
+ pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, str);
34
+ }
35
+
36
if ((str = pw_properties_get(props, "master")) != NULL ||
37
(str = pw_properties_get(props, "source_master")) != NULL) {
38
- pw_properties_set(playback_props, PW_KEY_NODE_TARGET, str);
39
+ pw_properties_set(capture_props, PW_KEY_NODE_TARGET, str);
40
pw_properties_set(props, "master", NULL);
41
}
42
43
- if (module_args_to_audioinfo(impl, props, &capture_info) < 0) {
44
+ if (module_args_to_audioinfo(impl, props, &playback_info) < 0) {
45
res = -EINVAL;
46
goto out;
47
}
48
- playback_info = capture_info;
49
+ capture_info = playback_info;
50
51
position_to_props(&capture_info, capture_props);
52
position_to_props(&playback_info, playback_props);
53
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c
Changed
10
1
2
3
pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index);
4
pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index);
5
+ pw_properties_setf(data->capture_props, "pulse.module.id", "%u", module->index);
6
+ pw_properties_setf(data->playback_props, "pulse.module.id", "%u", module->index);
7
8
f = open_memstream(&args, &size);
9
fprintf(f, "{");
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-null-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-null-sink.c
Changed
10
1
2
3
pw_core_add_listener(d->core, &d->core_listener, &core_events, module);
4
5
+ pw_properties_setf(module->props, "pulse.module.id", "%u", module->index);
6
+
7
d->proxy = pw_core_create_object(d->core,
8
"adapter", PW_TYPE_INTERFACE_Node, PW_VERSION_NODE,
9
module->props ? &module->props->dict : NULL, 0);
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c
Changed
10
1
2
&data->core_listener,
3
&core_events, data);
4
5
+ pw_properties_setf(data->capture_props, "pulse.module.id", "%u", module->index);
6
+
7
data->capture = pw_stream_new(data->core,
8
"pipesink capture", data->capture_props);
9
data->capture_props = NULL;
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c
Changed
11
1
2
&data->core_listener,
3
&core_events, data);
4
5
+ pw_properties_setf(data->playback_props, "pulse.module.id",
6
+ "%u", module->index);
7
+
8
data->playback = pw_stream_new(data->core,
9
"pipesource playback", data->playback_props);
10
data->playback_props = NULL;
11
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c
Changed
10
1
2
3
pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "remap-sink-%u", module->index);
4
pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "remap-sink-%u", module->index);
5
+ pw_properties_setf(data->capture_props, "pulse.module.id", "%u", module->index);
6
+ pw_properties_setf(data->playback_props, "pulse.module.id", "%u", module->index);
7
8
f = open_memstream(&args, &size);
9
fprintf(f, "{");
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c
Changed
10
1
2
3
pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "remap-source-%u", module->index);
4
pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "remap-source-%u", module->index);
5
+ pw_properties_setf(data->capture_props, "pulse.module.id", "%u", module->index);
6
+ pw_properties_setf(data->playback_props, "pulse.module.id", "%u", module->index);
7
8
f = open_memstream(&args, &size);
9
fprintf(f, "{");
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c
Changed
28
1
2
{
3
struct module_roc_sink_data *data = module->user_data;
4
FILE *f;
5
- const char *str;
6
char *args;
7
size_t size;
8
9
+ pw_properties_setf(data->sink_props, "pulse.module.id",
10
+ "%u", module->index);
11
+
12
f = open_memstream(&args, &size);
13
fprintf(f, "{");
14
- /* Can't just serialise this dict because the "null" method gets
15
- * interpreted as a JSON null */
16
- if ((str = pw_properties_get(data->roc_props, "local.ip")))
17
- fprintf(f, " local.ip = \"%s\"", str);
18
- if ((str = pw_properties_get(data->roc_props, "remote.ip")))
19
- fprintf(f, " remote.ip = \"%s\"", str);
20
- if ((str = pw_properties_get(data->roc_props, "remote.source.port")))
21
- fprintf(f, " remote.source.port = \"%s\"", str);
22
- if ((str = pw_properties_get(data->roc_props, "remote.repair.port")))
23
- fprintf(f, " remote.repair.port = \"%s\"", str);
24
+ pw_properties_serialize_dict(f, &data->roc_props->dict, 0);
25
fprintf(f, " } sink.props = {");
26
pw_properties_serialize_dict(f, &data->sink_props->dict, 0);
27
fprintf(f, " } }");
28
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c
Changed
30
1
2
{
3
struct module_roc_source_data *data = module->user_data;
4
FILE *f;
5
- const char *str;
6
char *args;
7
size_t size;
8
9
+ pw_properties_setf(data->source_props, "pulse.module.id",
10
+ "%u", module->index);
11
+
12
f = open_memstream(&args, &size);
13
fprintf(f, "{");
14
- /* Can't just serialise this dict because the "null" method gets
15
- * interpreted as a JSON null */
16
- if ((str = pw_properties_get(data->roc_props, "local.ip")))
17
- fprintf(f, " local.ip = \"%s\"", str);
18
- if ((str = pw_properties_get(data->roc_props, "local.source.port")))
19
- fprintf(f, " local.source.port = \"%s\"", str);
20
- if ((str = pw_properties_get(data->roc_props, "local.repair.port")))
21
- fprintf(f, " local.repair.port = \"%s\"", str);
22
- if ((str = pw_properties_get(data->roc_props, "sess.latency.msec")))
23
- fprintf(f, " sess.latency.msec = \"%s\"", str);
24
- if ((str = pw_properties_get(data->roc_props, "resampler.profile")))
25
- fprintf(f, " resampler.profile = \"%s\"", str);
26
+ pw_properties_serialize_dict(f, &data->roc_props->dict, 0);
27
fprintf(f, " } source.props = {");
28
pw_properties_serialize_dict(f, &data->source_props->dict, 0);
29
fprintf(f, " } }");
30
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c
Changed
11
1
2
3
server = pw_properties_get(module->props, "server");
4
5
+ pw_properties_setf(data->stream_props, "pulse.module.id",
6
+ "%u", module->index);
7
+
8
f = open_memstream(&args, &size);
9
fprintf(f, "{");
10
pw_properties_serialize_dict(f, &module->props->dict, 0);
11
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c
Changed
11
1
2
size_t size;
3
const char *server;
4
5
+ pw_properties_setf(data->stream_props, "pulse.module.id",
6
+ "%u", module->index);
7
+
8
server = pw_properties_get(module->props, "server");
9
10
f = open_memstream(&args, &size);
11
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c
Changed
10
1
2
}
3
4
data->manager = pw_manager_new(data->core);
5
- if (client->manager == NULL) {
6
+ if (data->manager == NULL) {
7
pw_log_error("failed to create pipewire manager: %m");
8
return -errno;
9
}
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/modules/registry.h -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/modules/registry.h
Changed
9
1
2
3
struct impl;
4
5
+struct module *create_module_always_sink(struct impl *impl, const char *argument);
6
struct module *create_module_combine_sink(struct impl *impl, const char *argument);
7
struct module *create_module_echo_cancel(struct impl *impl, const char *argument);
8
struct module *create_module_ladspa_sink(struct impl *impl, const char *argument);
9
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/operation.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/operation.c
Changed
44
1
2
#include "operation.h"
3
#include "reply.h"
4
5
-int operation_new(struct client *client, uint32_t tag)
6
+int operation_new_cb(struct client *client, uint32_t tag,
7
+ void (*callback)(void *data, struct client *client, uint32_t tag),
8
+ void *data)
9
{
10
struct operation *o;
11
12
13
14
o->client = client;
15
o->tag = tag;
16
+ o->callback = callback;
17
+ o->data = data;
18
19
spa_list_append(&client->operations, &o->link);
20
pw_manager_sync(client->manager);
21
22
return 0;
23
}
24
25
+int operation_new(struct client *client, uint32_t tag)
26
+{
27
+ return operation_new_cb(client, tag, NULL, NULL);
28
+}
29
+
30
void operation_free(struct operation *o)
31
{
32
spa_list_remove(&o->link);
33
34
35
pw_log_info("[%s]: tag:%u complete", client->name, o->tag);
36
37
- reply_simple_ack(client, o->tag);
38
+ if (o->callback)
39
+ o->callback(o->data, client, o->tag);
40
+ else
41
+ reply_simple_ack(client, o->tag);
42
operation_free(o);
43
}
44
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/operation.h -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/operation.h
Changed
16
1
2
struct spa_list link;
3
struct client *client;
4
uint32_t tag;
5
+ void (*callback) (void *data, struct client *client, uint32_t tag);
6
+ void *data;
7
};
8
9
int operation_new(struct client *client, uint32_t tag);
10
+int operation_new_cb(struct client *client, uint32_t tag,
11
+ void (*callback) (void *data, struct client *client, uint32_t tag),
12
+ void *data);
13
void operation_free(struct operation *o);
14
void operation_complete(struct operation *o);
15
16
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
419
1
2
}
3
4
static int send_object_event(struct client *client, struct pw_manager_object *o,
5
- uint32_t facility)
6
+ uint32_t type)
7
{
8
uint32_t event = 0, mask = 0, res_index = o->index;
9
10
if (pw_manager_object_is_sink(o)) {
11
client_queue_subscribe_event(client,
12
SUBSCRIPTION_MASK_SINK,
13
- SUBSCRIPTION_EVENT_SINK | facility,
14
+ SUBSCRIPTION_EVENT_SINK | type,
15
res_index);
16
}
17
if (pw_manager_object_is_source_or_monitor(o)) {
18
19
if (event != SPA_ID_INVALID)
20
client_queue_subscribe_event(client,
21
mask,
22
- event | facility,
23
+ event | type,
24
res_index);
25
return 0;
26
}
27
28
29
if (attr->maxlength == (uint32_t) -1 || attr->maxlength > MAXLENGTH)
30
attr->maxlength = MAXLENGTH;
31
- attr->maxlength -= attr->maxlength % frame_size;
32
- attr->maxlength = SPA_MAX(attr->maxlength, frame_size);
33
+ attr->maxlength = SPA_ROUND_UP(attr->maxlength, frame_size);
34
+
35
+ minreq = SPA_MIN(minreq, attr->maxlength);
36
37
if (attr->tlength == (uint32_t) -1)
38
attr->tlength = frac_to_bytes_round_up(s->default_tlength, &s->ss);
39
- if (attr->tlength > attr->maxlength)
40
- attr->tlength = attr->maxlength;
41
- attr->tlength -= attr->tlength % frame_size;
42
- attr->tlength = SPA_MAX(attr->tlength, frame_size);
43
+ attr->tlength = SPA_MIN(attr->tlength, attr->maxlength);
44
+ attr->tlength = SPA_ROUND_UP(attr->tlength, frame_size);
45
attr->tlength = SPA_MAX(attr->tlength, minreq);
46
47
if (attr->minreq == (uint32_t) -1) {
48
49
/* With low-latency, tlength/4 gives a decent default in all of traditional,
50
* adjust latency and early request modes. */
51
uint32_t m = attr->tlength / 4;
52
- m -= m % frame_size;
53
+ m = SPA_ROUND_DOWN(m, frame_size);
54
attr->minreq = SPA_MIN(process, m);
55
}
56
attr->minreq = SPA_MAX(attr->minreq, minreq);
57
58
if (attr->tlength < attr->minreq+frame_size)
59
- attr->tlength = attr->minreq + frame_size;
60
+ attr->tlength = SPA_MIN(attr->minreq + frame_size, attr->maxlength);
61
62
if (s->early_requests) {
63
latency = attr->minreq;
64
65
else
66
latency = attr->minreq;
67
68
- latency -= latency % frame_size;
69
+ latency = SPA_ROUND_DOWN(latency, frame_size);
70
71
if (attr->tlength >= latency)
72
attr->tlength -= latency;
73
74
}
75
76
if (attr->tlength < latency + 2 * attr->minreq)
77
- attr->tlength = latency + 2 * attr->minreq;
78
+ attr->tlength = SPA_MIN(latency + 2 * attr->minreq, attr->maxlength);
79
80
- attr->minreq -= attr->minreq % frame_size;
81
+ attr->minreq = SPA_ROUND_DOWN(attr->minreq, frame_size);
82
if (attr->minreq <= 0) {
83
attr->minreq = frame_size;
84
attr->tlength += frame_size*2;
85
}
86
if (attr->tlength <= attr->minreq)
87
- attr->tlength = attr->minreq*2 + frame_size;
88
+ attr->tlength = SPA_MIN(attr->minreq*2 + frame_size, attr->maxlength);
89
90
max_prebuf = attr->tlength + frame_size - attr->minreq;
91
if (attr->prebuf == (uint32_t) -1 || attr->prebuf > max_prebuf)
92
attr->prebuf = max_prebuf;
93
- attr->prebuf -= attr->prebuf % frame_size;
94
+ attr->prebuf = SPA_ROUND_DOWN(attr->prebuf, frame_size);
95
96
attr->fragsize = 0;
97
98
99
pw_log_info("[%s] SUBSCRIBE tag:%u mask:%08x",
100
client->name, tag, mask);
101
102
+ if (mask & ~SUBSCRIPTION_MASK_ALL)
103
+ return -EINVAL;
104
+
105
client->subscribed = mask;
106
107
return reply_simple_ack(client, tag);
108
109
return o;
110
}
111
112
-static void sample_play_ready(void *data, uint32_t index)
113
+static void sample_play_ready_reply(void *data, struct client *client, uint32_t tag)
114
{
115
struct pending_sample *ps = data;
116
- struct client *client = ps->client;
117
struct message *reply;
118
+ uint32_t index = id_to_index(client->manager, ps->play->id);
119
120
pw_log_info("[%s] PLAY_SAMPLE tag:%u index:%u",
121
client->name, ps->tag, index);
122
123
client_queue_message(client, reply);
124
}
125
126
+static void sample_play_ready(void *data, uint32_t id)
127
+{
128
+ struct pending_sample *ps = data;
129
+ struct client *client = ps->client;
130
+ operation_new_cb(client, ps->tag, sample_play_ready_reply, ps);
131
+}
132
+
133
static void on_sample_done(void *obj, void *data, int res, uint32_t id)
134
{
135
struct pending_sample *ps = obj;
136
137
snprintf(monitor_name, size, "%s.monitor", name);
138
139
if ((str = spa_dict_lookup(info->props, PW_KEY_MODULE_ID)) != NULL)
140
+ module_id = id_to_index(manager, (uint32_t)atoi(str));
141
+ if (module_id == SPA_ID_INVALID &&
142
+ (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL)
143
module_id = (uint32_t)atoi(str);
144
if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
145
card_id = (uint32_t)atoi(str);
146
147
TAG_STRING, desc,
148
TAG_SAMPLE_SPEC, &dev_info.ss,
149
TAG_CHANNEL_MAP, &dev_info.map,
150
- TAG_U32, id_to_index(manager, module_id), /* module index */
151
+ TAG_U32, module_id, /* module index */
152
TAG_CVOLUME, &dev_info.volume_info.volume,
153
TAG_BOOLEAN, dev_info.volume_info.mute,
154
TAG_U32, o->index, /* monitor source index */
155
156
snprintf(monitor_desc, size, "Monitor of %s", desc);
157
158
if ((str = spa_dict_lookup(info->props, PW_KEY_MODULE_ID)) != NULL)
159
+ module_id = id_to_index(manager, (uint32_t)atoi(str));
160
+ if (module_id == SPA_ID_INVALID &&
161
+ (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL)
162
module_id = (uint32_t)atoi(str);
163
if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
164
card_id = (uint32_t)atoi(str);
165
166
TAG_STRING, is_monitor ? monitor_desc : desc,
167
TAG_SAMPLE_SPEC, &dev_info.ss,
168
TAG_CHANNEL_MAP, &dev_info.map,
169
- TAG_U32, id_to_index(manager, module_id), /* module index */
170
+ TAG_U32, module_id, /* module index */
171
TAG_CVOLUME, &dev_info.volume_info.volume,
172
TAG_BOOLEAN, dev_info.volume_info.mute,
173
TAG_U32, is_monitor ? o->index : SPA_ID_INVALID,/* monitor of sink */
174
175
return -ENOENT;
176
177
if ((str = spa_dict_lookup(info->props, PW_KEY_MODULE_ID)) != NULL)
178
+ module_id = id_to_index(manager, (uint32_t)atoi(str));
179
+ if (module_id == SPA_ID_INVALID &&
180
+ (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL)
181
module_id = (uint32_t)atoi(str);
182
+
183
if (!pw_manager_object_is_virtual(o) &&
184
(str = spa_dict_lookup(info->props, PW_KEY_CLIENT_ID)) != NULL)
185
client_id = (uint32_t)atoi(str);
186
187
message_put(m,
188
TAG_U32, o->index, /* sink_input index */
189
TAG_STRING, get_media_name(info),
190
- TAG_U32, id_to_index(manager, module_id), /* module index */
191
+ TAG_U32, module_id, /* module index */
192
TAG_U32, id_to_index(manager, client_id), /* client index */
193
TAG_U32, peer_index, /* sink index */
194
TAG_SAMPLE_SPEC, &dev_info.ss,
195
196
return -ENOENT;
197
198
if ((str = spa_dict_lookup(info->props, PW_KEY_MODULE_ID)) != NULL)
199
+ module_id = id_to_index(manager, (uint32_t)atoi(str));
200
+ if (module_id == SPA_ID_INVALID &&
201
+ (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL)
202
module_id = (uint32_t)atoi(str);
203
+
204
if (!pw_manager_object_is_virtual(o) &&
205
(str = spa_dict_lookup(info->props, PW_KEY_CLIENT_ID)) != NULL)
206
client_id = (uint32_t)atoi(str);
207
208
message_put(m,
209
TAG_U32, o->index, /* source_output index */
210
TAG_STRING, get_media_name(info),
211
- TAG_U32, id_to_index(manager, module_id), /* module index */
212
+ TAG_U32, module_id, /* module index */
213
TAG_U32, id_to_index(manager, client_id), /* client index */
214
TAG_U32, peer_index, /* source index */
215
TAG_SAMPLE_SPEC, &dev_info.ss,
216
217
spa_assert(!SPA_RESULT_IS_ASYNC(result));
218
219
if (SPA_RESULT_IS_OK(result)) {
220
- pw_log_info("[%s] loaded module index:%u name:%s",
221
- client_name, module->index, module->name);
222
+ pw_log_info("[%s] loaded module index:%u name:%s tag:%d",
223
+ client_name, module->index, module->name, tag);
224
225
module->loaded = true;
226
227
228
}
229
}
230
else {
231
- pw_log_warn("%p: [%s] failed to load module index:%u name:%s result:%d (%s)",
232
+ pw_log_warn("%p: [%s] failed to load module index:%u name:%s tag:%d result:%d (%s)",
233
impl, client_name,
234
- module->index, module->name,
235
+ module->index, module->name, tag,
236
result, spa_strerror(result));
237
238
module_schedule_unload(module);
239
240
struct module *module;
241
struct spa_hook module_listener;
242
243
+ struct spa_hook manager_listener;
244
+
245
uint32_t tag;
246
+
247
+ int result;
248
+ bool wait_sync;
249
};
250
251
+static void finish_pending_module(struct pending_module *pm)
252
+{
253
+ spa_hook_remove(&pm->module_listener);
254
+
255
+ if (pm->client != NULL) {
256
+ spa_hook_remove(&pm->client_listener);
257
+ spa_hook_remove(&pm->manager_listener);
258
+ }
259
+
260
+ handle_module_loaded(pm->module, pm->client, pm->tag, pm->result);
261
+ free(pm);
262
+}
263
+
264
+static void on_load_module_manager_sync(void *data)
265
+{
266
+ struct pending_module *pm = data;
267
+
268
+ pw_log_debug("pending module %p: manager sync wait_sync:%d tag:%d",
269
+ pm, pm->wait_sync, pm->tag);
270
+
271
+ if (!pm->wait_sync)
272
+ return;
273
+
274
+ finish_pending_module(pm);
275
+}
276
+
277
static void on_module_loaded(void *data, int result)
278
{
279
struct pending_module *pm = data;
280
281
- if (pm->client != NULL)
282
- spa_hook_remove(&pm->client_listener);
283
+ pw_log_debug("pending module %p: loaded, result:%d tag:%d",
284
+ pm, result, pm->tag);
285
286
- spa_hook_remove(&pm->module_listener);
287
+ pm->result = result;
288
289
- handle_module_loaded(pm->module, pm->client, pm->tag, result);
290
+ /*
291
+ * Do manager sync first: the module may have its own core, so
292
+ * although things are completed on the server, our client
293
+ * might not yet see them.
294
+ */
295
296
- free(pm);
297
+ if (pm->client == NULL) {
298
+ finish_pending_module(pm);
299
+ } else {
300
+ pw_log_debug("pending module %p: wait manager sync tag:%d", pm, pm->tag);
301
+ pm->wait_sync = true;
302
+ pw_manager_sync(pm->client->manager);
303
+ }
304
}
305
306
static void on_module_destroy(void *data)
307
{
308
- on_module_loaded(data, -ECANCELED);
309
+ struct pending_module *pm = data;
310
+
311
+ pw_log_debug("pending module %p: destroyed, tag:%d",
312
+ pm, pm->tag);
313
+
314
+ pm->result = -ECANCELED;
315
+ finish_pending_module(pm);
316
}
317
318
static void on_client_disconnect(void *data)
319
{
320
struct pending_module *pm = data;
321
322
+ pw_log_debug("pending module %p: client disconnect tag:%d", pm, pm->tag);
323
+
324
spa_hook_remove(&pm->client_listener);
325
+ spa_hook_remove(&pm->manager_listener);
326
pm->client = NULL;
327
+
328
+ if (pm->wait_sync)
329
+ finish_pending_module(pm);
330
+}
331
+
332
+static void on_load_module_manager_disconnect(void *data)
333
+{
334
+ on_client_disconnect(data);
335
}
336
337
static int do_load_module(struct client *client, uint32_t command, uint32_t tag, struct message *m)
338
339
VERSION_CLIENT_EVENTS,
340
.disconnect = on_client_disconnect,
341
};
342
+ static const struct pw_manager_events manager_events = {
343
+ PW_VERSION_MANAGER_EVENTS,
344
+ .disconnect = on_load_module_manager_disconnect,
345
+ .sync = on_load_module_manager_sync,
346
+ };
347
348
const char *name, *argument;
349
struct module *module;
350
+ struct pending_module *pm;
351
int r;
352
353
if (message_get(m,
354
355
if (module == NULL)
356
return -errno;
357
358
+ pm = calloc(1, sizeof(*pm));
359
+ if (pm == NULL)
360
+ return -errno;
361
+
362
+ pm->tag = tag;
363
+ pm->client = client;
364
+ pm->module = module;
365
+
366
+ pw_log_debug("pending module %p: start tag:%d", pm, tag);
367
+
368
r = module_load(client, module);
369
- if (SPA_RESULT_IS_ASYNC(r)) {
370
- struct pending_module *pm = calloc(1, sizeof(*pm));
371
- if (pm == NULL)
372
- return -errno;
373
-
374
- pm->tag = tag;
375
- pm->client = client;
376
- pm->module = module;
377
378
- module_add_listener(module, &pm->module_listener, &module_events, pm);
379
- client_add_listener(client, &pm->client_listener, &client_events, pm);
380
- } else {
381
- handle_module_loaded(module, client, tag, r);
382
- }
383
+ module_add_listener(module, &pm->module_listener, &module_events, pm);
384
+ client_add_listener(client, &pm->client_listener, &client_events, pm);
385
+ pw_manager_add_listener(client->manager, &pm->manager_listener, &manager_events, pm);
386
+
387
+ if (!SPA_RESULT_IS_ASYNC(r))
388
+ on_module_loaded(pm, r);
389
390
/*
391
* return 0 to prevent `handle_packet()` from sending a reply
392
393
394
module_unload(module);
395
396
- return reply_simple_ack(client, tag);
397
+ return operation_new(client, tag);
398
}
399
400
static int do_send_object_message(struct client *client, uint32_t command, uint32_t tag, struct message *m)
401
402
pw_map_for_each(&impl->modules, impl_unload_module, impl);
403
pw_map_clear(&impl->modules);
404
405
-#if HAVE_DBUS
406
+#ifdef HAVE_DBUS
407
if (impl->dbus_name) {
408
dbus_release_name(impl->dbus_name);
409
impl->dbus_name = NULL;
410
411
pw_context_add_listener(context, &impl->context_listener,
412
&context_events, impl);
413
414
-#if HAVE_DBUS
415
+#ifdef HAVE_DBUS
416
impl->dbus_name = dbus_request_name(context, "org.pulseaudio.Server");
417
#endif
418
419
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/quirks.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/quirks.c
Changed
137
1
2
return 0;
3
}
4
5
-static bool find_match(struct spa_json *arr, const struct spa_dict *props)
6
-{
7
- struct spa_json it[1];
8
-
9
- while (spa_json_enter_object(arr, &it[0]) > 0) {
10
- char key[256], val[1024];
11
- const char *str, *value;
12
- int match = 0, fail = 0;
13
- int len;
14
-
15
- while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
16
- bool success = false;
17
-
18
- if ((len = spa_json_next(&it[0], &value)) <= 0)
19
- break;
20
-
21
- str = spa_dict_lookup(props, key);
22
-
23
- if (spa_json_is_null(value, len)) {
24
- success = str == NULL;
25
- } else {
26
- if (spa_json_parse_stringn(value, len, val, sizeof(val)) < 0)
27
- continue;
28
- value = val;
29
- len = strlen(val);
30
- }
31
- if (str != NULL) {
32
- if (value[0] == '~') {
33
- regex_t preg;
34
- if (regcomp(&preg, value+1, REG_EXTENDED | REG_NOSUB) == 0) {
35
- if (regexec(&preg, str, 0, NULL, 0) == 0)
36
- success = true;
37
- regfree(&preg);
38
- }
39
- } else if (strncmp(str, value, len) == 0 &&
40
- strlen(str) == (size_t)len) {
41
- success = true;
42
- }
43
- }
44
- if (success) {
45
- match++;
46
- pw_log_debug("'%s' match '%s' < > '%.*s'", key, str, len, value);
47
- }
48
- else
49
- fail++;
50
- }
51
- if (match > 0 && fail == 0)
52
- return true;
53
- }
54
- return false;
55
-}
56
-
57
-static int pw_conf_match_rules(const char *rules, size_t size, const struct spa_dict *props,
58
- int (*matched) (void *data, const char *action, const char *val, int len),
59
- void *data)
60
-{
61
- const char *val;
62
- struct spa_json it[4], actions;
63
- int count = 0;
64
-
65
- spa_json_init(&it[0], rules, size);
66
- if (spa_json_enter_array(&it[0], &it[1]) < 0)
67
- return 0;
68
-
69
- while (spa_json_enter_object(&it[1], &it[2]) > 0) {
70
- char key[64];
71
- bool have_match = false, have_actions = false;
72
-
73
- while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
74
- if (spa_streq(key, "matches")) {
75
- if (spa_json_enter_array(&it[2], &it[3]) < 0)
76
- break;
77
-
78
- have_match = find_match(&it[3], props);
79
- }
80
- else if (spa_streq(key, "actions")) {
81
- if (spa_json_enter_object(&it[2], &actions) > 0)
82
- have_actions = true;
83
- }
84
- else if (spa_json_next(&it[2], &val) <= 0)
85
- break;
86
- }
87
- if (!have_match || !have_actions)
88
- continue;
89
-
90
- while (spa_json_get_string(&actions, key, sizeof(key)) > 0) {
91
- int res, len;
92
- pw_log_debug("action %s", key);
93
-
94
- if ((len = spa_json_next(&actions, &val)) <= 0)
95
- break;
96
-
97
- if (spa_json_is_container(val, len))
98
- len = spa_json_container_len(&actions, val, len);
99
-
100
- if ((res = matched(data, key, val, len)) < 0)
101
- return res;
102
-
103
- count += res;
104
- }
105
- }
106
- return count;
107
-}
108
-
109
-static int client_rule_matched(void *data, const char *action, const char *val, int len)
110
+static int apply_match(void *data, const char *location, const char *action,
111
+ const char *val, size_t len)
112
{
113
struct client *client = data;
114
115
116
return 0;
117
}
118
119
-static int apply_pulse_rules(void *data, const char *location, const char *section,
120
- const char *str, size_t len)
121
-{
122
- struct client *client = data;
123
- pw_conf_match_rules(str, len, &client->props->dict,
124
- client_rule_matched, client);
125
- return 0;
126
-}
127
-
128
int client_update_quirks(struct client *client)
129
{
130
struct impl *impl = client->impl;
131
struct pw_context *context = impl->context;
132
- return pw_context_conf_section_for_each(context, "pulse.rules",
133
- apply_pulse_rules, client);
134
+ return pw_context_conf_section_match_rules(context, "pulse.rules",
135
+ &client->props->dict, apply_match, client);
136
}
137
pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/remap.c
Added
58
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2020 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <stddef.h>
27
+
28
+#include <pipewire/keys.h>
29
+
30
+#include "remap.h"
31
+
32
+const struct str_map media_role_map[] = {
33
+ { "Movie", "video", },
34
+ { "Music", "music", },
35
+ { "Game", "game", },
36
+ { "Notification", "event", },
37
+ { "Communication", "phone", },
38
+ { "Movie", "animation", },
39
+ { "Production", "production", },
40
+ { "Accessibility", "a11y", },
41
+ { "Test", "test", },
42
+ { NULL, NULL },
43
+};
44
+
45
+const struct str_map props_key_map[] = {
46
+ { PW_KEY_DEVICE_BUS_PATH, "device.bus_path" },
47
+ { PW_KEY_DEVICE_FORM_FACTOR, "device.form_factor" },
48
+ { PW_KEY_DEVICE_ICON_NAME, "device.icon_name" },
49
+ { PW_KEY_DEVICE_INTENDED_ROLES, "device.intended_roles" },
50
+ { PW_KEY_NODE_DESCRIPTION, "device.description" },
51
+ { PW_KEY_MEDIA_ICON_NAME, "media.icon_name" },
52
+ { PW_KEY_APP_ICON_NAME, "application.icon_name" },
53
+ { PW_KEY_APP_PROCESS_MACHINE_ID, "application.process.machine_id" },
54
+ { PW_KEY_APP_PROCESS_SESSION_ID, "application.process.session_id" },
55
+ { PW_KEY_MEDIA_ROLE, "media.role", media_role_map },
56
+ { NULL, NULL },
57
+};
58
pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/remap.h
Added
54
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2020 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#ifndef PULSE_SERVER_REMAP_H
27
+#define PULSE_SERVER_REMAP_H
28
+
29
+#include <stddef.h>
30
+
31
+#include <spa/utils/string.h>
32
+
33
+struct str_map {
34
+ const char *pw_str;
35
+ const char *pa_str;
36
+ const struct str_map *child;
37
+};
38
+
39
+extern const struct str_map media_role_map[];
40
+
41
+extern const struct str_map props_key_map[];
42
+
43
+static inline const struct str_map *str_map_find(const struct str_map *map, const char *pw, const char *pa)
44
+{
45
+ size_t i;
46
+ for (i = 0; map[i].pw_str; i++)
47
+ if ((pw && spa_streq(map[i].pw_str, pw)) ||
48
+ (pa && spa_streq(map[i].pa_str, pa)))
49
+ return &map[i];
50
+ return NULL;
51
+}
52
+
53
+#endif /* PULSE_SERVER_REMAP_H */
54
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/sample-play.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/sample-play.c
Changed
12
1
2
sample_play_emit_done(p, -EIO);
3
break;
4
case PW_STREAM_STATE_PAUSED:
5
- p->index = pw_stream_get_node_id(p->stream);
6
- sample_play_emit_ready(p, p->index);
7
+ p->id = pw_stream_get_node_id(p->stream);
8
+ sample_play_emit_ready(p, p->id);
9
break;
10
default:
11
break;
12
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/sample-play.h -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/sample-play.h
Changed
10
1
2
struct sample *sample;
3
struct pw_stream *stream;
4
struct spa_io_rate_match *rate_match;
5
- uint32_t index;
6
+ uint32_t id;
7
struct spa_hook listener;
8
struct pw_context *context;
9
struct pw_loop *main_loop;
10
pipewire-0.3.45.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.47.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
19
1
2
if (errno == EINTR)
3
continue;
4
res = -errno;
5
- if (res != -EAGAIN && res != -EWOULDBLOCK)
6
+ if (res != -EAGAIN && res != -EWOULDBLOCK &&
7
+ res != -EPIPE && res != -ECONNRESET)
8
pw_log_warn("recv client:%p res %zd: %m", client, r);
9
goto exit;
10
}
11
12
error:
13
switch (res) {
14
case -EPIPE:
15
+ case -ECONNRESET:
16
pw_log_info("server %p: client %p [%s] disconnected",
17
client->server, client, client->name);
18
SPA_FALLTHROUGH;
19
pipewire-0.3.45.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.47.tar.gz/src/modules/module-raop-sink.c
Changed
21
1
2
#define DEFAULT_CHANNELS "2"
3
#define DEFAULT_POSITION "[ FL FR ]"
4
5
+#define DEFAULT_LATENCY (DEFAULT_RATE*2)
6
+
7
#define MODULE_USAGE "[ node.latency=<latency as fraction> ] " \
8
"[ node.name=<name of the nodes> ] " \
9
"[ node.description=<description of the nodes> ] " \
10
11
12
if ((str = spa_dict_lookup(headers, "Audio-Latency")) != NULL) {
13
if (!spa_atou32(str, &impl->latency, 0))
14
- impl->latency = 0;
15
+ impl->latency = DEFAULT_LATENCY;
16
+ } else {
17
+ impl->latency = DEFAULT_LATENCY;
18
}
19
20
spa_zero(latency);
21
pipewire-0.3.45.tar.gz/src/pipewire/conf.c -> pipewire-0.3.47.tar.gz/src/pipewire/conf.c
Changed
223
1
2
#include <unistd.h>
3
#include <sys/wait.h>
4
#include <dirent.h>
5
-#if HAVE_PWD_H
6
+#include <regex.h>
7
+#ifdef HAVE_PWD_H
8
#include <pwd.h>
9
#endif
10
#ifdef __FreeBSD__
11
12
if (pid == 0) {
13
char *cmd, **argv;
14
15
+ /* Double fork to avoid zombies; we don't want to set SIGCHLD handler */
16
+ pid = fork();
17
+
18
+ if (pid < 0) {
19
+ pw_log_error("fork error: %m");
20
+ exit(1);
21
+ } else if (pid != 0) {
22
+ exit(0);
23
+ }
24
+
25
cmd = spa_aprintf("%s %s", key, args ? args : "");
26
argv = pw_split_strv(cmd, " \t", INT_MAX, &n_args);
27
free(cmd);
28
29
if (res == -1) {
30
res = -errno;
31
pw_log_error("execvp error '%s': %m", key);
32
- return res;
33
}
34
- }
35
- else {
36
+
37
+ exit(1);
38
+ } else if (pid < 0) {
39
+ pw_log_error("fork error: %m");
40
+ } else {
41
int status = 0;
42
- res = waitpid(pid, &status, WNOHANG);
43
- pw_log_info("exec got pid %d res:%d status:%d", pid, res, status);
44
+ do {
45
+ errno = 0;
46
+ res = waitpid(pid, &status, 0);
47
+ } while (res < 0 && errno == EINTR);
48
+ pw_log_debug("exec got pid %d res:%d status:%d", (int)pid, res, status);
49
}
50
return 0;
51
}
52
53
return res;
54
}
55
56
+
57
SPA_EXPORT
58
int pw_context_conf_section_for_each(struct pw_context *context, const char *section,
59
int (*callback) (void *data, const char *location, const char *section,
60
61
struct pw_properties *conf = context->conf;
62
const char *path = NULL;
63
const struct spa_dict_item *it;
64
- int res;
65
+ int res = 0;
66
67
spa_dict_for_each(it, &conf->dict) {
68
if (spa_strendswith(it->key, "config.path")) {
69
70
update_props, &data);
71
return data.count;
72
}
73
+
74
+struct match {
75
+ const struct spa_dict *props;
76
+ int (*matched) (void *data, const char *location, const char *action,
77
+ const char *val, size_t len);
78
+ void *data;
79
+};
80
+
81
+/*
82
+ * {
83
+ * # all keys must match the value. ~ in value starts regex.
84
+ * <key> = <value>
85
+ * ...
86
+ * }
87
+ */
88
+static bool find_match(struct spa_json *arr, const struct spa_dict *props)
89
+{
90
+ struct spa_json it[1];
91
+
92
+ while (spa_json_enter_object(arr, &it[0]) > 0) {
93
+ char key[256], val[1024];
94
+ const char *str, *value;
95
+ int match = 0, fail = 0;
96
+ int len;
97
+
98
+ while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
99
+ bool success = false;
100
+
101
+ if ((len = spa_json_next(&it[0], &value)) <= 0)
102
+ break;
103
+
104
+ str = spa_dict_lookup(props, key);
105
+
106
+ if (spa_json_is_null(value, len)) {
107
+ success = str == NULL;
108
+ } else {
109
+ if (spa_json_parse_stringn(value, len, val, sizeof(val)) < 0)
110
+ continue;
111
+ value = val;
112
+ len = strlen(val);
113
+ }
114
+ if (str != NULL) {
115
+ if (value[0] == '~') {
116
+ regex_t preg;
117
+ if (regcomp(&preg, value+1, REG_EXTENDED | REG_NOSUB) == 0) {
118
+ if (regexec(&preg, str, 0, NULL, 0) == 0)
119
+ success = true;
120
+ regfree(&preg);
121
+ }
122
+ } else if (strncmp(str, value, len) == 0 &&
123
+ strlen(str) == (size_t)len) {
124
+ success = true;
125
+ }
126
+ }
127
+ if (success) {
128
+ match++;
129
+ pw_log_debug("'%s' match '%s' < > '%.*s'", key, str, len, value);
130
+ }
131
+ else
132
+ fail++;
133
+ }
134
+ if (match > 0 && fail == 0)
135
+ return true;
136
+ }
137
+ return false;
138
+}
139
+
140
+/**
141
+ * rules = [
142
+ * {
143
+ * matches = [
144
+ * # any of the items in matches needs to match, it one does,
145
+ * # actions are emited.
146
+ * {
147
+ * # all keys must match the value. ~ in value starts regex.
148
+ * <key> = <value>
149
+ * ...
150
+ * }
151
+ * ...
152
+ * ]
153
+ * actions = {
154
+ * <action> = <value>
155
+ * ...
156
+ * }
157
+ * }
158
+ * ]
159
+ */
160
+static int match_rules(void *data, const char *location, const char *section,
161
+ const char *str, size_t len)
162
+{
163
+ struct match *match = data;
164
+ const struct spa_dict *props = match->props;
165
+ const char *val;
166
+ struct spa_json it[4], actions;
167
+
168
+ spa_json_init(&it[0], str, len);
169
+ if (spa_json_enter_array(&it[0], &it[1]) < 0)
170
+ return 0;
171
+
172
+ while (spa_json_enter_object(&it[1], &it[2]) > 0) {
173
+ char key[64];
174
+ bool have_match = false, have_actions = false;
175
+
176
+ while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
177
+ if (spa_streq(key, "matches")) {
178
+ if (spa_json_enter_array(&it[2], &it[3]) < 0)
179
+ break;
180
+
181
+ have_match = find_match(&it[3], props);
182
+ }
183
+ else if (spa_streq(key, "actions")) {
184
+ if (spa_json_enter_object(&it[2], &actions) > 0)
185
+ have_actions = true;
186
+ }
187
+ else if (spa_json_next(&it[2], &val) <= 0)
188
+ break;
189
+ }
190
+ if (!have_match || !have_actions)
191
+ continue;
192
+
193
+ while (spa_json_get_string(&actions, key, sizeof(key)) > 0) {
194
+ int res, len;
195
+ pw_log_debug("action %s", key);
196
+
197
+ if ((len = spa_json_next(&actions, &val)) <= 0)
198
+ break;
199
+
200
+ if (spa_json_is_container(val, len))
201
+ len = spa_json_container_len(&actions, val, len);
202
+
203
+ if ((res = match->matched(match->data, location, key, val, len)) < 0)
204
+ return res;
205
+ }
206
+ }
207
+ return 0;
208
+}
209
+
210
+SPA_EXPORT
211
+int pw_context_conf_section_match_rules(struct pw_context *context, const char *section,
212
+ struct spa_dict *props,
213
+ int (*callback) (void *data, const char *location, const char *action,
214
+ const char *str, size_t len),
215
+ void *data)
216
+{
217
+ struct match match = {
218
+ .props = props,
219
+ .matched = callback,
220
+ .data = data };
221
+ return pw_context_conf_section_for_each(context, section, match_rules, &match);
222
+}
223
pipewire-0.3.45.tar.gz/src/pipewire/context.c -> pipewire-0.3.47.tar.gz/src/pipewire/context.c
Changed
36
1
2
struct pw_impl_node *n, *s, *target, *fallback;
3
uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum;
4
uint32_t *rates, n_rates, def_rate;
5
- bool freewheel = false, global_force_rate, force_rate, global_force_quantum;
6
+ bool freewheel = false, global_force_rate, force_rate, force_quantum, global_force_quantum;
7
8
pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason);
9
10
11
get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &lim_quantum, &rate_quantum);
12
rates = get_rates(context, &def_rate, &n_rates, &global_force_rate);
13
14
- global_force_quantum = rate_quantum == 0;
15
+ force_quantum = global_force_quantum = rate_quantum == 0;
16
force_rate = global_force_rate;
17
18
/* start from all drivers and group all nodes that are linked
19
20
def_quantum = min_quantum = max_quantum = s->force_quantum;
21
rate_quantum = 0;
22
quantum_stamp = s->stamp;
23
+ force_quantum = true;
24
}
25
if (!global_force_rate && s->force_rate > 0 &&
26
s->stamp > rate_stamp) {
27
28
running = !n->passive;
29
}
30
31
+ if (force_quantum)
32
+ lock_quantum = false;
33
if (force_rate)
34
lock_rate = false;
35
36
pipewire-0.3.45.tar.gz/src/pipewire/context.h -> pipewire-0.3.47.tar.gz/src/pipewire/context.h
Changed
14
1
2
int (*callback) (void *data, const char *location, const char *section,
3
const char *str, size_t len),
4
void *data);
5
+/** emit callback for all matched properties. Since 0.3.46 */
6
+int pw_context_conf_section_match_rules(struct pw_context *context, const char *section,
7
+ struct spa_dict *props,
8
+ int (*callback) (void *data, const char *location, const char *action,
9
+ const char *str, size_t len),
10
+ void *data);
11
12
/** Get the context support objects */
13
const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support);
14
pipewire-0.3.45.tar.gz/src/pipewire/filter.c -> pipewire-0.3.47.tar.gz/src/pipewire/filter.c
Changed
99
1
2
#define MAX_BUFFERS 64
3
4
#define MASK_BUFFERS (MAX_BUFFERS-1)
5
-#define MAX_PORTS 1024
6
7
static bool mlock_warned = false;
8
9
10
} rt;
11
12
struct spa_list port_list;
13
- struct port *ports[2][MAX_PORTS];
14
+ struct pw_map ports[2];
15
16
uint32_t change_mask_all;
17
struct spa_node_info info;
18
19
enum spa_direction direction, uint32_t user_data_size)
20
{
21
struct port *p;
22
- int i;
23
-
24
- for (i = 0; i < MAX_PORTS; i++) {
25
- if ((filter->ports[direction][i]) == NULL)
26
- break;
27
- }
28
- if (i == MAX_PORTS)
29
- return NULL;
30
31
p = calloc(1, sizeof(struct port) + user_data_size);
32
p->filter = filter;
33
p->direction = direction;
34
- p->id = i;
35
p->latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
36
p->latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
37
38
spa_list_init(&p->param_list);
39
spa_ringbuffer_init(&p->dequeued.ring);
40
spa_ringbuffer_init(&p->queued.ring);
41
-
42
- filter->ports[direction][i] = p;
43
+ p->id = pw_map_insert_new(&filter->ports[direction], p);
44
spa_list_append(&filter->port_list, &p->link);
45
46
return p;
47
48
49
static inline struct port *get_port(struct filter *filter, enum spa_direction direction, uint32_t port_id)
50
{
51
- if ((direction != SPA_DIRECTION_INPUT && direction != SPA_DIRECTION_OUTPUT) ||
52
- port_id >= MAX_PORTS)
53
+ if ((direction != SPA_DIRECTION_INPUT && direction != SPA_DIRECTION_OUTPUT))
54
return NULL;
55
- return filter->ports[direction][port_id];
56
+ return pw_map_lookup(&filter->ports[direction], port_id);
57
}
58
59
static inline int push_queue(struct port *port, struct queue *queue, struct buffer *buffer)
60
61
62
spa_list_init(&impl->param_list);
63
spa_list_init(&impl->port_list);
64
+ pw_map_init(&impl->ports[SPA_DIRECTION_INPUT], 32, 32);
65
+ pw_map_init(&impl->ports[SPA_DIRECTION_OUTPUT], 32, 32);
66
67
spa_hook_list_init(&this->listener_list);
68
spa_list_init(&this->controls);
69
70
spa_hook_list_clean(&impl->hooks);
71
spa_hook_list_clean(&filter->listener_list);
72
73
+ pw_map_clear(&impl->ports[SPA_DIRECTION_INPUT]);
74
+ pw_map_clear(&impl->ports[SPA_DIRECTION_OUTPUT]);
75
+
76
free(filter->name);
77
78
if (impl->data.context)
79
80
SPA_NODE_CHANGE_MASK_PARAMS;
81
82
impl->info = SPA_NODE_INFO_INIT();
83
- impl->info.max_input_ports = MAX_PORTS;
84
- impl->info.max_output_ports = MAX_PORTS;
85
+ impl->info.max_input_ports = UINT32_MAX;
86
+ impl->info.max_output_ports = UINT32_MAX;
87
impl->info.flags = impl->process_rt ? SPA_NODE_FLAG_RT : 0;
88
impl->info.props = &filter->properties->dict;
89
impl->params[IDX_Props] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_WRITE);
90
91
spa_node_emit_port_info(&impl->hooks, port->direction, port->id, NULL);
92
93
spa_list_remove(&port->link);
94
- impl->ports[port->direction][port->id] = NULL;
95
+ pw_map_remove(&impl->ports[port->direction], port->id);
96
97
clear_buffers(port);
98
clear_params(impl, port, SPA_ID_INVALID);
99
pipewire-0.3.45.tar.gz/src/pipewire/map.h -> pipewire-0.3.47.tar.gz/src/pipewire/map.h
Changed
10
1
2
*/
3
static inline void pw_map_init(struct pw_map *map, size_t size, size_t extend)
4
{
5
- pw_array_init(&map->items, extend);
6
+ pw_array_init(&map->items, extend * sizeof(union pw_map_item));
7
pw_array_ensure_size(&map->items, size * sizeof(union pw_map_item));
8
map->free_list = SPA_ID_INVALID;
9
}
10
pipewire-0.3.45.tar.gz/src/pipewire/proxy.c -> pipewire-0.3.47.tar.gz/src/pipewire/proxy.c
Changed
34
1
2
pw_proxy_emit_destroy(proxy);
3
}
4
5
- spa_hook_list_clean(&proxy->listener_list);
6
- spa_hook_list_clean(&proxy->object_listener_list);
7
-
8
pw_proxy_unref(proxy);
9
}
10
11
12
pw_log_debug("%p: free %u", proxy, proxy->id);
13
/** client must explicitly destroy all proxies */
14
assert(proxy->destroyed);
15
+
16
+#if DEBUG_LISTENERS
17
+ {
18
+ struct spa_hook *h;
19
+ spa_list_for_each(h, &proxy->object_listener_list.list, link) {
20
+ pw_log_warn("%p: proxy %u: leaked object listener %p",
21
+ proxy, proxy->id, h);
22
+ break;
23
+ }
24
+ spa_list_for_each(h, &proxy->listener_list.list, link) {
25
+ pw_log_warn("%p: proxy %u: leaked listener %p",
26
+ proxy, proxy->id, h);
27
+ break;
28
+ }
29
+ }
30
+#endif
31
free(proxy);
32
}
33
34
pipewire-0.3.45.tar.gz/src/pipewire/stream.c -> pipewire-0.3.47.tar.gz/src/pipewire/stream.c
Changed
9
1
2
#define MAX_BUFFERS 64
3
4
#define MASK_BUFFERS (MAX_BUFFERS-1)
5
-#define MAX_PORTS 1
6
7
static bool mlock_warned = false;
8
9
pipewire-0.3.45.tar.gz/src/pipewire/utils.c -> pipewire-0.3.47.tar.gz/src/pipewire/utils.c
Changed
10
1
2
#include <fcntl.h>
3
#include <unistd.h>
4
#include <errno.h>
5
-#if HAVE_SYS_RANDOM_H
6
+#ifdef HAVE_SYS_RANDOM_H
7
#include <sys/random.h>
8
#endif
9
#include <string.h>
10
pipewire-0.3.45.tar.gz/src/tools/meson.build -> pipewire-0.3.47.tar.gz/src/tools/meson.build
Changed
10
1
2
endif
3
4
build_pw_cat = false
5
-if not get_option('pw-cat').disabled() and sndfile_dep.found()
6
+if get_option('pw-cat').allowed() and sndfile_dep.found()
7
build_pw_cat = true
8
9
pwcat_sources = [
10
pipewire-0.3.45.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.47.tar.gz/src/tools/pw-cat.c
Changed
53
1
2
struct data *data = userdata;
3
4
if (data->verbose)
5
- fprintf(stdout, "remote %"PRIu32" is named \"%s\"\n",
6
+ printf("remote %"PRIu32" is named \"%s\"\n",
7
info->id, info->name);
8
}
9
10
11
id, type, name, media_class, desc ? : "", prio);
12
13
spa_dict_for_each(item, props) {
14
- fprintf(stdout, "\t\t%s = \"%s\"\n", item->key, item->value);
15
+ printf("\t\t%s = \"%s\"\n", item->key, item->value);
16
}
17
}
18
19
20
return EXIT_SUCCESS;
21
22
case OPT_VERSION:
23
- fprintf(stdout, "%s\n"
24
+ printf("%s\n"
25
"Compiled with libpipewire %s\n"
26
"Linked with libpipewire %s\n",
27
prog,
28
29
}
30
31
error_connect_fail:
32
- if (data.stream)
33
+ if (data.stream) {
34
+ spa_hook_remove(&data.stream_listener);
35
pw_stream_destroy(data.stream);
36
+ }
37
error_no_stream:
38
- if (data.metadata)
39
+ if (data.metadata) {
40
+ spa_hook_remove(&data.metadata_listener);
41
pw_proxy_destroy((struct pw_proxy*)data.metadata);
42
- if (data.registry)
43
+ }
44
+ if (data.registry) {
45
+ spa_hook_remove(&data.registry_listener);
46
pw_proxy_destroy((struct pw_proxy*)data.registry);
47
+ }
48
error_no_registry:
49
+ spa_hook_remove(&data.core_listener);
50
pw_core_disconnect(data.core);
51
error_ctx_connect_failed:
52
pw_context_destroy(data.context);
53
pipewire-0.3.45.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.47.tar.gz/src/tools/pw-cli.c
Changed
947
1
2
#define FNM_EXTMATCH 0
3
#endif
4
5
-#define spa_debug(...) fprintf(stdout,__VA_ARGS__);fputc('\n', stdout)
6
+#define spa_debug(fmt,...) printf(fmt, ## __VA_ARGS__)
7
8
#include <spa/utils/result.h>
9
#include <spa/utils/string.h>
10
11
const struct spa_dict_item *item;
12
13
if (header)
14
- fprintf(stdout, "%c\tproperties:\n", mark);
15
+ printf("%c\tproperties:\n", mark);
16
if (props == NULL || props->n_items == 0) {
17
if (header)
18
- fprintf(stdout, "\t\tnone\n");
19
+ printf("\t\tnone\n");
20
return;
21
}
22
23
spa_dict_for_each(item, props) {
24
- fprintf(stdout, "%c\t\t%s = \"%s\"\n", mark, item->key, item->value);
25
+ printf("%c\t\t%s = \"%s\"\n", mark, item->key, item->value);
26
}
27
}
28
29
30
uint32_t i;
31
32
if (header)
33
- fprintf(stdout, "%c\tparams: (%u)\n", mark, n_params);
34
+ printf("%c\tparams: (%u)\n", mark, n_params);
35
if (params == NULL || n_params == 0) {
36
if (header)
37
- fprintf(stdout, "\t\tnone\n");
38
+ printf("\t\tnone\n");
39
return;
40
}
41
for (i = 0; i < n_params; i++) {
42
const struct spa_type_info *type_info = spa_type_param;
43
44
- fprintf(stdout, "%c\t %d (%s) %c%c\n",
45
+ printf("%c\t %d (%s) %c%c\n",
46
params[i].user > 0 ? mark : ' ', params[i].id,
47
spa_debug_type_find_name(type_info, params[i].id),
48
params[i].flags & SPA_PARAM_INFO_READ ? 'r' : '-',
49
50
{
51
size_t i;
52
53
- fprintf(stdout, "Available commands:\n");
54
+ printf("Available commands:\n");
55
for (i = 0; i < SPA_N_ELEMENTS(command_list); i++) {
56
- fprintf(stdout, "\t%-20.20s\t%s\n", command_list[i].name, command_list[i].description);
57
+ printf("\t%-20.20s\t%s\n", command_list[i].name, command_list[i].description);
58
}
59
return true;
60
}
61
62
}
63
64
id = pw_map_insert_new(&data->vars, module);
65
- fprintf(stdout, "%d = @module:%d\n", id, pw_global_get_id(pw_impl_module_get_global(module)));
66
+ printf("%d = @module:%d\n", id, pw_global_get_id(pw_impl_module_get_global(module)));
67
68
return true;
69
}
70
71
free(rd->name);
72
rd->name = info->name ? strdup(info->name) : NULL;
73
if (rd->data->interactive)
74
- fprintf(stdout, "remote %d is named '%s'\n", rd->id, rd->name);
75
+ printf("remote %d is named '%s'\n", rd->id, rd->name);
76
}
77
78
static void set_prompt(struct remote_data *rd)
79
80
if (filter && !global_matches(global, filter))
81
return 0;
82
83
- fprintf(stdout, "\tid %d, type %s/%d\n", global->id,
84
+ printf("\tid %d, type %s/%d\n", global->id,
85
global->type, global->version);
86
if (global->properties)
87
print_properties(&global->properties->dict, ' ', false);
88
89
global->properties = props ? pw_properties_new_dict(props) : NULL;
90
91
if (rd->data->monitoring) {
92
- fprintf(stdout, "remote %d added global: ", rd->id);
93
+ printf("remote %d added global: ", rd->id);
94
print_global(global, NULL);
95
}
96
97
98
ret = bind_global(rd, global, &error);
99
if (!ret) {
100
if (rd->data->interactive)
101
- fprintf(stdout, "Error: \"%s\"\n", error);
102
+ fprintf(stderr, "Error: \"%s\"\n", error);
103
free(error);
104
}
105
}
106
107
108
global = pw_map_lookup(&rd->globals, id);
109
if (global == NULL) {
110
- fprintf(stdout, "remote %d removed unknown global %d\n", rd->id, id);
111
+ fprintf(stderr, "remote %d removed unknown global %d\n", rd->id, id);
112
return;
113
}
114
115
if (rd->data->monitoring) {
116
- fprintf(stdout, "remote %d removed global: ", rd->id);
117
+ printf("remote %d removed global: ", rd->id);
118
print_global(global, NULL);
119
}
120
121
122
spa_list_append(&data->remotes, &rd->link);
123
124
if (rd->data->interactive)
125
- fprintf(stdout, "%d = @remote:%p\n", rd->id, rd->core);
126
+ printf("%d = @remote:%p\n", rd->id, rd->core);
127
128
data->current = rd;
129
130
131
struct remote_data *rd;
132
133
spa_list_for_each(rd, &data->remotes, link)
134
- fprintf(stdout, "\t%d = @remote:%p '%s'\n", rd->id, rd->core, rd->name);
135
+ printf("\t%d = @remote:%p '%s'\n", rd->id, rd->core, rd->name);
136
137
return true;
138
}
139
140
if (global == NULL)
141
return;
142
143
- fprintf(stdout, "\tid: %d\n", global->id);
144
- fprintf(stdout, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
145
+ printf("\tid: %d\n", global->id);
146
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
147
PW_PERMISSION_ARGS(global->permissions));
148
- fprintf(stdout, "\ttype: %s/%d\n", global->type, global->version);
149
+ printf("\ttype: %s/%d\n", global->type, global->version);
150
}
151
152
static void info_core(struct proxy_data *pd)
153
154
struct pw_core_info *info = pd->info;
155
156
info_global(pd);
157
- fprintf(stdout, "\tcookie: %u\n", info->cookie);
158
- fprintf(stdout, "\tuser-name: \"%s\"\n", info->user_name);
159
- fprintf(stdout, "\thost-name: \"%s\"\n", info->host_name);
160
- fprintf(stdout, "\tversion: \"%s\"\n", info->version);
161
- fprintf(stdout, "\tname: \"%s\"\n", info->name);
162
+ printf("\tcookie: %u\n", info->cookie);
163
+ printf("\tuser-name: \"%s\"\n", info->user_name);
164
+ printf("\thost-name: \"%s\"\n", info->host_name);
165
+ printf("\tversion: \"%s\"\n", info->version);
166
+ printf("\tname: \"%s\"\n", info->name);
167
print_properties(info->props, MARK_CHANGE(PW_CORE_CHANGE_MASK_PROPS), true);
168
info->change_mask = 0;
169
}
170
171
struct pw_module_info *info = pd->info;
172
173
info_global(pd);
174
- fprintf(stdout, "\tname: \"%s\"\n", info->name);
175
- fprintf(stdout, "\tfilename: \"%s\"\n", info->filename);
176
- fprintf(stdout, "\targs: \"%s\"\n", info->args);
177
+ printf("\tname: \"%s\"\n", info->name);
178
+ printf("\tfilename: \"%s\"\n", info->filename);
179
+ printf("\targs: \"%s\"\n", info->args);
180
print_properties(info->props, MARK_CHANGE(PW_MODULE_CHANGE_MASK_PROPS), true);
181
info->change_mask = 0;
182
}
183
184
struct pw_node_info *info = pd->info;
185
186
info_global(pd);
187
- fprintf(stdout, "%c\tinput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_INPUT_PORTS),
188
+ printf("%c\tinput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_INPUT_PORTS),
189
info->n_input_ports, info->max_input_ports);
190
- fprintf(stdout, "%c\toutput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_OUTPUT_PORTS),
191
+ printf("%c\toutput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_OUTPUT_PORTS),
192
info->n_output_ports, info->max_output_ports);
193
- fprintf(stdout, "%c\tstate: \"%s\"", MARK_CHANGE(PW_NODE_CHANGE_MASK_STATE),
194
+ printf("%c\tstate: \"%s\"", MARK_CHANGE(PW_NODE_CHANGE_MASK_STATE),
195
pw_node_state_as_string(info->state));
196
if (info->state == PW_NODE_STATE_ERROR && info->error)
197
- fprintf(stdout, " \"%s\"\n", info->error);
198
+ printf(" \"%s\"\n", info->error);
199
else
200
- fprintf(stdout, "\n");
201
+ printf("\n");
202
print_properties(info->props, MARK_CHANGE(PW_NODE_CHANGE_MASK_PROPS), true);
203
print_params(info->params, info->n_params, MARK_CHANGE(PW_NODE_CHANGE_MASK_PARAMS), true);
204
info->change_mask = 0;
205
206
struct pw_port_info *info = pd->info;
207
208
info_global(pd);
209
- fprintf(stdout, "\tdirection: \"%s\"\n", pw_direction_as_string(info->direction));
210
+ printf("\tdirection: \"%s\"\n", pw_direction_as_string(info->direction));
211
print_properties(info->props, MARK_CHANGE(PW_PORT_CHANGE_MASK_PROPS), true);
212
print_params(info->params, info->n_params, MARK_CHANGE(PW_PORT_CHANGE_MASK_PARAMS), true);
213
info->change_mask = 0;
214
215
struct pw_factory_info *info = pd->info;
216
217
info_global(pd);
218
- fprintf(stdout, "\tname: \"%s\"\n", info->name);
219
- fprintf(stdout, "\tobject-type: %s/%d\n", info->type, info->version);
220
+ printf("\tname: \"%s\"\n", info->name);
221
+ printf("\tobject-type: %s/%d\n", info->type, info->version);
222
print_properties(info->props, MARK_CHANGE(PW_FACTORY_CHANGE_MASK_PROPS), true);
223
info->change_mask = 0;
224
}
225
226
struct pw_link_info *info = pd->info;
227
228
info_global(pd);
229
- fprintf(stdout, "\toutput-node-id: %u\n", info->output_node_id);
230
- fprintf(stdout, "\toutput-port-id: %u\n", info->output_port_id);
231
- fprintf(stdout, "\tinput-node-id: %u\n", info->input_node_id);
232
- fprintf(stdout, "\tinput-port-id: %u\n", info->input_port_id);
233
+ printf("\toutput-node-id: %u\n", info->output_node_id);
234
+ printf("\toutput-port-id: %u\n", info->output_port_id);
235
+ printf("\tinput-node-id: %u\n", info->input_node_id);
236
+ printf("\tinput-port-id: %u\n", info->input_port_id);
237
238
- fprintf(stdout, "%c\tstate: \"%s\"", MARK_CHANGE(PW_LINK_CHANGE_MASK_STATE),
239
+ printf("%c\tstate: \"%s\"", MARK_CHANGE(PW_LINK_CHANGE_MASK_STATE),
240
pw_link_state_as_string(info->state));
241
if (info->state == PW_LINK_STATE_ERROR && info->error)
242
printf(" \"%s\"\n", info->error);
243
else
244
printf("\n");
245
- fprintf(stdout, "%c\tformat:\n", MARK_CHANGE(PW_LINK_CHANGE_MASK_FORMAT));
246
+ printf("%c\tformat:\n", MARK_CHANGE(PW_LINK_CHANGE_MASK_FORMAT));
247
if (info->format)
248
spa_debug_pod(2, NULL, info->format);
249
else
250
- fprintf(stdout, "\t\tnone\n");
251
+ printf("\t\tnone\n");
252
print_properties(info->props, MARK_CHANGE(PW_LINK_CHANGE_MASK_PROPS), true);
253
info->change_mask = 0;
254
}
255
256
const char *direction;
257
258
info_global(pd);
259
- fprintf(stdout, "\tname: %s\n", info->name);
260
- fprintf(stdout, "\tmedia-class: %s\n", info->media_class);
261
+ printf("\tname: %s\n", info->name);
262
+ printf("\tmedia-class: %s\n", info->media_class);
263
switch(info->direction) {
264
case PW_DIRECTION_OUTPUT:
265
direction = "source";
266
267
direction = "invalid";
268
break;
269
}
270
- fprintf(stdout, "\tdirection: %s\n", direction);
271
- fprintf(stdout, "\tflags: 0x%x\n", info->flags);
272
- fprintf(stdout, "%c\tstreams: %u\n", MARK_CHANGE(0), info->n_streams);
273
- fprintf(stdout, "%c\tsession: %u\n", MARK_CHANGE(1), info->session_id);
274
+ printf("\tdirection: %s\n", direction);
275
+ printf("\tflags: 0x%x\n", info->flags);
276
+ printf("%c\tstreams: %u\n", MARK_CHANGE(0), info->n_streams);
277
+ printf("%c\tsession: %u\n", MARK_CHANGE(1), info->session_id);
278
print_properties(info->props, MARK_CHANGE(2), true);
279
print_params(info->params, info->n_params, MARK_CHANGE(3), true);
280
info->change_mask = 0;
281
282
struct pw_endpoint_stream_info *info = pd->info;
283
284
info_global(pd);
285
- fprintf(stdout, "\tid: %u\n", info->id);
286
- fprintf(stdout, "\tendpoint-id: %u\n", info->endpoint_id);
287
- fprintf(stdout, "\tname: %s\n", info->name);
288
+ printf("\tid: %u\n", info->id);
289
+ printf("\tendpoint-id: %u\n", info->endpoint_id);
290
+ printf("\tname: %s\n", info->name);
291
print_properties(info->props, MARK_CHANGE(1), true);
292
print_params(info->params, info->n_params, MARK_CHANGE(2), true);
293
info->change_mask = 0;
294
295
struct proxy_data *pd = object;
296
struct remote_data *rd = pd->rd;
297
if (pd->info)
298
- fprintf(stdout, "remote %d core %d changed\n", rd->id, info->id);
299
+ printf("remote %d core %d changed\n", rd->id, info->id);
300
pd->info = pw_core_info_update(pd->info, info);
301
if (pd->global == NULL)
302
pd->global = pw_map_lookup(&rd->globals, info->id);
303
304
struct proxy_data *pd = object;
305
struct remote_data *rd = pd->rd;
306
if (pd->info)
307
- fprintf(stdout, "remote %d module %d changed\n", rd->id, info->id);
308
+ printf("remote %d module %d changed\n", rd->id, info->id);
309
pd->info = pw_module_info_update(pd->info, info);
310
if (pd->global == NULL)
311
pd->global = pw_map_lookup(&rd->globals, info->id);
312
313
struct proxy_data *pd = object;
314
struct remote_data *rd = pd->rd;
315
if (pd->info)
316
- fprintf(stdout, "remote %d node %d changed\n", rd->id, info->id);
317
+ printf("remote %d node %d changed\n", rd->id, info->id);
318
pd->info = pw_node_info_update(pd->info, info);
319
if (pd->global == NULL)
320
pd->global = pw_map_lookup(&rd->globals, info->id);
321
322
struct remote_data *rd = data->rd;
323
324
if (rd->data->interactive)
325
- fprintf(stdout, "remote %d object %d param %d index %d\n",
326
+ printf("remote %d object %d param %d index %d\n",
327
rd->id, data->global->id, id, index);
328
329
spa_debug_pod(2, NULL, param);
330
331
struct proxy_data *pd = object;
332
struct remote_data *rd = pd->rd;
333
if (pd->info)
334
- fprintf(stdout, "remote %d port %d changed\n", rd->id, info->id);
335
+ printf("remote %d port %d changed\n", rd->id, info->id);
336
pd->info = pw_port_info_update(pd->info, info);
337
if (pd->global == NULL)
338
pd->global = pw_map_lookup(&rd->globals, info->id);
339
340
struct proxy_data *pd = object;
341
struct remote_data *rd = pd->rd;
342
if (pd->info)
343
- fprintf(stdout, "remote %d factory %d changed\n", rd->id, info->id);
344
+ printf("remote %d factory %d changed\n", rd->id, info->id);
345
pd->info = pw_factory_info_update(pd->info, info);
346
if (pd->global == NULL)
347
pd->global = pw_map_lookup(&rd->globals, info->id);
348
349
struct proxy_data *pd = object;
350
struct remote_data *rd = pd->rd;
351
if (pd->info)
352
- fprintf(stdout, "remote %d client %d changed\n", rd->id, info->id);
353
+ printf("remote %d client %d changed\n", rd->id, info->id);
354
pd->info = pw_client_info_update(pd->info, info);
355
if (pd->global == NULL)
356
pd->global = pw_map_lookup(&rd->globals, info->id);
357
358
struct remote_data *rd = data->rd;
359
uint32_t i;
360
361
- fprintf(stdout, "remote %d node %d index %d\n",
362
+ printf("remote %d node %d index %d\n",
363
rd->id, data->global->id, index);
364
365
for (i = 0; i < n_permissions; i++) {
366
if (permissions[i].id == PW_ID_ANY)
367
- fprintf(stdout, " default:");
368
+ printf(" default:");
369
else
370
- fprintf(stdout, " %u:", permissions[i].id);
371
- fprintf(stdout, " "PW_PERMISSION_FORMAT"\n",
372
+ printf(" %u:", permissions[i].id);
373
+ printf(" "PW_PERMISSION_FORMAT"\n",
374
PW_PERMISSION_ARGS(permissions[i].permissions));
375
}
376
}
377
378
struct proxy_data *pd = object;
379
struct remote_data *rd = pd->rd;
380
if (pd->info)
381
- fprintf(stdout, "remote %d link %d changed\n", rd->id, info->id);
382
+ printf("remote %d link %d changed\n", rd->id, info->id);
383
pd->info = pw_link_info_update(pd->info, info);
384
if (pd->global == NULL)
385
pd->global = pw_map_lookup(&rd->globals, info->id);
386
387
struct proxy_data *pd = object;
388
struct remote_data *rd = pd->rd;
389
if (pd->info)
390
- fprintf(stdout, "remote %d device %d changed\n", rd->id, info->id);
391
+ printf("remote %d device %d changed\n", rd->id, info->id);
392
pd->info = pw_device_info_update(pd->info, info);
393
if (pd->global == NULL)
394
pd->global = pw_map_lookup(&rd->globals, info->id);
395
396
pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd);
397
398
id = pw_map_insert_new(&data->vars, proxy);
399
- fprintf(stdout, "%d = @proxy:%d\n", id, pw_proxy_get_id(proxy));
400
+ printf("%d = @proxy:%d\n", id, pw_proxy_get_id(proxy));
401
402
return true;
403
}
404
405
pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd);
406
407
id = pw_map_insert_new(&data->vars, proxy);
408
- fprintf(stdout, "%d = @proxy:%d\n", id, pw_proxy_get_id(proxy));
409
+ printf("%d = @proxy:%d\n", id, pw_proxy_get_id(proxy));
410
411
return true;
412
}
413
414
pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd);
415
416
id = pw_map_insert_new(&data->vars, proxy);
417
- fprintf(stdout, "%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy));
418
+ printf("%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy));
419
420
return true;
421
}
422
423
proxy = pw_core_export(rd->core, PW_TYPE_INTERFACE_Node, NULL, node, 0);
424
425
id = pw_map_insert_new(&data->vars, proxy);
426
- fprintf(stdout, "%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy));
427
+ printf("%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy));
428
429
return true;
430
431
432
}
433
434
p = strtol(a[2], NULL, 0);
435
- fprintf(stderr, "setting permissions: "PW_PERMISSION_FORMAT"\n",
436
+ printf("setting permissions: "PW_PERMISSION_FORMAT"\n",
437
PW_PERMISSION_ARGS(p));
438
439
permissions[0] = PW_PERMISSION_INIT(atoi(a[1]), p);
440
441
442
ind = INDENT(level + 2);
443
spa_dict_for_each(item, props) {
444
- fprintf(stdout, "%s%s = \"%s\"",
445
+ printf("%s%s = \"%s\"",
446
ind, item->key, item->value);
447
448
extra = NULL;
449
450
}
451
452
if (extra)
453
- fprintf(stdout, " (\"%s\")", extra);
454
+ printf(" (\"%s\")", extra);
455
456
- fprintf(stdout, "\n");
457
+ printf("\n");
458
}
459
}
460
461
462
for (i = 0; i < n_params; i++) {
463
const struct spa_type_info *type_info = spa_type_param;
464
465
- fprintf(stdout, "%s %d (%s) %c%c\n", ind,
466
+ printf("%s %d (%s) %c%c\n", ind,
467
params[i].id,
468
spa_debug_type_find_name(type_info, params[i].id),
469
params[i].flags & SPA_PARAM_INFO_READ ? 'r' : '-',
470
471
472
if (!(flags & is_short)) {
473
ind = INDENT(level + 1);
474
- fprintf(stdout, "%sid: %"PRIu32"\n", ind, global->id);
475
- fprintf(stdout, "%spermissions: "PW_PERMISSION_FORMAT"\n", ind,
476
+ printf("%sid: %"PRIu32"\n", ind, global->id);
477
+ printf("%spermissions: "PW_PERMISSION_FORMAT"\n", ind,
478
PW_PERMISSION_ARGS(global->permissions));
479
- fprintf(stdout, "%stype: %s/%d\n", ind,
480
+ printf("%stype: %s/%d\n", ind,
481
global->type, global->version);
482
} else {
483
ind = INDENT(level);
484
- fprintf(stdout, "%s%"PRIu32":", ind, global->id);
485
+ printf("%s%"PRIu32":", ind, global->id);
486
if (!(flags & is_notype))
487
- fprintf(stdout, " %s", pw_interface_short(global->type));
488
+ printf(" %s", pw_interface_short(global->type));
489
}
490
}
491
492
493
info = pd->info;
494
if (!(flags & is_short)) {
495
ind = INDENT(level + 1);
496
- fprintf(stdout, "%scookie: %u\n", ind, info->cookie);
497
- fprintf(stdout, "%suser-name: \"%s\"\n", ind, info->user_name);
498
- fprintf(stdout, "%shost-name: \"%s\"\n", ind, info->host_name);
499
- fprintf(stdout, "%sversion: \"%s\"\n", ind, info->version);
500
- fprintf(stdout, "%sname: \"%s\"\n", ind, info->name);
501
- fprintf(stdout, "%sproperties:\n", ind);
502
+ printf("%scookie: %u\n", ind, info->cookie);
503
+ printf("%suser-name: \"%s\"\n", ind, info->user_name);
504
+ printf("%shost-name: \"%s\"\n", ind, info->host_name);
505
+ printf("%sversion: \"%s\"\n", ind, info->version);
506
+ printf("%sname: \"%s\"\n", ind, info->name);
507
+ printf("%sproperties:\n", ind);
508
dump_properties(data, global, flags, level);
509
} else {
510
- fprintf(stdout, " u=\"%s\" h=\"%s\" v=\"%s\" n=\"%s\"",
511
+ printf(" u=\"%s\" h=\"%s\" v=\"%s\" n=\"%s\"",
512
info->user_name, info->host_name, info->version, info->name);
513
- fprintf(stdout, "\n");
514
+ printf("\n");
515
}
516
517
return true;
518
519
520
if (!(flags & is_short)) {
521
ind = INDENT(level + 1);
522
- fprintf(stdout, "%sname: \"%s\"\n", ind, info->name);
523
- fprintf(stdout, "%sfilename: \"%s\"\n", ind, info->filename);
524
- fprintf(stdout, "%sargs: \"%s\"\n", ind, info->args);
525
- fprintf(stdout, "%sproperties:\n", ind);
526
+ printf("%sname: \"%s\"\n", ind, info->name);
527
+ printf("%sfilename: \"%s\"\n", ind, info->filename);
528
+ printf("%sargs: \"%s\"\n", ind, info->args);
529
+ printf("%sproperties:\n", ind);
530
dump_properties(data, global, flags, level);
531
} else {
532
desc = spa_dict_lookup(info->props, PW_KEY_MODULE_DESCRIPTION);
533
args = info->args && strcmp(info->args, "(null)") ? info->args : NULL;
534
- fprintf(stdout, " n=\"%s\" f=\"%s\"" "%s%s%s" "%s%s%s",
535
+ printf(" n=\"%s\" f=\"%s\"" "%s%s%s" "%s%s%s",
536
info->name, info->filename,
537
args ? " a=\"" : "",
538
args ? args : "",
539
540
desc ? " d=\"" : "",
541
desc ? desc : "",
542
desc ? "\"" : "");
543
- fprintf(stdout, "\n");
544
+ printf("\n");
545
}
546
547
if (!(flags & is_deep))
548
549
factory_count = children_of(rd, global->id, PW_TYPE_INTERFACE_Factory, &factories);
550
if (factory_count >= 0) {
551
ind = INDENT(level + 1);
552
- fprintf(stdout, "%sfactories:\n", ind);
553
+ printf("%sfactories:\n", ind);
554
for (i = 0; i < factory_count; i++) {
555
global_factory = obj_global(rd, factories[i]);
556
if (!global_factory)
557
558
559
if (!(flags & is_short)) {
560
ind = INDENT(level + 1);
561
- fprintf(stdout, "%sproperties:\n", ind);
562
+ printf("%sproperties:\n", ind);
563
dump_properties(data, global, flags, level);
564
- fprintf(stdout, "%sparams:\n", ind);
565
+ printf("%sparams:\n", ind);
566
dump_params(data, global, info->params, info->n_params, flags, level);
567
} else {
568
media_class = spa_dict_lookup(info->props, PW_KEY_MEDIA_CLASS);
569
570
desc = spa_dict_lookup(info->props, PW_KEY_DEVICE_DESCRIPTION);
571
api = spa_dict_lookup(info->props, PW_KEY_DEVICE_API);
572
573
- fprintf(stdout, "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s",
574
+ printf("%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s",
575
media_class ? " c=\"" : "",
576
media_class ? media_class : "",
577
media_class ? "\"" : "",
578
579
alsa_path = spa_dict_lookup(info->props, SPA_KEY_API_ALSA_PATH);
580
alsa_card_id = spa_dict_lookup(info->props, SPA_KEY_API_ALSA_CARD_ID);
581
582
- fprintf(stdout, "%s%s%s" "%s%s%s",
583
+ printf("%s%s%s" "%s%s%s",
584
alsa_path ? " p=\"" : "",
585
alsa_path ? alsa_path : "",
586
alsa_path ? "\"" : "",
587
588
alsa_card_id ? "\"" : "");
589
}
590
591
- fprintf(stdout, "\n");
592
+ printf("\n");
593
}
594
595
if (!(flags & is_deep))
596
597
node_count = children_of(rd, global->id, PW_TYPE_INTERFACE_Node, &nodes);
598
if (node_count >= 0) {
599
ind = INDENT(level + 1);
600
- fprintf(stdout, "%snodes:\n", ind);
601
+ printf("%snodes:\n", ind);
602
for (i = 0; i < node_count; i++) {
603
global_node = obj_global(rd, nodes[i]);
604
if (!global_node)
605
606
607
if (!(flags & is_short)) {
608
ind = INDENT(level + 1);
609
- fprintf(stdout, "%sinput ports: %u/%u\n", ind, info->n_input_ports, info->max_input_ports);
610
- fprintf(stdout, "%soutput ports: %u/%u\n", ind, info->n_output_ports, info->max_output_ports);
611
- fprintf(stdout, "%sstate: \"%s\"", ind, pw_node_state_as_string(info->state));
612
+ printf("%sinput ports: %u/%u\n", ind, info->n_input_ports, info->max_input_ports);
613
+ printf("%soutput ports: %u/%u\n", ind, info->n_output_ports, info->max_output_ports);
614
+ printf("%sstate: \"%s\"", ind, pw_node_state_as_string(info->state));
615
if (info->state == PW_NODE_STATE_ERROR && info->error)
616
- fprintf(stdout, " \"%s\"\n", info->error);
617
+ printf(" \"%s\"\n", info->error);
618
else
619
- fprintf(stdout, "\n");
620
- fprintf(stdout, "%sproperties:\n", ind);
621
+ printf("\n");
622
+ printf("%sproperties:\n", ind);
623
dump_properties(data, global, flags, level);
624
- fprintf(stdout, "%sparams:\n", ind);
625
+ printf("%sparams:\n", ind);
626
dump_params(data, global, info->params, info->n_params, flags, level);
627
} else {
628
name = spa_dict_lookup(info->props, PW_KEY_NODE_NAME);
629
path = spa_dict_lookup(info->props, SPA_KEY_OBJECT_PATH);
630
631
- fprintf(stdout, " s=\"%s\"", pw_node_state_as_string(info->state));
632
+ printf(" s=\"%s\"", pw_node_state_as_string(info->state));
633
634
if (info->max_input_ports) {
635
- fprintf(stdout, " i=%u/%u", info->n_input_ports, info->max_input_ports);
636
+ printf(" i=%u/%u", info->n_input_ports, info->max_input_ports);
637
}
638
if (info->max_output_ports) {
639
- fprintf(stdout, " o=%u/%u", info->n_output_ports, info->max_output_ports);
640
+ printf(" o=%u/%u", info->n_output_ports, info->max_output_ports);
641
}
642
643
- fprintf(stdout, "%s%s%s" "%s%s%s",
644
+ printf("%s%s%s" "%s%s%s",
645
name ? " n=\"" : "",
646
name ? name : "",
647
name ? "\"" : "",
648
649
path ? path : "",
650
path ? "\"" : "");
651
652
- fprintf(stdout, "\n");
653
+ printf("\n");
654
}
655
656
if (!(flags & is_deep))
657
658
port_count = children_of(rd, global->id, PW_TYPE_INTERFACE_Port, &ports);
659
if (port_count >= 0) {
660
ind = INDENT(level + 1);
661
- fprintf(stdout, "%sports:\n", ind);
662
+ printf("%sports:\n", ind);
663
for (i = 0; i < port_count; i++) {
664
global_port = obj_global(rd, ports[i]);
665
if (!global_port)
666
667
668
if (!(flags & is_short)) {
669
ind = INDENT(level + 1);
670
- fprintf(stdout, "%sdirection: \"%s\"\n", ind,
671
+ printf("%sdirection: \"%s\"\n", ind,
672
pw_direction_as_string(info->direction));
673
- fprintf(stdout, "%sproperties:\n", ind);
674
+ printf("%sproperties:\n", ind);
675
dump_properties(data, global, flags, level);
676
- fprintf(stdout, "%sparams:\n", ind);
677
+ printf("%sparams:\n", ind);
678
dump_params(data, global, info->params, info->n_params, flags, level);
679
} else {
680
- fprintf(stdout, " d=\"%s\"", pw_direction_as_string(info->direction));
681
+ printf(" d=\"%s\"", pw_direction_as_string(info->direction));
682
683
name = spa_dict_lookup(info->props, PW_KEY_PORT_NAME);
684
format = spa_dict_lookup(info->props, PW_KEY_FORMAT_DSP);
685
686
- fprintf(stdout, "%s%s%s" "%s%s%s",
687
+ printf("%s%s%s" "%s%s%s",
688
name ? " n=\"" : "",
689
name ? name : "",
690
name ? "\"" : "",
691
692
format ? format : "",
693
format ? "\"" : "");
694
695
- fprintf(stdout, "\n");
696
+ printf("\n");
697
}
698
699
(void)rd;
700
701
702
if (!(flags & is_short)) {
703
ind = INDENT(level + 1);
704
- fprintf(stdout, "%sname: \"%s\"\n", ind, info->name);
705
- fprintf(stdout, "%sproperties:\n", ind);
706
+ printf("%sname: \"%s\"\n", ind, info->name);
707
+ printf("%sproperties:\n", ind);
708
dump_properties(data, global, flags, level);
709
} else {
710
- fprintf(stdout, " n=\"%s\"", info->name);
711
+ printf(" n=\"%s\"", info->name);
712
713
module_id = spa_dict_lookup(info->props, PW_KEY_MODULE_ID);
714
module_name = module_id ? obj_lookup(rd, atoi(module_id), PW_KEY_MODULE_NAME) : NULL;
715
716
- fprintf(stdout, "%s%s%s",
717
+ printf("%s%s%s",
718
module_name ? " m=\"" : "",
719
module_name ? module_name : "",
720
module_name ? "\"" : "");
721
722
- fprintf(stdout, "\n");
723
+ printf("\n");
724
}
725
726
return true;
727
728
729
if (!(flags & is_short)) {
730
ind = INDENT(level + 1);
731
- fprintf(stdout, "%sproperties:\n", ind);
732
+ printf("%sproperties:\n", ind);
733
dump_properties(data, global, flags, level);
734
} else {
735
app_name = spa_dict_lookup(info->props, PW_KEY_APP_NAME);
736
app_pid = spa_dict_lookup(info->props, PW_KEY_APP_PROCESS_ID);
737
738
- fprintf(stdout, "%s%s%s" "%s%s%s",
739
+ printf("%s%s%s" "%s%s%s",
740
app_name ? " ap=\"" : "",
741
app_name ? app_name : "",
742
app_name ? "\"" : "",
743
744
app_pid ? app_pid : "",
745
app_pid ? "\"" : "");
746
747
- fprintf(stdout, "\n");
748
+ printf("\n");
749
}
750
751
(void)rd;
752
753
754
if (!(flags & is_short)) {
755
ind = INDENT(level + 1);
756
- fprintf(stdout, "%soutput-node-id: %u\n", ind, info->output_node_id);
757
- fprintf(stdout, "%soutput-port-id: %u\n", ind, info->output_port_id);
758
- fprintf(stdout, "%sinput-node-id: %u\n", ind, info->input_node_id);
759
- fprintf(stdout, "%sinput-port-id: %u\n", ind, info->input_port_id);
760
+ printf("%soutput-node-id: %u\n", ind, info->output_node_id);
761
+ printf("%soutput-port-id: %u\n", ind, info->output_port_id);
762
+ printf("%sinput-node-id: %u\n", ind, info->input_node_id);
763
+ printf("%sinput-port-id: %u\n", ind, info->input_port_id);
764
765
- fprintf(stdout, "%sstate: \"%s\"", ind,
766
+ printf("%sstate: \"%s\"", ind,
767
pw_link_state_as_string(info->state));
768
if (info->state == PW_LINK_STATE_ERROR && info->error)
769
printf(" \"%s\"\n", info->error);
770
else
771
printf("\n");
772
- fprintf(stdout, "%sformat:\n", ind);
773
+ printf("%sformat:\n", ind);
774
if (info->format)
775
spa_debug_pod(8 * (level + 1) + 2, NULL, info->format);
776
else
777
- fprintf(stdout, "%s\tnone\n", ind);
778
+ printf("%s\tnone\n", ind);
779
780
- fprintf(stdout, "%sproperties:\n", ind);
781
+ printf("%sproperties:\n", ind);
782
dump_properties(data, global, flags, level);
783
} else {
784
out_node_name = obj_lookup(rd, info->output_node_id, PW_KEY_NODE_NAME);
785
786
out_port_name = obj_lookup(rd, info->output_port_id, PW_KEY_PORT_NAME);
787
in_port_name = obj_lookup(rd, info->input_port_id, PW_KEY_PORT_NAME);
788
789
- fprintf(stdout, " s=\"%s\"", pw_link_state_as_string(info->state));
790
+ printf(" s=\"%s\"", pw_link_state_as_string(info->state));
791
792
if (out_node_name && out_port_name)
793
- fprintf(stdout, " on=\"%s\"" " op=\"%s\"",
794
+ printf(" on=\"%s\"" " op=\"%s\"",
795
out_node_name, out_port_name);
796
if (in_node_name && in_port_name)
797
- fprintf(stdout, " in=\"%s\"" " ip=\"%s\"",
798
+ printf(" in=\"%s\"" " ip=\"%s\"",
799
in_node_name, in_port_name);
800
801
- fprintf(stdout, "\n");
802
+ printf("\n");
803
}
804
805
(void)rd;
806
807
808
if (!(flags & is_short)) {
809
ind = INDENT(level + 1);
810
- fprintf(stdout, "%sproperties:\n", ind);
811
+ printf("%sproperties:\n", ind);
812
dump_properties(data, global, flags, level);
813
- fprintf(stdout, "%sparams:\n", ind);
814
+ printf("%sparams:\n", ind);
815
dump_params(data, global, info->params, info->n_params, flags, level);
816
} else {
817
- fprintf(stdout, "\n");
818
+ printf("\n");
819
}
820
821
(void)rd;
822
823
824
if (!(flags & is_short)) {
825
ind = INDENT(level + 1);
826
- fprintf(stdout, "%sname: %s\n", ind, info->name);
827
- fprintf(stdout, "%smedia-class: %s\n", ind, info->media_class);
828
- fprintf(stdout, "%sdirection: %s\n", ind, direction);
829
- fprintf(stdout, "%sflags: 0x%x\n", ind, info->flags);
830
- fprintf(stdout, "%sstreams: %u\n", ind, info->n_streams);
831
- fprintf(stdout, "%ssession: %u\n", ind, info->session_id);
832
- fprintf(stdout, "%sproperties:\n", ind);
833
+ printf("%sname: %s\n", ind, info->name);
834
+ printf("%smedia-class: %s\n", ind, info->media_class);
835
+ printf("%sdirection: %s\n", ind, direction);
836
+ printf("%sflags: 0x%x\n", ind, info->flags);
837
+ printf("%sstreams: %u\n", ind, info->n_streams);
838
+ printf("%ssession: %u\n", ind, info->session_id);
839
+ printf("%sproperties:\n", ind);
840
dump_properties(data, global, flags, level);
841
- fprintf(stdout, "%sparams:\n", ind);
842
+ printf("%sparams:\n", ind);
843
dump_params(data, global, info->params, info->n_params, flags, level);
844
} else {
845
- fprintf(stdout, " n=\"%s\" c=\"%s\" d=\"%s\" s=%u si=%"PRIu32"",
846
+ printf(" n=\"%s\" c=\"%s\" d=\"%s\" s=%u si=%"PRIu32"",
847
info->name, info->media_class, direction,
848
info->n_streams, info->session_id);
849
- fprintf(stdout, "\n");
850
+ printf("\n");
851
}
852
853
(void)rd;
854
855
856
if (!(flags & is_short)) {
857
ind = INDENT(level + 1);
858
- fprintf(stdout, "%sid: %u\n", ind, info->id);
859
- fprintf(stdout, "%sendpoint-id: %u\n", ind, info->endpoint_id);
860
- fprintf(stdout, "%sname: %s\n", ind, info->name);
861
- fprintf(stdout, "%sproperties:\n", ind);
862
+ printf("%sid: %u\n", ind, info->id);
863
+ printf("%sendpoint-id: %u\n", ind, info->endpoint_id);
864
+ printf("%sname: %s\n", ind, info->name);
865
+ printf("%sproperties:\n", ind);
866
dump_properties(data, global, flags, level);
867
- fprintf(stdout, "%sparams:\n", ind);
868
+ printf("%sparams:\n", ind);
869
dump_params(data, global, info->params, info->n_params, flags, level);
870
} else {
871
- fprintf(stdout, " n=\"%s\" i=%"PRIu32" ei=%"PRIu32"",
872
+ printf(" n=\"%s\" i=%"PRIu32" ei=%"PRIu32"",
873
info->name, info->id, info->endpoint_id);
874
- fprintf(stdout, "\n");
875
+ printf("\n");
876
}
877
878
(void)rd;
879
880
if (line[0] != '\0') {
881
add_history(line);
882
if (!parse(d, line, &error)) {
883
- fprintf(stdout, "Error: \"%s\"\n", error);
884
+ fprintf(stderr, "Error: \"%s\"\n", error);
885
free(error);
886
}
887
}
888
889
pw_main_loop_quit(d->loop);
890
}
891
892
-static void show_help(struct data *data, const char *name)
893
+static void show_help(struct data *data, const char *name, bool error)
894
{
895
- fprintf(stdout, _("%s [options] [command]\n"
896
+ fprintf(error ? stderr : stdout, _("%s [options] [command]\n"
897
" -h, --help Show this help\n"
898
" --version Show version\n"
899
" -d, --daemon Start as daemon (Default false)\n"
900
901
};
902
int c, i;
903
904
+ setlinebuf(stdout);
905
+
906
pw_init(&argc, &argv);
907
908
while ((c = getopt_long(argc, argv, "hVdr:", long_options, NULL)) != -1) {
909
switch (c) {
910
case 'h':
911
- show_help(&data, argv[0]);
912
+ show_help(&data, argv[0], false);
913
return 0;
914
case 'V':
915
- fprintf(stdout, "%s\n"
916
+ printf("%s\n"
917
"Compiled with libpipewire %s\n"
918
"Linked with libpipewire %s\n",
919
argv[0],
920
921
opt_remote = optarg;
922
break;
923
default:
924
- show_help(&data, argv[0]);
925
+ show_help(&data, argv[0], true);
926
return -1;
927
}
928
}
929
930
if (optind == argc) {
931
data.interactive = true;
932
933
- fprintf(stdout, "Welcome to PipeWire version %s. Type 'help' for usage.\n",
934
+ printf("Welcome to PipeWire version %s. Type 'help' for usage.\n",
935
pw_get_library_version());
936
937
readline_init();
938
939
pw_main_loop_run(data.loop);
940
941
if (!parse(&data, buf, &error)) {
942
- fprintf(stdout, "Error: \"%s\"\n", error);
943
+ fprintf(stderr, "Error: \"%s\"\n", error);
944
free(error);
945
}
946
if (!data.quit && data.current) {
947
pipewire-0.3.45.tar.gz/src/tools/pw-dot.c -> pipewire-0.3.47.tar.gz/src/tools/pw-dot.c
Changed
54
1
2
static void destroy_proxy(void *user_data)
3
{
4
struct global *g = user_data;
5
+ spa_hook_remove(&g->object_listener);
6
+ spa_hook_remove(&g->proxy_listener);
7
pw_properties_free(g->props);
8
if (g->info)
9
g->info_destroy(g->info);
10
11
pw_main_loop_quit(d->loop);
12
}
13
14
-static void show_help(const char *name)
15
+static void show_help(const char *name, bool error)
16
{
17
- fprintf(stdout, "%s [options]\n"
18
+ fprintf(error ? stderr : stdout, "%s [options]\n"
19
" -h, --help Show this help\n"
20
" --version Show version\n"
21
" -a, --all Show all object types\n"
22
23
while ((c = getopt_long(argc, argv, "hVasdr:o:L9", long_options, NULL)) != -1) {
24
switch (c) {
25
case 'h' :
26
- show_help(argv[0]);
27
+ show_help(argv[0], false);
28
return 0;
29
case 'V' :
30
- fprintf(stdout, "%s\n"
31
+ printf("%s\n"
32
"Compiled with libpipewire %s\n"
33
"Linked with libpipewire %s\n",
34
argv[0],
35
36
fprintf(stderr, "orthogonal edges enabled\n");
37
break;
38
default:
39
- show_help(argv[0]);
40
+ show_help(argv[0], true);
41
return -1;
42
}
43
}
44
45
draw_graph(&data, dot_path);
46
47
dot_str_clear(&data.dot_str);
48
+ spa_hook_remove(&data.registry_listener);
49
pw_proxy_destroy((struct pw_proxy*)data.registry);
50
+ spa_hook_remove(&data.core_listener);
51
pw_context_destroy(data.context);
52
pw_main_loop_destroy(data.loop);
53
pw_deinit();
54
pipewire-0.3.45.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.47.tar.gz/src/tools/pw-dump.c
Changed
57
1
2
pw_main_loop_quit(d->loop);
3
}
4
5
-static void show_help(struct data *data, const char *name)
6
+static void show_help(struct data *data, const char *name, bool error)
7
{
8
- fprintf(stdout, "%s [options] [<id>]\n"
9
+ fprintf(error ? stderr : stdout, "%s [options] [<id>]\n"
10
" -h, --help Show this help\n"
11
" --version Show version\n"
12
" -r, --remote Remote daemon name\n"
13
14
data.out = stdout;
15
if (isatty(fileno(data.out)) && getenv("NO_COLOR") == NULL)
16
colors = true;
17
+ setlinebuf(data.out);
18
19
while ((c = getopt_long(argc, argv, "hVr:mNC", long_options, NULL)) != -1) {
20
switch (c) {
21
case 'h' :
22
- show_help(&data, argv[0]);
23
+ show_help(&data, argv[0], false);
24
return 0;
25
case 'V' :
26
- fprintf(stdout, "%s\n"
27
+ printf("%s\n"
28
"Compiled with libpipewire %s\n"
29
"Linked with libpipewire %s\n",
30
argv[0],
31
32
else if (!strcmp(optarg, "always"))
33
colors = true;
34
else {
35
- show_help(&data, argv[0]);
36
+ fprintf(stderr, "Unknown color: %s\n", optarg);
37
+ show_help(&data, argv[0], true);
38
return -1;
39
}
40
break;
41
default:
42
- show_help(&data, argv[0]);
43
+ show_help(&data, argv[0], true);
44
return -1;
45
}
46
}
47
48
if (data.info)
49
pw_core_info_free(data.info);
50
51
+ spa_hook_remove(&data.registry_listener);
52
pw_proxy_destroy((struct pw_proxy*)data.registry);
53
+ spa_hook_remove(&data.core_listener);
54
pw_context_destroy(data.context);
55
pw_main_loop_destroy(data.loop);
56
pw_deinit();
57
pipewire-0.3.45.tar.gz/src/tools/pw-link.c -> pipewire-0.3.47.tar.gz/src/tools/pw-link.c
Changed
125
1
2
prefix2 = " ";
3
}
4
5
- fprintf(stdout, "%s%s%s%s\n", data->prefix, prefix,
6
+ printf("%s%s%s%s\n", data->prefix, prefix,
7
id, port_name(buffer, sizeof(buffer), n, p));
8
if (verbose) {
9
port_path(buffer, sizeof(buffer), n, p);
10
if (buffer[0] != '\0')
11
- fprintf(stdout, "%s %s%s%s\n", data->prefix, prefix2, prefix, buffer);
12
+ printf("%s %s%s%s\n", data->prefix, prefix2, prefix, buffer);
13
port_alias(buffer, sizeof(buffer), n, p);
14
if (buffer[0] != '\0')
15
- fprintf(stdout, "%s %s%s%s\n", data->prefix, prefix2, prefix, buffer);
16
+ printf("%s %s%s%s\n", data->prefix, prefix2, prefix, buffer);
17
}
18
}
19
20
21
if (data->opt_id)
22
snprintf(id, sizeof(id), "%4d ", link->id);
23
24
- fprintf(stdout, "%s%s%s -> %s\n", data->prefix, id,
25
+ printf("%s%s%s -> %s\n", data->prefix, id,
26
port_name(buffer1, sizeof(buffer1), n1, p1),
27
port_name(buffer2, sizeof(buffer2), n2, p2));
28
return 0;
29
30
pw_main_loop_quit(data->loop);
31
}
32
33
-static void show_help(struct data *data, const char *name)
34
+static void show_help(struct data *data, const char *name, bool error)
35
{
36
- fprintf(stdout, "%1$s : PipeWire port and link manager.\n"
37
+ fprintf(error ? stderr : stdout, "%1$s : PipeWire port and link manager.\n"
38
"Generic: %1$s [options]\n"
39
" -h, --help Show this help\n"
40
" --version Show version\n"
41
42
" -o, --output List output ports\n"
43
" -i, --input List input ports\n"
44
" -l, --links List links\n"
45
- " -m, --monitor Monitor links\n"
46
+ " -m, --monitor Monitor links and ports\n"
47
" -I, --id List IDs\n"
48
" -v, --verbose Verbose port properties\n"
49
"Connect: %1$s [options] output input\n"
50
- " -L, --linger Linger (for use with -m)\n"
51
+ " -L, --linger Linger (default, unless -m is used)\n"
52
" -P, --passive Passive link\n"
53
" -p, --props=PROPS Properties as JSON object\n"
54
"Disconnect: %1$s -d [options] output input\n"
55
56
pw_init(&argc, &argv);
57
spa_list_init(&data.objects);
58
59
+ setlinebuf(stdout);
60
+
61
data.props = pw_properties_new(NULL, NULL);
62
if (data.props == NULL) {
63
fprintf(stderr, "can't create properties: %m\n");
64
65
while ((c = getopt_long(argc, argv, "hVr:oilmIvLPp:d", long_options, NULL)) != -1) {
66
switch (c) {
67
case 'h':
68
- show_help(&data, argv[0]);
69
+ show_help(&data, argv[0], NULL);
70
return 0;
71
case 'V':
72
- fprintf(stdout, "%s\n"
73
+ printf("%s\n"
74
"Compiled with libpipewire %s\n"
75
"Linked with libpipewire %s\n",
76
argv[0],
77
78
data.opt_mode |= MODE_DISCONNECT;
79
break;
80
default:
81
- show_help(&data, argv[0]);
82
+ show_help(&data, argv[0], true);
83
return -1;
84
}
85
}
86
if (argc == 1)
87
- show_help(&data, argv[0]);
88
+ show_help(&data, argv[0], true);
89
+
90
+ if (data.opt_id && (data.opt_mode & MODE_LIST) == 0) {
91
+ fprintf(stderr, "-I option needs one or more of -l, -i or -o\n");
92
+ return -1;
93
+ }
94
95
if ((data.opt_mode & MODE_MONITOR) == 0)
96
pw_properties_set(data.props, PW_KEY_OBJECT_LINGER, "true");
97
98
do_list(&data);
99
} else if (data.opt_mode & MODE_DISCONNECT) {
100
if (data.opt_output == NULL) {
101
- fprintf(stderr, "missing link-id or output and input port names\n");
102
+ fprintf(stderr, "missing link-id or output and input port names to disconnect\n");
103
return -1;
104
}
105
if ((res = do_unlink_ports(&data)) < 0) {
106
107
} else {
108
if (data.opt_output == NULL ||
109
data.opt_input == NULL) {
110
- fprintf(stderr, "missing output and input port names\n");
111
+ fprintf(stderr, "missing output and input port names to connect\n");
112
return -1;
113
}
114
if ((res = do_link_ports(&data)) < 0) {
115
116
regfree(data.out_regex);
117
if (data.in_regex)
118
regfree(data.in_regex);
119
+ spa_hook_remove(&data.registry_listener);
120
pw_proxy_destroy((struct pw_proxy*)data.registry);
121
+ spa_hook_remove(&data.core_listener);
122
pw_core_disconnect(data.core);
123
pw_context_destroy(data.context);
124
pw_main_loop_destroy(data.loop);
125
pipewire-0.3.45.tar.gz/src/tools/pw-loopback.c -> pipewire-0.3.47.tar.gz/src/tools/pw-loopback.c
Changed
35
1
2
};
3
4
5
-static void show_help(struct data *data, const char *name)
6
+static void show_help(struct data *data, const char *name, bool error)
7
{
8
- fprintf(stdout, "%s [options]\n"
9
+ fprintf(error ? stderr : stdout, "%s [options]\n"
10
" -h, --help Show this help\n"
11
" --version Show version\n"
12
" -r, --remote Remote daemon name\n"
13
14
while ((c = getopt_long(argc, argv, "hVr:g:c:m:l:C:P:i:o:", long_options, NULL)) != -1) {
15
switch (c) {
16
case 'h':
17
- show_help(&data, argv[0]);
18
+ show_help(&data, argv[0], false);
19
return 0;
20
case 'V':
21
- fprintf(stdout, "%s\n"
22
+ printf("%s\n"
23
"Compiled with libpipewire %s\n"
24
"Linked with libpipewire %s\n",
25
argv[0],
26
27
pw_properties_update_string(data.playback_props, optarg, strlen(optarg));
28
break;
29
default:
30
- show_help(&data, argv[0]);
31
+ show_help(&data, argv[0], true);
32
return -1;
33
}
34
}
35
pipewire-0.3.45.tar.gz/src/tools/pw-metadata.c -> pipewire-0.3.47.tar.gz/src/tools/pw-metadata.c
Changed
98
1
2
if ((d->opt_id == SPA_ID_INVALID || d->opt_id == id) &&
3
(d->opt_key == NULL || spa_streq(d->opt_key, key))) {
4
if (key == NULL) {
5
- fprintf(stdout, "remove: id:%u all keys\n", id);
6
+ printf("remove: id:%u all keys\n", id);
7
} else if (value == NULL) {
8
- fprintf(stdout, "remove: id:%u key:'%s'\n", id, key);
9
+ printf("remove: id:%u key:'%s'\n", id, key);
10
} else {
11
- fprintf(stdout, "update: id:%u key:'%s' value:'%s' type:'%s'\n", id, key, value, type);
12
+ printf("update: id:%u key:'%s' value:'%s' type:'%s'\n", id, key, value, type);
13
}
14
}
15
16
17
return;
18
}
19
20
- fprintf(stdout, "Found \"%s\" metadata %d\n", d->opt_name, id);
21
+ printf("Found \"%s\" metadata %d\n", d->opt_name, id);
22
d->metadata = pw_registry_bind(d->registry,
23
id, type, PW_VERSION_METADATA, 0);
24
25
if (d->opt_delete) {
26
if (d->opt_id != SPA_ID_INVALID) {
27
if (d->opt_key != NULL)
28
- fprintf(stdout, "delete property: id:%u key:%s\n", d->opt_id, d->opt_key);
29
+ printf("delete property: id:%u key:%s\n", d->opt_id, d->opt_key);
30
else
31
- fprintf(stdout, "delete properties: id:%u\n", d->opt_id);
32
+ printf("delete properties: id:%u\n", d->opt_id);
33
pw_metadata_set_property(d->metadata, d->opt_id, d->opt_key, NULL, NULL);
34
} else {
35
- fprintf(stdout, "delete all properties\n");
36
+ printf("delete all properties\n");
37
pw_metadata_clear(d->metadata);
38
}
39
} else if (d->opt_id != SPA_ID_INVALID && d->opt_key != NULL && d->opt_value != NULL) {
40
- fprintf(stdout, "set property: id:%u key:%s value:%s type:%s\n",
41
+ printf("set property: id:%u key:%s value:%s type:%s\n",
42
d->opt_id, d->opt_key, d->opt_value, d->opt_type);
43
pw_metadata_set_property(d->metadata, d->opt_id, d->opt_key, d->opt_type, d->opt_value);
44
} else {
45
46
pw_main_loop_quit(data->loop);
47
}
48
49
-static void show_help(struct data *data, const char *name)
50
+static void show_help(struct data *data, const char *name, bool error)
51
{
52
- fprintf(stdout, "%s [options] [ id [ key [ value [ type ] ] ] ]\n"
53
+ fprintf(error ? stderr : stdout, "%s [options] [ id [ key [ value [ type ] ] ] ]\n"
54
" -h, --help Show this help\n"
55
" --version Show version\n"
56
" -r, --remote Remote daemon name\n"
57
58
{ NULL, 0, NULL, 0}
59
};
60
61
+ setlinebuf(stdout);
62
+
63
pw_init(&argc, &argv);
64
65
data.opt_name = "default";
66
67
while ((c = getopt_long(argc, argv, "hVr:mdn:", long_options, NULL)) != -1) {
68
switch (c) {
69
case 'h':
70
- show_help(&data, argv[0]);
71
+ show_help(&data, argv[0], false);
72
return 0;
73
case 'V':
74
- fprintf(stdout, "%s\n"
75
+ printf("%s\n"
76
"Compiled with libpipewire %s\n"
77
"Linked with libpipewire %s\n",
78
argv[0],
79
80
data.opt_name = optarg;
81
break;
82
default:
83
- show_help(&data, argv[0]);
84
+ show_help(&data, argv[0], true);
85
return -1;
86
}
87
}
88
89
90
if (data.metadata)
91
pw_proxy_destroy((struct pw_proxy*)data.metadata);
92
+ spa_hook_remove(&data.registry_listener);
93
pw_proxy_destroy((struct pw_proxy*)data.registry);
94
+ spa_hook_remove(&data.core_listener);
95
pw_core_disconnect(data.core);
96
pw_context_destroy(data.context);
97
pw_main_loop_destroy(data.loop);
98
pipewire-0.3.45.tar.gz/src/tools/pw-mididump.c -> pipewire-0.3.47.tar.gz/src/tools/pw-mididump.c
Changed
49
1
2
ev.data = SPA_POD_BODY(&c->value),
3
ev.size = SPA_POD_BODY_SIZE(&c->value);
4
5
- fprintf(stdout, "%4d: ", c->offset);
6
+ printf("%4d: ", c->offset);
7
midi_file_dump_event(stdout, &ev);
8
}
9
10
11
return 0;
12
}
13
14
-static void show_help(const char *name)
15
+static void show_help(const char *name, bool error)
16
{
17
- fprintf(stdout, "%s [options] [FILE]\n"
18
+ fprintf(error ? stderr : stdout, "%s [options] [FILE]\n"
19
" -h, --help Show this help\n"
20
" --version Show version\n"
21
" -r, --remote Remote daemon name\n",
22
23
24
pw_init(&argc, &argv);
25
26
+ setlinebuf(stdout);
27
+
28
while ((c = getopt_long(argc, argv, "hVr:", long_options, NULL)) != -1) {
29
switch (c) {
30
case 'h':
31
- show_help(argv[0]);
32
+ show_help(argv[0], false);
33
return 0;
34
case 'V':
35
- fprintf(stdout, "%s\n"
36
+ printf("%s\n"
37
"Compiled with libpipewire %s\n"
38
"Linked with libpipewire %s\n",
39
argv[0],
40
41
data.opt_remote = optarg;
42
break;
43
default:
44
- show_help(argv[0]);
45
+ show_help(argv[0], true);
46
return -1;
47
}
48
}
49
pipewire-0.3.45.tar.gz/src/tools/pw-mon.c -> pipewire-0.3.47.tar.gz/src/tools/pw-mon.c
Changed
425
1
2
{ .prefix = "*", .suffix = "" },
3
};
4
5
-#define with_prefix(use_prefix_, stream_) \
6
- for (bool once_ = !!fprintf(stream_, "%s", (pprefix[!!(use_prefix_)]).prefix); \
7
+#define with_prefix(use_prefix_) \
8
+ for (bool once_ = !!printf("%s", (pprefix[!!(use_prefix_)]).prefix); \
9
once_; \
10
- once_ = false, fprintf(stream_, "%s", (pprefix[!!(use_prefix_)]).suffix))
11
+ once_ = false, printf("%s", (pprefix[!!(use_prefix_)]).suffix))
12
13
14
struct param {
15
16
{
17
struct param *p;
18
19
- with_prefix(use_prefix, stderr) {
20
- fprintf(stderr, "\tparams:\n");
21
+ with_prefix(use_prefix) {
22
+ printf("\tparams:\n");
23
}
24
25
spa_list_for_each(p, &data->param_list, link) {
26
- with_prefix(p->changed, stderr) {
27
- fprintf(stderr, "\t id:%u (%s)\n",
28
+ with_prefix(p->changed) {
29
+ printf("\t id:%u (%s)\n",
30
p->id,
31
spa_debug_type_find_name(spa_type_param, p->id));
32
if (spa_pod_is_object_type(p->param, SPA_TYPE_OBJECT_Format))
33
34
{
35
const struct spa_dict_item *item;
36
37
- with_prefix(use_prefix, stderr) {
38
- fprintf(stderr, "\tproperties:\n");
39
+ with_prefix(use_prefix) {
40
+ printf("\tproperties:\n");
41
if (props == NULL || props->n_items == 0) {
42
- fprintf(stderr, "\t\tnone\n");
43
+ printf("\t\tnone\n");
44
return;
45
}
46
}
47
48
spa_dict_for_each(item, props) {
49
- with_prefix(use_prefix, stderr) {
50
+ with_prefix(use_prefix) {
51
if (item->value)
52
- fprintf(stderr, "\t\t%s = \"%s\"\n", item->key, item->value);
53
+ printf("\t\t%s = \"%s\"\n", item->key, item->value);
54
else
55
- fprintf(stderr, "\t\t%s = (null)\n", item->key);
56
+ printf("\t\t%s = (null)\n", item->key);
57
}
58
}
59
}
60
61
{
62
bool print_all = true, print_mark = true;
63
64
- fprintf(stderr, "\ttype: %s\n", PW_TYPE_INTERFACE_Core);
65
- fprintf(stderr, "\tcookie: %u\n", info->cookie);
66
- fprintf(stderr, "\tuser-name: \"%s\"\n", info->user_name);
67
- fprintf(stderr, "\thost-name: \"%s\"\n", info->host_name);
68
- fprintf(stderr, "\tversion: \"%s\"\n", info->version);
69
- fprintf(stderr, "\tname: \"%s\"\n", info->name);
70
+ printf("\ttype: %s\n", PW_TYPE_INTERFACE_Core);
71
+ printf("\tcookie: %u\n", info->cookie);
72
+ printf("\tuser-name: \"%s\"\n", info->user_name);
73
+ printf("\thost-name: \"%s\"\n", info->host_name);
74
+ printf("\tversion: \"%s\"\n", info->version);
75
+ printf("\tname: \"%s\"\n", info->name);
76
if (print_all) {
77
print_properties(info->props, MARK_CHANGE(PW_CORE_CHANGE_MASK_PROPS));
78
}
79
80
81
print_all = true;
82
if (data->info == NULL) {
83
- fprintf(stderr, "added:\n");
84
+ printf("added:\n");
85
print_mark = false;
86
}
87
else {
88
- fprintf(stderr, "changed:\n");
89
+ printf("changed:\n");
90
print_mark = true;
91
}
92
93
info = data->info = pw_module_info_update(data->info, info);
94
95
- fprintf(stderr, "\tid: %d\n", data->id);
96
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
97
+ printf("\tid: %d\n", data->id);
98
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
99
PW_PERMISSION_ARGS(data->permissions));
100
- fprintf(stderr, "\ttype: %s (version %d)\n", data->type, data->version);
101
- fprintf(stderr, "\tname: \"%s\"\n", info->name);
102
- fprintf(stderr, "\tfilename: \"%s\"\n", info->filename);
103
- fprintf(stderr, "\targs: \"%s\"\n", info->args);
104
+ printf("\ttype: %s (version %d)\n", data->type, data->version);
105
+ printf("\tname: \"%s\"\n", info->name);
106
+ printf("\tfilename: \"%s\"\n", info->filename);
107
+ printf("\targs: \"%s\"\n", info->args);
108
if (print_all) {
109
print_properties(info->props, MARK_CHANGE(PW_MODULE_CHANGE_MASK_PROPS));
110
}
111
112
113
print_all = true;
114
if (data->first) {
115
- fprintf(stderr, "added:\n");
116
+ printf("added:\n");
117
print_mark = false;
118
data->first = false;
119
}
120
else {
121
- fprintf(stderr, "changed:\n");
122
+ printf("changed:\n");
123
print_mark = true;
124
}
125
126
- fprintf(stderr, "\tid: %d\n", data->id);
127
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
128
+ printf("\tid: %d\n", data->id);
129
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
130
PW_PERMISSION_ARGS(data->permissions));
131
- fprintf(stderr, "\ttype: %s (version %d)\n", data->type, data->version);
132
+ printf("\ttype: %s (version %d)\n", data->type, data->version);
133
if (print_all) {
134
print_params(data, MARK_CHANGE(PW_NODE_CHANGE_MASK_PARAMS));
135
- with_prefix(MARK_CHANGE(PW_NODE_CHANGE_MASK_INPUT_PORTS), stderr) {
136
- fprintf(stderr, "\tinput ports: %u/%u\n",
137
+ with_prefix(MARK_CHANGE(PW_NODE_CHANGE_MASK_INPUT_PORTS)) {
138
+ printf("\tinput ports: %u/%u\n",
139
info->n_input_ports, info->max_input_ports);
140
}
141
- with_prefix(MARK_CHANGE(PW_NODE_CHANGE_MASK_OUTPUT_PORTS), stderr) {
142
- fprintf(stderr, "\toutput ports: %u/%u\n",
143
+ with_prefix(MARK_CHANGE(PW_NODE_CHANGE_MASK_OUTPUT_PORTS)) {
144
+ printf("\toutput ports: %u/%u\n",
145
info->n_output_ports, info->max_output_ports);
146
}
147
- with_prefix(MARK_CHANGE(PW_NODE_CHANGE_MASK_STATE), stderr) {
148
- fprintf(stderr, "\tstate: \"%s\"",
149
+ with_prefix(MARK_CHANGE(PW_NODE_CHANGE_MASK_STATE)) {
150
+ printf("\tstate: \"%s\"",
151
pw_node_state_as_string(info->state));
152
}
153
if (info->state == PW_NODE_STATE_ERROR && info->error)
154
- fprintf(stderr, " \"%s\"\n", info->error);
155
+ printf(" \"%s\"\n", info->error);
156
else
157
- fprintf(stderr, "\n");
158
+ printf("\n");
159
print_properties(info->props, MARK_CHANGE(PW_NODE_CHANGE_MASK_PROPS));
160
}
161
}
162
163
164
print_all = true;
165
if (data->first) {
166
- fprintf(stderr, "added:\n");
167
+ printf("added:\n");
168
print_mark = false;
169
data->first = false;
170
}
171
else {
172
- fprintf(stderr, "changed:\n");
173
+ printf("changed:\n");
174
print_mark = true;
175
}
176
177
- fprintf(stderr, "\tid: %d\n", data->id);
178
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
179
+ printf("\tid: %d\n", data->id);
180
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
181
PW_PERMISSION_ARGS(data->permissions));
182
- fprintf(stderr, "\ttype: %s (version %d)\n", data->type, data->version);
183
+ printf("\ttype: %s (version %d)\n", data->type, data->version);
184
185
- fprintf(stderr, "\tdirection: \"%s\"\n", pw_direction_as_string(info->direction));
186
+ printf("\tdirection: \"%s\"\n", pw_direction_as_string(info->direction));
187
if (print_all) {
188
print_params(data, MARK_CHANGE(PW_PORT_CHANGE_MASK_PARAMS));
189
print_properties(info->props, MARK_CHANGE(PW_PORT_CHANGE_MASK_PROPS));
190
191
192
print_all = true;
193
if (data->info == NULL) {
194
- fprintf(stderr, "added:\n");
195
+ printf("added:\n");
196
print_mark = false;
197
}
198
else {
199
- fprintf(stderr, "changed:\n");
200
+ printf("changed:\n");
201
print_mark = true;
202
}
203
204
info = data->info = pw_factory_info_update(data->info, info);
205
206
- fprintf(stderr, "\tid: %d\n", data->id);
207
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
208
+ printf("\tid: %d\n", data->id);
209
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
210
PW_PERMISSION_ARGS(data->permissions));
211
- fprintf(stderr, "\ttype: %s (version %d)\n", data->type, data->version);
212
+ printf("\ttype: %s (version %d)\n", data->type, data->version);
213
214
- fprintf(stderr, "\tname: \"%s\"\n", info->name);
215
- fprintf(stderr, "\tobject-type: %s/%d\n", info->type, info->version);
216
+ printf("\tname: \"%s\"\n", info->name);
217
+ printf("\tobject-type: %s/%d\n", info->type, info->version);
218
if (print_all) {
219
print_properties(info->props, MARK_CHANGE(PW_FACTORY_CHANGE_MASK_PROPS));
220
}
221
222
223
print_all = true;
224
if (data->info == NULL) {
225
- fprintf(stderr, "added:\n");
226
+ printf("added:\n");
227
print_mark = false;
228
}
229
else {
230
- fprintf(stderr, "changed:\n");
231
+ printf("changed:\n");
232
print_mark = true;
233
}
234
235
info = data->info = pw_client_info_update(data->info, info);
236
237
- fprintf(stderr, "\tid: %d\n", data->id);
238
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
239
+ printf("\tid: %d\n", data->id);
240
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
241
PW_PERMISSION_ARGS(data->permissions));
242
- fprintf(stderr, "\ttype: %s (version %d)\n", data->type, data->version);
243
+ printf("\ttype: %s (version %d)\n", data->type, data->version);
244
245
if (print_all) {
246
print_properties(info->props, MARK_CHANGE(PW_CLIENT_CHANGE_MASK_PROPS));
247
248
249
print_all = true;
250
if (data->info == NULL) {
251
- fprintf(stderr, "added:\n");
252
+ printf("added:\n");
253
print_mark = false;
254
}
255
else {
256
- fprintf(stderr, "changed:\n");
257
+ printf("changed:\n");
258
print_mark = true;
259
}
260
261
info = data->info = pw_link_info_update(data->info, info);
262
263
- fprintf(stderr, "\tid: %d\n", data->id);
264
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
265
+ printf("\tid: %d\n", data->id);
266
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
267
PW_PERMISSION_ARGS(data->permissions));
268
- fprintf(stderr, "\ttype: %s (version %d)\n", data->type, data->version);
269
+ printf("\ttype: %s (version %d)\n", data->type, data->version);
270
271
- fprintf(stderr, "\toutput-node-id: %u\n", info->output_node_id);
272
- fprintf(stderr, "\toutput-port-id: %u\n", info->output_port_id);
273
- fprintf(stderr, "\tinput-node-id: %u\n", info->input_node_id);
274
- fprintf(stderr, "\tinput-port-id: %u\n", info->input_port_id);
275
+ printf("\toutput-node-id: %u\n", info->output_node_id);
276
+ printf("\toutput-port-id: %u\n", info->output_port_id);
277
+ printf("\tinput-node-id: %u\n", info->input_node_id);
278
+ printf("\tinput-port-id: %u\n", info->input_port_id);
279
if (print_all) {
280
- with_prefix(MARK_CHANGE(PW_LINK_CHANGE_MASK_STATE), stderr) {
281
- fprintf(stderr, "\tstate: \"%s\"",
282
+ with_prefix(MARK_CHANGE(PW_LINK_CHANGE_MASK_STATE)) {
283
+ printf("\tstate: \"%s\"",
284
pw_link_state_as_string(info->state));
285
}
286
if (info->state == PW_LINK_STATE_ERROR && info->error)
287
- fprintf(stderr, " \"%s\"\n", info->error);
288
+ printf(" \"%s\"\n", info->error);
289
else
290
- fprintf(stderr, "\n");
291
- with_prefix(MARK_CHANGE(PW_LINK_CHANGE_MASK_FORMAT), stderr) {
292
- fprintf(stderr, "\tformat:\n");
293
+ printf("\n");
294
+ with_prefix(MARK_CHANGE(PW_LINK_CHANGE_MASK_FORMAT)) {
295
+ printf("\tformat:\n");
296
if (info->format)
297
spa_debug_format(2, NULL, info->format);
298
else
299
- fprintf(stderr, "\t\tnone\n");
300
+ printf("\t\tnone\n");
301
}
302
print_properties(info->props, MARK_CHANGE(PW_LINK_CHANGE_MASK_PROPS));
303
}
304
305
306
print_all = true;
307
if (data->first) {
308
- fprintf(stderr, "added:\n");
309
+ printf("added:\n");
310
print_mark = false;
311
data->first = false;
312
}
313
else {
314
- fprintf(stderr, "changed:\n");
315
+ printf("changed:\n");
316
print_mark = true;
317
}
318
319
- fprintf(stderr, "\tid: %d\n", data->id);
320
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
321
+ printf("\tid: %d\n", data->id);
322
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
323
PW_PERMISSION_ARGS(data->permissions));
324
- fprintf(stderr, "\ttype: %s (version %d)\n", data->type, data->version);
325
+ printf("\ttype: %s (version %d)\n", data->type, data->version);
326
327
if (print_all) {
328
print_params(data, MARK_CHANGE(PW_DEVICE_CHANGE_MASK_PARAMS));
329
330
331
spa_list_remove(&pd->global_link);
332
333
+ spa_hook_remove(&pd->object_listener);
334
+ spa_hook_remove(&pd->proxy_listener);
335
+
336
clear_params(pd);
337
remove_pending(pd);
338
free(pd->type);
339
340
client_version = PW_VERSION_LINK;
341
destroy = (pw_destroy_t) pw_link_info_free;
342
} else {
343
- fprintf(stderr, "added:\n");
344
- fprintf(stderr, "\tid: %u\n", id);
345
- fprintf(stderr, "\tpermissions: "PW_PERMISSION_FORMAT"\n",
346
+ printf("added:\n");
347
+ printf("\tid: %u\n", id);
348
+ printf("\tpermissions: "PW_PERMISSION_FORMAT"\n",
349
PW_PERMISSION_ARGS(permissions));
350
- fprintf(stderr, "\ttype: %s (version %d)\n", type, version);
351
+ printf("\ttype: %s (version %d)\n", type, version);
352
print_properties(props, false);
353
return;
354
}
355
356
struct data *d = object;
357
struct proxy_data *pd;
358
359
- fprintf(stderr, "removed:\n");
360
- fprintf(stderr, "\tid: %u\n", id);
361
+ printf("removed:\n");
362
+ printf("\tid: %u\n", id);
363
364
pd = find_proxy(d, id);
365
if (pd == NULL)
366
367
pw_main_loop_quit(d->loop);
368
}
369
370
-static void show_help(const char *name)
371
+static void show_help(const char *name, bool error)
372
{
373
- fprintf(stdout, "%s [options]\n"
374
+ fprintf(error ? stderr : stdout, "%s [options]\n"
375
" -h, --help Show this help\n"
376
" --version Show version\n"
377
" -r, --remote Remote daemon name\n"
378
379
380
pw_init(&argc, &argv);
381
382
+ setlinebuf(stdout);
383
+
384
if (isatty(STDERR_FILENO) && getenv("NO_COLOR") == NULL)
385
colors = true;
386
387
while ((c = getopt_long(argc, argv, "hVr:", long_options, NULL)) != -1) {
388
switch (c) {
389
case 'h':
390
- show_help(argv[0]);
391
+ show_help(argv[0], false);
392
return 0;
393
case 'V':
394
- fprintf(stdout, "%s\n"
395
+ printf("%s\n"
396
"Compiled with libpipewire %s\n"
397
"Linked with libpipewire %s\n",
398
argv[0],
399
400
else if (!strcmp(optarg, "always"))
401
colors = true;
402
else {
403
- show_help(argv[0]);
404
+ fprintf(stderr, "Invalid color: %s\n", optarg);
405
+ show_help(argv[0], true);
406
return -1;
407
}
408
break;
409
default:
410
- show_help(argv[0]);
411
+ show_help(argv[0], true);
412
return -1;
413
}
414
}
415
416
417
pw_main_loop_run(data.loop);
418
419
+ spa_hook_remove(&data.registry_listener);
420
pw_proxy_destroy((struct pw_proxy*)data.registry);
421
+ spa_hook_remove(&data.core_listener);
422
pw_context_destroy(data.context);
423
pw_main_loop_destroy(data.loop);
424
pw_deinit();
425
pipewire-0.3.45.tar.gz/src/tools/pw-profiler.c -> pipewire-0.3.47.tar.gz/src/tools/pw-profiler.c
Changed
113
1
2
3
if (d->driver_id == 0) {
4
d->driver_id = driver_id;
5
- fprintf(stderr, "logging driver %u\n", driver_id);
6
+ printf("logging driver %u\n", driver_id);
7
}
8
else if (d->driver_id != driver_id)
9
return -1;
10
11
strncpy(d->followers[idx].name, name, MAX_NAME);
12
d->followers[idx].name[MAX_NAME-1] = '\0';
13
d->followers[idx].id = id;
14
- fprintf(stderr, "logging follower %u (\"%s\")\n", id, name);
15
+ printf("logging follower %u (\"%s\")\n", id, name);
16
17
return idx;
18
}
19
20
d->last_status = point->clock.nsec;
21
}
22
else if (point->clock.nsec - d->last_status > SPA_NSEC_PER_SEC) {
23
- fprintf(stderr, "logging %"PRIi64" samples %"PRIi64" seconds [CPU %f %f %f]\r",
24
+ printf("logging %"PRIi64" samples %"PRIi64" seconds [CPU %f %f %f]\r",
25
d->count, (int64_t) ((d->last_status - d->start_status) / SPA_NSEC_PER_SEC),
26
point->cpu_load[0], point->cpu_load[1], point->cpu_load[2]);
27
d->last_status = point->clock.nsec;
28
29
if (d->driver_id == 0)
30
return;
31
32
- fprintf(stderr, "\ndumping scripts for %d followers\n", d->n_followers);
33
+ printf("\ndumping scripts for %d followers\n", d->n_followers);
34
35
out = fopen("Timing1.plot", "w");
36
if (out == NULL) {
37
38
"gnuplot Timing5.plot\n");
39
fclose(out);
40
}
41
- fprintf(stderr, "run 'sh generate_timings.sh' and load Timings.html in a browser\n");
42
+ printf("run 'sh generate_timings.sh' and load Timings.html in a browser\n");
43
}
44
45
static void profiler_profile(void *data, const struct spa_pod *pod)
46
47
if (proxy == NULL)
48
goto error_proxy;
49
50
- fprintf(stderr, "Attaching to Profiler id:%d\n", id);
51
+ printf("Attaching to Profiler id:%d\n", id);
52
d->profiler = proxy;
53
pw_proxy_add_object_listener(proxy, &d->profiler_listener, &profiler_events, d);
54
55
56
pw_main_loop_quit(d->loop);
57
}
58
59
-static void show_help(const char *name)
60
+static void show_help(const char *name, bool error)
61
{
62
- fprintf(stdout, "%s [options]\n"
63
+ fprintf(error ? stderr : stdout, "%s [options]\n"
64
" -h, --help Show this help\n"
65
" --version Show version\n"
66
" -r, --remote Remote daemon name\n"
67
68
while ((c = getopt_long(argc, argv, "hVr:o:", long_options, NULL)) != -1) {
69
switch (c) {
70
case 'h':
71
- show_help(argv[0]);
72
+ show_help(argv[0], false);
73
return 0;
74
case 'V':
75
- fprintf(stdout, "%s\n"
76
+ printf("%s\n"
77
"Compiled with libpipewire %s\n"
78
"Linked with libpipewire %s\n",
79
argv[0],
80
81
opt_remote = optarg;
82
break;
83
default:
84
- show_help(argv[0]);
85
+ show_help(argv[0], true);
86
return -1;
87
}
88
}
89
90
return -1;
91
}
92
93
- fprintf(stderr, "Logging to %s\n", data.filename);
94
+ printf("Logging to %s\n", data.filename);
95
96
pw_core_add_listener(data.core,
97
&data.core_listener,
98
99
100
pw_main_loop_run(data.loop);
101
102
- pw_proxy_destroy((struct pw_proxy*)data.profiler);
103
+ if (data.profiler) {
104
+ spa_hook_remove(&data.profiler_listener);
105
+ pw_proxy_destroy((struct pw_proxy*)data.profiler);
106
+ }
107
+ spa_hook_remove(&data.registry_listener);
108
pw_proxy_destroy((struct pw_proxy*)data.registry);
109
+ spa_hook_remove(&data.core_listener);
110
pw_context_destroy(data.context);
111
pw_main_loop_destroy(data.loop);
112
113
pipewire-0.3.45.tar.gz/src/tools/pw-reserve.c -> pipewire-0.3.47.tar.gz/src/tools/pw-reserve.c
Changed
71
1
2
3
static void reserve_acquired(void *data, struct rd_device *d)
4
{
5
- fprintf(stdout, "reserve acquired\n");
6
+ printf("reserve acquired\n");
7
}
8
9
static void reserve_release(void *data, struct rd_device *d, int forced)
10
{
11
struct impl *impl = data;
12
- fprintf(stdout, "reserve release\n");
13
+ printf("reserve release\n");
14
rd_device_complete_release(impl->device, true);
15
}
16
17
static void reserve_busy(void *data, struct rd_device *d, const char *name, int32_t prio)
18
{
19
- fprintf(stdout, "reserve busy %s, prio %d\n", name, prio);
20
+ printf("reserve busy %s, prio %d\n", name, prio);
21
}
22
23
static void reserve_available(void *data, struct rd_device *d, const char *name)
24
{
25
- fprintf(stdout, "reserve available %s\n", name);
26
+ printf("reserve available %s\n", name);
27
}
28
29
static const struct rd_device_callbacks reserve_callbacks = {
30
31
#define DEFAULT_APPNAME "pw-reserve"
32
#define DEFAULT_PRIORITY 0
33
34
-static void show_help(const char *name)
35
+static void show_help(const char *name, bool error)
36
{
37
- fprintf(stdout, "%s [options]\n"
38
+ fprintf(error ? stderr : stdout, "%s [options]\n"
39
" -h, --help Show this help\n"
40
" --version Show version\n"
41
" -n, --name Name to reserve (Audio0, Midi0, Video0, ..)\n"
42
43
{ NULL, 0, NULL, 0}
44
};
45
46
+ setlinebuf(stdout);
47
+
48
pw_init(&argc, &argv);
49
50
while ((c = getopt_long(argc, argv, "hVn:a:p:m", long_options, NULL)) != -1) {
51
switch (c) {
52
case 'h':
53
- show_help(argv[0]);
54
+ show_help(argv[0], false);
55
return 0;
56
case 'V':
57
- fprintf(stdout, "%s\n"
58
+ printf("%s\n"
59
"Compiled with libpipewire %s\n"
60
"Linked with libpipewire %s\n",
61
argv[0],
62
63
opt_monitor = true;
64
break;
65
default:
66
- fprintf(stderr, "invalid option '%c'\n", c);
67
+ show_help(argv[0], true);
68
return -1;
69
}
70
}
71
pipewire-0.3.45.tar.gz/src/tools/pw-top.c -> pipewire-0.3.47.tar.gz/src/tools/pw-top.c
Changed
59
1
2
}
3
} else if (spa_streq(type, PW_TYPE_INTERFACE_Profiler)) {
4
if (d->profiler != NULL) {
5
- fprintf(stderr, "Ignoring profiler %d: already attached\n", id);
6
+ printf("Ignoring profiler %d: already attached\n", id);
7
return;
8
}
9
10
11
pw_main_loop_quit(d->loop);
12
}
13
14
-static void show_help(const char *name)
15
+static void show_help(const char *name, bool error)
16
{
17
- fprintf(stdout, "%s [options]\n"
18
+ fprintf(error ? stderr : stdout, "%s [options]\n"
19
" -h, --help Show this help\n"
20
" --version Show version\n"
21
" -r, --remote Remote daemon name\n",
22
23
while ((c = getopt_long(argc, argv, "hVr:o:", long_options, NULL)) != -1) {
24
switch (c) {
25
case 'h':
26
- show_help(argv[0]);
27
+ show_help(argv[0], false);
28
return 0;
29
case 'V':
30
- fprintf(stdout, "%s\n"
31
+ printf("%s\n"
32
"Compiled with libpipewire %s\n"
33
"Linked with libpipewire %s\n",
34
argv[0],
35
36
opt_remote = optarg;
37
break;
38
default:
39
- show_help(argv[0]);
40
+ show_help(argv[0], true);
41
return -1;
42
}
43
}
44
45
spa_list_consume(n, &data.node_list, link)
46
remove_node(&data, n);
47
48
- pw_proxy_destroy((struct pw_proxy*)data.profiler);
49
+ if (data.profiler) {
50
+ spa_hook_remove(&data.profiler_listener);
51
+ pw_proxy_destroy((struct pw_proxy*)data.profiler);
52
+ }
53
+ spa_hook_remove(&data.registry_listener);
54
pw_proxy_destroy((struct pw_proxy*)data.registry);
55
+ spa_hook_remove(&data.core_listener);
56
pw_context_destroy(data.context);
57
pw_main_loop_destroy(data.loop);
58
59
pipewire-0.3.45.tar.gz/test/meson.build -> pipewire-0.3.47.tar.gz/test/meson.build
Changed
16
1
2
link_with: pwtest_lib)
3
)
4
5
+test('test-loop',
6
+ executable('test-loop',
7
+ 'test-loop.c',
8
+ include_directories: pwtest_inc,
9
+ dependencies: [ spa_dep ],
10
+ link_with: pwtest_lib)
11
+)
12
+
13
test('test-context',
14
executable('test-context',
15
'test-context.c',
16
pipewire-0.3.45.tar.gz/test/pwtest-compat.c -> pipewire-0.3.47.tar.gz/test/pwtest-compat.c
Changed
10
1
2
3
#include "config.h"
4
5
-#if !HAVE_SIGABBREV_NP
6
+#ifndef HAVE_SIGABBREV_NP
7
#include <stddef.h>
8
#include <signal.h>
9
10
pipewire-0.3.45.tar.gz/test/pwtest.c -> pipewire-0.3.47.tar.gz/test/pwtest.c
Changed
74
1
2
#include <stdio.h>
3
#include <unistd.h>
4
#include <signal.h>
5
-#if HAVE_PIDFD_OPEN
6
+#ifdef HAVE_PIDFD_OPEN
7
#include <sys/syscall.h>
8
#endif
9
-#if HAVE_LIBCAP
10
+#ifdef HAVE_LIBCAP
11
#include <sys/capability.h>
12
#endif
13
#include <sys/epoll.h>
14
15
16
static void pwtest_backtrace(pid_t p)
17
{
18
-#if HAVE_GSTACK
19
+#ifdef HAVE_GSTACK
20
char pid[11];
21
pid_t parent, child;
22
int status;
23
24
struct spa_handle **hnd;
25
26
SPA_FOR_EACH_ELEMENT(plugin->handles, hnd) {
27
- if (*hnd)
28
+ if (*hnd) {
29
+ spa_handle_clear(*hnd);
30
free(*hnd);
31
+ }
32
}
33
SPA_FOR_EACH_ELEMENT(plugin->dlls, dll) {
34
if (*dll)
35
- dlclose(dll);
36
+ dlclose(*dll);
37
}
38
free(plugin);
39
}
40
41
r = spa_handle_factory_init(factory, handle, info, plugin->support, plugin->nsupport);
42
pwtest_neg_errno_ok(r);
43
if ((r = spa_handle_get_interface(handle, interface_name, &iface)) != 0) {
44
- dlclose(hnd);
45
+ spa_handle_clear(handle);
46
free(handle);
47
+ dlclose(hnd);
48
return -ENOSYS;
49
}
50
51
- plugin->handles[plugin->ndlls++] = hnd;
52
+ plugin->dlls[plugin->ndlls++] = hnd;
53
plugin->handles[plugin->nhandles++] = handle;
54
plugin->support[plugin->nsupport++] = SPA_SUPPORT_INIT(interface_name, iface);
55
56
57
size_t nevents = 0;
58
int r;
59
60
-#if HAVE_PIDFD_OPEN
61
+#ifdef HAVE_PIDFD_OPEN
62
pidfd = syscall(SYS_pidfd_open, pid, 0);
63
#else
64
errno = ENOSYS;
65
66
static bool is_debugger_attached(void)
67
{
68
bool rc = false;
69
-#if HAVE_LIBCAP
70
+#ifdef HAVE_LIBCAP
71
int status;
72
int pid = fork();
73
74
pipewire-0.3.45.tar.gz/test/test-context.c -> pipewire-0.3.47.tar.gz/test/test-context.c
Changed
10
1
2
SPA_TYPE_INTERFACE_Loop,
3
SPA_TYPE_INTERFACE_LoopUtils,
4
SPA_TYPE_INTERFACE_Log,
5
-#if HAVE_DBUS
6
+#ifdef HAVE_DBUS
7
SPA_TYPE_INTERFACE_DBus,
8
#endif
9
SPA_TYPE_INTERFACE_CPU
10
pipewire-0.3.45.tar.gz/test/test-lib.c -> pipewire-0.3.47.tar.gz/test/test-lib.c
Changed
10
1
2
pwtest_str_eq(headerversion, version_expected);
3
pwtest_str_eq(libversion, version_expected);
4
5
+ pw_deinit();
6
+
7
return PWTEST_PASS;
8
}
9
10
pipewire-0.3.47.tar.gz/test/test-loop.c
Added
239
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <stdio.h>
27
+#include <stdint.h>
28
+#include <stdlib.h>
29
+#include <unistd.h>
30
+#include <sys/eventfd.h>
31
+
32
+#include "pwtest.h"
33
+
34
+#include <pipewire/pipewire.h>
35
+
36
+struct obj {
37
+ int x;
38
+ struct spa_source source;
39
+};
40
+
41
+struct data {
42
+ struct pw_main_loop *ml;
43
+ struct pw_loop *l;
44
+ struct obj *a, *b;
45
+ int count;
46
+};
47
+
48
+static void on_event(struct spa_source *source)
49
+{
50
+ struct data *d = source->data;
51
+
52
+ pw_loop_remove_source(d->l, &d->a->source);
53
+ pw_loop_remove_source(d->l, &d->b->source);
54
+ close(d->a->source.fd);
55
+ close(d->b->source.fd);
56
+ free(d->a);
57
+ free(d->b);
58
+
59
+ pw_main_loop_quit(d->ml);
60
+}
61
+
62
+PWTEST(pwtest_loop_destroy2)
63
+{
64
+ struct data data;
65
+
66
+ pw_init(0, NULL);
67
+
68
+ spa_zero(data);
69
+ data.ml = pw_main_loop_new(NULL);
70
+ pwtest_ptr_notnull(data.ml);
71
+
72
+ data.l = pw_main_loop_get_loop(data.ml);
73
+ pwtest_ptr_notnull(data.l);
74
+
75
+ data.a = calloc(1, sizeof(*data.a));
76
+ data.b = calloc(1, sizeof(*data.b));
77
+
78
+ data.a->source.func = on_event;
79
+ data.a->source.fd = eventfd(0, 0);
80
+ data.a->source.mask = SPA_IO_IN;
81
+ data.a->source.data = &data;
82
+ data.b->source.func = on_event;
83
+ data.b->source.fd = eventfd(0, 0);
84
+ data.b->source.mask = SPA_IO_IN;
85
+ data.b->source.data = &data;
86
+
87
+ pw_loop_add_source(data.l, &data.a->source);
88
+ pw_loop_add_source(data.l, &data.b->source);
89
+
90
+ write(data.a->source.fd, &(uint64_t){1}, sizeof(uint64_t));
91
+ write(data.b->source.fd, &(uint64_t){1}, sizeof(uint64_t));
92
+
93
+ pw_main_loop_run(data.ml);
94
+ pw_main_loop_destroy(data.ml);
95
+
96
+ pw_deinit();
97
+
98
+ return PWTEST_PASS;
99
+}
100
+
101
+static void
102
+on_event_recurse1(struct spa_source *source)
103
+{
104
+ static bool first = true;
105
+ struct data *d = source->data;
106
+ uint64_t val;
107
+
108
+ ++d->count;
109
+ pwtest_int_lt(d->count, 3);
110
+
111
+ read(source->fd, &val, sizeof(val));
112
+
113
+ if (first) {
114
+ first = false;
115
+ pw_loop_enter(d->l);
116
+ pw_loop_iterate(d->l, -1);
117
+ pw_loop_leave(d->l);
118
+ }
119
+ pw_main_loop_quit(d->ml);
120
+}
121
+
122
+PWTEST(pwtest_loop_recurse1)
123
+{
124
+ struct data data;
125
+
126
+ pw_init(0, NULL);
127
+
128
+ spa_zero(data);
129
+ data.ml = pw_main_loop_new(NULL);
130
+ pwtest_ptr_notnull(data.ml);
131
+
132
+ data.l = pw_main_loop_get_loop(data.ml);
133
+ pwtest_ptr_notnull(data.l);
134
+
135
+ data.a = calloc(1, sizeof(*data.a));
136
+ data.b = calloc(1, sizeof(*data.b));
137
+
138
+ data.a->source.func = on_event_recurse1;
139
+ data.a->source.fd = eventfd(0, 0);
140
+ data.a->source.mask = SPA_IO_IN;
141
+ data.a->source.data = &data;
142
+ data.b->source.func = on_event_recurse1;
143
+ data.b->source.fd = eventfd(0, 0);
144
+ data.b->source.mask = SPA_IO_IN;
145
+ data.b->source.data = &data;
146
+
147
+ pw_loop_add_source(data.l, &data.a->source);
148
+ pw_loop_add_source(data.l, &data.b->source);
149
+
150
+ write(data.a->source.fd, &(uint64_t){1}, sizeof(uint64_t));
151
+ write(data.b->source.fd, &(uint64_t){1}, sizeof(uint64_t));
152
+
153
+ pw_main_loop_run(data.ml);
154
+ pw_main_loop_destroy(data.ml);
155
+
156
+ pw_deinit();
157
+
158
+ free(data.a);
159
+ free(data.b);
160
+
161
+ return PWTEST_PASS;
162
+}
163
+
164
+static void
165
+on_event_recurse2(struct spa_source *source)
166
+{
167
+ static bool first = true;
168
+ struct data *d = source->data;
169
+ uint64_t val;
170
+
171
+ ++d->count;
172
+ pwtest_int_lt(d->count, 3);
173
+
174
+ read(source->fd, &val, sizeof(val));
175
+
176
+ if (first) {
177
+ first = false;
178
+ pw_loop_enter(d->l);
179
+ pw_loop_iterate(d->l, -1);
180
+ pw_loop_leave(d->l);
181
+ } else {
182
+ pw_loop_remove_source(d->l, &d->a->source);
183
+ pw_loop_remove_source(d->l, &d->b->source);
184
+ close(d->a->source.fd);
185
+ close(d->b->source.fd);
186
+ free(d->a);
187
+ free(d->b);
188
+ }
189
+ pw_main_loop_quit(d->ml);
190
+}
191
+
192
+PWTEST(pwtest_loop_recurse2)
193
+{
194
+ struct data data;
195
+
196
+ pw_init(0, NULL);
197
+
198
+ spa_zero(data);
199
+ data.ml = pw_main_loop_new(NULL);
200
+ pwtest_ptr_notnull(data.ml);
201
+
202
+ data.l = pw_main_loop_get_loop(data.ml);
203
+ pwtest_ptr_notnull(data.l);
204
+
205
+ data.a = calloc(1, sizeof(*data.a));
206
+ data.b = calloc(1, sizeof(*data.b));
207
+
208
+ data.a->source.func = on_event_recurse2;
209
+ data.a->source.fd = eventfd(0, 0);
210
+ data.a->source.mask = SPA_IO_IN;
211
+ data.a->source.data = &data;
212
+ data.b->source.func = on_event_recurse2;
213
+ data.b->source.fd = eventfd(0, 0);
214
+ data.b->source.mask = SPA_IO_IN;
215
+ data.b->source.data = &data;
216
+
217
+ pw_loop_add_source(data.l, &data.a->source);
218
+ pw_loop_add_source(data.l, &data.b->source);
219
+
220
+ write(data.a->source.fd, &(uint64_t){1}, sizeof(uint64_t));
221
+ write(data.b->source.fd, &(uint64_t){1}, sizeof(uint64_t));
222
+
223
+ pw_main_loop_run(data.ml);
224
+ pw_main_loop_destroy(data.ml);
225
+
226
+ pw_deinit();
227
+
228
+ return PWTEST_PASS;
229
+}
230
+
231
+PWTEST_SUITE(support)
232
+{
233
+ pwtest_add(pwtest_loop_destroy2, PWTEST_NOARG);
234
+ pwtest_add(pwtest_loop_recurse1, PWTEST_NOARG);
235
+ pwtest_add(pwtest_loop_recurse2, PWTEST_NOARG);
236
+
237
+ return PWTEST_PASS;
238
+}
239
pipewire-0.3.45.tar.gz/test/test-pwtest.c -> pipewire-0.3.47.tar.gz/test/test-pwtest.c
Changed
10
1
2
3
PWTEST(compat_sigabbrev_np)
4
{
5
-#if !HAVE_SIGABBREV_NP
6
+#ifndef HAVE_SIGABBREV_NP
7
pwtest_str_eq(sigabbrev_np(SIGABRT), "ABRT");
8
pwtest_str_eq(sigabbrev_np(SIGSEGV), "SEGV");
9
pwtest_str_eq(sigabbrev_np(SIGSTOP), "STOP");
10