We truncated the diff of some files because they were too big.
If you want to see the full diff for every file, click here.
Changes of Revision 23
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Mon Mar 13 12:30:13 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.66
6
+
7
+-------------------------------------------------------------------
8
Thu Jan 26 20:45:06 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.65
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.65
6
+Version: 0.3.66
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.65.tar.gz/spa/plugins/libcamera/libcamera-client.c
Deleted
201
1
2
-/* Spa libcamera client
3
- *
4
- * Copyright (C) 2020, Collabora Ltd.
5
- * Author: Raghavendra Rao Sidlagatta <raghavendra.rao@collabora.com>
6
- *
7
- * libcamera-client.c
8
- *
9
- * Permission is hereby granted, free of charge, to any person obtaining a
10
- * copy of this software and associated documentation files (the "Software"),
11
- * to deal in the Software without restriction, including without limitation
12
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
- * and/or sell copies of the Software, and to permit persons to whom the
14
- * Software is furnished to do so, subject to the following conditions:
15
- *
16
- * The above copyright notice and this permission notice (including the next
17
- * paragraph) shall be included in all copies or substantial portions of the
18
- * Software.
19
- *
20
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
- * DEALINGS IN THE SOFTWARE.
27
- */
28
-
29
-#include <errno.h>
30
-#include <stddef.h>
31
-#include <stdio.h>
32
-#include <sys/types.h>
33
-#include <sys/stat.h>
34
-#include <fcntl.h>
35
-
36
-#include <spa/support/log.h>
37
-#include <spa/support/loop.h>
38
-#include <spa/support/plugin.h>
39
-#include <spa/utils/type.h>
40
-#include <spa/utils/keys.h>
41
-#include <spa/utils/names.h>
42
-#include <spa/utils/string.h>
43
-#include <spa/monitor/device.h>
44
-#include <spa/monitor/utils.h>
45
-
46
-#include "libcamera.h"
47
-
48
-struct impl {
49
- struct spa_handle handle;
50
- struct spa_device device;
51
-
52
- struct spa_log *log;
53
- struct spa_loop *main_loop;
54
-
55
- struct spa_hook_list hooks;
56
-
57
- uint64_t info_all;
58
- struct spa_device_info info;
59
-
60
- struct spa_source source;
61
-};
62
-
63
-static int emit_object_info(struct impl *this, uint32_t id)
64
-{
65
- struct spa_device_object_info info;
66
- struct spa_dict_item items20;
67
- uint32_t n_items = 0;
68
-
69
- info = SPA_DEVICE_OBJECT_INFO_INIT();
70
-
71
- info.type = SPA_TYPE_INTERFACE_Device;
72
- info.factory_name = SPA_NAME_API_LIBCAMERA_DEVICE;
73
- info.change_mask = (SPA_DEVICE_OBJECT_CHANGE_MASK_FLAGS |
74
- SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS);
75
- info.flags = 0;
76
-
77
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ENUM_API,"libcamera-client");
78
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "libcamera");
79
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Video/Device");
80
-
81
- info.props = &SPA_DICT_INIT(items, n_items);
82
- spa_device_emit_object_info(&this->hooks, id, &info);
83
-
84
- return 1;
85
-}
86
-
87
-static const struct spa_dict_item device_info_items = {
88
- { SPA_KEY_DEVICE_API, "libcamera" },
89
- { SPA_KEY_DEVICE_NICK, "libcamera-client" },
90
- { SPA_KEY_API_UDEV_MATCH, "libcamera" },
91
-};
92
-
93
-
94
-static void emit_device_info(struct impl *this, bool full)
95
-{
96
- uint64_t old = full ? this->info.change_mask : 0;
97
- if (full)
98
- this->info.change_mask = this->info_all;
99
- if (this->info.change_mask) {
100
- this->info.props = &SPA_DICT_INIT_ARRAY(device_info_items);
101
- spa_device_emit_info(&this->hooks, &this->info);
102
- this->info.change_mask = old;
103
- }
104
-}
105
-
106
-static void impl_hook_removed(struct spa_hook *hook)
107
-{
108
- return;
109
-}
110
-
111
-static int
112
-impl_device_add_listener(void *object, struct spa_hook *listener,
113
- const struct spa_device_events *events, void *data)
114
-{
115
- struct impl *this = object;
116
- struct spa_hook_list save;
117
-
118
- spa_return_val_if_fail(this != NULL, -EINVAL);
119
- spa_return_val_if_fail(events != NULL, -EINVAL);
120
-
121
- spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
122
-
123
- emit_device_info(this, true);
124
-
125
- emit_object_info(this, 0);
126
-
127
- spa_hook_list_join(&this->hooks, &save);
128
-
129
- listener->removed = impl_hook_removed;
130
- listener->priv = this;
131
-
132
- return 0;
133
-}
134
-
135
-static const struct spa_device_methods impl_device = {
136
- SPA_VERSION_DEVICE_METHODS,
137
- .add_listener = impl_device_add_listener,
138
-};
139
-
140
-static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
141
-{
142
- struct impl *this;
143
-
144
- spa_return_val_if_fail(handle != NULL, -EINVAL);
145
- spa_return_val_if_fail(interface != NULL, -EINVAL);
146
-
147
- this = (struct impl *) handle;
148
-
149
- if (spa_streq(type, SPA_TYPE_INTERFACE_Device))
150
- *interface = &this->device;
151
- else
152
- return -ENOENT;
153
-
154
- return 0;
155
-}
156
-
157
-static int impl_clear(struct spa_handle *handle)
158
-{
159
- struct impl *this = (struct impl *) handle;
160
-
161
- if(this->dev.camera) {
162
- deleteLibCamera(this->dev.camera);
163
- this->dev.camera = NULL;
164
- }
165
- return 0;
166
-}
167
-
168
-static size_t
169
-impl_get_size(const struct spa_handle_factory *factory,
170
- const struct spa_dict *params)
171
-{
172
- return sizeof(struct impl);
173
-}
174
-
175
-static int
176
-impl_init(const struct spa_handle_factory *factory,
177
- struct spa_handle *handle,
178
- const struct spa_dict *info,
179
- const struct spa_support *support,
180
- uint32_t n_support)
181
-{
182
- struct impl *this;
183
-
184
- spa_return_val_if_fail(factory != NULL, -EINVAL);
185
- spa_return_val_if_fail(handle != NULL, -EINVAL);
186
-
187
- handle->get_interface = impl_get_interface;
188
- handle->clear = impl_clear;
189
-
190
- this = (struct impl *) handle;
191
-
192
- this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
193
- libcamera_log_topic_init(this->log);
194
-
195
- this->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
196
-
197
- if (this->main_loop == NULL) {
198
- spa_log_error(this->log, "a main-loop is needed");
199
- return -EINVAL;
200
- }
201
pipewire-0.3.65.tar.gz/.gitignore -> pipewire-0.3.66.tar.gz/.gitignore
Changed
13
1
2
subprojects/wireplumber
3
subprojects/media-session
4
subprojects/packagecache
5
+subprojects/googletest*
6
+subprojects/gtest.wrap
7
+subprojects/libyaml.wrap
8
+subprojects/libyaml
9
+subprojects/libcamera
10
11
# Created by https://www.gitignore.io/api/vim
12
13
pipewire-0.3.65.tar.gz/.gitlab-ci.yml -> pipewire-0.3.66.tar.gz/.gitlab-ci.yml
Changed
18
1
2
.fedora:
3
variables:
4
# Update this tag when you want to trigger a rebuild
5
- FDO_DISTRIBUTION_TAG: '2022-11-07.0'
6
+ FDO_DISTRIBUTION_TAG: '2023-01-18.0'
7
FDO_DISTRIBUTION_VERSION: '35'
8
FDO_DISTRIBUTION_PACKAGES: >-
9
alsa-lib-devel
10
11
jack-audio-connection-kit-devel
12
libcanberra-devel
13
libldac-devel
14
+ libmysofa-devel
15
libsndfile-devel
16
libusb-devel
17
lilv-devel
18
pipewire-0.3.65.tar.gz/NEWS -> pipewire-0.3.66.tar.gz/NEWS
Changed
93
1
2
+# PipeWire 0.3.66 (2023-02-16)
3
+
4
+This is a bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+ - Fix a regression in the pulseaudio module-combine-stream because the new
9
+ module-combine-stream was not installed.
10
+ - PipeWire can now generate a limits.d config file with our recommended
11
+ settings for priorities and memlock.
12
+
13
+
14
+## PipeWire
15
+ - Avoid rate switches when the graph is idle.
16
+ - The rate selection algorithm was improved. This ensures minimal performance
17
+ and quality loss when resampling.
18
+ - The default min.quantum was set to 32 again after it got erronously changed
19
+ to (the too low) 16 in version 0.3.45.
20
+ - Fix compilation issues with rust bindings because of macros in defines.
21
+ Work around it for now. (#2952)
22
+ - Invalid file mappings are now refused (#2617 #2914 #3007)
23
+ - Modules, exec and objects can now be loaded depending on conditions. One
24
+ example is the X11-bell module that can now be disabled with a custom
25
+ property override.
26
+ - Filter now also supports _trigger_process() to drive the graph.
27
+ - TID is now added to the journald log.
28
+ - PipeWire generates and installs */etc/security/limits.d/25-pw-rlimits.conf*
29
+ that by default contains project's recommended settings. Creation of the
30
+ pipewire group is left to the distro or user ( `groupadd -r pipewire` ).
31
+ See the rlimits-* Meson options for controlling this behavior.
32
+ - Additionally there is now by default disabled Meson option that will
33
+ install */etc/security/limits.d/20-pw-defaults.conf* with the current Linux
34
+ default memlock value. Distros with only kernels >=5.16 or always using
35
+ systemd v251 or newer do not need this. But all other builds should set the
36
+ `-Dpam-defaults-install=true` Meson option to ensure that the memlock value
37
+ is always large enough. Thanks to Rickie Schroeder for pointing out that
38
+ the default Linux memlock value has been somewhat recently increased.
39
+
40
+## modules
41
+ - Install module-combine-stream.
42
+ - RTP source now has support for custom channel names.
43
+ - RTP source will now stop when inactive.
44
+ - There is now
45
+ - Filter-chain has a new mysofa based spacializer plugin.
46
+ - The RTP modules can now use direct clock timestamps to send and receive
47
+ packets. This makes it possible to synchronize sender and receiver with
48
+ a PTP clock, for example.
49
+ - Filter-chain now has an invert plugin to invert the polarity of a
50
+ signal. (#3008)
51
+
52
+## SPA
53
+ - There is now an option to set the channels used for probing Pro Audio
54
+ devices. This could unlock more samplerates for some devices when they are
55
+ probed with fewer channels. (#2990)
56
+ - Support was added for other clocks than the MONOTONIC clock in the
57
+ driver nodes. This can be used to synchronize the graph to a PTP clock,
58
+ for example.
59
+ - The ALSA source has some more headroom when rate matching to avoid
60
+ stuttering when following another driver.
61
+ - libcamera controls are now mapped to standard PipeWire property values.
62
+ - The channelmixer has seen some improvements. MONO and undefined channel
63
+ layouts are now upmixed and downmixed more correctly. (#3010)
64
+
65
+## Bluetooth
66
+ - Many BAP support fixes.
67
+
68
+## GStreamer
69
+ - The gstreamer elements now support buffer video metadata so that strides
70
+ are correctly handled.
71
+ - pipewiresrc will now error out correctly in more cases. (#2935)
72
+
73
+## JACK
74
+ - The frame to/from time functions are improved to also work with negative
75
+ time and frame offsets.
76
+
77
+Older versions:
78
+
79
+
80
# PipeWire 0.3.65 (2023-01-26)
81
82
This is a bugfix release that is API and ABI compatible with previous
83
84
this.
85
- pipewiresrc will now always be a live source unless told otherwise.
86
87
-Older versions:
88
-
89
-
90
# PipeWire 0.3.64 (2023-01-12)
91
92
This is a bugfix release that is API and ABI compatible with previous
93
pipewire-0.3.65.tar.gz/meson.build -> pipewire-0.3.66.tar.gz/meson.build
Changed
18
1
2
project('pipewire', 'c' ,
3
- version : '0.3.65',
4
+ version : '0.3.66',
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
sndfile_dep = dependency('sndfile', version : '>= 1.0.20', required : get_option('sndfile'))
10
summary({'sndfile': sndfile_dep.found()}, bool_yn: true, section: 'pw-cat/pw-play/pw-dump/filter-chain')
11
cdata.set('HAVE_SNDFILE', sndfile_dep.found())
12
+libmysofa_dep = dependency('libmysofa', required : get_option('libmysofa'))
13
+summary({'libmysofa': libmysofa_dep.found()}, bool_yn: true, section: 'filter-chain')
14
+cdata.set('HAVE_LIBMYSOFA', libmysofa_dep.found())
15
pulseaudio_dep = dependency('libpulse', required : get_option('libpulse'))
16
summary({'libpulse': pulseaudio_dep.found()}, bool_yn: true, section: 'Streaming between daemons')
17
avahi_dep = dependency('avahi-client', required : get_option('avahi'))
18
pipewire-0.3.65.tar.gz/meson_options.txt -> pipewire-0.3.66.tar.gz/meson_options.txt
Changed
49
1
2
description: 'Enable code that depends on libsndfile',
3
type: 'feature',
4
value: 'auto')
5
+option('libmysofa',
6
+ description: 'Enable code that depends on libmysofa',
7
+ type: 'feature',
8
+ value: 'auto')
9
option('libpulse',
10
description: 'Enable code that depends on libpulse',
11
type: 'feature',
12
13
description: 'Enable ALSA Compress-Offload support',
14
type: 'feature',
15
value: 'disabled')
16
+option('pam-defaults-install',
17
+ description: 'Install limits.d file modifying defaults for all PAM users. Only for old kernels/systemd!',
18
+ type: 'boolean',
19
+ value: 'false')
20
+option('pam-memlock-default',
21
+ description : 'The default memlock value for any PAM user in kilobytes. Multiples of 64 recommended.',
22
+ type : 'integer',
23
+ min: 640,
24
+ value: 8192)
25
+option('rlimits-install',
26
+ description: 'Install PAM limits.d file. Voids all following rlimits-* options, if false',
27
+ type: 'boolean',
28
+ value: 'true')
29
+option('rlimits-match',
30
+ description : 'PAM match rule for the generated limits.d file. @<name> denotes matching a group.',
31
+ type : 'string',
32
+ value: '@pipewire')
33
+option('rlimits-rtprio',
34
+ description : 'RR and FIFO scheduler priority permitted for realtime threads of the matching user(s)',
35
+ type : 'integer',
36
+ min: 11,
37
+ max: 99,
38
+ value: 95)
39
+option('rlimits-memlock',
40
+ description : 'kB of memory each process of the user matched by the rule can lock. Can be unlimited .',
41
+ type : 'string',
42
+ value: '4194304')
43
+option('rlimits-nice',
44
+ description : 'Not niceness permitted for non-realtime threads of the matching user(s)',
45
+ type : 'integer',
46
+ min: -20,
47
+ max: -1,
48
+ value: -19)
49
pipewire-0.3.65.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.66.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
46
1
2
{
3
struct client *c = (struct client *) client;
4
struct spa_io_position *pos;
5
- double df;
6
7
spa_return_val_if_fail(c != NULL, -EINVAL);
8
9
- if (SPA_UNLIKELY((pos = c->rt.position) == NULL))
10
+ if (SPA_UNLIKELY((pos = c->rt.position) == NULL) || c->buffer_frames == 0)
11
return 0;
12
13
- df = (frames - pos->clock.position) * (double)SPA_NSEC_PER_SEC / c->sample_rate;
14
- return (pos->clock.nsec + (int64_t)rint(df)) / SPA_NSEC_PER_USEC;
15
+ uint32_t nf = (uint32_t)pos->clock.position;
16
+ uint64_t w = pos->clock.nsec/SPA_NSEC_PER_USEC;
17
+ uint64_t nw = pos->clock.next_nsec/SPA_NSEC_PER_USEC;
18
+ int32_t df = frames - nf;
19
+ int64_t dp = nw - w;
20
+ return w + (int64_t)rint((double) df * (double) dp / c->buffer_frames);
21
}
22
23
SPA_EXPORT
24
25
{
26
struct client *c = (struct client *) client;
27
struct spa_io_position *pos;
28
- double du;
29
30
spa_return_val_if_fail(c != NULL, -EINVAL);
31
32
if (SPA_UNLIKELY((pos = c->rt.position) == NULL))
33
return 0;
34
35
- du = (usecs - pos->clock.nsec/SPA_NSEC_PER_USEC) * (double)c->sample_rate / SPA_USEC_PER_SEC;
36
- return pos->clock.position + (int32_t)rint(du);
37
+ uint32_t nf = (uint32_t)pos->clock.position;
38
+ uint64_t w = pos->clock.nsec/SPA_NSEC_PER_USEC;
39
+ uint64_t nw = pos->clock.next_nsec/SPA_NSEC_PER_USEC;
40
+ int64_t du = usecs - w;
41
+ int64_t dp = nw - w;
42
+ return nf + (int32_t)rint((double)du / (double)dp * c->buffer_frames);
43
}
44
45
SPA_EXPORT
46
pipewire-0.3.65.tar.gz/po/oc.po -> pipewire-0.3.66.tar.gz/po/oc.po
Changed
201
1
2
-# French translation of pipewire.
3
+# Occitan translation of pipewire.
4
# Copyright (C) 2006-2008 Lennart Poettering
5
# This file is distributed under the same license as the pipewire package.
6
# Robert-André Mauchin <zebob.m@pengzone.org>, 2008.
7
8
# Thomas Canniot <mrtom@fedoraproject.org>, 2009, 2012.
9
# Cédric Valmary (Tot en Òc) <cvalmary@yahoo.fr>, 2015.
10
# Cédric Valmary (totenoc.eu) <cvalmary@yahoo.fr>, 2016.
11
+# Quentin PAGÈS, 2023.
12
msgid ""
13
msgstr ""
14
"Project-Id-Version: pipewire trunk\n"
15
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
16
"issues/new\n"
17
-"POT-Creation-Date: 2021-04-18 16:54+0800\n"
18
-"PO-Revision-Date: 2016-10-12 22:20+0200\n"
19
-"Last-Translator: Cédric Valmary (totenoc.eu) <cvalmary@yahoo.fr>\n"
20
+"POT-Creation-Date: 2022-06-30 12:50+0200\n"
21
+"PO-Revision-Date: 2023-02-11 00:11+0100\n"
22
+"Last-Translator: Quentin PAGÈS\n"
23
"Language-Team: Tot En Òc\n"
24
"Language: oc\n"
25
"MIME-Version: 1.0\n"
26
"Content-Type: text/plain; charset=UTF-8\n"
27
"Content-Transfer-Encoding: 8bit\n"
28
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
29
-"X-Generator: Virtaal 0.7.1\n"
30
+"X-Generator: Poedit 3.2.2\n"
31
"X-Launchpad-Export-Date: 2016-10-12 20:12+0000\n"
32
33
-#: src/daemon/pipewire.c:43
34
+#: src/daemon/pipewire.c:46
35
#, c-format
36
msgid ""
37
"%s options\n"
38
39
" --version Show version\n"
40
" -c, --config Load config (Default %s)\n"
41
msgstr ""
42
+"%s opcions\n"
43
+" -h, --help Afichar aquesta ajuda\n"
44
+" --version Afichar la version\n"
45
+" -c, --config Cargar la conf. (Defaut %s)\n"
46
47
-#: src/daemon/pipewire.desktop.in:4
48
-msgid "PipeWire Media System"
49
-msgstr ""
50
-
51
-#: src/daemon/pipewire.desktop.in:5
52
-msgid "Start the PipeWire Media System"
53
-msgstr ""
54
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180
55
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
56
+#, c-format
57
+msgid "Tunnel to %s/%s"
58
+msgstr "Tunèl cap a %s/%s"
59
60
-#: src/examples/media-session/alsa-monitor.c:526
61
-#: spa/plugins/alsa/acp/compat.c:187
62
-msgid "Built-in Audio"
63
-msgstr "Àudio integrat"
64
+#: src/modules/module-fallback-sink.c:51
65
+msgid "Dummy Output"
66
+msgstr "Sortida factícia"
67
68
-#: src/examples/media-session/alsa-monitor.c:530
69
-#: spa/plugins/alsa/acp/compat.c:192
70
-msgid "Modem"
71
-msgstr "Modèm"
72
+#: src/modules/module-pulse-tunnel.c:662
73
+#, c-format
74
+msgid "Tunnel for %s@%s"
75
+msgstr "Tunèl per %s@%s"
76
77
-#: src/examples/media-session/alsa-monitor.c:539
78
+#: src/modules/module-zeroconf-discover.c:332
79
msgid "Unknown device"
80
-msgstr ""
81
+msgstr "Periferic desconegut"
82
+
83
+#: src/modules/module-zeroconf-discover.c:344
84
+#, c-format
85
+msgid "%s on %s@%s"
86
+msgstr "%s sus %s@%s"
87
88
-#: src/tools/pw-cat.c:991
89
+#: src/modules/module-zeroconf-discover.c:348
90
+#, c-format
91
+msgid "%s on %s"
92
+msgstr "%s sus %s"
93
+
94
+#: src/tools/pw-cat.c:784
95
#, c-format
96
msgid ""
97
-"%s options <file>\n"
98
+"%s options <file>|-\n"
99
" -h, --help Show this help\n"
100
" --version Show version\n"
101
" -v, --verbose Enable verbose operations\n"
102
"\n"
103
msgstr ""
104
+"%s opcions <file>|-\n"
105
+" -h, --help Afichar aquesta ajuda\n"
106
+" --version Afichar la version\n"
107
+" -v, --verbose Activar las operacions verbosas\n"
108
+"\n"
109
110
-#: src/tools/pw-cat.c:998
111
+#: src/tools/pw-cat.c:791
112
#, c-format
113
msgid ""
114
" -R, --remote Remote daemon name\n"
115
116
" or direct samples (256)\n"
117
" the rate is the one of the source "
118
"file\n"
119
-" --list-targets List available targets for --target\n"
120
+" -P --properties Set node properties\n"
121
"\n"
122
msgstr ""
123
124
-#: src/tools/pw-cat.c:1016
125
+#: src/tools/pw-cat.c:809
126
#, c-format
127
msgid ""
128
" --rate Sample rate (req. for rec) (default "
129
130
"\n"
131
msgstr ""
132
133
-#: src/tools/pw-cat.c:1033
134
+#: src/tools/pw-cat.c:826
135
msgid ""
136
" -p, --playback Playback mode\n"
137
" -r, --record Recording mode\n"
138
" -m, --midi Midi mode\n"
139
+" -d, --dsd DSD mode\n"
140
"\n"
141
msgstr ""
142
+" -p, --playback Mòde lectura\n"
143
+" -r, --record Mòde enregistrament\n"
144
+" -m, --midi Mòde Midi\n"
145
+" -d, --dsd Mòde DSD\n"
146
+"\n"
147
148
-#: src/tools/pw-cli.c:2932
149
+#: src/tools/pw-cli.c:2250
150
#, c-format
151
msgid ""
152
"%s options command\n"
153
154
" -r, --remote Remote daemon name\n"
155
"\n"
156
msgstr ""
157
+"%s opcions comanda\n"
158
+" -h, --help Afichar aquesta ajuda\n"
159
+" --version Afichar la version\n"
160
+" -d, --daemon Aviar coma demòni (Per defaut "
161
+"false)\n"
162
+" -r, --remote Remote daemon name\n"
163
+"\n"
164
165
-#: spa/plugins/alsa/acp/acp.c:290
166
+#: spa/plugins/alsa/acp/acp.c:321
167
msgid "Pro Audio"
168
msgstr ""
169
170
-#: spa/plugins/alsa/acp/acp.c:411 spa/plugins/alsa/acp/alsa-mixer.c:4704
171
-#: spa/plugins/bluez5/bluez5-device.c:1000
172
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
173
+#: spa/plugins/bluez5/bluez5-device.c:1236
174
msgid "Off"
175
msgstr "Atudat"
176
177
-#: spa/plugins/alsa/acp/channelmap.h:466
178
-msgid "(invalid)"
179
-msgstr "(invalid)"
180
-
181
-#: spa/plugins/alsa/acp/alsa-mixer.c:2709
182
+#: spa/plugins/alsa/acp/alsa-mixer.c:2652
183
msgid "Input"
184
msgstr "Entrada"
185
186
-#: spa/plugins/alsa/acp/alsa-mixer.c:2710
187
+#: spa/plugins/alsa/acp/alsa-mixer.c:2653
188
msgid "Docking Station Input"
189
msgstr "Entrada de l'estacion d'acuèlh"
190
191
-#: spa/plugins/alsa/acp/alsa-mixer.c:2711
192
+#: spa/plugins/alsa/acp/alsa-mixer.c:2654
193
msgid "Docking Station Microphone"
194
msgstr "Microfòn de l'estacion d'acuèlh"
195
196
-#: spa/plugins/alsa/acp/alsa-mixer.c:2712
197
+#: spa/plugins/alsa/acp/alsa-mixer.c:2655
198
msgid "Docking Station Line In"
199
msgstr "Entrada linha de l'estacion d'acuèlh"
200
201
pipewire-0.3.65.tar.gz/po/uk.po -> pipewire-0.3.66.tar.gz/po/uk.po
Changed
201
1
2
# Copyright (C) 2009 Free Software Foundation, Inc.
3
# This file is distributed under the same license as the pipewire package.
4
#
5
-# Yuri Chornoivan <yurchor@ukr.net>, 2009-2021, 2022.
6
+# Yuri Chornoivan <yurchor@ukr.net>, 2009-2021, 2022, 2023.
7
msgid ""
8
msgstr ""
9
"Project-Id-Version: pipewire\n"
10
-"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/issue"
11
-"s\n"
12
-"POT-Creation-Date: 2022-05-20 15:26+0000\n"
13
-"PO-Revision-Date: 2022-06-18 13:07+0300\n"
14
+"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/issu"
15
+"es\n"
16
+"POT-Creation-Date: 2023-02-06 15:27+0000\n"
17
+"PO-Revision-Date: 2023-02-11 17:42+0200\n"
18
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
19
"Language-Team: Ukrainian <trans-uk@lists.fedoraproject.org>\n"
20
"Language: uk\n"
21
22
msgid "Start the PipeWire Media System"
23
msgstr "Запустити мультимедійну систему PipeWire"
24
25
-#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:183
26
-#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:183
27
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:179
28
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:179
29
#, c-format
30
msgid "Tunnel to %s/%s"
31
msgstr "Тунель до %s/%s"
32
33
msgid "Dummy Output"
34
msgstr "Фіктивний вихід"
35
36
-#: src/modules/module-pulse-tunnel.c:639
37
+#: src/modules/module-pulse-tunnel.c:695
38
#, c-format
39
msgid "Tunnel for %s@%s"
40
msgstr "Тунель для %s@%s"
41
42
-#: src/modules/module-zeroconf-discover.c:332
43
+#: src/modules/module-zeroconf-discover.c:335
44
msgid "Unknown device"
45
msgstr "Невідомий пристрій"
46
47
-#: src/modules/module-zeroconf-discover.c:344
48
+#: src/modules/module-zeroconf-discover.c:347
49
#, c-format
50
msgid "%s on %s@%s"
51
msgstr "%s на %s@%s"
52
53
-#: src/modules/module-zeroconf-discover.c:348
54
+#: src/modules/module-zeroconf-discover.c:351
55
#, c-format
56
msgid "%s on %s"
57
msgstr "%s на %s"
58
59
-#: src/tools/pw-cat.c:872
60
+#: src/tools/pw-cat.c:940
61
#, c-format
62
-#| msgid ""
63
-#| "%s options <file>\n"
64
-#| " -h, --help Show this help\n"
65
-#| " --version Show version\n"
66
-#| " -v, --verbose Enable verbose operations\n"
67
-#| "\n"
68
msgid ""
69
"%s options <file>|-\n"
70
" -h, --help Show this help\n"
71
72
"інформації\n"
73
"\n"
74
75
-#: src/tools/pw-cat.c:879
76
+#: src/tools/pw-cat.c:947
77
#, c-format
78
#| msgid ""
79
#| " -R, --remote Remote daemon name\n"
80
81
#| " or direct samples (256)\n"
82
#| " the rate is the one of the "
83
#| "source file\n"
84
+#| " -P --properties Set node properties\n"
85
#| "\n"
86
msgid ""
87
" -R, --remote Remote daemon name\n"
88
" --media-type Set media type (default %s)\n"
89
" --media-category Set media category (default %s)\n"
90
" --media-role Set media role (default %s)\n"
91
-" --target Set node target (default %s)\n"
92
+" --target Set node target serial or name "
93
+"(default %s)\n"
94
" 0 means don't link\n"
95
" --latency Set node latency (default %s)\n"
96
" Xunit (unit = s, ms, us, ns)\n"
97
98
"(типово, %s)\n"
99
" --media-role встановити роль мультимедіа (типово, "
100
"%s)\n"
101
-" --target встановити ціль вузла (типово, %s)\n"
102
+" --target встановити назву або серійний номер"
103
+" цілі вузла (типово, %s)\n"
104
" 0 — не пов'язувати\n"
105
" --latency встановити затримку вузла (типово, "
106
"%s)\n"
107
108
" -P --properties встановити властивості вузла\n"
109
"\n"
110
111
-#: src/tools/pw-cat.c:897
112
+#: src/tools/pw-cat.c:965
113
#, c-format
114
msgid ""
115
" --rate Sample rate (req. for rec) (default "
116
117
"(типово, %d)\n"
118
"\n"
119
120
-#: src/tools/pw-cat.c:914
121
+#: src/tools/pw-cat.c:982
122
+#| msgid ""
123
+#| " -p, --playback Playback mode\n"
124
+#| " -r, --record Recording mode\n"
125
+#| " -m, --midi Midi mode\n"
126
+#| " -d, --dsd DSD mode\n"
127
+#| "\n"
128
msgid ""
129
" -p, --playback Playback mode\n"
130
" -r, --record Recording mode\n"
131
" -m, --midi Midi mode\n"
132
" -d, --dsd DSD mode\n"
133
+" -o, --encoded\t\t\t Encoded mode\n"
134
"\n"
135
msgstr ""
136
" -p, --playback режим відтворення\n"
137
" -r, --record режим запису\n"
138
" -m, --midi режим MIDI\n"
139
" -d, --dsd режим DSD\n"
140
+" -o, --encoded\t\t\t закодований режим\n"
141
"\n"
142
143
-#: src/tools/pw-cli.c:3139
144
+#: src/tools/pw-cli.c:2236
145
#, c-format
146
+#| msgid ""
147
+#| "%s options command\n"
148
+#| " -h, --help Show this help\n"
149
+#| " --version Show version\n"
150
+#| " -d, --daemon Start as daemon (Default false)\n"
151
+#| " -r, --remote Remote daemon name\n"
152
+#| "\n"
153
msgid ""
154
"%s options command\n"
155
" -h, --help Show this help\n"
156
" --version Show version\n"
157
" -d, --daemon Start as daemon (Default false)\n"
158
" -r, --remote Remote daemon name\n"
159
+" -m, --monitor Monitor activity\n"
160
"\n"
161
msgstr ""
162
"%s параметри команда\n"
163
164
" -d, --daemon запустити як фонову службу (типово, "
165
"false)\n"
166
" -r, --remote назва віддаленої фонової служби\n"
167
+" -m, --monitor спостерігати за діями\n"
168
"\n"
169
170
-#: spa/plugins/alsa/acp/acp.c:321
171
+#: spa/plugins/alsa/acp/acp.c:323
172
msgid "Pro Audio"
173
msgstr "Професійний звук"
174
175
-#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
176
-#: spa/plugins/bluez5/bluez5-device.c:1161
177
+#: spa/plugins/alsa/acp/acp.c:447 spa/plugins/alsa/acp/alsa-mixer.c:4648
178
+#: spa/plugins/bluez5/bluez5-device.c:1303
179
msgid "Off"
180
msgstr "Вимкнено"
181
182
183
184
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
185
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
186
-#: spa/plugins/bluez5/bluez5-device.c:1330
187
+#: spa/plugins/bluez5/bluez5-device.c:1536
188
msgid "Microphone"
189
msgstr "Мікрофон"
190
191
192
msgstr "Без підсилення"
193
194
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
195
-#: spa/plugins/bluez5/bluez5-device.c:1335
196
+#: spa/plugins/bluez5/bluez5-device.c:1542
197
msgid "Speaker"
198
msgstr "Динамік"
199
200
201
pipewire-0.3.65.tar.gz/spa/include/spa/param/port-config.h -> pipewire-0.3.66.tar.gz/spa/include/spa/param/port-config.h
Changed
10
1
2
/** properties for SPA_TYPE_OBJECT_ParamPortConfig */
3
enum spa_param_port_config {
4
SPA_PARAM_PORT_CONFIG_START,
5
- SPA_PARAM_PORT_CONFIG_direction, /**< direction, input/output (Id enum spa_direction) */
6
+ SPA_PARAM_PORT_CONFIG_direction, /**< (Id enum spa_direction) direction */
7
SPA_PARAM_PORT_CONFIG_mode, /**< (Id enum spa_param_port_config_mode) mode */
8
SPA_PARAM_PORT_CONFIG_monitor, /**< (Bool) enable monitor output ports on input ports */
9
SPA_PARAM_PORT_CONFIG_control, /**< (Bool) enable control ports */
10
pipewire-0.3.65.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.66.tar.gz/spa/include/spa/utils/defs.h
Changed
10
1
2
for ((ptr) = arr; (void*)(ptr) < SPA_PTROFF(arr, sizeof(arr), void); (ptr)++)
3
4
#define SPA_FOR_EACH_ELEMENT_VAR(arr, var) \
5
- for (__typeof__((arr)0)* (var) = arr; (void*)(var) < SPA_PTROFF(arr, sizeof(arr), void); (var)++)
6
+ for (__typeof__((arr)0)* var = arr; (void*)(var) < SPA_PTROFF(arr, sizeof(arr), void); (var)++)
7
8
#define SPA_ABS(a) \
9
({ \
10
pipewire-0.3.65.tar.gz/spa/meson.build -> pipewire-0.3.66.tar.gz/spa/meson.build
Changed
28
1
2
# plugin-specific dependencies
3
alsa_dep = dependency('alsa', required: get_option('alsa'))
4
summary({'ALSA': alsa_dep.found()}, bool_yn: true, section: 'Backend')
5
+
6
bluez_dep = dependency('bluez', version : '>= 4.101', required: get_option('bluez5'))
7
gio_dep = dependency('gio-2.0', required : get_option('bluez5'))
8
gio_unix_dep = dependency('gio-unix-2.0', required : get_option('bluez5'))
9
- bluez_deps_found = bluez_dep.found() and gio_dep.found() and gio_unix_dep.found()
10
+ bluez_glib2_dep = dependency('glib-2.0', required : get_option('bluez5'))
11
+ sbc_dep = dependency('sbc', required: get_option('bluez5'))
12
+ summary({'SBC': sbc_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
13
+ bluez5_deps = mathlib, dbus_dep, sbc_dep, bluez_dep, bluez_glib2_dep, gio_dep, gio_unix_dep
14
+ bluez_deps_found = get_option('bluez5').allowed()
15
+ foreach dep: bluez5_deps
16
+ if get_option('bluez5').enabled() and not dep.found()
17
+ error('bluez5 enabled, but dependency not found: ' + dep.name())
18
+ endif
19
+ bluez_deps_found = bluez_deps_found and dep.found()
20
+ endforeach
21
summary({'Bluetooth audio': bluez_deps_found}, bool_yn: true, section: 'Backend')
22
if bluez_deps_found
23
- sbc_dep = dependency('sbc', required: get_option('bluez5'))
24
- summary({'SBC': sbc_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
25
ldac_dep = dependency('ldacBT-enc', required : get_option('bluez5-codec-ldac'))
26
summary({'LDAC': ldac_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
27
ldac_abr_dep = dependency('ldacBT-abr', required : get_option('bluez5-codec-ldac'))
28
pipewire-0.3.65.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.66.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
27
1
2
3
ss.format = PA_SAMPLE_S32LE;
4
ss.rate = impl->rate;
5
- ss.channels = 64;
6
+ ss.channels = impl->pro_channels;
7
8
ap = pa_xnew0(pa_alsa_profile, 1);
9
ap->profile_set = ps;
10
11
impl->auto_port = true;
12
impl->ignore_dB = false;
13
impl->rate = DEFAULT_RATE;
14
+ impl->pro_channels = 64;
15
16
if (props) {
17
if ((s = acp_dict_lookup(props, "api.alsa.use-ucm")) != NULL)
18
19
impl->auto_port = spa_atob(s);
20
if ((s = acp_dict_lookup(props, "api.acp.probe-rate")) != NULL)
21
impl->rate = atoi(s);
22
+ if ((s = acp_dict_lookup(props, "api.acp.pro-channels")) != NULL)
23
+ impl->pro_channels = atoi(s);
24
}
25
26
impl->ucm.default_sample_spec.format = PA_SAMPLE_S16NE;
27
pipewire-0.3.65.tar.gz/spa/plugins/alsa/acp/card.h -> pipewire-0.3.66.tar.gz/spa/plugins/alsa/acp/card.h
Changed
9
1
2
bool auto_port;
3
bool ignore_dB;
4
uint32_t rate;
5
+ uint32_t pro_channels;
6
7
pa_alsa_ucm_config ucm;
8
pa_alsa_profile_set *profile_set;
9
pipewire-0.3.65.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.66.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
10
1
2
} else {
3
*delay = avail;
4
*target = SPA_MAX(*target, state->read_size);
5
+ if (state->matching)
6
+ *target += 32;
7
}
8
*target = SPA_CLAMP(*target, state->min_delay, state->buffer_frames);
9
return 0;
10
pipewire-0.3.65.tar.gz/spa/plugins/audioconvert/channelmix-ops.c -> pipewire-0.3.66.tar.gz/spa/plugins/audioconvert/channelmix-ops.c
Changed
201
1
2
#define MATRIX_DOLBY 1
3
#define MATRIX_DPLII 2
4
5
-#define _CH(ch) ((SPA_AUDIO_CHANNEL_ ## ch)-3)
6
+#define _SH 2
7
+#define _CH(ch) ((SPA_AUDIO_CHANNEL_ ## ch)-_SH)
8
#define _MASK(ch) (1ULL << _CH(ch))
9
#define FRONT (_MASK(FC))
10
#define STEREO (_MASK(FL)|_MASK(FR))
11
#define REAR (_MASK(RL)|_MASK(RR))
12
#define SIDE (_MASK(SL)|_MASK(SR))
13
14
+static uint32_t mask_to_ch(struct channelmix *mix, uint64_t mask)
15
+{
16
+ uint32_t ch = 0;
17
+ while (mask > 1) {
18
+ ch++;
19
+ mask >>= 1;
20
+ }
21
+ return ch;
22
+}
23
+
24
+static void distribute_mix(struct channelmix *mix,
25
+ float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS,
26
+ uint64_t mask)
27
+{
28
+ uint32_t i, ch = mask_to_ch(mix, mask);
29
+ for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
30
+ matrixich= 1.0f;
31
+}
32
+static void average_mix(struct channelmix *mix,
33
+ float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS,
34
+ uint64_t mask)
35
+{
36
+ uint32_t i, ch = mask_to_ch(mix, mask);
37
+ for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
38
+ matrixchi= 1.0f;
39
+}
40
+static void pair_mix(float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS)
41
+{
42
+ uint32_t i;
43
+ for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
44
+ matrixii= 1.0f;
45
+}
46
+static bool match_mix(struct channelmix *mix,
47
+ float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS,
48
+ uint64_t src_mask, uint64_t dst_mask)
49
+{
50
+ bool matched = false;
51
+ uint32_t i;
52
+ for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) {
53
+ if ((src_mask & dst_mask & (1ULL << i))) {
54
+ spa_log_info(mix->log, "matched channel %u (%f)", i, 1.0f);
55
+ matrixii = 1.0f;
56
+ matched = true;
57
+ }
58
+ }
59
+ return matched;
60
+}
61
+
62
static int make_matrix(struct channelmix *mix)
63
{
64
float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS = {{ 0.0f }};
65
- uint64_t src_mask = mix->src_mask;
66
- uint64_t dst_mask = mix->dst_mask;
67
+ uint64_t src_mask = mix->src_mask, src_paired;
68
+ uint64_t dst_mask = mix->dst_mask, dst_paired;
69
uint32_t src_chan = mix->src_chan;
70
uint32_t dst_chan = mix->dst_chan;
71
uint64_t unassigned, keep;
72
73
float slev = SQRT1_2;
74
float llev = 0.5f;
75
float maxsum = 0.0f;
76
- bool filter_fc = false, filter_lfe = false;
77
+ bool filter_fc = false, filter_lfe = false, matched = false, normalize;
78
#define _MATRIX(s,d) matrix_CH(s)_CH(d)
79
80
+ normalize = SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_NORMALIZE);
81
+
82
spa_log_debug(mix->log, "src-mask:%08"PRIx64" dst-mask:%08"PRIx64
83
" options:%08x", src_mask, dst_mask, mix->options);
84
85
- /* move the MONO mask to FRONT so that the lower bits can be shifted
86
- * away. */
87
- if ((src_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0) {
88
- if (src_chan == 1)
89
- src_mask = 0;
90
- else
91
- src_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
92
- }
93
- if ((dst_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0)
94
- dst_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
95
+ /* shift so that bit 0 is MONO */
96
+ src_mask >>= _SH;
97
+ dst_mask >>= _SH;
98
99
- /* shift so that bit 0 is FL */
100
- src_mask >>= 3;
101
- dst_mask >>= 3;
102
+ if (src_chan > 1 && (src_mask & _MASK(MONO)))
103
+ src_mask = 0;
104
+ if (dst_chan > 1 && (dst_mask & _MASK(MONO)))
105
+ dst_mask = 0;
106
107
- /* unknown channels or just 1 channel */
108
+ src_paired = src_mask;
109
+ dst_paired = dst_mask;
110
+
111
+ /* unknown channels */
112
if (src_mask == 0 || dst_mask == 0) {
113
if (src_chan == 1) {
114
- /* one FC/MONO src goes everywhere */
115
- spa_log_debug(mix->log, "distribute FC/MONO (%f)", 1.0f);
116
- for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
117
- matrixi0= 1.0f;
118
+ /* one src channel goes everywhere */
119
+ spa_log_info(mix->log, "distribute UNK (%f) %"PRIu64, 1.0f, src_mask);
120
+ distribute_mix(mix, matrix, src_mask);
121
} else if (dst_chan == 1) {
122
- /* one FC/MONO dst get average of everything */
123
- spa_log_debug(mix->log, "average FC/MONO (%f)", 1.0f / src_chan);
124
- for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
125
- matrix0i= 1.0f / src_chan;
126
+ /* one dst channel get average of everything */
127
+ spa_log_info(mix->log, "average UNK (%f) %"PRIu64, 1.0f / src_chan, dst_mask);
128
+ average_mix(mix, matrix, dst_mask);
129
+ normalize = true;
130
} else {
131
/* just pair channels */
132
- spa_log_debug(mix->log, "pairing channels (%f)", 1.0f);
133
- for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
134
- matrixii= 1.0f;
135
+ spa_log_info(mix->log, "pairing UNK channels (%f)", 1.0f);
136
+ if (src_mask == 0)
137
+ src_paired = dst_mask;
138
+ else if (dst_mask == 0)
139
+ dst_paired = src_mask;
140
+ pair_mix(matrix);
141
}
142
- if (dst_mask & FRONT)
143
- filter_fc = true;
144
- if (dst_mask & _MASK(LFE))
145
- filter_lfe = true;
146
- src_mask = dst_mask = ~0LU;
147
goto done;
148
} else {
149
spa_log_debug(mix->log, "matching channels");
150
- for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) {
151
- if ((src_mask & dst_mask & (1ULL << i))) {
152
- spa_log_debug(mix->log, "matched channel %u (%f)", i, 1.0f);
153
- matrixii= 1.0f;
154
- }
155
- }
156
+ matched = match_mix(mix, matrix, src_mask, dst_mask);
157
}
158
159
unassigned = src_mask & ~dst_mask;
160
keep = dst_mask & ~src_mask;
161
162
if (!SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_UPMIX)) {
163
+ /* upmix completely disabled */
164
keep = 0;
165
} else {
166
+ /* some upmixing (FC and LFE) enabled. */
167
if (mix->upmix == CHANNELMIX_UPMIX_NONE)
168
keep = 0;
169
- keep |= FRONT;
170
+ if (mix->fc_cutoff > 0.0f)
171
+ keep |= FRONT;
172
+ else
173
+ keep &= ~FRONT;
174
if (mix->lfe_cutoff > 0.0f)
175
keep |= _MASK(LFE);
176
else
177
keep &= ~_MASK(LFE);
178
}
179
+ /* if we have no channel matched, try to upmix or keep the stereo
180
+ * pair or else we might end up with silence. */
181
+ if (dst_mask & STEREO && !matched)
182
+ keep |= STEREO;
183
+
184
+ spa_log_info(mix->log, "unassigned downmix %08" PRIx64 " %08" PRIx64, unassigned, keep);
185
+
186
+ if (unassigned & _MASK(MONO)) {
187
+ if ((dst_mask & STEREO) == STEREO) {
188
+ spa_log_info(mix->log, "assign MONO to STEREO (%f)", 1.0f);
189
+ _MATRIX(FL,MONO) += 1.0f;
190
+ _MATRIX(FR,MONO) += 1.0f;
191
+ keep &= ~STEREO;
192
+ } else if ((dst_mask & FRONT) == FRONT) {
193
+ spa_log_info(mix->log, "assign MONO to FRONT (%f)", 1.0f);
194
+ _MATRIX(FC,MONO) += 1.0f;
195
+ normalize = true;
196
+ } else {
197
+ spa_log_warn(mix->log, "can't assign MONO");
198
+ }
199
+ }
200
201
pipewire-0.3.65.tar.gz/spa/plugins/audioconvert/test-audioconvert.c -> pipewire-0.3.66.tar.gz/spa/plugins/audioconvert/test-audioconvert.c
Changed
22
1
2
#include <spa/node/node.h>
3
#include <spa/node/io.h>
4
#include <spa/debug/mem.h>
5
+#include <spa/debug/log.h>
6
#include <spa/support/log-impl.h>
7
8
SPA_LOG_IMPL(logger);
9
10
res = memcmp(b->datasj.data, out_data->datak, out_data->size);
11
if (res != 0) {
12
fprintf(stderr, "error port %d plane %d\n", i, j);
13
- spa_debug_mem(0, b->datasj.data, out_data->size);
14
- spa_debug_mem(0, out_data->datak, out_data->size);
15
+ spa_debug_log_mem(&logger.log, SPA_LOG_LEVEL_WARN,
16
+ 0, b->datasj.data, out_data->size);
17
+ spa_debug_log_mem(&logger.log, SPA_LOG_LEVEL_WARN,
18
+ 2, out_data->datak, out_data->size);
19
}
20
spa_assert_se(res == 0);
21
22
pipewire-0.3.65.tar.gz/spa/plugins/audioconvert/test-channelmix.c -> pipewire-0.3.66.tar.gz/spa/plugins/audioconvert/test-channelmix.c
Changed
135
1
2
mix.src_mask = src_mask;
3
mix.dst_mask = dst_mask;
4
mix.log = &logger.log;
5
+ mix.fc_cutoff = 120.0f;
6
+ mix.lfe_cutoff = 12000.0f;
7
8
spa_assert_se(channelmix_init(&mix) == 0);
9
channelmix_set_volume(&mix, 1.0f, false, 0, NULL);
10
11
test_mix(1, _M(MONO), 2, _M(FL)|_M(FR), 0,
12
MATRIX(1.0, 1.0));
13
test_mix(1, _M(MONO), 3, _M(FL)|_M(FR)|_M(LFE), 0,
14
+ MATRIX(1.0, 1.0, 0.0));
15
+ test_mix(1, _M(MONO), 3, _M(FL)|_M(FR)|_M(LFE), CHANNELMIX_OPTION_UPMIX,
16
MATRIX(1.0, 1.0, 1.0));
17
test_mix(1, _M(MONO), 4, _M(FL)|_M(FR)|_M(LFE)|_M(FC), 0,
18
+ MATRIX(1.0, 1.0, 0.0, 0.0));
19
+ test_mix(1, _M(MONO), 4, _M(FL)|_M(FR)|_M(LFE)|_M(FC), CHANNELMIX_OPTION_UPMIX,
20
MATRIX(1.0, 1.0, 1.0, 1.0));
21
test_mix(1, _M(MONO), 4, _M(FL)|_M(FR)|_M(RL)|_M(RR), 0,
22
- MATRIX(1.0, 1.0, 1.0, 1.0));
23
+ MATRIX(1.0, 1.0, 0.0, 0.0));
24
+ test_mix(1, _M(MONO), 4, _M(FL)|_M(FR)|_M(RL)|_M(RR), CHANNELMIX_OPTION_UPMIX,
25
+ MATRIX(1.0, 1.0, 0.0, 0.0));
26
test_mix(1, _M(MONO), 12, 0, 0,
27
MATRIX(1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
28
1.0, 1.0, 1.0, 1.0, 1.0, 1.0));
29
30
test_mix(1, _M(FC), 1, _M(FC), 0,
31
MATRIX(1.0));
32
test_mix(2, _M(FL)|_M(FR), 1, _M(MONO), 0,
33
- MATRIX(0.707107, 0.707107));
34
+ MATRIX(0.5, 0.5));
35
test_mix(12, 0, 1, _M(MONO), 0,
36
MATRIX(0.083333, 0.083333, 0.083333, 0.083333, 0.083333, 0.083333,
37
0.083333, 0.083333, 0.083333, 0.083333, 0.083333, 0.0833333));
38
}
39
40
+static void test_2_N(void)
41
+{
42
+ test_mix(2, _M(FL)|_M(FR), 1, _M(MONO), 0, MATRIX(0.5, 0.5));
43
+ test_mix(2, _M(FL)|_M(FR), 1, 0, 0, MATRIX(0.5, 0.5));
44
+ test_mix(2, _M(FL)|_M(FR), 2, 0, 0, MATRIX(1.0, 0.0, 0.0, 1.0));
45
+ test_mix(2, _M(FL)|_M(FR), 2, _M(MONO), 0, MATRIX(1.0, 0.0, 0.0, 1.0));
46
+ test_mix(2, _M(FL)|_M(FR), 2, _M(FL)|_M(FR), 0, MATRIX(1.0, 0.0, 0.0, 1.0));
47
+ test_mix(2, _M(FL)|_M(FR), 4, _M(FL)|_M(FR)|_M(LFE)|_M(FC), 0,
48
+ MATRIX(1.0, 0.0,
49
+ 0.0, 1.0,
50
+ 0.0, 0.0,
51
+ 0.0, 0.0));
52
+ test_mix(2, _M(FL)|_M(FR), 4, _M(FL)|_M(FR)|_M(LFE)|_M(FC), CHANNELMIX_OPTION_UPMIX,
53
+ MATRIX(1.0, 0.0,
54
+ 0.0, 1.0,
55
+ 0.707107, 0.707107,
56
+ 0.5, 0.5));
57
+ test_mix(2, _M(FL)|_M(FR), 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR), 0,
58
+ MATRIX(1.0, 0.0,
59
+ 0.0, 1.0,
60
+ 0.0, 0.0,
61
+ 0.0, 0.0,
62
+ 0.0, 0.0,
63
+ 0.0, 0.0));
64
+ test_mix(2, _M(FL)|_M(FR), 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR), CHANNELMIX_OPTION_UPMIX,
65
+ MATRIX(1.0, 0.0,
66
+ 0.0, 1.0,
67
+ 0.707107, 0.707107,
68
+ 0.5, 0.5,
69
+ 0.0, 0.0,
70
+ 0.0, 0.0));
71
+}
72
+
73
static void test_3p1_N(void)
74
{
75
test_mix(4, _M(FL)|_M(FR)|_M(LFE)|_M(FC), 1, _M(MONO), 0,
76
- MATRIX(0.707107, 0.707107, 1.0, 0.0));
77
+ MATRIX(0.333333, 0.333333, 0.333333, 0.0));
78
test_mix(4, _M(FL)|_M(FR)|_M(LFE)|_M(FC), 2, _M(FL)|_M(FR), 0,
79
MATRIX(1.0, 0.0, 0.707107, 0.0,
80
0.0, 1.0, 0.707107, 0.0 ));
81
82
static void test_4_N(void)
83
{
84
test_mix(4, _M(FL)|_M(FR)|_M(RL)|_M(RR), 1, _M(MONO), 0,
85
- MATRIX(0.707107, 0.707107, 0.5, 0.5));
86
+ MATRIX(0.25, 0.25, 0.25, 0.25));
87
test_mix(4, _M(FL)|_M(FR)|_M(SL)|_M(SR), 1, _M(MONO), 0,
88
- MATRIX(0.707107, 0.707107, 0.5, 0.5));
89
+ MATRIX(0.25, 0.25, 0.25, 0.25));
90
test_mix(4, _M(FL)|_M(FR)|_M(RL)|_M(RR), 2, _M(FL)|_M(FR), 0,
91
MATRIX(1.0, 0.0, 0.707107, 0.0,
92
0.0, 1.0, 0.0, 0.707107));
93
94
MATRIX(1.0, 0.0, 0.707107, 0.0,
95
0.0, 1.0, 0.0, 0.707107,
96
0.707107, 0.707107, 0.0, 0.0,
97
- 0.0, 0.0, 0.0, 0.0));
98
+ 0.5, 0.5, 0.0, 0.0));
99
}
100
101
static void test_5p1_N(void)
102
{
103
test_mix(6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR), 1, _M(MONO), 0,
104
- MATRIX(0.707107, 0.707107, 1.0, 0.0, 0.5, 0.5));
105
+ MATRIX(0.20, 0.20, 0.20, 0.0, 0.20, 0.20));
106
test_mix(6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR), 2, _M(FL)|_M(FR), 0,
107
MATRIX(1.0, 0.0, 0.707107, 0.0, 0.707107, 0.0,
108
0.0, 1.0, 0.707107, 0.0, 0.0, 0.707107));
109
110
static void test_6p1_N(void)
111
{
112
test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RC)|_M(SL)|_M(SR), 1, _M(MONO), 0,
113
- MATRIX(0.707107, 0.707107, 1.0, 0.0, 0.5, 0.5, 0.5));
114
+ MATRIX(0.166667, 0.166667, 0.166667, 0.0, 0.166667, 0.166667, 0.166667));
115
test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RC),
116
6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR), 0,
117
MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
118
119
static void test_7p1_N(void)
120
{
121
test_mix(8, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RL)|_M(RR), 1, _M(MONO), 0,
122
- MATRIX(0.707107, 0.707107, 1.0, 0.0, 0.5, 0.5, 0.5, 0.5));
123
+ MATRIX(0.142857, 0.142857, 0.142857, 0.0, 0.142857, 0.142857, 0.142857, 0.142857));
124
test_mix(8, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RL)|_M(RR), 2, _M(FL)|_M(FR), 0,
125
MATRIX(1.0, 0.0, 0.707107, 0.0, 0.707107, 0.0, 0.707107, 0.0,
126
0.0, 1.0, 0.707107, 0.0, 0.0, 0.707107, 0.0, 0.707107));
127
128
test_1_N_MONO();
129
test_1_N_FC();
130
test_N_1();
131
+ test_2_N();
132
test_3p1_N();
133
test_4_N();
134
test_5p1_N();
135
pipewire-0.3.65.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.66.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
201
1
2
3
/* A reference audio info for A2DP codec configuration. */
4
struct media_codec_audio_info default_audio_info;
5
-
6
- bool le_audio_supported;
7
};
8
9
/* Stream endpoints owned by BlueZ for each device */
10
11
return 0;
12
}
13
14
+static int adapter_media_update_props(struct spa_bt_adapter *adapter,
15
+ DBusMessageIter *props_iter,
16
+ DBusMessageIter *invalidated_iter)
17
+{
18
+ /* Handle org.bluez.Media1 interface properties of .Adapter1 objects */
19
+ struct spa_bt_monitor *monitor = adapter->monitor;
20
+
21
+ while (dbus_message_iter_get_arg_type(props_iter) != DBUS_TYPE_INVALID) {
22
+ DBusMessageIter it2;
23
+ const char *key;
24
+
25
+ dbus_message_iter_recurse(props_iter, &it0);
26
+ dbus_message_iter_get_basic(&it0, &key);
27
+ dbus_message_iter_next(&it0);
28
+ dbus_message_iter_recurse(&it0, &it1);
29
+
30
+ if (spa_streq(key, "SupportedUUIDs")) {
31
+ DBusMessageIter iter;
32
+
33
+ if (!check_iter_signature(&it1, "as"))
34
+ goto next;
35
+
36
+ dbus_message_iter_recurse(&it1, &iter);
37
+
38
+ while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
39
+ const char *uuid;
40
+
41
+ dbus_message_iter_get_basic(&iter, &uuid);
42
+
43
+ if (spa_streq(uuid, SPA_BT_UUID_BAP_SINK)) {
44
+ adapter->le_audio_supported = true;
45
+ spa_log_info(monitor->log, "Adapter %s: LE Audio supported",
46
+ adapter->path);
47
+ }
48
+ dbus_message_iter_next(&iter);
49
+ }
50
+ }
51
+ else
52
+ spa_log_debug(monitor->log, "media: unhandled key %s", key);
53
+
54
+next:
55
+ dbus_message_iter_next(props_iter);
56
+ }
57
+ return 0;
58
+}
59
+
60
static void adapter_update_devices(struct spa_bt_adapter *adapter)
61
{
62
struct spa_bt_monitor *monitor = adapter->monitor;
63
64
{
65
struct spa_bt_monitor *monitor = device->monitor;
66
struct spa_bt_remote_endpoint *ep;
67
+ enum spa_bt_profile codec_profile;
68
+ struct spa_bt_transport *t;
69
const struct { enum spa_bluetooth_audio_codec codec; uint32_t mask; } quirks = {
70
{ SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ, SPA_BT_FEATURE_SBC_XQ },
71
{ SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, SPA_BT_FEATURE_FASTSTREAM },
72
73
if (!is_media_codec_enabled(device->monitor, codec))
74
return false;
75
76
- if (!device->adapter->application_registered) {
77
+ if (!device->adapter->a2dp_application_registered && !codec->bap) {
78
/* Codec switching not supported: only plain SBC allowed */
79
- return (codec->codec_id == A2DP_CODEC_SBC && spa_streq(codec->name, "sbc"));
80
+ return (codec->codec_id == A2DP_CODEC_SBC && spa_streq(codec->name, "sbc") &&
81
+ device->adapter->legacy_endpoints_registered);
82
}
83
+ if (!device->adapter->bap_application_registered && codec->bap)
84
+ return false;
85
86
/* Check codec quirks */
87
for (i = 0; i < SPA_N_ELEMENTS(quirks); ++i) {
88
89
return false;
90
}
91
92
+ if (codec->bap)
93
+ codec_profile = sink ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_BAP_SOURCE;
94
+ else
95
+ codec_profile = sink ? SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
96
+
97
spa_list_for_each(ep, &device->remote_endpoint_list, device_link) {
98
const enum spa_bt_profile profile = spa_bt_profile_from_uuid(ep->uuid);
99
- enum spa_bt_profile expected;
100
101
- if (codec->bap)
102
- expected = sink ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_BAP_SOURCE;
103
- else
104
- expected = sink ? SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
105
-
106
- if (profile != expected)
107
+ if (profile != codec_profile)
108
continue;
109
110
if (media_codec_check_caps(codec, ep->codec, ep->capabilities, ep->capabilities_len,
111
112
return true;
113
}
114
115
+ /* Codecs on configured transports are always supported.
116
+ *
117
+ * Remote BAP endpoints correspond to capabilities of the remote
118
+ * BAP Server, not to remote BAP Client, and need not be the same.
119
+ * BAP Clients may not have any remote endpoints. In this case we
120
+ * can only know that the currently configured codec is supported.
121
+ */
122
+ spa_list_for_each(t, &device->transport_list, device_link) {
123
+ if (t->profile != codec_profile)
124
+ continue;
125
+
126
+ if (codec == t->media_codec)
127
+ return true;
128
+ }
129
+
130
return false;
131
}
132
133
134
const struct media_codec *preferred_codec = NULL;
135
size_t i, j, num_codecs, num_eps;
136
137
- if (!device->adapter->application_registered) {
138
+ if (!device->adapter->a2dp_application_registered &&
139
+ !device->adapter->bap_application_registered) {
140
/* Codec switching not supported */
141
return -ENOTSUP;
142
}
143
144
return res;
145
}
146
147
-static void bluez_register_endpoint_reply(DBusPendingCall *pending, void *user_data)
148
+static void bluez_register_endpoint_legacy_reply(DBusPendingCall *pending, void *user_data)
149
{
150
- struct spa_bt_monitor *monitor = user_data;
151
+ struct spa_bt_adapter *adapter = user_data;
152
+ struct spa_bt_monitor *monitor = adapter->monitor;
153
DBusMessage *r;
154
155
r = dbus_pending_call_steal_reply(pending);
156
157
goto finish;
158
}
159
160
+ adapter->legacy_endpoints_registered = true;
161
+
162
finish:
163
dbus_message_unref(r);
164
}
165
166
dbus_message_iter_close_container(dict, &dict_entry_it);
167
}
168
169
-static int bluez_register_endpoint(struct spa_bt_monitor *monitor,
170
- const char *path, enum spa_bt_media_direction direction,
171
+static int bluez_register_endpoint_legacy(struct spa_bt_adapter *adapter,
172
+ enum spa_bt_media_direction direction,
173
const char *uuid, const struct media_codec *codec)
174
{
175
+ struct spa_bt_monitor *monitor = adapter->monitor;
176
+ const char *path = adapter->path;
177
char *object_path = NULL;
178
DBusMessage *m;
179
DBusMessageIter object_it, dict_it;
180
181
dbus_message_iter_close_container(&object_it, &dict_it);
182
183
dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
184
- dbus_pending_call_set_notify(call, bluez_register_endpoint_reply, monitor, NULL);
185
+ dbus_pending_call_set_notify(call, bluez_register_endpoint_legacy_reply, adapter, NULL);
186
dbus_message_unref(m);
187
188
free(object_path);
189
190
return ret;
191
}
192
193
-static int adapter_register_endpoints(struct spa_bt_adapter *a)
194
+static int adapter_register_endpoints_legacy(struct spa_bt_adapter *a)
195
{
196
struct spa_bt_monitor *monitor = a->monitor;
197
const struct media_codec * const * const media_codecs = monitor->media_codecs;
198
int i;
199
int err = 0;
200
+ bool registered = false;
201
pipewire-0.3.65.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.66.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
136
1
2
return media_codec;
3
}
4
5
+static bool is_bap_client(struct impl *this)
6
+{
7
+ struct spa_bt_device *device = this->bt_dev;
8
+ struct spa_bt_transport *t;
9
+
10
+ spa_list_for_each(t, &device->transport_list, device_link) {
11
+ if (t->bap_initiator)
12
+ return true;
13
+ }
14
+
15
+ return false;
16
+}
17
+
18
+static bool can_bap_codec_switch(struct impl *this)
19
+{
20
+ if (!is_bap_client(this))
21
+ return false;
22
+
23
+ /* XXX: codec switching for source/duplex is not currently
24
+ * XXX: implemented properly. TODO: fix this
25
+ */
26
+ if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_BAP_SOURCE)
27
+ return false;
28
+
29
+ return true;
30
+}
31
+
32
static unsigned int get_hfp_codec(enum spa_bluetooth_audio_codec id)
33
{
34
switch (id) {
35
36
* A2DP/BAP: ensure there's a transport with the selected codec (0 means any).
37
* Don't try to switch codecs when the device is in the A2DP source role, since
38
* devices do not appear to like that.
39
+ *
40
+ * For BAP, only BAP client can configure the codec.
41
+ *
42
+ * XXX: codec switching also currently does not work in the duplex or
43
+ * XXX: source-only case, as it will only switch the sink, and we only
44
+ * XXX: list the sink codecs here. TODO: fix this
45
*/
46
- if ((profile == DEVICE_PROFILE_A2DP || profile == DEVICE_PROFILE_BAP)
47
- && !(this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE)) {
48
+ if ((profile == DEVICE_PROFILE_A2DP || (profile == DEVICE_PROFILE_BAP && can_bap_codec_switch(this)))
49
+ && !(this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE)) {
50
int ret;
51
const struct media_codec *codecs64;
52
53
54
if (profile == 0)
55
return NULL;
56
57
- if (!codec) {
58
- errno = EINVAL;
59
- return NULL;
60
- }
61
-
62
if (profile & (SPA_BT_PROFILE_BAP_SINK))
63
n_sink++;
64
if (profile & (SPA_BT_PROFILE_BAP_SOURCE))
65
66
67
name = spa_bt_profile_name(profile);
68
69
- media_codec = get_supported_media_codec(this, codec, &idx);
70
- if (media_codec == NULL) {
71
- errno = EINVAL;
72
+ /* If we can't codec switch, emit codecless profile */
73
+ if (current && !can_bap_codec_switch(this)) {
74
+ codec = 0;
75
+ index = get_index_from_profile(this, profile_index, codec);
76
+ } else if ((codec != 0) != can_bap_codec_switch(this)) {
77
+ errno = -EINVAL;
78
return NULL;
79
}
80
- name_and_codec = spa_aprintf("%s-%s", name, media_codec->name);
81
- name = name_and_codec;
82
- switch (profile) {
83
- case SPA_BT_PROFILE_BAP_SINK:
84
- desc_and_codec = spa_aprintf(_("High Fidelity Playback (BAP Sink, codec %s)"),
85
- media_codec->description);
86
- break;
87
- case SPA_BT_PROFILE_BAP_SOURCE:
88
- desc_and_codec = spa_aprintf(_("High Fidelity Input (BAP Source, codec %s)"),
89
- media_codec->description);
90
- break;
91
- default:
92
- desc_and_codec = spa_aprintf(_("High Fidelity Duplex (BAP Source/Sink, codec %s)"),
93
- media_codec->description);
94
+
95
+ if (codec) {
96
+ media_codec = get_supported_media_codec(this, codec, &idx);
97
+ if (media_codec == NULL) {
98
+ errno = EINVAL;
99
+ return NULL;
100
+ }
101
+ name_and_codec = spa_aprintf("%s-%s", name, media_codec->name);
102
+ name = name_and_codec;
103
+ switch (profile) {
104
+ case SPA_BT_PROFILE_BAP_SINK:
105
+ desc_and_codec = spa_aprintf(_("High Fidelity Playback (BAP Sink, codec %s)"),
106
+ media_codec->description);
107
+ break;
108
+ case SPA_BT_PROFILE_BAP_SOURCE:
109
+ desc_and_codec = spa_aprintf(_("High Fidelity Input (BAP Source, codec %s)"),
110
+ media_codec->description);
111
+ break;
112
+ default:
113
+ desc_and_codec = spa_aprintf(_("High Fidelity Duplex (BAP Source/Sink, codec %s)"),
114
+ media_codec->description);
115
+ }
116
+ desc = desc_and_codec;
117
+ priority = 128 + this->supported_codec_count - idx; /* order as in codec list */
118
+ } else {
119
+ switch (profile) {
120
+ case SPA_BT_PROFILE_BAP_SINK:
121
+ desc = _("High Fidelity Playback (BAP Sink)");
122
+ break;
123
+ case SPA_BT_PROFILE_BAP_SOURCE:
124
+ desc = _("High Fidelity Input (BAP Source)");
125
+ break;
126
+ default:
127
+ desc = _("High Fidelity Duplex (BAP Source/Sink)");
128
+ }
129
+ priority = 128;
130
}
131
- desc = desc_and_codec;
132
- priority = 128 + this->supported_codec_count - idx; /* order as in codec list */
133
break;
134
}
135
case DEVICE_PROFILE_HSP_HFP:
136
pipewire-0.3.65.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.66.tar.gz/spa/plugins/bluez5/defs.h
Changed
38
1
2
#define HFP_AUDIO_CODEC_CVSD 0x01
3
#define HFP_AUDIO_CODEC_MSBC 0x02
4
5
-#define MEDIA_OBJECT_MANAGER_PATH "/MediaEndpoint"
6
-#define A2DP_SINK_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/A2DPSink"
7
-#define A2DP_SOURCE_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/A2DPSource"
8
+#define A2DP_OBJECT_MANAGER_PATH "/MediaEndpoint"
9
+#define A2DP_SINK_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSink"
10
+#define A2DP_SOURCE_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSource"
11
12
-#define BAP_SINK_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/BAPSink"
13
-#define BAP_SOURCE_ENDPOINT MEDIA_OBJECT_MANAGER_PATH "/BAPSource"
14
+#define BAP_OBJECT_MANAGER_PATH "/MediaEndpointLE"
15
+#define BAP_SINK_ENDPOINT BAP_OBJECT_MANAGER_PATH "/BAPSink"
16
+#define BAP_SOURCE_ENDPOINT BAP_OBJECT_MANAGER_PATH "/BAPSource"
17
18
#define SPA_BT_UNKNOWN_DELAY 0
19
20
21
int powered;
22
unsigned int has_msbc:1;
23
unsigned int msbc_probed:1;
24
- unsigned int endpoints_registered:1;
25
- unsigned int application_registered:1;
26
+ unsigned int legacy_endpoints_registered:1;
27
+ unsigned int a2dp_application_registered:1;
28
+ unsigned int bap_application_registered:1;
29
unsigned int player_registered:1;
30
unsigned int has_battery_provider:1;
31
unsigned int battery_provider_unavailable:1;
32
+ unsigned int le_audio_supported:1;
33
+ unsigned int has_adapter1_interface:1;
34
+ unsigned int has_media1_interface:1;
35
};
36
37
enum spa_bt_form_factor {
38
pipewire-0.3.65.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.66.tar.gz/spa/plugins/bluez5/meson.build
Changed
14
1
2
gnome = import('gnome')
3
4
-bluez5_deps = mathlib, dbus_dep, glib2_dep, sbc_dep, bluez_dep, gio_dep, gio_unix_dep
5
-foreach dep: bluez5_deps
6
- if not dep.found()
7
- subdir_done()
8
- endif
9
-endforeach
10
-
11
cdata.set('HAVE_BLUEZ_5_BACKEND_NATIVE',
12
get_option('bluez5-backend-hsp-native').allowed() or
13
get_option('bluez5-backend-hfp-native').allowed())
14
pipewire-0.3.65.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp -> pipewire-0.3.66.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp
Changed
86
1
2
#include <limits.h>
3
4
#include <linux/media.h>
5
+#include <libcamera/control_ids.h>
6
7
int spa_libcamera_open(struct impl *impl)
8
{
9
10
11
}
12
13
+static struct {
14
+ uint32_t id;
15
+ uint32_t spa_id;
16
+} control_map = {
17
+ { libcamera::controls::BRIGHTNESS, SPA_PROP_brightness },
18
+ { libcamera::controls::CONTRAST, SPA_PROP_contrast },
19
+ { libcamera::controls::SATURATION, SPA_PROP_saturation },
20
+ { libcamera::controls::EXPOSURE_TIME, SPA_PROP_exposure },
21
+ { libcamera::controls::ANALOGUE_GAIN, SPA_PROP_gain },
22
+ { libcamera::controls::SHARPNESS, SPA_PROP_sharpness },
23
+};
24
+
25
+static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id)
26
+{
27
+ SPA_FOR_EACH_ELEMENT_VAR(control_map, c) {
28
+ if (c->id == control_id)
29
+ return c->spa_id;
30
+ }
31
+ return SPA_PROP_START_CUSTOM + control_id;
32
+}
33
+
34
+static uint32_t prop_id_to_control(struct impl *impl, uint32_t prop_id)
35
+{
36
+ SPA_FOR_EACH_ELEMENT_VAR(control_map, c) {
37
+ if (c->spa_id == prop_id)
38
+ return c->id;
39
+ }
40
+ if (prop_id >= SPA_PROP_START_CUSTOM)
41
+ return prop_id - SPA_PROP_START_CUSTOM;
42
+ return SPA_ID_INVALID;
43
+}
44
+
45
static int
46
spa_libcamera_enum_controls(struct impl *impl, struct port *port, int seq,
47
uint32_t start, uint32_t num,
48
49
struct spa_pod_frame f2;
50
struct spa_result_node_params result;
51
struct spa_pod *ctrl;
52
- uint32_t count = 0, skip;
53
+ uint32_t count = 0, skip, id;
54
int res;
55
const ControlId *ctrl_id;
56
ControlInfo ctrl_info;
57
58
ctrl_id = it->first;
59
ctrl_info = it->second;
60
61
+ id = control_to_prop_id(impl, ctrl_id->id());
62
+
63
spa_pod_builder_init(&b, buffer, sizeof(buffer));
64
spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo);
65
spa_pod_builder_add(&b,
66
- SPA_PROP_INFO_id, SPA_POD_Id(ctrl_id->id()),
67
+ SPA_PROP_INFO_id, SPA_POD_Id(id),
68
SPA_PROP_INFO_description, SPA_POD_String(ctrl_id->name().c_str()),
69
0);
70
71
72
const ControlId *ctrl_id;
73
int res;
74
struct val d;
75
+ uint32_t control_id;
76
+
77
+ control_id = prop_id_to_control(impl, prop->key);
78
+ if (control_id == SPA_ID_INVALID)
79
+ return -ENOENT;
80
81
- auto v = info.idmap().find(prop->key);
82
+ auto v = info.idmap().find(control_id);
83
if (v == info.idmap().end())
84
return -ENOENT;
85
86
pipewire-0.3.65.tar.gz/spa/plugins/libcamera/meson.build -> pipewire-0.3.66.tar.gz/spa/plugins/libcamera/meson.build
Changed
20
1
2
'libcamera-source.cpp'
3
4
5
-libdrm_dep = dependency('libdrm', version : '>= 2.4.98',
6
- required : get_option('libcamera'))
7
-summary({'libdrm': libdrm_dep.found()}, bool_yn: true, section: 'Backend')
8
-if libdrm_dep.found()
9
- libcameralib = shared_library('spa-libcamera',
10
- libcamera_sources,
11
- dependencies : spa_dep, libudev_dep, libcamera_dep, pthread_lib, libdrm_dep ,
12
- install : true,
13
- install_dir : spa_plugindir / 'libcamera')
14
-endif
15
+libcameralib = shared_library('spa-libcamera',
16
+ libcamera_sources,
17
+ dependencies : spa_dep, libudev_dep, libcamera_dep, pthread_lib ,
18
+ install : true,
19
+ install_dir : spa_plugindir / 'libcamera')
20
pipewire-0.3.65.tar.gz/spa/plugins/support/journal.c -> pipewire-0.3.66.tar.gz/spa/plugins/support/journal.c
Changed
20
1
2
* DEALINGS IN THE SOFTWARE.
3
*/
4
5
+#include "config.h"
6
+
7
#include <stddef.h>
8
#include <unistd.h>
9
#include <string.h>
10
11
sd_journal_send_with_location(file_buffer, line_buffer, func,
12
"MESSAGE=%s", message_buffer,
13
"PRIORITY=%i", priority,
14
+#ifdef HAVE_GETTID
15
+ "TID=%jd", (intmax_t) gettid(),
16
+#endif
17
NULL);
18
}
19
20
pipewire-0.3.65.tar.gz/spa/plugins/support/meson.build -> pipewire-0.3.66.tar.gz/spa/plugins/support/meson.build
Changed
18
1
2
spa_support_lib = shared_library('spa-support',
3
spa_support_sources,
4
c_args : simd_cargs ,
5
- dependencies : spa_dep, pthread_lib, epoll_shim_dep ,
6
+ dependencies : spa_dep, pthread_lib, epoll_shim_dep, mathlib ,
7
install : true,
8
install_dir : spa_plugindir / 'support')
9
spa_support_dep = declare_dependency(link_with: spa_support_lib)
10
11
12
spa_journal_lib = shared_library('spa-journal',
13
spa_journal_sources,
14
+ include_directories : configinc ,
15
dependencies : spa_dep, systemd_dep ,
16
install : true,
17
install_dir : spa_plugindir / 'support')
18
pipewire-0.3.65.tar.gz/spa/plugins/support/node-driver.c -> pipewire-0.3.66.tar.gz/spa/plugins/support/node-driver.c
Changed
201
1
2
#include <unistd.h>
3
#include <string.h>
4
#include <stdio.h>
5
+#include <fcntl.h>
6
7
#include <spa/support/plugin.h>
8
#include <spa/support/log.h>
9
10
#include <spa/utils/names.h>
11
#include <spa/utils/result.h>
12
#include <spa/utils/string.h>
13
+#include <spa/utils/dll.h>
14
#include <spa/node/node.h>
15
#include <spa/node/keys.h>
16
#include <spa/node/io.h>
17
18
#define NAME "driver"
19
20
#define DEFAULT_FREEWHEEL false
21
-#define DEFAULT_CLOCK_NAME "clock.system.monotonic"
22
+#define DEFAULT_CLOCK_PREFIX "clock.system"
23
+#define DEFAULT_CLOCK_ID CLOCK_MONOTONIC
24
+
25
+#define CLOCKFD 3
26
+#define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD)
27
+#define CLOCKID_TO_FD(clk) ((unsigned int) ~((clk) >> 3))
28
+
29
+#define BW_PERIOD (3 * SPA_NSEC_PER_SEC)
30
+#define MAX_ERROR_MS 1
31
32
struct props {
33
bool freewheel;
34
char clock_name64;
35
+ clockid_t clock_id;
36
};
37
38
struct impl {
39
40
41
struct spa_source timer_source;
42
struct itimerspec timerspec;
43
+ int clock_fd;
44
45
bool started;
46
bool following;
47
+ bool tracking;
48
+ clockid_t timer_clockid;
49
uint64_t next_time;
50
+ uint64_t last_time;
51
+ uint64_t base_time;
52
+ struct spa_dll dll;
53
+ double max_error;
54
};
55
56
static void reset_props(struct props *props)
57
{
58
props->freewheel = DEFAULT_FREEWHEEL;
59
- spa_scnprintf(props->clock_name, sizeof(props->clock_name),
60
- "%s", DEFAULT_CLOCK_NAME);
61
+ spa_zero(props->clock_name);
62
+ props->clock_id = CLOCK_MONOTONIC;
63
}
64
65
+static const struct clock_info {
66
+ const char *name;
67
+ clockid_t id;
68
+} clock_info = {
69
+ { "realtime", CLOCK_REALTIME },
70
+ { "tai", CLOCK_TAI },
71
+ { "monotonic", CLOCK_MONOTONIC },
72
+ { "monotonic-raw", CLOCK_MONOTONIC_RAW },
73
+ { "boottime", CLOCK_BOOTTIME },
74
+};
75
+
76
+static bool clock_for_timerfd(clockid_t id)
77
+{
78
+ return id == CLOCK_REALTIME ||
79
+ id == CLOCK_MONOTONIC ||
80
+ id == CLOCK_BOOTTIME;
81
+}
82
+
83
+static clockid_t clock_name_to_id(const char *name)
84
+{
85
+ SPA_FOR_EACH_ELEMENT_VAR(clock_info, i) {
86
+ if (spa_streq(i->name, name))
87
+ return i->id;
88
+ }
89
+ return -1;
90
+}
91
+static const char *clock_id_to_name(clockid_t id)
92
+{
93
+ SPA_FOR_EACH_ELEMENT_VAR(clock_info, i) {
94
+ if (i->id == id)
95
+ return i->name;
96
+ }
97
+ return "custom";
98
+}
99
+
100
+
101
static void set_timeout(struct impl *this, uint64_t next_time)
102
{
103
spa_log_trace(this->log, "set timeout %"PRIu64, next_time);
104
105
this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &this->timerspec, NULL);
106
}
107
108
+static inline uint64_t gettime_nsec(struct impl *this, clockid_t clock_id)
109
+{
110
+ struct timespec now = { 0 };
111
+ uint64_t nsec;
112
+ if (spa_system_clock_gettime(this->data_system, clock_id, &now) < 0)
113
+ return 0;
114
+ nsec = SPA_TIMESPEC_TO_NSEC(&now);
115
+ spa_log_trace(this->log, "%p now:%"PRIu64, this, nsec);
116
+ return nsec;
117
+}
118
+
119
static int set_timers(struct impl *this)
120
{
121
- struct timespec now;
122
- int res;
123
+ this->next_time = gettime_nsec(this, this->timer_clockid);
124
125
- if ((res = spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &now)) < 0)
126
- return res;
127
- this->next_time = SPA_TIMESPEC_TO_NSEC(&now);
128
+ spa_log_debug(this->log, "%p now:%"PRIu64, this, this->next_time);
129
130
if (this->following) {
131
set_timeout(this, 0);
132
133
return 0;
134
}
135
136
+static inline uint64_t scale_u64(uint64_t val, uint32_t num, uint32_t denom)
137
+{
138
+#if 0
139
+ return ((__uint128_t)val * num) / denom;
140
+#else
141
+ return (double)val / denom * num;
142
+#endif
143
+}
144
+
145
static void on_timeout(struct spa_source *source)
146
{
147
struct impl *this = source->data;
148
- uint64_t expirations, nsec, duration;
149
+ uint64_t expirations, nsec, duration, current_time, current_position, position;
150
uint32_t rate;
151
+ double corr = 1.0, err = 0.0;
152
int res;
153
154
- spa_log_trace(this->log, "timeout");
155
-
156
if ((res = spa_system_timerfd_read(this->data_system,
157
this->timer_source.fd, &expirations)) < 0) {
158
if (res != EAGAIN)
159
160
this, spa_strerror(res));
161
return;
162
}
163
-
164
- nsec = this->next_time;
165
-
166
if (SPA_LIKELY(this->position)) {
167
duration = this->position->clock.duration;
168
rate = this->position->clock.rate.denom;
169
170
duration = 1024;
171
rate = 48000;
172
}
173
+ nsec = this->next_time;
174
+
175
+ if (this->tracking)
176
+ /* we are actually following another clock */
177
+ current_time = gettime_nsec(this, this->props.clock_id);
178
+ else
179
+ current_time = nsec;
180
+
181
+ current_position = scale_u64(current_time, rate, SPA_NSEC_PER_SEC);
182
+
183
+ if (SPA_LIKELY(this->clock))
184
+ position = this->clock->position;
185
+ else
186
+ position = current_position;
187
+
188
+ if (this->last_time == 0) {
189
+ spa_dll_set_bw(&this->dll, SPA_DLL_BW_MIN, duration, rate);
190
+ this->max_error = rate * MAX_ERROR_MS / 1000;
191
+ position = current_position;
192
+ }
193
194
- this->next_time = nsec + duration * SPA_NSEC_PER_SEC / rate;
195
+ /* check the elapsed time of the other clock against
196
+ * the graph clock elapsed time, feed this error into the
197
+ * dll and adjust the timeout of our MONOTONIC clock. */
198
+ err = (double)position - (double)current_position;
199
+ if (err > this->max_error)
200
+ err = this->max_error;
201
pipewire-0.3.65.tar.gz/src/daemon/client-rt.conf.in -> pipewire-0.3.66.tar.gz/src/daemon/client-rt.conf.in
Changed
13
1
2
3
context.modules =
4
#{ name = <module-name>
5
- # args = { <key> = <value> ... }
6
- # flags = ifexists nofail
7
+ # ( args = { <key> = <value> ... } )
8
+ # ( flags = ( ifexists ) ( nofail ) )
9
+ # ( condition = { <key> = <value> ... } ... )
10
#}
11
#
12
# Loads a module with the given parameters.
13
pipewire-0.3.65.tar.gz/src/daemon/client.conf.in -> pipewire-0.3.66.tar.gz/src/daemon/client.conf.in
Changed
13
1
2
3
context.modules =
4
#{ name = <module-name>
5
- # args = { <key> = <value> ... }
6
- # flags = ifexists nofail
7
+ # ( args = { <key> = <value> ... } )
8
+ # ( flags = ( ifexists ) ( nofail ) )
9
+ # ( condition = { <key> = <value> ... } ... )
10
#}
11
#
12
# Loads a module with the given parameters.
13
pipewire-0.3.65.tar.gz/src/daemon/filter-chain.conf.in -> pipewire-0.3.66.tar.gz/src/daemon/filter-chain.conf.in
Changed
13
1
2
3
context.modules =
4
#{ name = <module-name>
5
- # args = { <key> = <value> ... }
6
- # flags = ifexists nofail
7
+ # ( args = { <key> = <value> ... } )
8
+ # ( flags = ( ifexists ) ( nofail ) )
9
+ # ( condition = { <key> = <value> ... } ... )
10
#}
11
#
12
# Loads a module with the given parameters.
13
pipewire-0.3.66.tar.gz/src/daemon/filter-chain/spatializer-7.1.conf
Added
159
1
2
+# Headphone surround sink
3
+#
4
+# Copy this file into a conf.d/ directory such as
5
+# ~/.config/pipewire/filter-chain.conf.d/
6
+#
7
+context.modules =
8
+ { name = libpipewire-module-filter-chain
9
+ args = {
10
+ node.description = "Spatial Sink"
11
+ media.name = "Spatial Sink"
12
+ filter.graph = {
13
+ nodes =
14
+ {
15
+ type = sofa
16
+ label = spatializer
17
+ name = spFL
18
+ config = {
19
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
20
+ }
21
+ control = {
22
+ "Azimuth" = 30.0
23
+ "Elevation" = 0.0
24
+ "Radius" = 3.0
25
+ }
26
+ }
27
+ {
28
+ type = sofa
29
+ label = spatializer
30
+ name = spFR
31
+ config = {
32
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
33
+ }
34
+ control = {
35
+ "Azimuth" = 330.0
36
+ "Elevation" = 0.0
37
+ "Radius" = 3.0
38
+ }
39
+ }
40
+ {
41
+ type = sofa
42
+ label = spatializer
43
+ name = spFC
44
+ config = {
45
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
46
+ }
47
+ control = {
48
+ "Azimuth" = 0.0
49
+ "Elevation" = 0.0
50
+ "Radius" = 3.0
51
+ }
52
+ }
53
+ {
54
+ type = sofa
55
+ label = spatializer
56
+ name = spRL
57
+ config = {
58
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
59
+ }
60
+ control = {
61
+ "Azimuth" = 150.0
62
+ "Elevation" = 0.0
63
+ "Radius" = 3.0
64
+ }
65
+ }
66
+ {
67
+ type = sofa
68
+ label = spatializer
69
+ name = spRR
70
+ config = {
71
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
72
+ }
73
+ control = {
74
+ "Azimuth" = 210.0
75
+ "Elevation" = 0.0
76
+ "Radius" = 3.0
77
+ }
78
+ }
79
+ {
80
+ type = sofa
81
+ label = spatializer
82
+ name = spSL
83
+ config = {
84
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
85
+ }
86
+ control = {
87
+ "Azimuth" = 90.0
88
+ "Elevation" = 0.0
89
+ "Radius" = 3.0
90
+ }
91
+ }
92
+ {
93
+ type = sofa
94
+ label = spatializer
95
+ name = spSR
96
+ config = {
97
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
98
+ }
99
+ control = {
100
+ "Azimuth" = 270.0
101
+ "Elevation" = 0.0
102
+ "Radius" = 3.0
103
+ }
104
+ }
105
+ {
106
+ type = sofa
107
+ label = spatializer
108
+ name = spLFE
109
+ config = {
110
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
111
+ }
112
+ control = {
113
+ "Azimuth" = 0.0
114
+ "Elevation" = -60.0
115
+ "Radius" = 3.0
116
+ }
117
+ }
118
+
119
+ { type = builtin label = mixer name = mixL }
120
+ { type = builtin label = mixer name = mixR }
121
+
122
+ links =
123
+ # output
124
+ { output = "spFL:Out L" input="mixL:In 1" }
125
+ { output = "spFL:Out R" input="mixR:In 1" }
126
+ { output = "spFR:Out L" input="mixL:In 2" }
127
+ { output = "spFR:Out R" input="mixR:In 2" }
128
+ { output = "spFC:Out L" input="mixL:In 3" }
129
+ { output = "spFC:Out R" input="mixR:In 3" }
130
+ { output = "spRL:Out L" input="mixL:In 4" }
131
+ { output = "spRL:Out R" input="mixR:In 4" }
132
+ { output = "spRR:Out L" input="mixL:In 5" }
133
+ { output = "spRR:Out R" input="mixR:In 5" }
134
+ { output = "spSL:Out L" input="mixL:In 6" }
135
+ { output = "spSL:Out R" input="mixR:In 6" }
136
+ { output = "spSR:Out L" input="mixL:In 7" }
137
+ { output = "spSR:Out R" input="mixR:In 7" }
138
+ { output = "spLFE:Out L" input="mixL:In 8" }
139
+ { output = "spLFE:Out R" input="mixR:In 8" }
140
+
141
+ inputs = "spFL:In" "spFR:In" "spFC:In" "spLFE:In" "spRL:In" "spRR:In", "spSL:In", "spSR:In"
142
+ outputs = "mixL:Out" "mixR:Out"
143
+ }
144
+ capture.props = {
145
+ node.name = "effect_input.spatializer"
146
+ media.class = Audio/Sink
147
+ audio.channels = 8
148
+ audio.position = FL FR FC LFE RL RR SL SR
149
+ }
150
+ playback.props = {
151
+ node.name = "effect_output.spatializer"
152
+ node.passive = true
153
+ audio.channels = 2
154
+ audio.position = FL FR
155
+ }
156
+ }
157
+ }
158
+
159
pipewire-0.3.66.tar.gz/src/daemon/filter-chain/spatializer-single.conf
Added
47
1
2
+# A virtual sound source sink
3
+# Useful for testing spatial effects by moving it around with controls
4
+#
5
+# Copy this file into a conf.d/ directory such as
6
+# ~/.config/pipewire/filter-chain.conf.d/
7
+#
8
+context.modules =
9
+ { name = libpipewire-module-filter-chain
10
+ args = {
11
+ node.description = "3D Sink"
12
+ media.name = "3D Sink"
13
+ filter.graph = {
14
+ nodes =
15
+ {
16
+ type = sofa
17
+ label = spatializer
18
+ name = sp
19
+ config = {
20
+ filename = "~/.config/hrtf-sofa/hrtf b_nh724.sofa"
21
+ }
22
+ control = {
23
+ "Azimuth" = 220.0
24
+ "Elevation" = 0.0
25
+ "Radius" = 3.0
26
+ }
27
+ }
28
+
29
+ inputs = "sp:In"
30
+ outputs = "sp:Out L" "sp:Out R"
31
+ }
32
+ capture.props = {
33
+ node.name = "effect_input.3d"
34
+ media.class = Audio/Sink
35
+ audio.channels = 1
36
+ audio.position = FC
37
+ }
38
+ playback.props = {
39
+ node.name = "effect_output.3d"
40
+ node.passive = true
41
+ audio.channels = 2
42
+ audio.position = FL FR
43
+ }
44
+ }
45
+ }
46
+
47
pipewire-0.3.65.tar.gz/src/daemon/jack.conf.in -> pipewire-0.3.66.tar.gz/src/daemon/jack.conf.in
Changed
13
1
2
3
context.modules =
4
#{ name = <module-name>
5
- # args = { <key> = <value> ... }
6
- # flags = ifexists nofail
7
+ # ( args = { <key> = <value> ... } )
8
+ # ( flags = ( ifexists ) ( nofail ) )
9
+ # ( condition = { <key> = <value> ... } ... )
10
#}
11
#
12
# Loads a module with the given parameters.
13
pipewire-0.3.65.tar.gz/src/daemon/meson.build -> pipewire-0.3.66.tar.gz/src/daemon/meson.build
Changed
24
1
2
'minimal.conf',
3
'pipewire-pulse.conf',
4
'pipewire-avb.conf',
5
+ 'pipewire-aes67.conf',
6
7
8
foreach c : conf_files
9
10
dependencies : spa_dep, pipewire_dep, ,
11
)
12
13
+executable('pipewire-aes67',
14
+ pipewire_daemon_sources,
15
+ install: true,
16
+ c_args : pipewire_c_args,
17
+ include_directories : configinc ,
18
+ dependencies : spa_dep, pipewire_dep, ,
19
+)
20
+
21
ln = find_program('ln')
22
23
custom_target('pipewire-uninstalled',
24
pipewire-0.3.65.tar.gz/src/daemon/minimal.conf.in -> pipewire-0.3.66.tar.gz/src/daemon/minimal.conf.in
Changed
37
1
2
3
context.modules =
4
#{ name = <module-name>
5
- # args = { <key> = <value> ... }
6
- # flags = ifexists nofail
7
+ # ( args = { <key> = <value> ... } )
8
+ # ( flags = ( ifexists ) ( nofail ) )
9
+ # ( condition = { <key> = <value> ... } ... )
10
#}
11
#
12
# Loads a module with the given parameters.
13
14
15
context.objects =
16
#{ factory = <factory-name>
17
- # args = { <key> = <value> ... }
18
- # flags = nofail
19
+ # ( args = { <key> = <value> ... } )
20
+ # ( flags = ( nofail ) )
21
+ # ( condition = { <key> = <value> ... } ... )
22
#}
23
#
24
# Creates an object from a PipeWire factory with the given parameters.
25
26
27
28
context.exec =
29
- #{ path = <program-name> args = "<arguments>" }
30
+ #{ path = <program-name>
31
+ # ( args = "<arguments>" )
32
+ # ( condition = { <key> = <value> ... } ... )
33
+ #}
34
#
35
# Execute the given program with arguments.
36
#
37
pipewire-0.3.66.tar.gz/src/daemon/pipewire-aes67.conf.in
Added
54
1
2
+# AES67 config file for PipeWire version @VERSION@ #
3
+#
4
+# Copy and edit this file in @PIPEWIRE_CONFIG_DIR@ for system-wide changes
5
+# or in ~/.config/pipewire for local changes.
6
+#
7
+# It is also possible to place a file with an updated section in
8
+# @PIPEWIRE_CONFIG_DIR@/pipewire-aes67.conf.d/ for system-wide changes or in
9
+# ~/.config/pipewire/pipewire-aes67.conf.d/ for local changes.
10
+#
11
+
12
+context.properties = {
13
+ ## Configure properties in the system.
14
+ #mem.warn-mlock = false
15
+ #mem.allow-mlock = true
16
+ #mem.mlock-all = false
17
+ #log.level = 2
18
+
19
+ #default.clock.quantum-limit = 8192
20
+}
21
+
22
+#context.spa-libs = {
23
+# audio.convert.* = audioconvert/libspa-audioconvert
24
+# support.* = support/libspa-support
25
+#}
26
+
27
+context.modules =
28
+ { name = libpipewire-module-rt
29
+ args = {
30
+ nice.level = -11
31
+ #rt.prio = 88
32
+ #rt.time.soft = -1
33
+ #rt.time.hard = -1
34
+ }
35
+ flags = ifexists nofail
36
+ }
37
+ { name = libpipewire-module-protocol-native }
38
+ { name = libpipewire-module-client-node }
39
+ { name = libpipewire-module-adapter }
40
+ { name = libpipewire-module-rtp-source
41
+ args = {
42
+ sap.ip = 239.255.255.255
43
+ sap.port = 9875
44
+ sess.latency.msec = 10
45
+ local.ifname = eth0
46
+ stream.props = {
47
+ media.class = "Audio/Source"
48
+ node.virtual = false
49
+ device.api = aes67
50
+ }
51
+ }
52
+ }
53
+
54
pipewire-0.3.65.tar.gz/src/daemon/pipewire-pulse.conf.in -> pipewire-0.3.66.tar.gz/src/daemon/pipewire-pulse.conf.in
Changed
15
1
2
# Extra commands can be executed here.
3
# load-module : loads a module with args and flags
4
# args = "<module-name> <module-args>"
5
-# flags = "no-fail"
6
+# ( flags = nofail )
7
pulse.cmd =
8
{ cmd = "load-module" args = "module-always-sink" flags = }
9
#{ cmd = "load-module" args = "module-switch-on-connect" }
10
- #{ cmd = "load-module" args = "module-gsettings" flags = "nofail" }
11
+ #{ cmd = "load-module" args = "module-gsettings" flags = nofail }
12
13
14
stream.properties = {
15
pipewire-0.3.65.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.66.tar.gz/src/daemon/pipewire.conf.in
Changed
109
1
2
#default.clock.rate = 48000
3
#default.clock.allowed-rates = 48000
4
#default.clock.quantum = 1024
5
- default.clock.min-quantum = 16
6
+ #default.clock.min-quantum = 32
7
#default.clock.max-quantum = 2048
8
#default.clock.quantum-limit = 8192
9
#default.video.width = 640
10
11
vm.overrides = {
12
default.clock.min-quantum = 1024
13
}
14
+
15
+ # keys checked below to disable module loading
16
+ module.x11.bell = true
17
}
18
19
context.spa-libs = {
20
21
22
context.modules =
23
#{ name = <module-name>
24
- # args = { <key> = <value> ... }
25
- # flags = ifexists nofail
26
+ # ( args = { <key> = <value> ... } )
27
+ # ( flags = ( ifexists ) ( nofail ) )
28
+ # ( condition = { <key> = <value> ... } ... )
29
#}
30
#
31
# Loads a module with the given parameters.
32
# If ifexists is given, the module is ignored when it is not found.
33
# If nofail is given, module initialization failures are ignored.
34
+ # If condition is given, the module is loaded only when the context
35
+ # properties all match the match rules.
36
#
37
38
# Uses realtime scheduling to boost the audio thread priorities. This uses
39
40
#x11.xauthority = null
41
}
42
flags = ifexists nofail
43
+ condition = { module.x11.bell = true }
44
}
45
46
47
context.objects =
48
#{ factory = <factory-name>
49
- # args = { <key> = <value> ... }
50
- # flags = nofail
51
+ # ( args = { <key> = <value> ... } )
52
+ # ( flags = ( nofail ) )
53
+ # ( condition = { <key> = <value> ... } ... )
54
#}
55
#
56
# Creates an object from a PipeWire factory with the given parameters.
57
# If nofail is given, errors are ignored (and no object is created).
58
+ # If condition is given, the object is created only when the context properties
59
+ # all match the match rules.
60
#
61
#{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
62
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = nofail }
63
64
node.name = Dummy-Driver
65
node.group = pipewire.dummy
66
priority.driver = 20000
67
+ #clock.id = monotonic # realtime | tai | monotonic-raw | boottime
68
+ #clock.name = "clock.system.monotonic"
69
}
70
}
71
{ factory = spa-node-factory
72
73
node.freewheel = true
74
}
75
}
76
+ # An example clock reading from /dev/ptp0. Another option is to sync the
77
+ # ptp clock to CLOCK_TAI and then set clock.id = tai.
78
+ #{ factory = spa-node-factory
79
+ # args = {
80
+ # factory.name = support.node.driver
81
+ # node.name = PTP0-Driver
82
+ # node.group = pipewire.ptp0
83
+ # priority.driver = 30000
84
+ # clock.name = "clock.system.ptp0"
85
+ # #clock.id = tai
86
+ # clock.device = "/dev/ptp0"
87
+ # }
88
+ #}
89
+
90
# This creates a new Source node. It will have input ports
91
# that you can link, to provide audio for this source.
92
#{ factory = adapter
93
94
95
96
context.exec =
97
- #{ path = <program-name> args = "<arguments>" }
98
+ #{ path = <program-name>
99
+ # ( args = "<arguments>" )
100
+ # ( condition = { <key> = <value> ... } ... )
101
+ #}
102
#
103
# Execute the given program with arguments.
104
+ # If condition is given, the program is executed only when the context
105
+ # properties all match the match rules.
106
#
107
# You can optionally start the session manager here,
108
# but it is better to start it as a systemd service.
109
pipewire-0.3.65.tar.gz/src/gst/gstpipewirepool.c -> pipewire-0.3.66.tar.gz/src/gst/gstpipewirepool.c
Changed
69
1
2
gst_buffer_insert_memory (buf, i, gmem);
3
}
4
5
+ if (pool->add_metavideo) {
6
+ gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
7
+ GST_VIDEO_INFO_FORMAT (&pool->video_info),
8
+ GST_VIDEO_INFO_WIDTH (&pool->video_info),
9
+ GST_VIDEO_INFO_HEIGHT (&pool->video_info),
10
+ GST_VIDEO_INFO_N_PLANES (&pool->video_info),
11
+ pool->video_info.offset,
12
+ pool->video_info.stride);
13
+ }
14
+
15
data->pool = gst_object_ref (pool);
16
data->owner = NULL;
17
data->header = spa_buffer_find_meta_data (b->buffer, SPA_META_Header, sizeof(*data->header));
18
19
}
20
}
21
22
+static const gchar **
23
+get_options (GstBufferPool * pool)
24
+{
25
+ static const gchar *options = { GST_BUFFER_POOL_OPTION_VIDEO_META, NULL };
26
+ return options;
27
+}
28
+
29
+static gboolean
30
+set_config (GstBufferPool * pool, GstStructure * config)
31
+{
32
+ GstPipeWirePool *p = GST_PIPEWIRE_POOL (pool);
33
+ GstCaps *caps;
34
+ guint size, min_buffers, max_buffers;
35
+ gboolean has_video;
36
+
37
+ if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers)) {
38
+ GST_WARNING_OBJECT (pool, "invalid config");
39
+ return FALSE;
40
+ }
41
+
42
+ if (caps == NULL) {
43
+ GST_WARNING_OBJECT (pool, "no caps in config");
44
+ return FALSE;
45
+ }
46
+
47
+ has_video = gst_video_info_from_caps (&p->video_info, caps);
48
+
49
+ p->add_metavideo = has_video && gst_buffer_pool_config_has_option (config,
50
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
51
+
52
+ gst_buffer_pool_config_set_params (config, caps, p->video_info.size, min_buffers, max_buffers);
53
+
54
+ return GST_BUFFER_POOL_CLASS (gst_pipewire_pool_parent_class)->set_config (pool, config);
55
+}
56
+
57
static void
58
flush_start (GstBufferPool * pool)
59
{
60
61
62
gobject_class->finalize = gst_pipewire_pool_finalize;
63
64
+ bufferpool_class->get_options = get_options;
65
+ bufferpool_class->set_config = set_config;
66
bufferpool_class->start = do_start;
67
bufferpool_class->flush_start = flush_start;
68
bufferpool_class->acquire_buffer = acquire_buffer;
69
pipewire-0.3.65.tar.gz/src/gst/gstpipewirepool.h -> pipewire-0.3.66.tar.gz/src/gst/gstpipewirepool.h
Changed
20
1
2
3
#include <gst/gst.h>
4
5
+#include <gst/video/video.h>
6
+
7
#include <pipewire/pipewire.h>
8
9
G_BEGIN_DECLS
10
11
struct pw_stream *stream;
12
struct pw_type *t;
13
14
+ gboolean add_metavideo;
15
+ GstVideoInfo video_info;
16
+
17
GstAllocator *fd_allocator;
18
GstAllocator *dmabuf_allocator;
19
20
pipewire-0.3.65.tar.gz/src/gst/gstpipewiresink.c -> pipewire-0.3.66.tar.gz/src/gst/gstpipewiresink.c
Changed
32
1
2
GstPipeWireSink *pwsink = GST_PIPEWIRE_SINK (bsink);
3
4
gst_query_add_allocation_pool (query, GST_BUFFER_POOL_CAST (pwsink->pool), 0, 0, 0);
5
+ gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
6
return TRUE;
7
}
8
9
10
d->chunk->stride = 0;
11
}
12
13
+ GstVideoMeta *meta = gst_buffer_get_video_meta (buffer);
14
+ if (meta) {
15
+ if (meta->n_planes == b->n_datas) {
16
+ gsize video_size = 0;
17
+ for (i = 0; i < meta->n_planes; i++) {
18
+ struct spa_data *d = &b->datasi;
19
+ d->chunk->offset += meta->offseti - video_size;
20
+ d->chunk->stride = meta->stridei;
21
+
22
+ video_size += d->chunk->size;
23
+ }
24
+ } else {
25
+ GST_ERROR ("plane num not matching, meta:%u buffer:%u", meta->n_planes, b->n_datas);
26
+ }
27
+ }
28
+
29
if ((res = pw_stream_queue_buffer (pwsink->stream, data->b)) < 0) {
30
g_warning ("can't send buffer %s", spa_strerror(res));
31
}
32
pipewire-0.3.65.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.66.tar.gz/src/gst/gstpipewiresrc.c
Changed
48
1
2
}
3
}
4
5
+ if (pwsrc->is_video) {
6
+ gsize video_size = 0;
7
+ GstVideoInfo *info = &pwsrc->video_info;
8
+ GstVideoMeta *meta = gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
9
+ GST_VIDEO_INFO_FORMAT (info),
10
+ GST_VIDEO_INFO_WIDTH (info),
11
+ GST_VIDEO_INFO_HEIGHT (info),
12
+ GST_VIDEO_INFO_N_PLANES (info),
13
+ info->offset,
14
+ info->stride);
15
+
16
+ meta->n_planes = MIN(meta->n_planes, b->buffer->n_datas);
17
+ for (i = 0; i < meta->n_planes; i++) {
18
+ struct spa_data *d = &b->buffer->datasi;
19
+ meta->offseti = video_size;
20
+ meta->stridei = d->chunk->stride;
21
+
22
+ video_size += d->chunk->size;
23
+ }
24
+ }
25
+
26
for (i = 0; i < b->buffer->n_datas; i++) {
27
struct spa_data *d = &b->buffer->datasi;
28
GstMemory *pmem = gst_buffer_peek_memory (data->buf, i);
29
30
case PW_STREAM_STATE_STREAMING:
31
break;
32
case PW_STREAM_STATE_ERROR:
33
+ pw_stream_set_error (pwsrc->stream, -EPIPE, "%s", error);
34
GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED,
35
("stream error: %s", error), (NULL));
36
break;
37
38
gst_caps_unref(pwsrc->caps);
39
pwsrc->caps = gst_caps_from_format (param);
40
41
+ pwsrc->is_video = pwsrc->caps != NULL
42
+ ? gst_video_info_from_caps (&pwsrc->video_info, pwsrc->caps)
43
+ : FALSE;
44
+
45
pwsrc->negotiated = pwsrc->caps != NULL;
46
47
if (pwsrc->negotiated) {
48
pipewire-0.3.65.tar.gz/src/gst/gstpipewiresrc.h -> pipewire-0.3.66.tar.gz/src/gst/gstpipewiresrc.h
Changed
20
1
2
#include <gst/gst.h>
3
#include <gst/base/gstpushsrc.h>
4
5
+#include <gst/video/video.h>
6
+
7
#include <pipewire/pipewire.h>
8
#include <gst/gstpipewirepool.h>
9
#include <gst/gstpipewirecore.h>
10
11
12
GstCaps *caps;
13
14
+ gboolean is_video;
15
+ GstVideoInfo video_info;
16
+
17
gboolean negotiated;
18
gboolean flushing;
19
gboolean started;
20
pipewire-0.3.65.tar.gz/src/modules/meson.build -> pipewire-0.3.66.tar.gz/src/modules/meson.build
Changed
201
1
2
+subdir('module-rt')
3
subdir('spa')
4
5
# The list of "main" source files for modules, the ones that have the
6
7
'module-filter-chain/biquad.c',
8
'module-filter-chain/ladspa_plugin.c',
9
'module-filter-chain/builtin_plugin.c',
10
+ 'module-filter-chain/sofa_plugin.c',
11
'module-filter-chain/convolver.c'
12
13
filter_chain_dependencies =
14
- mathlib, dl_lib, pipewire_dep, sndfile_dep, audioconvert_dep
15
+ mathlib, dl_lib, pipewire_dep, sndfile_dep, audioconvert_dep, libmysofa_dep
16
17
18
if lilv_lib.found()
19
20
pipewire_module_combine_stream = shared_library('pipewire-module-combine-stream',
21
'module-combine-stream.c' ,
22
include_directories : configinc,
23
- install : false,
24
+ install : true,
25
install_dir : modules_install_dir,
26
install_rpath: modules_install_dir,
27
dependencies : spa_dep, dl_lib, pipewire_dep,
28
29
30
build_module_rtkit = dbus_dep.found() and (get_option('legacy-rtkit') == true)
31
if build_module_rtkit
32
-# TODO: This serves as a temporary alias to prevent breaking existing setups
33
-# while `module-rtkit` is being migrated to `module-rt`
34
-pipewire_module_rtkit = shared_library('pipewire-module-rtkit', 'module-rt.c' ,
35
- include_directories : configinc,
36
- install : true,
37
- install_dir : modules_install_dir,
38
- install_rpath: modules_install_dir,
39
- dependencies : dbus_dep, mathlib, dl_lib, pipewire_dep,
40
-)
41
+ pipewire_module_rtkit = shared_library('pipewire-module-rtkit', 'module-rt.c' ,
42
+ include_directories : configinc,
43
+ install : true,
44
+ install_dir : modules_install_dir,
45
+ install_rpath: modules_install_dir,
46
+ dependencies : dbus_dep, mathlib, dl_lib, pipewire_dep,
47
+ )
48
endif
49
summary({'rt': '@0@ RTKit'.format(build_module_rtkit ? 'with' : 'without')}, section: 'Optional Modules')
50
51
build_module_portal = dbus_dep.found()
52
if build_module_portal
53
-pipewire_module_portal = shared_library('pipewire-module-portal', 'module-portal.c' ,
54
- include_directories : configinc,
55
- install : true,
56
- install_dir : modules_install_dir,
57
- install_rpath: modules_install_dir,
58
- dependencies : dbus_dep, mathlib, dl_lib, pipewire_dep,
59
-)
60
+ pipewire_module_portal = shared_library('pipewire-module-portal', 'module-portal.c' ,
61
+ include_directories : configinc,
62
+ install : true,
63
+ install_dir : modules_install_dir,
64
+ install_rpath: modules_install_dir,
65
+ dependencies : dbus_dep, mathlib, dl_lib, pipewire_dep,
66
+ )
67
endif
68
summary({'portal': build_module_portal}, bool_yn: true, section: 'Optional Modules')
69
70
71
)
72
73
build_module_pulse_tunnel = pulseaudio_dep.found()
74
-if build_module_pulse_tunnel
75
- pipewire_module_pulse_tunnel = shared_library('pipewire-module-pulse-tunnel',
76
- 'module-pulse-tunnel.c',
77
- 'module-protocol-pulse/format.c' ,
78
- include_directories : configinc,
79
- install : true,
80
- install_dir : modules_install_dir,
81
- install_rpath: modules_install_dir,
82
- dependencies : mathlib, dl_lib, pipewire_dep, pulseaudio_dep,
83
-)
84
+ if build_module_pulse_tunnel
85
+ pipewire_module_pulse_tunnel = shared_library('pipewire-module-pulse-tunnel',
86
+ 'module-pulse-tunnel.c',
87
+ 'module-protocol-pulse/format.c' ,
88
+ include_directories : configinc,
89
+ install : true,
90
+ install_dir : modules_install_dir,
91
+ install_rpath: modules_install_dir,
92
+ dependencies : mathlib, dl_lib, pipewire_dep, pulseaudio_dep,
93
+ )
94
endif
95
summary({'pulse-tunnel': build_module_pulse_tunnel}, bool_yn: true, section: 'Optional Modules')
96
97
98
99
build_module_zeroconf_discover = avahi_dep.found()
100
if build_module_zeroconf_discover
101
-pipewire_module_zeroconf_discover = shared_library('pipewire-module-zeroconf-discover',
102
- 'module-zeroconf-discover.c',
103
- 'module-protocol-pulse/format.c',
104
- 'module-zeroconf-discover/avahi-poll.c' ,
105
- include_directories : configinc,
106
- install : true,
107
- install_dir : modules_install_dir,
108
- install_rpath: modules_install_dir,
109
- dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, avahi_dep,
110
-)
111
+ pipewire_module_zeroconf_discover = shared_library('pipewire-module-zeroconf-discover',
112
+ 'module-zeroconf-discover.c',
113
+ 'module-protocol-pulse/format.c',
114
+ 'module-zeroconf-discover/avahi-poll.c' ,
115
+ include_directories : configinc,
116
+ install : true,
117
+ install_dir : modules_install_dir,
118
+ install_rpath: modules_install_dir,
119
+ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, avahi_dep,
120
+ )
121
endif
122
summary({'zeroconf-discover': build_module_zeroconf_discover}, bool_yn: true, section: 'Optional Modules')
123
124
build_module_raop_discover = avahi_dep.found()
125
if build_module_raop_discover
126
-pipewire_module_raop_discover = shared_library('pipewire-module-raop-discover',
127
- 'module-raop-discover.c',
128
- 'module-zeroconf-discover/avahi-poll.c' ,
129
- include_directories : configinc,
130
- install : true,
131
- install_dir : modules_install_dir,
132
- install_rpath: modules_install_dir,
133
- dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, avahi_dep,
134
-)
135
+ pipewire_module_raop_discover = shared_library('pipewire-module-raop-discover',
136
+ 'module-raop-discover.c',
137
+ 'module-zeroconf-discover/avahi-poll.c' ,
138
+ include_directories : configinc,
139
+ install : true,
140
+ install_dir : modules_install_dir,
141
+ install_rpath: modules_install_dir,
142
+ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, avahi_dep,
143
+ )
144
endif
145
summary({'raop-discover (needs Avahi)': build_module_raop_discover}, bool_yn: true, section: 'Optional Modules')
146
147
build_module_raop = openssl_lib.found()
148
if build_module_raop
149
-pipewire_module_raop_sink = shared_library('pipewire-module-raop-sink',
150
- 'module-raop-sink.c',
151
- 'module-raop/rtsp-client.c' ,
152
- include_directories : configinc,
153
- install : true,
154
- install_dir : modules_install_dir,
155
- install_rpath: modules_install_dir,
156
- dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, openssl_lib,
157
-)
158
+ pipewire_module_raop_sink = shared_library('pipewire-module-raop-sink',
159
+ 'module-raop-sink.c',
160
+ 'module-raop/rtsp-client.c' ,
161
+ include_directories : configinc,
162
+ install : true,
163
+ install_dir : modules_install_dir,
164
+ install_rpath: modules_install_dir,
165
+ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, openssl_lib,
166
+ )
167
endif
168
summary({'raop-sink (requires OpenSSL)': build_module_raop}, bool_yn: true, section: 'Optional Modules')
169
170
171
172
build_module_roc = roc_dep.found()
173
if build_module_roc
174
-pipewire_module_roc_sink = shared_library('pipewire-module-roc-sink',
175
- 'module-roc-sink.c' ,
176
- include_directories : configinc,
177
- install : true,
178
- install_dir : modules_install_dir,
179
- install_rpath: modules_install_dir,
180
- dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, roc_dep,
181
-)
182
+ pipewire_module_roc_sink = shared_library('pipewire-module-roc-sink',
183
+ 'module-roc-sink.c' ,
184
+ include_directories : configinc,
185
+ install : true,
186
+ install_dir : modules_install_dir,
187
+ install_rpath: modules_install_dir,
188
+ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, roc_dep,
189
+ )
190
191
-pipewire_module_roc_source = shared_library('pipewire-module-roc-source',
192
- 'module-roc-source.c' ,
193
- include_directories : configinc,
194
- install : true,
195
- install_dir : modules_install_dir,
196
- install_rpath: modules_install_dir,
197
- dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, roc_dep,
198
-)
199
+ pipewire_module_roc_source = shared_library('pipewire-module-roc-source',
200
+ 'module-roc-source.c' ,
201
pipewire-0.3.65.tar.gz/src/modules/module-combine-stream.c -> pipewire-0.3.66.tar.gz/src/modules/module-combine-stream.c
Changed
9
1
2
}
3
4
static const struct pw_proxy_events core_proxy_events = {
5
+ PW_VERSION_PROXY_EVENTS,
6
.removed = core_removed,
7
};
8
9
pipewire-0.3.65.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.66.tar.gz/src/modules/module-filter-chain.c
Changed
130
1
2
* - `max-delay` the maximum delay in seconds. The "Delay (s)" parameter will
3
* be clamped to this value.
4
*
5
+ * ### Invert
6
+ *
7
+ * The invert plugin can be used to invert the phase of the signal.
8
+ *
9
+ * It has an input port "In" and an output port "Out".
10
+ *
11
* ## General options
12
*
13
* Options with well-known behavior. Most options can be added to the global
14
15
struct plugin {
16
struct spa_list link;
17
int ref;
18
- char type64;
19
+ char type256;
20
char pathPATH_MAX;
21
22
struct fc_plugin *plugin;
23
24
unsigned int n_deps;
25
unsigned int visited:1;
26
unsigned int disabled:1;
27
+ unsigned int control_changed:1;
28
};
29
30
struct link {
31
32
old = port->control_data;
33
port->control_data = value ? *value : desc->default_controlport->idx;
34
pw_log_info("control %d ('%s') from %f to %f", port->idx, name, old, port->control_data);
35
- return old == port->control_data ? 0 : 1;
36
+ node->control_changed = old != port->control_data;
37
+ return node->control_changed ? 1 : 0;
38
}
39
40
static int parse_params(struct graph *graph, const struct spa_pod *pod)
41
42
d->activate(*hndl->hndl);
43
}
44
}
45
+
46
+static void node_control_changed(struct node *node)
47
+{
48
+ const struct fc_descriptor *d = node->desc->desc;
49
+ uint32_t i;
50
+
51
+ if (!node->control_changed)
52
+ return;
53
+
54
+ for (i = 0; i < node->n_hndl; i++) {
55
+ if (node->hndli == NULL)
56
+ continue;
57
+ if (d->control_changed)
58
+ d->control_changed(node->hndli);
59
+ }
60
+ node->control_changed = false;
61
+}
62
+
63
static void param_props_changed(struct impl *impl, const struct spa_pod *param)
64
{
65
struct spa_pod_object *obj = (struct spa_pod_object *) param;
66
67
uint8_t buffer1024;
68
struct spa_pod_dynamic_builder b;
69
const struct spa_pod *params1;
70
+ struct node *node;
71
+
72
+ spa_list_for_each(node, &graph->node_list, link)
73
+ node_control_changed(node);
74
75
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
76
params0 = get_props_param(graph, &b.b);
77
78
if (spa_streq(type, "builtin")) {
79
pl = load_builtin_plugin(support, n_support, &impl->dsp, path, NULL);
80
}
81
+ else if (spa_streq(type, "sofa")) {
82
+ pl = load_sofa_plugin(support, n_support, &impl->dsp, path, NULL);
83
+ }
84
else if (spa_streq(type, "ladspa")) {
85
pl = load_ladspa_plugin(support, n_support, &impl->dsp, path, NULL);
86
}
87
88
free(node->output_port);
89
free(node->control_port);
90
free(node->notify_port);
91
+ free(node->config);
92
free(node);
93
}
94
95
96
}
97
if (d->activate)
98
d->activate(node->hndli);
99
+ if (node->control_changed && d->control_changed)
100
+ d->control_changed(node->hndli);
101
}
102
}
103
return 0;
104
105
pw_log_error("input port %s not found", v);
106
goto error;
107
} else {
108
+ bool disabled = false;
109
+
110
desc = port->node->desc;
111
d = desc->desc;
112
if (i == 0 && port->external != SPA_ID_INVALID) {
113
114
gp->hndl = &peer->node->hndli;
115
gp->port = peer->p;
116
gp->next = true;
117
+ disabled = true;
118
}
119
if (gp != NULL)
120
gp->next = false;
121
}
122
- port->node->disabled = true;
123
- } else {
124
+ port->node->disabled = disabled;
125
+ }
126
+ if (!disabled) {
127
pw_log_info("input port %s%d:%s",
128
port->node->name, i, d->portsport->p.name);
129
port->external = graph->n_input;
130
pipewire-0.3.65.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.66.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
49
1
2
.cleanup = delay_cleanup,
3
};
4
5
+static void invert_run(void * Instance, unsigned long SampleCount)
6
+{
7
+ struct builtin *impl = Instance;
8
+ float *in = impl->port1, *out = impl->port0;
9
+ unsigned long n;
10
+ for (n = 0; n < SampleCount; n++)
11
+ outn = -inn;
12
+}
13
+
14
+static struct fc_port invert_ports = {
15
+ { .index = 0,
16
+ .name = "Out",
17
+ .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
18
+ },
19
+ { .index = 1,
20
+ .name = "In",
21
+ .flags = FC_PORT_INPUT | FC_PORT_AUDIO,
22
+ },
23
+};
24
+
25
+static const struct fc_descriptor invert_desc = {
26
+ .name = "invert",
27
+
28
+ .n_ports = 2,
29
+ .ports = invert_ports,
30
+
31
+ .instantiate = builtin_instantiate,
32
+ .connect_port = builtin_connect_port,
33
+ .run = invert_run,
34
+ .cleanup = builtin_cleanup,
35
+};
36
+
37
static const struct fc_descriptor * builtin_descriptor(unsigned long Index)
38
{
39
switch(Index) {
40
41
return &convolve_desc;
42
case 11:
43
return &delay_desc;
44
+ case 12:
45
+ return &invert_desc;
46
}
47
return NULL;
48
}
49
pipewire-0.3.65.tar.gz/src/modules/module-filter-chain/plugin.h -> pipewire-0.3.66.tar.gz/src/modules/module-filter-chain/plugin.h
Changed
17
1
2
void (*cleanup) (void *instance);
3
4
void (*connect_port) (void *instance, unsigned long port, float *data);
5
+ void (*control_changed) (void *instance);
6
7
void (*activate) (void *instance);
8
void (*deactivate) (void *instance);
9
10
struct dsp_ops *dsp, const char *path, const char *config);
11
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
12
struct dsp_ops *dsp, const char *path, const char *config);
13
+struct fc_plugin *load_sofa_plugin(const struct spa_support *support, uint32_t n_support,
14
+ struct dsp_ops *dsp, const char *path, const char *config);
15
16
#endif /* PLUGIN_H */
17
pipewire-0.3.66.tar.gz/src/modules/module-filter-chain/sofa_plugin.c
Added
201
1
2
+#include "config.h"
3
+
4
+#include <spa/utils/json.h>
5
+#include <spa/support/loop.h>
6
+
7
+#include <pipewire/log.h>
8
+#include "plugin.h"
9
+#include "convolver.h"
10
+#include "dsp-ops.h"
11
+#include "pffft.h"
12
+
13
+#ifdef HAVE_LIBMYSOFA
14
+#include <mysofa.h>
15
+
16
+#define MAX_SAMPLES 8192u
17
+#endif
18
+
19
+static struct dsp_ops *dsp_ops;
20
+static struct spa_loop *data_loop;
21
+static struct spa_loop *main_loop;
22
+
23
+struct spatializer_impl {
24
+ unsigned long rate;
25
+ float *port6;
26
+ int n_samples, blocksize, tailsize;
27
+ float *tmp2;
28
+
29
+#ifdef HAVE_LIBMYSOFA
30
+ struct MYSOFA_EASY *sofa;
31
+#endif
32
+ unsigned int interpolate:1;
33
+ struct convolver *l_conv3;
34
+ struct convolver *r_conv3;
35
+};
36
+
37
+static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
38
+ unsigned long SampleRate, int index, const char *config)
39
+{
40
+#ifdef HAVE_LIBMYSOFA
41
+ struct spatializer_impl *impl;
42
+ struct spa_json it2;
43
+ const char *val;
44
+ char key256;
45
+ char filenamePATH_MAX = "";
46
+
47
+ errno = EINVAL;
48
+ if (config == NULL)
49
+ return NULL;
50
+
51
+ spa_json_init(&it0, config, strlen(config));
52
+ if (spa_json_enter_object(&it0, &it1) <= 0)
53
+ return NULL;
54
+
55
+ impl = calloc(1, sizeof(*impl));
56
+ if (impl == NULL) {
57
+ errno = ENOMEM;
58
+ return NULL;
59
+ }
60
+
61
+ while (spa_json_get_string(&it1, key, sizeof(key)) > 0) {
62
+ if (spa_streq(key, "blocksize")) {
63
+ if (spa_json_get_int(&it1, &impl->blocksize) <= 0) {
64
+ pw_log_error("spatializer:blocksize requires a number");
65
+ errno = EINVAL;
66
+ goto error;
67
+ }
68
+ }
69
+ else if (spa_streq(key, "tailsize")) {
70
+ if (spa_json_get_int(&it1, &impl->tailsize) <= 0) {
71
+ pw_log_error("spatializer:tailsize requires a number");
72
+ errno = EINVAL;
73
+ goto error;
74
+ }
75
+ }
76
+ else if (spa_streq(key, "filename")) {
77
+ if (spa_json_get_string(&it1, filename, sizeof(filename)) <= 0) {
78
+ pw_log_error("spatializer:filename requires a string");
79
+ errno = EINVAL;
80
+ goto error;
81
+ }
82
+ }
83
+ else if (spa_json_next(&it1, &val) < 0)
84
+ break;
85
+ }
86
+ if (!filename0) {
87
+ pw_log_error("spatializer:filename was not given");
88
+ errno = EINVAL;
89
+ goto error;
90
+ }
91
+
92
+ int ret = MYSOFA_OK;
93
+
94
+ impl->sofa = mysofa_open_cached(filename, SampleRate, &impl->n_samples, &ret);
95
+
96
+ if (ret != MYSOFA_OK) {
97
+ pw_log_error("Unable to load HRTF from %s: %d", filename, ret);
98
+ errno = ENOENT;
99
+ goto error;
100
+ }
101
+
102
+ if (impl->blocksize <= 0)
103
+ impl->blocksize = SPA_CLAMP(impl->n_samples, 64, 256);
104
+ if (impl->tailsize <= 0)
105
+ impl->tailsize = SPA_CLAMP(4096, impl->blocksize, 32768);
106
+
107
+ pw_log_info("using n_samples:%u %d:%d blocksize sofa:%s", impl->n_samples,
108
+ impl->blocksize, impl->tailsize, filename);
109
+
110
+ impl->tmp0 = calloc(MAX_SAMPLES, sizeof(float));
111
+ impl->tmp1 = calloc(MAX_SAMPLES, sizeof(float));
112
+ impl->rate = SampleRate;
113
+ return impl;
114
+error:
115
+ if (impl->sofa)
116
+ mysofa_close_cached(impl->sofa);
117
+ free(impl);
118
+ return NULL;
119
+#else
120
+ pw_log_error("libmysofa is required for spatializer, but disabled at compile time");
121
+ errno = EINVAL;
122
+ return NULL;
123
+#endif
124
+}
125
+
126
+#ifdef HAVE_LIBMYSOFA
127
+static int
128
+do_switch(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
129
+ size_t size, void *user_data)
130
+{
131
+ struct spatializer_impl *impl = user_data;
132
+
133
+ if (impl->l_conv0 == NULL) {
134
+ SPA_SWAP(impl->l_conv0, impl->l_conv2);
135
+ SPA_SWAP(impl->r_conv0, impl->r_conv2);
136
+ } else {
137
+ SPA_SWAP(impl->l_conv1, impl->l_conv2);
138
+ SPA_SWAP(impl->r_conv1, impl->r_conv2);
139
+ }
140
+ impl->interpolate = impl->l_conv0 && impl->l_conv1;
141
+
142
+ return 0;
143
+}
144
+
145
+static void spatializer_reload(void * Instance)
146
+{
147
+ struct spatializer_impl *impl = Instance;
148
+ float *left_ir = calloc(impl->n_samples, sizeof(float));
149
+ float *right_ir = calloc(impl->n_samples, sizeof(float));
150
+ float left_delay;
151
+ float right_delay;
152
+ float coords3;
153
+
154
+ for (uint8_t i = 0; i < 3; i++)
155
+ coordsi = impl->port3 + i0;
156
+
157
+ mysofa_s2c(coords);
158
+ mysofa_getfilter_float(
159
+ impl->sofa,
160
+ coords0,
161
+ coords1,
162
+ coords2,
163
+ left_ir,
164
+ right_ir,
165
+ &left_delay,
166
+ &right_delay
167
+ );
168
+
169
+ // TODO: make use of delay
170
+ if ((left_delay || right_delay) && (!isnan(left_delay) || !isnan(right_delay))) {
171
+ pw_log_warn("delay dropped l: %f, r: %f", left_delay, right_delay);
172
+ }
173
+
174
+ if (impl->l_conv2)
175
+ convolver_free(impl->l_conv2);
176
+ if (impl->r_conv2)
177
+ convolver_free(impl->r_conv2);
178
+
179
+ impl->l_conv2 = convolver_new(dsp_ops, impl->blocksize, impl->tailsize,
180
+ left_ir, impl->n_samples);
181
+ impl->r_conv2 = convolver_new(dsp_ops, impl->blocksize, impl->tailsize,
182
+ right_ir, impl->n_samples);
183
+
184
+ free(left_ir);
185
+ free(right_ir);
186
+
187
+ if (impl->l_conv2 == NULL || impl->r_conv2 == NULL) {
188
+ pw_log_error("reloading left or right convolver failed");
189
+ return;
190
+ }
191
+ spa_loop_invoke(data_loop, do_switch, 1, NULL, 0, true, impl);
192
+}
193
+
194
+struct free_data {
195
+ void *item2;
196
+};
197
+
198
+static int
199
+do_free(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
200
+ size_t size, void *user_data)
201
pipewire-0.3.65.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.66.tar.gz/src/modules/module-loopback.c
Changed
34
1
2
*
3
*\endcode
4
*
5
+ * ## Example configuration of a virtual source
6
+ *
7
+ * This Virtual source routes the front-left channel of a multi-channel input to a mono channel.
8
+ * This is useful for splitting up multi-channel inputs from USB audio interfaces that are not yet fully supported by alsa.
9
+ *
10
+ *\code{.unparsed}
11
+ * context.modules =
12
+ * { name = libpipewire-module-loopback
13
+ * args = {
14
+ * node.description = "Scarlett Focusrite Line 1"
15
+ * capture.props = {
16
+ * audio.position = FL
17
+ * stream.dont-remix = true
18
+ * node.target = "alsa_input.usb-Focusrite_Scarlett_Solo_USB_Y7ZD17C24495BC-00.analog-stereo"
19
+ * node.passive = true
20
+ * }
21
+ * playback.props = {
22
+ * node.name = "SF_mono_in_1"
23
+ * media.class = "Audio/Source"
24
+ * audio.position = MONO
25
+ * }
26
+ * }
27
+ * }
28
+ *
29
+ *\endcode
30
+ *
31
* ## See also
32
*
33
* `pw-loopback` : a tool that loads the loopback module with given parameters.
34
pipewire-0.3.65.tar.gz/src/modules/module-protocol-pulse/cmd.c -> pipewire-0.3.66.tar.gz/src/modules/module-protocol-pulse/cmd.c
Changed
13
1
2
3
/*
4
* pulse.cmd =
5
- * { cmd = <command> args = "<arguments>" }
6
+ * { cmd = <command>
7
+ * ( args = "<arguments>" )
8
+ * ( flags = ( nofail ) )
9
+ * }
10
* ...
11
*
12
*/
13
pipewire-0.3.66.tar.gz/src/modules/module-rt
Added
2
1
+(directory)
2
pipewire-0.3.66.tar.gz/src/modules/module-rt/20-pw-defaults.conf.in
Added
22
1
2
+# This file was installed by PipeWire project for buffer locking to always work
3
+
4
+# Required to memlock audio buffers for all client types
5
+#
6
+# This will match all PAM users i.e. those going through the login procedure but
7
+# it should not get applied to system daemons, since they are run bypassing PAM.
8
+#
9
+# While at first glance this might appear very relevant, in fact abusing this
10
+# can at most allow for either more rapid OOM or enhance malicious system memory
11
+# thrashing while evading systemd-oomd limits that are based on the requirement
12
+# that swap utilization must be high before issues arise. As such it's perfectly
13
+# reasonable to just set a limit where each client can lock a few megabytes with
14
+# nearly no impact on regular systems. Meanwhile malicious attackers can OOM
15
+# just as they could. And instead tooling for OOM and resource abuse should be
16
+# improved, if such denial of service attacks are a serious consideration at all.
17
+#
18
+# Starting with Linux 5.16 or systemd v253 the default is 8192 which is plenty
19
+# good enough and this file should not be installed on such systems.
20
+#
21
+* - memlock @PAM_MEMLOCK@
22
pipewire-0.3.66.tar.gz/src/modules/module-rt/25-pw-rlimits.conf.in
Added
10
1
2
+# This file was installed by PipeWire project for its libpipewire-module-rt.so
3
+
4
+# It's believed to be acceptable to have match rules that will never be true
5
+# i.e. a group that does not exist.
6
+#
7
+@MATCH@ - rtprio @RTPRIO@
8
+@MATCH@ - nice @NICE@
9
+@MATCH@ - memlock @MEMLOCK@
10
pipewire-0.3.66.tar.gz/src/modules/module-rt/meson.build
Added
25
1
2
+rlimits_install = get_option('rlimits-install')
3
+rlimits_data = configuration_data()
4
+rlimits_data.set('MATCH', get_option('rlimits-match'))
5
+rlimits_data.set('RTPRIO', get_option('rlimits-rtprio'))
6
+rlimits_data.set('NICE', get_option('rlimits-nice'))
7
+rlimits_data.set('MEMLOCK', get_option('rlimits-memlock'))
8
+configure_file(input: '25-pw-rlimits.conf.in',
9
+ output: '25-pw-rlimits.conf',
10
+ install: rlimits_install,
11
+ install_dir: get_option('sysconfdir') / 'security' / 'limits.d',
12
+ configuration: rlimits_data)
13
+summary({'RLIMITs': '@0@ limits.d file affecting matching PAM users'.format(rlimits_install ? 'with' : 'without')})
14
+
15
+# The pam-defaults-install related code can be removed once all Linux <5.16 kernels are EOL (projected Dec, 2026)
16
+pam_defaults_install = get_option('pam-defaults-install')
17
+pam_defaults_data = configuration_data()
18
+pam_defaults_data.set('PAM_MEMLOCK', get_option('pam-memlock-default'))
19
+configure_file(input: '20-pw-defaults.conf.in',
20
+ output: '20-pw-defaults.conf',
21
+ install: pam_defaults_install,
22
+ install_dir: get_option('sysconfdir') / 'security' / 'limits.d',
23
+ configuration: pam_defaults_data)
24
+summary({'PAM defaults': '@0@ limits.d file affecting all PAM users (not needed with modern systemd or kernel)'.format(pam_defaults_install ? 'with' : 'without')})
25
pipewire-0.3.65.tar.gz/src/modules/module-rtp-sink.c -> pipewire-0.3.66.tar.gz/src/modules/module-rtp-sink.c
Changed
201
1
2
* - `sess.min-ptime = <int>`: minimum packet time in milliseconds, default 2
3
* - `sess.max-ptime = <int>`: maximum packet time in milliseconds, default 20
4
* - `sess.name = <str>`: a session name
5
+ * - `sess.ts-offset = <int>`: an offset to apply to the timestamp, default -1 = random offset
6
+ * - `sess.ts-refclk = <string>`: the name of a reference clock
7
* - `stream.props = {}`: properties to be passed to the stream
8
*
9
* ## General options
10
11
12
#define DEFAULT_MIN_PTIME 2
13
#define DEFAULT_MAX_PTIME 20
14
+#define DEFAULT_TS_OFFSET -1
15
16
#define USAGE "sap.ip=<SAP IP address to send announce, default:"DEFAULT_SAP_IP"> " \
17
"sap.port=<SAP port to send on, default:"SPA_STRINGIFY(DEFAULT_SAP_PORT)"> " \
18
19
struct pw_stream *stream;
20
struct spa_hook stream_listener;
21
22
+ struct spa_io_position *io_position;
23
+
24
unsigned int do_disconnect:1;
25
26
char *ifname;
27
28
int mtu;
29
bool ttl;
30
bool mcast_loop;
31
- uint32_t min_ptime;
32
- uint32_t max_ptime;
33
- uint32_t pbytes;
34
+ float min_ptime;
35
+ float max_ptime;
36
+ uint32_t psamples;
37
38
struct sockaddr_storage src_addr;
39
socklen_t src_len;
40
41
42
struct spa_audio_info_raw info;
43
const struct format_info *format_info;
44
- uint32_t frame_size;
45
+ uint32_t stride;
46
int payload;
47
uint16_t seq;
48
- uint32_t timestamp;
49
uint32_t ssrc;
50
+ uint32_t ts_offset;
51
+ char ts_refclk64;
52
53
struct spa_ringbuffer ring;
54
uint8_t bufferBUFFER_SIZE;
55
56
int rtp_fd;
57
int sap_fd;
58
+
59
+ unsigned sync:1;
60
};
61
62
63
64
static void flush_packets(struct impl *impl)
65
{
66
int32_t avail;
67
- uint32_t index;
68
+ uint32_t stride, timestamp;
69
struct iovec iov3;
70
struct msghdr msg;
71
ssize_t n;
72
struct rtp_header header;
73
int32_t tosend;
74
75
- avail = spa_ringbuffer_get_read_index(&impl->ring, &index);
76
-
77
- tosend = impl->pbytes;
78
+ avail = spa_ringbuffer_get_read_index(&impl->ring, ×tamp);
79
+ tosend = impl->psamples;
80
81
if (avail < tosend)
82
return;
83
84
+ stride = impl->stride;
85
+
86
spa_zero(header);
87
header.v = 2;
88
header.pt = impl->payload;
89
90
91
while (avail >= tosend) {
92
header.sequence_number = htons(impl->seq);
93
- header.timestamp = htonl(impl->timestamp);
94
+ header.timestamp = htonl(impl->ts_offset + timestamp);
95
96
set_iovec(&impl->ring,
97
impl->buffer, BUFFER_SIZE,
98
- index & BUFFER_MASK,
99
- &iov1, tosend);
100
+ (timestamp * stride) & BUFFER_MASK,
101
+ &iov1, tosend * stride);
102
103
+ pw_log_trace("sending %d timestamp:%d", tosend, timestamp);
104
n = sendmsg(impl->rtp_fd, &msg, MSG_NOSIGNAL);
105
if (n < 0) {
106
switch (errno) {
107
108
pw_log_debug("remote end not listening");
109
break;
110
default:
111
- pw_log_warn("sendmsg() failed: %m");
112
+ pw_log_warn("sendmsg() failed, seq:%u dropped: %m",
113
+ impl->seq);
114
break;
115
}
116
}
117
118
impl->seq++;
119
- impl->timestamp += tosend / impl->frame_size;
120
121
- index += tosend;
122
+ timestamp += tosend;
123
avail -= tosend;
124
}
125
- spa_ringbuffer_read_update(&impl->ring, index);
126
+ spa_ringbuffer_read_update(&impl->ring, timestamp);
127
}
128
129
static void stream_process(void *data)
130
131
struct impl *impl = data;
132
struct pw_buffer *buf;
133
struct spa_data *d;
134
- uint32_t index;
135
- int32_t filled, wanted;
136
+ uint32_t offs, size, timestamp, expected_timestamp, stride;
137
+ int32_t filled, wanted;
138
139
if ((buf = pw_stream_dequeue_buffer(impl->stream)) == NULL) {
140
pw_log_debug("Out of stream buffers: %m");
141
142
}
143
d = buf->buffer->datas;
144
145
- wanted = d0.chunk->size;
146
+ offs = SPA_MIN(d0.chunk->offset, d0.maxsize);
147
+ size = SPA_MIN(d0.chunk->size, d0.maxsize - offs);
148
+ stride = impl->stride;
149
+ wanted = size / stride;
150
+
151
+ filled = spa_ringbuffer_get_write_index(&impl->ring, &expected_timestamp);
152
+ if (SPA_LIKELY(impl->io_position))
153
+ timestamp = impl->io_position->clock.position;
154
+ else
155
+ timestamp = expected_timestamp;
156
+
157
+ if (impl->sync) {
158
+ if (expected_timestamp != timestamp) {
159
+ pw_log_warn("expected %u != timestamp %u", expected_timestamp, timestamp);
160
+ impl->sync = false;
161
+ } else if (filled + wanted > (int32_t)(BUFFER_SIZE / stride)) {
162
+ pw_log_warn("overrun %u + %u > %u", filled, wanted, BUFFER_SIZE / stride);
163
+ impl->sync = false;
164
+ }
165
+ }
166
+ if (!impl->sync) {
167
+ pw_log_info("sync to timestamp %u", timestamp);
168
+ impl->ring.readindex = impl->ring.writeindex = timestamp;
169
+ memset(impl->buffer, 0, BUFFER_SIZE);
170
+ impl->sync = true;
171
+ }
172
173
- filled = spa_ringbuffer_get_write_index(&impl->ring, &index);
174
+ spa_ringbuffer_write_data(&impl->ring,
175
+ impl->buffer,
176
+ BUFFER_SIZE,
177
+ (timestamp * stride) & BUFFER_MASK,
178
+ SPA_PTROFF(d0.data, offs, void), wanted * stride);
179
+ timestamp += wanted;
180
+ spa_ringbuffer_write_update(&impl->ring, timestamp);
181
182
- if (filled + wanted > (int32_t)BUFFER_SIZE) {
183
- pw_log_warn("overrun %u + %u > %u", filled, wanted, BUFFER_SIZE);
184
- } else {
185
- spa_ringbuffer_write_data(&impl->ring,
186
- impl->buffer,
187
- BUFFER_SIZE,
188
- index & BUFFER_MASK,
189
- d0.data, wanted);
190
-
191
- index += wanted;
192
- spa_ringbuffer_write_update(&impl->ring, index);
193
- }
194
pw_stream_queue_buffer(impl->stream, buf);
195
196
flush_packets(impl);
197
}
198
199
+static void stream_io_changed(void *data, uint32_t id, void *area, uint32_t size)
200
+{
201
pipewire-0.3.65.tar.gz/src/modules/module-rtp-source.c -> pipewire-0.3.66.tar.gz/src/modules/module-rtp-source.c
Changed
201
1
2
#include "config.h"
3
4
#include <limits.h>
5
+#include <string.h>
6
#include <unistd.h>
7
#include <sys/stat.h>
8
#include <sys/socket.h>
9
10
* #sap.port = 9875
11
* #local.ifname = eth0
12
* sess.latency.msec = 100
13
+ * #node.always-process = false # true to receive even when not running
14
* stream.props = {
15
* #media.class = "Audio/Source"
16
* #node.name = "rtp-source"
17
18
* #rtp.payload = "127"
19
* #rtp.fmt = "L16/48000/2"
20
* #rtp.session = "PipeWire RTP Stream on fedora"
21
+ * #rtp.ts-offset = 0
22
+ * #rtp.ts-refclk = "private"
23
* }
24
*
25
* actions = {
26
* create-stream = {
27
* #sess.latency.msec = 100
28
+ * #sess.ts-direct = false
29
* #target.object = ""
30
* }
31
* }
32
33
34
char *ifname;
35
char *sap_ip;
36
+ bool always_process;
37
int sap_port;
38
int sess_latency_msec;
39
uint32_t cleanup_interval;
40
41
42
char origin128;
43
char session256;
44
+ char channelmap512;
45
46
struct sockaddr_storage sa;
47
socklen_t salen;
48
49
const struct format_info *format_info;
50
struct spa_audio_info_raw info;
51
uint32_t stride;
52
+
53
+ uint32_t ts_offset;
54
+ char refclk64;
55
};
56
57
struct session {
58
59
uint8_t bufferBUFFER_SIZE;
60
61
struct spa_io_rate_match *rate_match;
62
+ struct spa_io_position *position;
63
struct spa_dll dll;
64
uint32_t target_buffer;
65
- uint32_t last_packet_size;
66
float max_error;
67
- unsigned buffering:1;
68
unsigned first:1;
69
+ unsigned receiving:1;
70
+ unsigned direct_timestamp:1;
71
};
72
73
static void stream_destroy(void *d)
74
75
struct session *sess = data;
76
struct pw_buffer *buf;
77
struct spa_data *d;
78
- uint32_t index, target_buffer;
79
- int32_t avail, wanted;
80
+ uint32_t wanted, timestamp, target_buffer, stride, maxsize;
81
+ int32_t avail;
82
83
if ((buf = pw_stream_dequeue_buffer(sess->stream)) == NULL) {
84
pw_log_debug("Out of stream buffers: %m");
85
86
}
87
d = buf->buffer->datas;
88
89
- wanted = buf->requested ?
90
- SPA_MIN(buf->requested * sess->info.stride, d0.maxsize)
91
- : d0.maxsize;
92
+ stride = sess->info.stride;
93
94
- avail = spa_ringbuffer_get_read_index(&sess->ring, &index);
95
+ maxsize = d0.maxsize / stride;
96
+ wanted = buf->requested ? SPA_MIN(buf->requested, maxsize) : maxsize;
97
98
- target_buffer = sess->target_buffer + sess->last_packet_size / 2;
99
+ if (sess->position && sess->direct_timestamp) {
100
+ /* in direct mode, read directly from the timestamp index,
101
+ * because sender and receiver are in sync, this would keep
102
+ * target_buffer of bytes available. */
103
+ spa_ringbuffer_read_update(&sess->ring,
104
+ sess->position->clock.position);
105
+ }
106
+ avail = spa_ringbuffer_get_read_index(&sess->ring, ×tamp);
107
108
- if (avail < wanted || sess->buffering) {
109
- memset(d0.data, 0, wanted);
110
- if (!sess->buffering && sess->have_sync) {
111
- pw_log_debug("underrun %u/%u < %u, buffering...",
112
- avail, target_buffer, wanted);
113
- sess->buffering = true;
114
+ target_buffer = sess->target_buffer;
115
+
116
+ if (avail < (int32_t)wanted) {
117
+ enum spa_log_level level;
118
+ memset(d0.data, 0, wanted * stride);
119
+ if (sess->have_sync) {
120
+ sess->have_sync = false;
121
+ level = SPA_LOG_LEVEL_WARN;
122
+ } else {
123
+ level = SPA_LOG_LEVEL_DEBUG;
124
}
125
+ pw_log(level, "underrun %d/%u < %u",
126
+ avail, target_buffer, wanted);
127
} else {
128
float error, corr;
129
- if (avail > (int32_t)SPA_MIN(target_buffer * 8, BUFFER_SIZE)) {
130
+ if (avail > (int32_t)SPA_MIN(target_buffer * 8, BUFFER_SIZE / stride)) {
131
pw_log_warn("overrun %u > %u", avail, target_buffer * 8);
132
- index += avail - target_buffer;
133
+ timestamp += avail - target_buffer;
134
avail = target_buffer;
135
- } else {
136
- if (sess->first) {
137
- if ((uint32_t)avail > target_buffer) {
138
- uint32_t skip = avail - target_buffer;
139
- pw_log_debug("first: avail:%d skip:%u target:%u",
140
+ } else if (sess->first) {
141
+ if ((uint32_t)avail > target_buffer) {
142
+ uint32_t skip = avail - target_buffer;
143
+ pw_log_debug("first: avail:%d skip:%u target:%u",
144
avail, skip, target_buffer);
145
- index += skip;
146
- avail = target_buffer;
147
- }
148
- sess->first = false;
149
+ timestamp += skip;
150
+ avail = target_buffer;
151
}
152
+ sess->first = false;
153
+ }
154
+ if (!sess->direct_timestamp) {
155
+ /* when not using direct timestamp and clocks are not
156
+ * in sync, try to adjust our playback rate to keep the
157
+ * requested target_buffer bytes in the ringbuffer */
158
error = (float)target_buffer - (float)avail;
159
error = SPA_CLAMP(error, -sess->max_error, sess->max_error);
160
161
162
target_buffer, error, corr);
163
164
if (sess->rate_match) {
165
- SPA_FLAG_SET(sess->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE);
166
+ SPA_FLAG_SET(sess->rate_match->flags,
167
+ SPA_IO_RATE_MATCH_FLAG_ACTIVE);
168
sess->rate_match->rate = 1.0f / corr;
169
}
170
}
171
spa_ringbuffer_read_data(&sess->ring,
172
sess->buffer,
173
BUFFER_SIZE,
174
- index & BUFFER_MASK,
175
- d0.data, wanted);
176
+ (timestamp * stride) & BUFFER_MASK,
177
+ d0.data, wanted * stride);
178
179
- index += wanted;
180
- spa_ringbuffer_read_update(&sess->ring, index);
181
+ timestamp += wanted;
182
+ spa_ringbuffer_read_update(&sess->ring, timestamp);
183
}
184
- d0.chunk->size = wanted;
185
- d0.chunk->stride = sess->info.stride;
186
+ d0.chunk->size = wanted * stride;
187
+ d0.chunk->stride = stride;
188
d0.chunk->offset = 0;
189
- buf->size = wanted / sess->info.stride;
190
+ buf->size = wanted;
191
192
pw_stream_queue_buffer(sess->stream, buf);
193
}
194
195
-static void on_stream_state_changed(void *d, enum pw_stream_state old,
196
- enum pw_stream_state state, const char *error)
197
-{
198
- struct session *sess = d;
199
- struct impl *impl = sess->impl;
200
-
201
pipewire-0.3.65.tar.gz/src/pipewire/conf.c -> pipewire-0.3.66.tar.gz/src/pipewire/conf.c
Changed
201
1
2
}
3
4
/*
5
+ * {
6
+ * # all keys must match the value. ~ in value starts regex.
7
+ * <key> = <value>
8
+ * ...
9
+ * }
10
+ */
11
+static bool find_match(struct spa_json *arr, const struct spa_dict *props)
12
+{
13
+ struct spa_json it1;
14
+
15
+ while (spa_json_enter_object(arr, &it0) > 0) {
16
+ char key256, val1024;
17
+ const char *str, *value;
18
+ int match = 0, fail = 0;
19
+ int len;
20
+
21
+ while (spa_json_get_string(&it0, key, sizeof(key)) > 0) {
22
+ bool success = false;
23
+
24
+ if ((len = spa_json_next(&it0, &value)) <= 0)
25
+ break;
26
+
27
+ str = spa_dict_lookup(props, key);
28
+
29
+ if (spa_json_is_null(value, len)) {
30
+ success = str == NULL;
31
+ } else {
32
+ if (spa_json_parse_stringn(value, len, val, sizeof(val)) < 0)
33
+ continue;
34
+ value = val;
35
+ len = strlen(val);
36
+ }
37
+ if (str != NULL) {
38
+ if (value0 == '~') {
39
+ regex_t preg;
40
+ if (regcomp(&preg, value+1, REG_EXTENDED | REG_NOSUB) == 0) {
41
+ if (regexec(&preg, str, 0, NULL, 0) == 0)
42
+ success = true;
43
+ regfree(&preg);
44
+ }
45
+ } else if (strncmp(str, value, len) == 0 &&
46
+ strlen(str) == (size_t)len) {
47
+ success = true;
48
+ }
49
+ }
50
+ if (success) {
51
+ match++;
52
+ pw_log_debug("'%s' match '%s' < > '%.*s'", key, str, len, value);
53
+ }
54
+ else
55
+ fail++;
56
+ }
57
+ if (match > 0 && fail == 0)
58
+ return true;
59
+ }
60
+ return false;
61
+}
62
+
63
+/*
64
* context.modules =
65
* { name = <module-name>
66
- * args = { <key> = <value> ... }
67
- * flags = ifexists nofail
68
+ * ( args = { <key> = <value> ... } )
69
+ * ( flags = ( ifexists ) ( nofail )
70
+ * ( condition = { key = value, .. } .. )
71
* }
72
*
73
*/
74
75
{
76
struct data *d = user_data;
77
struct pw_context *context = d->context;
78
- struct spa_json it3;
79
+ struct spa_json it4;
80
char key512, *s;
81
int res = 0;
82
83
84
85
while (spa_json_enter_object(&it1, &it2) > 0) {
86
char *name = NULL, *args = NULL, *flags = NULL;
87
+ bool have_match = true;
88
89
while (spa_json_get_string(&it2, key, sizeof(key)) > 0) {
90
const char *val;
91
92
len = spa_json_container_len(&it2, val, len);
93
flags = (char*)val;
94
spa_json_parse_stringn(val, len, flags, len+1);
95
+ } else if (spa_streq(key, "condition")) {
96
+ if (!spa_json_is_array(val, len))
97
+ break;
98
+ spa_json_enter(&it2, &it3);
99
+ have_match = find_match(&it3, &context->properties->dict);
100
}
101
}
102
+ if (!have_match)
103
+ continue;
104
+
105
if (name != NULL)
106
res = load_module(context, name, args, flags);
107
108
109
/*
110
* context.objects =
111
* { factory = <factory-name>
112
- * args = { <key> = <value> ... }
113
- * flags = nofail
114
+ * ( args = { <key> = <value> ... } )
115
+ * ( flags = ( nofail ) )
116
+ * ( condition = { key = value, .. } .. )
117
* }
118
*
119
*/
120
121
{
122
struct data *d = user_data;
123
struct pw_context *context = d->context;
124
- struct spa_json it3;
125
+ struct spa_json it4;
126
char key512, *s;
127
int res = 0;
128
129
130
131
while (spa_json_enter_object(&it1, &it2) > 0) {
132
char *factory = NULL, *args = NULL, *flags = NULL;
133
+ bool have_match = true;
134
135
while (spa_json_get_string(&it2, key, sizeof(key)) > 0) {
136
const char *val;
137
138
139
flags = (char*)val;
140
spa_json_parse_stringn(val, len, flags, len+1);
141
+ } else if (spa_streq(key, "condition")) {
142
+ if (!spa_json_is_array(val, len))
143
+ break;
144
+ spa_json_enter(&it2, &it3);
145
+ have_match = find_match(&it3, &context->properties->dict);
146
}
147
}
148
+ if (!have_match)
149
+ continue;
150
+
151
if (factory != NULL)
152
res = create_object(context, factory, args, flags);
153
154
155
156
/*
157
* context.exec =
158
- * { path = <program-name>
159
- * args = "<arguments>"
160
+ * { path = <program-name>
161
+ * ( args = "<arguments>" )
162
+ * ( condition = { key = value, .. } .. )
163
* }
164
*
165
*/
166
167
{
168
struct data *d = user_data;
169
struct pw_context *context = d->context;
170
- struct spa_json it3;
171
+ struct spa_json it4;
172
char key512, *s;
173
int res = 0;
174
175
176
177
while (spa_json_enter_object(&it1, &it2) > 0) {
178
char *path = NULL, *args = NULL;
179
+ bool have_match = true;
180
181
while (spa_json_get_string(&it2, key, sizeof(key)) > 0) {
182
const char *val;
183
184
} else if (spa_streq(key, "args")) {
185
args = (char*)val;
186
spa_json_parse_stringn(val, len, args, len+1);
187
+ } else if (spa_streq(key, "condition")) {
188
+ if (!spa_json_is_array(val, len))
189
+ break;
190
+ spa_json_enter(&it2, &it3);
191
+ have_match = find_match(&it3, &context->properties->dict);
192
}
193
}
194
+ if (!have_match)
195
+ continue;
196
+
197
if (path != NULL)
198
res = do_exec(context, path, args);
199
200
201
pipewire-0.3.65.tar.gz/src/pipewire/context.c -> pipewire-0.3.66.tar.gz/src/pipewire/context.c
Changed
136
1
2
return fa < fb ? -1 : (fa > fb ? 1 : 0);
3
}
4
5
-static uint32_t find_best_rate(const uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t best)
6
+static inline uint32_t calc_gcd(uint32_t a, uint32_t b)
7
{
8
- uint32_t i;
9
+ while (b != 0) {
10
+ uint32_t temp = a;
11
+ a = b;
12
+ b = temp % b;
13
+ }
14
+ return a;
15
+}
16
+
17
+struct rate_info {
18
+ uint32_t rate;
19
+ uint32_t gcd;
20
+ uint32_t diff;
21
+};
22
+
23
+static inline void update_highest_rate(struct rate_info *best, struct rate_info *current)
24
+{
25
+ /* find highest rate */
26
+ if (best->rate == 0 || best->rate < current->rate)
27
+ *best = *current;
28
+}
29
+
30
+static inline void update_nearest_gcd(struct rate_info *best, struct rate_info *current)
31
+{
32
+ /* find nearest GCD */
33
+ if (best->rate == 0 ||
34
+ (best->gcd < current->gcd) ||
35
+ (best->gcd == current->gcd && best->diff > current->diff))
36
+ *best = *current;
37
+}
38
+static inline void update_nearest_rate(struct rate_info *best, struct rate_info *current)
39
+{
40
+ /* find nearest rate */
41
+ if (best->rate == 0 || best->diff > current->diff)
42
+ *best = *current;
43
+}
44
+
45
+static uint32_t find_best_rate(const uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t def)
46
+{
47
+ uint32_t i, limit;
48
+ struct rate_info best;
49
+ struct rate_info infon_rates;
50
+
51
+ for (i = 0; i < n_rates; i++) {
52
+ infoi.rate = ratesi;
53
+ infoi.gcd = calc_gcd(rate, ratesi);
54
+ infoi.diff = SPA_ABS((int32_t)rate - (int32_t)ratesi);
55
+ }
56
+
57
+ /* first find higher nearest GCD. This tries to find next bigest rate that
58
+ * requires the least amount of resample filter banks. Usually these are
59
+ * rates that are multiples of eachother or multiples of a common rate.
60
+ *
61
+ * 44100 and 32000 56000 88200 96000 -> 88200
62
+ * 48000 and 32000 56000 88200 96000 -> 96000
63
+ * 88200 and 44100 48000 96000 192000 -> 96000
64
+ * 32000 and 44100 192000 -> 44100
65
+ * 8000 and 44100 48000 -> 48000
66
+ * 8000 and 44100 192000 -> 44100
67
+ * 11025 and 44100 48000 -> 44100
68
+ * 44100 and 48000 176400 -> 48000
69
+ */
70
+ spa_zero(best);
71
+ /* Don't try to do excessive upsampling by limiting the max rate
72
+ * for desired < default to default*2. For other rates allow
73
+ * a x3 upsample rate max */
74
+ limit = rate < def ? def*2 : rate*3;
75
+ for (i = 0; i < n_rates; i++) {
76
+ if (infoi.rate >= rate && infoi.rate <= limit)
77
+ update_nearest_gcd(&best, &infoi);
78
+ }
79
+ if (best.rate != 0)
80
+ return best.rate;
81
+
82
+ /* we would need excessive upsampling, pick a nearest higher rate */
83
+ spa_zero(best);
84
+ for (i = 0; i < n_rates; i++) {
85
+ if (infoi.rate >= rate)
86
+ update_nearest_rate(&best, &infoi);
87
+ }
88
+ if (best.rate != 0)
89
+ return best.rate;
90
+
91
+ /* There is nothing above the rate, we need to downsample. Try to downsample
92
+ * but only to something that is from a common rate family. Also don't
93
+ * try to downsample to something that will sound worse (< 44100).
94
+ *
95
+ * 88200 and 22050 44100 48000 -> 44100
96
+ * 88200 and 22050 48000 -> 48000
97
+ */
98
+ spa_zero(best);
99
for (i = 0; i < n_rates; i++) {
100
- if (SPA_ABS((int32_t)rate - (int32_t)ratesi) <
101
- SPA_ABS((int32_t)rate - (int32_t)best))
102
- best = ratesi;
103
+ if (infoi.rate >= 44100)
104
+ update_nearest_gcd(&best, &infoi);
105
}
106
- return best;
107
+ if (best.rate != 0)
108
+ return best.rate;
109
+
110
+ /* There is nothing to downsample above our threshold. Downsample to whatever
111
+ * is the highest rate then. */
112
+ spa_zero(best);
113
+ for (i = 0; i < n_rates; i++)
114
+ update_highest_rate(&best, &infoi);
115
+ if (best.rate != 0)
116
+ return best.rate;
117
+
118
+ return def;
119
}
120
121
/* here we evaluate the complete state of the graph.
122
123
running = true;
124
125
current_rate = n->current_rate.denom;
126
- if (lock_rate || n->reconfigure ||
127
+ if (lock_rate || n->reconfigure || !running ||
128
(!force_rate &&
129
(n->info.state > PW_NODE_STATE_IDLE)))
130
/* when someone wants us to lock the rate of this driver or
131
+ * when we are in the process of reconfiguring the driver or
132
+ * when we are not running any followers or
133
* when the driver is busy and we don't need to force a rate,
134
* keep the current rate */
135
target_rate = current_rate;
136
pipewire-0.3.65.tar.gz/src/pipewire/filter.c -> pipewire-0.3.66.tar.gz/src/pipewire/filter.c
Changed
201
1
2
3
struct pw_properties *props;
4
5
- uint32_t change_mask_all;
6
+ uint64_t change_mask_all;
7
struct spa_port_info info;
8
struct spa_list param_list;
9
-#define IDX_EnumFormat 0
10
-#define IDX_Meta 1
11
-#define IDX_IO 2
12
-#define IDX_Format 3
13
-#define IDX_Buffers 4
14
-#define IDX_Latency 5
15
+#define PORT_EnumFormat 0
16
+#define PORT_Meta 1
17
+#define PORT_IO 2
18
+#define PORT_Format 3
19
+#define PORT_Buffers 4
20
+#define PORT_Latency 5
21
#define N_PORT_PARAMS 6
22
struct spa_param_info paramsN_PORT_PARAMS;
23
24
25
struct spa_node impl_node;
26
struct spa_hook_list hooks;
27
struct spa_callbacks callbacks;
28
+ struct spa_io_clock *clock;
29
struct spa_io_position *position;
30
31
struct {
32
33
struct spa_list port_list;
34
struct pw_map ports2;
35
36
- uint32_t change_mask_all;
37
+ uint64_t change_mask_all;
38
struct spa_node_info info;
39
struct spa_list param_list;
40
-#define IDX_PropInfo 0
41
-#define IDX_Props 1
42
-#define IDX_ProcessLatency 2
43
+#define NODE_PropInfo 0
44
+#define NODE_Props 1
45
+#define NODE_ProcessLatency 2
46
#define N_NODE_PARAMS 3
47
struct spa_param_info paramsN_NODE_PARAMS;
48
49
50
unsigned int allow_mlock:1;
51
unsigned int warn_mlock:1;
52
unsigned int process_rt:1;
53
+ unsigned int driving:1;
54
};
55
56
static int get_param_index(uint32_t id)
57
{
58
switch (id) {
59
case SPA_PARAM_PropInfo:
60
- return IDX_PropInfo;
61
+ return NODE_PropInfo;
62
case SPA_PARAM_Props:
63
- return IDX_Props;
64
+ return NODE_Props;
65
case SPA_PARAM_ProcessLatency:
66
- return IDX_ProcessLatency;
67
+ return NODE_ProcessLatency;
68
default:
69
return -1;
70
}
71
72
{
73
switch (id) {
74
case SPA_PARAM_EnumFormat:
75
- return IDX_EnumFormat;
76
+ return PORT_EnumFormat;
77
case SPA_PARAM_Meta:
78
- return IDX_Meta;
79
+ return PORT_Meta;
80
case SPA_PARAM_IO:
81
- return IDX_IO;
82
+ return PORT_IO;
83
case SPA_PARAM_Format:
84
- return IDX_Format;
85
+ return PORT_Format;
86
case SPA_PARAM_Buffers:
87
- return IDX_Buffers;
88
+ return PORT_Buffers;
89
case SPA_PARAM_Latency:
90
- return IDX_Latency;
91
+ return PORT_Latency;
92
default:
93
return -1;
94
}
95
96
pw_log_debug("%p: io %d %p/%zd", impl, id, data, size);
97
98
switch(id) {
99
+ case SPA_IO_Clock:
100
+ if (data && size >= sizeof(struct spa_io_clock))
101
+ impl->clock = data;
102
+ else
103
+ impl->clock = NULL;
104
+ break;
105
case SPA_IO_Position:
106
if (data && size >= sizeof(struct spa_io_position))
107
impl->position = data;
108
109
do_set_position, 1, NULL, 0, true, impl);
110
break;
111
}
112
+ impl->driving = impl->clock && impl->position && impl->position->clock.id == impl->clock->id;
113
pw_filter_emit_io_changed(&impl->this, NULL, id, data, size);
114
115
return 0;
116
117
impl->info.max_output_ports = UINT32_MAX;
118
impl->info.flags = impl->process_rt ? SPA_NODE_FLAG_RT : 0;
119
impl->info.props = &filter->properties->dict;
120
- impl->paramsIDX_PropInfo = SPA_PARAM_INFO(SPA_PARAM_PropInfo, 0);
121
- impl->paramsIDX_Props = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_WRITE);
122
- impl->paramsIDX_ProcessLatency = SPA_PARAM_INFO(SPA_PARAM_ProcessLatency, 0);
123
+ impl->paramsNODE_PropInfo = SPA_PARAM_INFO(SPA_PARAM_PropInfo, 0);
124
+ impl->paramsNODE_Props = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_WRITE);
125
+ impl->paramsNODE_ProcessLatency = SPA_PARAM_INFO(SPA_PARAM_ProcessLatency, 0);
126
impl->info.params = impl->params;
127
impl->info.n_params = N_NODE_PARAMS;
128
impl->info.change_mask = impl->change_mask_all;
129
130
p->info.flags |= SPA_PORT_FLAG_CAN_ALLOC_BUFFERS;
131
p->info.props = &p->props->dict;
132
p->change_mask_all |= SPA_PORT_CHANGE_MASK_PARAMS;
133
- p->paramsIDX_EnumFormat = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, 0);
134
- p->paramsIDX_Meta = SPA_PARAM_INFO(SPA_PARAM_Meta, 0);
135
- p->paramsIDX_IO = SPA_PARAM_INFO(SPA_PARAM_IO, 0);
136
- p->paramsIDX_Format = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
137
- p->paramsIDX_Buffers = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
138
- p->paramsIDX_Latency = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_WRITE);
139
+ p->paramsPORT_EnumFormat = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, 0);
140
+ p->paramsPORT_Meta = SPA_PARAM_INFO(SPA_PARAM_Meta, 0);
141
+ p->paramsPORT_IO = SPA_PARAM_INFO(SPA_PARAM_IO, 0);
142
+ p->paramsPORT_Format = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
143
+ p->paramsPORT_Buffers = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
144
+ p->paramsPORT_Latency = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_WRITE);
145
p->info.params = p->params;
146
p->info.n_params = N_PORT_PARAMS;
147
148
149
return NULL;
150
}
151
152
-SPA_EXPORT
153
-int pw_filter_remove_port(void *port_data)
154
+static inline void free_port(struct filter *impl, struct port *port)
155
{
156
- struct port *port = SPA_CONTAINER_OF(port_data, struct port, user_data);
157
- struct filter *impl = port->filter;
158
-
159
- spa_node_emit_port_info(&impl->hooks, port->direction, port->id, NULL);
160
-
161
spa_list_remove(&port->link);
162
+ spa_node_emit_port_info(&impl->hooks, port->direction, port->id, NULL);
163
pw_map_remove(&impl->portsport->direction, port->id);
164
-
165
clear_buffers(port);
166
clear_params(impl, port, SPA_ID_INVALID);
167
pw_properties_free(port->props);
168
free(port);
169
+}
170
171
+SPA_EXPORT
172
+int pw_filter_remove_port(void *port_data)
173
+{
174
+ struct port *port = SPA_CONTAINER_OF(port_data, struct port, user_data);
175
+ struct filter *impl = port->filter;
176
+ free_port(impl, port);
177
return 0;
178
}
179
180
181
return 0;
182
}
183
184
-static int
185
-do_process(struct spa_loop *loop,
186
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
187
-{
188
- struct filter *impl = user_data;
189
- int res = impl_node_process(impl);
190
- return spa_node_call_ready(&impl->callbacks, res);
191
-}
192
-
193
-static inline int call_trigger(struct filter *impl)
194
-{
195
- int res = 0;
196
- if (SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_DRIVER)) {
197
- res = pw_loop_invoke(impl->context->data_loop,
198
- do_process, 1, NULL, 0, false, impl);
199
- }
200
- return res;
201
pipewire-0.3.65.tar.gz/src/pipewire/filter.h -> pipewire-0.3.66.tar.gz/src/pipewire/filter.h
Changed
18
1
2
* be called when all data is played or recorded */
3
int pw_filter_flush(struct pw_filter *filter, bool drain);
4
5
+/** Check if the filter is driving. The filter needs to have the
6
+ * PW_FILTER_FLAG_DRIVER set. When the filter is driving,
7
+ * pw_filter_trigger_process() needs to be called when data is
8
+ * available (output) or needed (input). Since 0.3.66 */
9
+bool pw_filter_is_driving(struct pw_filter *filter);
10
+
11
+/** Trigger a push/pull on the filter. One iteration of the graph will
12
+ * be scheduled and process() will be called. Since 0.3.66 */
13
+int pw_filter_trigger_process(struct pw_filter *filter);
14
+
15
/**
16
* \}
17
*/
18
pipewire-0.3.65.tar.gz/src/pipewire/impl-core.c -> pipewire-0.3.66.tar.gz/src/pipewire/impl-core.c
Changed
10
1
2
if (obj == NULL)
3
goto error_create_failed;
4
5
- return 0;
6
+ return obj;
7
8
error_no_factory:
9
res = -ENOENT;
10
pipewire-0.3.65.tar.gz/src/pipewire/keys.h -> pipewire-0.3.66.tar.gz/src/pipewire/keys.h
Changed
17
1
2
* and object name or object.serial */
3
4
#ifndef PW_REMOVE_DEPRECATED
5
-#define PW_KEY_PRIORITY_MASTER PW_DEPRECATED("priority.master") /**< deprecated, use priority.driver */
6
-#define PW_KEY_NODE_TARGET PW_DEPRECATED("node.target") /**< deprecated since 0.3.64, use target.object. */
7
+# ifdef PW_ENABLE_DEPRECATED
8
+# define PW_KEY_PRIORITY_MASTER "priority.master" /**< deprecated, use priority.driver */
9
+# define PW_KEY_NODE_TARGET "node.target" /**< deprecated since 0.3.64, use target.object. */
10
+# else
11
+# define PW_KEY_PRIORITY_MASTER PW_DEPRECATED("priority.master")
12
+# define PW_KEY_NODE_TARGET PW_DEPRECATED("node.target")
13
+# endif /* PW_ENABLE_DEPRECATED */
14
#endif /* PW_REMOVE_DEPRECATED */
15
16
/** \}
17
pipewire-0.3.65.tar.gz/src/pipewire/log.c -> pipewire-0.3.66.tar.gz/src/pipewire/log.c
Changed
29
1
2
3
#include <spa/pod/pod.h>
4
#include <spa/debug/types.h>
5
+#include <spa/debug/format.h>
6
#include <spa/pod/iter.h>
7
#include <spa/utils/list.h>
8
9
10
{
11
struct spa_debug_log_ctx ctx = SPA_LOGF_DEBUG_INIT(global_log, level,
12
topic, file, line, func );
13
- if (flags & PW_LOG_OBJECT_POD) {
14
+ if (object == NULL) {
15
+ pw_log_logt(level, topic, file, line, func, "NULL");
16
+ } else {
17
const struct spa_pod *pod = object;
18
- if (pod == NULL) {
19
- pw_log_logt(level, topic, file, line, func, "NULL");
20
- } else {
21
+ if (flags & PW_LOG_OBJECT_POD)
22
spa_debugc_pod(&ctx.ctx, 0, SPA_TYPE_ROOT, pod);
23
- }
24
+ else if (flags & PW_LOG_OBJECT_FORMAT)
25
+ spa_debugc_format(&ctx.ctx, 0, NULL, pod);
26
}
27
}
28
29
pipewire-0.3.65.tar.gz/src/pipewire/mem.c -> pipewire-0.3.66.tar.gz/src/pipewire/mem.c
Changed
33
1
2
#include <unistd.h>
3
#include <stdlib.h>
4
#include <sys/syscall.h>
5
+#include <sys/stat.h>
6
7
#include <spa/utils/list.h>
8
#include <spa/buffer/buffer.h>
9
10
struct mapping *m;
11
struct memmap *mm;
12
struct pw_map_range range;
13
+ struct stat sb;
14
+
15
+ if (fstat(b->this.fd, &sb) != 0)
16
+ return NULL;
17
+
18
+ const bool valid = (int64_t) offset + size <= (int64_t) sb.st_size;
19
+ pw_log(valid ? SPA_LOG_LEVEL_DEBUG : SPA_LOG_LEVEL_ERROR,
20
+ "%p: block %p%u mapping %" PRIu32 "+%" PRIu32 " of file=%d/%" PRIu64 ":%" PRIu64 " with size=%" PRId64,
21
+ block->pool, block, block->id,
22
+ offset, size,
23
+ block->fd, (uint64_t) sb.st_dev, (uint64_t) sb.st_ino,
24
+ (int64_t) sb.st_size);
25
+
26
+ if (!valid) {
27
+ errno = -EINVAL;
28
+ return NULL;
29
+ }
30
31
pw_map_range_init(&range, offset, size, p->pagesize);
32
33
pipewire-0.3.65.tar.gz/src/pipewire/private.h -> pipewire-0.3.66.tar.gz/src/pipewire/private.h
Changed
18
1
2
void pw_impl_client_unref(struct pw_impl_client *client);
3
4
#define PW_LOG_OBJECT_POD (1<<0)
5
+#define PW_LOG_OBJECT_FORMAT (1<<1)
6
void pw_log_log_object(enum spa_log_level level, const struct spa_log_topic *topic,
7
const char *file, int line, const char *func, uint32_t flags,
8
const void *object);
9
10
})
11
12
#define pw_log_pod(lev,pod) pw_log_object(lev,PW_LOG_TOPIC_DEFAULT,PW_LOG_OBJECT_POD,pod)
13
-#define pw_log_format(lev,pod) pw_log_object(lev,PW_LOG_TOPIC_DEFAULT,PW_LOG_OBJECT_POD,pod)
14
+#define pw_log_format(lev,pod) pw_log_object(lev,PW_LOG_TOPIC_DEFAULT,PW_LOG_OBJECT_FORMAT,pod)
15
16
bool pw_log_is_default(void);
17
18
pipewire-0.3.65.tar.gz/src/pipewire/stream.c -> pipewire-0.3.66.tar.gz/src/pipewire/stream.c
Changed
19
1
2
struct spa_io_position *position;
3
} rt;
4
5
- uint32_t port_change_mask_all;
6
+ uint64_t port_change_mask_all;
7
struct spa_port_info port_info;
8
struct pw_properties *port_props;
9
#define PORT_EnumFormat 0
10
11
12
struct spa_list param_list;
13
14
- uint32_t change_mask_all;
15
+ uint64_t change_mask_all;
16
struct spa_node_info info;
17
#define NODE_PropInfo 0
18
#define NODE_Props 1
19
pipewire-0.3.65.tar.gz/src/pipewire/thread-loop.c -> pipewire-0.3.66.tar.gz/src/pipewire/thread-loop.c
Changed
10
1
2
*
3
*/
4
SPA_EXPORT
5
-int pw_thread_loop_timed_wait_full(struct pw_thread_loop *loop, struct timespec *abstime)
6
+int pw_thread_loop_timed_wait_full(struct pw_thread_loop *loop, const struct timespec *abstime)
7
{
8
int ret;
9
loop->n_waiting++;
10
pipewire-0.3.65.tar.gz/src/pipewire/thread-loop.h -> pipewire-0.3.66.tar.gz/src/pipewire/thread-loop.h
Changed
10
1
2
/** Release the lock and wait up to \a abstime until some thread calls
3
* \ref pw_thread_loop_signal. Use \ref pw_thread_loop_get_time to make a timeout.
4
* Since: 0.3.7 */
5
-int pw_thread_loop_timed_wait_full(struct pw_thread_loop *loop, struct timespec *abstime);
6
+int pw_thread_loop_timed_wait_full(struct pw_thread_loop *loop, const struct timespec *abstime);
7
8
/** Signal all threads waiting with \ref pw_thread_loop_wait */
9
void pw_thread_loop_signal(struct pw_thread_loop *loop, bool wait_for_accept);
10
pipewire-0.3.65.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.66.tar.gz/src/tools/pw-cat.c
Changed
58
1
2
static int encoded_playback_fill(struct data *d, void *dest, unsigned int n_frames)
3
{
4
int ret, size = 0;
5
- uint8_t buffer16384 = { 0 };
6
+ uint8_t buffer16384;
7
8
- ret = fread(buffer, 1, 16384, d->encoded_file);
9
+ ret = fread(buffer, 1, SPA_MIN(n_frames, sizeof(buffer)), d->encoded_file);
10
if (ret > 0) {
11
memcpy(dest, buffer, ret);
12
size = ret;
13
}
14
-
15
return (int)size;
16
}
17
18
19
n_frames = d->maxsize / data->stride;
20
n_frames = SPA_MIN(n_frames, (int)b->requested);
21
22
-#ifdef HAVE_PW_CAT_FFMPEG_INTEGRATION
23
- n_fill_frames = data->fill(data, p, n_frames);
24
-
25
- if (n_fill_frames > 0 || n_frames == 0) {
26
- d->chunk->offset = 0;
27
- if (data->data_type == TYPE_ENCODED) {
28
- d->chunk->stride = 0;
29
- // encoded_playback_fill returns number of bytes
30
- // read and not number of frames like other
31
- // functions for raw audio.
32
- d->chunk->size = n_fill_frames;
33
- b->size = n_fill_frames;
34
- } else {
35
- d->chunk->stride = data->stride;
36
- d->chunk->size = n_fill_frames * data->stride;
37
- b->size = n_frames;
38
- }
39
- have_data = true;
40
- } else if (n_fill_frames < 0) {
41
- fprintf(stderr, "fill error %d\n", n_fill_frames);
42
- } else {
43
- if (data->verbose)
44
- printf("drain start\n");
45
- }
46
-#else
47
n_fill_frames = data->fill(data, p, n_frames);
48
49
if (n_fill_frames > 0 || n_frames == 0) {
50
51
if (data->verbose)
52
printf("drain start\n");
53
}
54
-#endif
55
} else {
56
offset = SPA_MIN(d->chunk->offset, d->maxsize);
57
size = SPA_MIN(d->chunk->size, d->maxsize - offset);
58
pipewire-0.3.66.tar.gz/subprojects/libcamera.wrap
Added
5
1
2
+wrap-git
3
+url = https://git.libcamera.org/libcamera/libcamera.git
4
+revision = head
5