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 14
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Wed Sep 7 13:36:51 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.57
6
+
7
+-------------------------------------------------------------------
8
Thu Jul 21 12:08:38 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.56
11
pipewire-aptx.spec
Changed
18
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.56
6
+Version: 0.3.57
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
11
BuildRequires: pkgconfig
12
BuildRequires: pkgconfig(bluez)
13
BuildRequires: pkgconfig(dbus-1)
14
+BuildRequires: pkgconfig(glib-2.0)
15
BuildRequires: pkgconfig(libfreeaptx)
16
BuildRequires: pkgconfig(sbc)
17
18
pipewire-0.3.56.tar.gz/.cirrus.yml -> pipewire-0.3.57.tar.gz/.cirrus.yml
Changed
10
1
2
task:
3
freebsd_instance:
4
matrix:
5
- - image_family: freebsd-13-0-snap
6
+ - image_family: freebsd-13-1-snap
7
env:
8
# /usr/ports/Mk/Uses/localbase.mk localbase:ldflags
9
LOCALBASE: /usr/local
10
pipewire-0.3.56.tar.gz/NEWS -> pipewire-0.3.57.tar.gz/NEWS
Changed
104
1
2
+# PipeWire 0.3.57 (2022-09-02)
3
+
4
+This is a bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+
9
+## PipeWire
10
+ - Support masking of conf.d/ files. (#2629)
11
+ - Add some more debug info to memfd.
12
+ - Improve data-loop invoke method. Also flush pending items. (#2631)
13
+ - Add a filter-chain systemd service file than can be used to start
14
+ custom filters placed in ~/.conf/pipewire/filter-chain.d/ (#2553)
15
+ - Improve triggered timestamps for remote nodes.
16
+ - Fix some potential cross compilation problems due to wrong
17
+ host_machine.
18
+ - Check return values of pw_getrandom().
19
+
20
+
21
+## Tools
22
+ - Updates to pw-cli manpages. (#2552)
23
+ - Remove the pw-cli dump command. It is mostly implemented as part of
24
+ wpctl status, pw-dump, pw-link, pw-top and others.
25
+ - Clean up resource in pw-cat correctly on errors. (#2651)
26
+
27
+## Modules
28
+ - Fix compilation of AVB on big-endian. Enable AVB only on Linux.
29
+ - Use org.freedesktop.portal.Realtime when available. This does the
30
+ correct PID/TID mappings to make realtime also work from flatpaks.
31
+ - Fix compilation of ROC module when headers are missing. (#2513)
32
+ - Improve some error cleanup paths in protocol-native. Improve connect
33
+ and disconnect.
34
+ - Fix a potential crash in FFT unload in filter-chain.
35
+ - Implement PIPEWIRE_NOTIFICATION_FD for notification when the socket
36
+ is ready.
37
+ - Try to use rtkit if set_nice() fails.
38
+ - Fix rate adjustement logic in pulse-tunnel. This would cause
39
+ increasing delays and hickups when using tunnels. (#2548)
40
+ - Handle disconnect in pulse-tunnel.
41
+
42
+## Bluetooth
43
+ - Add OPUS as a new vendor codec. Add OPUS-A2DP spec. PipeWire can now
44
+ send and reveive OPUS data over bluetooth.
45
+ - An AAC decoder was added so that PipeWire can now also function as
46
+ an A2DP AAC receiver.
47
+
48
+## SPA
49
+ - Tweak the resampler window function some more. (#2574)
50
+ - Improve format convert performance in some fallback cases.
51
+ - Fix rounding in format conversion on ARM NEON.
52
+ - Fix libcamera build error. (#2575)
53
+ - Fix some issues where the wrong samplerate was used. (#2614)
54
+ - Don't wait for more samples that can fit in the ringbuffer in ALSA.
55
+ - Improve buffer size handling in audioconvert, scale the buffers based
56
+ on the rate conversion and make things work with really large rate
57
+ conversions as well.
58
+ - Add more and better debug for ALSA devices.
59
+ - Improve channel mix: Filter FC and LFE when copying from a different
60
+ layout. Implement STEREO from FC. Avoid generating REAR from FC in PSD
61
+ mode.
62
+ - Fix rate match for sources. This fixes an error where follower sources
63
+ would generate many resync warnings.
64
+ - Improve ALSA format negotiation. If the ALSA node is not running and
65
+ there was a previously configured format, close and reopen the device
66
+ to enumerate and accept all possible formats again. (#2625).
67
+
68
+## ALSA
69
+ - The alsa plugin will now also save the volumes set with the control
70
+ API. This saves the volumes set with alsa-mixer, for example.
71
+
72
+## Pulse-server
73
+ - Flatpak apps with devices=all (Zoom) will now be granted Manager
74
+ permissions.
75
+ - Small tweaks to the amount of data sent to clients to work around an
76
+ issue in freerdp.
77
+
78
+## JACK
79
+ - Clean up the transport correctly when closing a client. (#2569)
80
+ - Match context properties in addition to node properties for the jack
81
+ client rules. (#2580)
82
+ - Make sure to return an error when disconnected from the server. (#2606)
83
+ - Fix thread cast problem in jack_client_thread_id().
84
+ - Increase jack_client_name_size() length and make sure we have space for
85
+ the \0 byte.
86
+ - JACK clients from the same application will be added to the same group
87
+ so that they share the quantum and rate.
88
+
89
+
90
+Older versions:
91
+
92
# PipeWire 0.3.56 (2022-07-19)
93
94
This is a quick bugfix release that is API and ABI compatible with previous
95
96
- Add the resampler delay to delay reporting as well.
97
98
99
-Older versions:
100
-
101
# PipeWire 0.3.55 (2022-07-12)
102
103
This is a quick bugfix release that is API and ABI compatible with previous
104
pipewire-0.3.56.tar.gz/doc/tutorial3.c -> pipewire-0.3.57.tar.gz/doc/tutorial3.c
Changed
124
1
2
#include <pipewire/pipewire.h>
3
4
/* roundtrip */
5
-static int roundtrip(struct pw_core *core, struct pw_main_loop *loop)
6
+struct roundtrip_data {
7
+ int pending;
8
+ struct pw_main_loop *loop;
9
+};
10
+
11
+static void on_core_done(void *data, uint32_t id, int seq)
12
+{
13
+ struct roundtrip_data *d = data;
14
+
15
+ if (id == PW_ID_CORE && seq == d->pending)
16
+ pw_main_loop_quit(d->loop);
17
+}
18
+
19
+static void roundtrip(struct pw_core *core, struct pw_main_loop *loop)
20
{
21
- struct spa_hook core_listener;
22
- int pending, done = 0;
23
- void core_event_done(void *object, uint32_t id, int seq) {
24
- if (id == PW_ID_CORE && seq == pending) {
25
- done = 1;
26
- pw_main_loop_quit(loop);
27
- }
28
- }
29
- const struct pw_core_events core_events = {
30
- PW_VERSION_CORE_EVENTS,
31
- .done = core_event_done,
32
- };
33
-
34
- spa_zero(core_listener);
35
- pw_core_add_listener(core, &core_listener,
36
- &core_events, NULL);
37
-
38
- pending = pw_core_sync(core, PW_ID_CORE, 0);
39
-
40
- while (!done) {
41
- pw_main_loop_run(loop);
42
- }
43
- spa_hook_remove(&core_listener);
44
- return 0;
45
+ static const struct pw_core_events core_events = {
46
+ PW_VERSION_CORE_EVENTS,
47
+ .done = on_core_done,
48
+ };
49
+
50
+ struct roundtrip_data d = { .loop = loop };
51
+ struct spa_hook core_listener;
52
+
53
+ pw_core_add_listener(core, &core_listener, &core_events, &d);
54
+
55
+ d.pending = pw_core_sync(core, PW_ID_CORE, 0);
56
+
57
+ pw_main_loop_run(loop);
58
+
59
+ spa_hook_remove(&core_listener);
60
}
61
/* roundtrip */
62
63
64
65
int main(int argc, char *argv)
66
{
67
- struct pw_main_loop *loop;
68
- struct pw_context *context;
69
- struct pw_core *core;
70
- struct pw_registry *registry;
71
- struct spa_hook registry_listener;
72
+ struct pw_main_loop *loop;
73
+ struct pw_context *context;
74
+ struct pw_core *core;
75
+ struct pw_registry *registry;
76
+ struct spa_hook registry_listener;
77
78
- pw_init(&argc, &argv);
79
+ pw_init(&argc, &argv);
80
81
- loop = pw_main_loop_new(NULL /* properties */);
82
- context = pw_context_new(pw_main_loop_get_loop(loop),
83
- NULL /* properties */,
84
- 0 /* user_data size */);
85
+ loop = pw_main_loop_new(NULL /* properties */);
86
+ context = pw_context_new(pw_main_loop_get_loop(loop),
87
+ NULL /* properties */,
88
+ 0 /* user_data size */);
89
90
- core = pw_context_connect(context,
91
- NULL /* properties */,
92
- 0 /* user_data size */);
93
+ core = pw_context_connect(context,
94
+ NULL /* properties */,
95
+ 0 /* user_data size */);
96
97
- registry = pw_core_get_registry(core, PW_VERSION_REGISTRY,
98
- 0 /* user_data size */);
99
+ registry = pw_core_get_registry(core, PW_VERSION_REGISTRY,
100
+ 0 /* user_data size */);
101
102
- spa_zero(registry_listener);
103
- pw_registry_add_listener(registry, ®istry_listener,
104
- ®istry_events, NULL);
105
+ pw_registry_add_listener(registry, ®istry_listener,
106
+ ®istry_events, NULL);
107
108
- roundtrip(core, loop);
109
+ roundtrip(core, loop);
110
111
- pw_proxy_destroy((struct pw_proxy*)registry);
112
- pw_core_disconnect(core);
113
- pw_context_destroy(context);
114
- pw_main_loop_destroy(loop);
115
+ pw_proxy_destroy((struct pw_proxy*)registry);
116
+ pw_core_disconnect(core);
117
+ pw_context_destroy(context);
118
+ pw_main_loop_destroy(loop);
119
120
- return 0;
121
+ return 0;
122
}
123
/* code */
124
pipewire-0.3.56.tar.gz/doc/tutorial3.dox -> pipewire-0.3.57.tar.gz/doc/tutorial3.dox
Changed
114
1
2
Let's take a look at what this method does.
3
4
\code{.c}
5
- struct spa_hook core_listener;
6
- spa_zero(core_listener);
7
- pw_core_add_listener(core, &core_listener,
8
- &core_events, NULL);
9
+ struct spa_hook core_listener;
10
+
11
+ pw_core_add_listener(core, &core_listener, &core_events, &d);
12
\endcode
13
14
First of all we add a listener for the events of the core
15
16
tutorial. This is the event handler:
17
18
\code{.c}
19
- int pending, done = 0;
20
-
21
- void core_event_done(void *data, uint32_t id, int seq) {
22
- if (id == PW_ID_CORE && seq == pending) {
23
- done = 1;
24
- pw_main_loop_quit(loop);
25
- }
26
- }
27
- const struct pw_core_events core_events = {
28
- PW_VERSION_CORE_EVENTS,
29
- .done = core_event_done,
30
- };
31
+static void on_core_done(void *data, uint32_t id, int seq)
32
+{
33
+ struct roundtrip_data *d = data;
34
+
35
+ if (id == PW_ID_CORE && seq == d->pending)
36
+ pw_main_loop_quit(d->loop);
37
+}
38
\endcode
39
40
-When the done event is received for an object with id `PW_ID_CORE`
41
-and a certain sequence number `seq`, this function will set the done
42
-variable to 1 and call `pw_main_loop_quit()`.
43
+When the done event is received for an object with id `PW_ID_CORE` and
44
+a certain sequence number `seq`, this function will call `pw_main_loop_quit()`.
45
46
Next we do:
47
48
\code{.c}
49
- pending = pw_core_sync(core, PW_ID_CORE, 0);
50
+ d.pending = pw_core_sync(core, PW_ID_CORE, 0);
51
\endcode
52
53
This triggers the `sync` method on the core object with id
54
`PW_ID_CORE` and sequence number 0.
55
56
Because this is a method on a proxy object, it will be executed
57
-asynchronously and the returns value will reflect this. PipeWire
58
+asynchronously and the return value will reflect this. PipeWire
59
uses the return values of the underlying SPA (Simple Plugin API)
60
-helper objects (See also error codes(spa-design.md#error-codes)).
61
+helper objects (See also \ref page_spa_design ).
62
63
Because all messages on the PipeWire server are handled sequentially,
64
the sync method will be executed after all previous methods are
65
66
receive the events:
67
68
\code{.c}
69
- while (!done) {
70
- pw_main_loop_run(loop);
71
- }
72
+ pw_main_loop_run(loop);
73
\endcode
74
75
When we get the done event, we can compare it to the sync method
76
77
remove the listener:
78
79
\code{.c}
80
- spa_hook_remove(&core_listener);
81
+ spa_hook_remove(&core_listener);
82
\endcode
83
84
If we add this roundtrip method to our code and call it instead of the
85
86
created them:
87
88
\code{.c}
89
- pw_proxy_destroy((struct pw_proxy*)registry);
90
+ pw_proxy_destroy((struct pw_proxy*)registry);
91
\endcode
92
93
The registry is a proxy and can be destroyed with the generic proxy destroy
94
95
We can disconnect from the server with:
96
97
\code{.c}
98
- pw_core_disconnect(core);
99
+ pw_core_disconnect(core);
100
\endcode
101
102
This will also destroy the core proxy object and will remove the proxies
103
104
We can finally destroy our context and mainloop to conclude this tutorial:
105
106
\code{.c}
107
- pw_context_destroy(context);
108
- pw_main_loop_destroy(loop);
109
+ pw_context_destroy(context);
110
+ pw_main_loop_destroy(loop);
111
\endcode
112
113
\ref page_tutorial2 | \ref page_tutorial "Index" | \ref page_tutorial4
114
pipewire-0.3.56.tar.gz/man/pw-cli.1.rst.in -> pipewire-0.3.57.tar.gz/man/pw-cli.1.rst.in
Changed
100
1
2
GENERAL COMMANDS
3
================
4
5
-help
6
- Show a quick help on the commands available.
7
+help | h
8
+ Show a quick help on the commands available. It also lists the aliases
9
+ for many commands.
10
11
-quit
12
+quit | q
13
Exit from **pw-cli**
14
15
MODULE MANAGEMENT
16
=================
17
18
-| Modules are loaded and unloaded in the local instance and can add
19
-| functionality or objects to the local instance.
20
+| Modules are loaded and unloaded in the local instance, thus the pw-cli
21
+| binary itself and can add functionality or objects to the local
22
+| instance. It is not possible in PipeWire to load modules in another
23
+| instance.
24
25
load-module *name* *arguments...*
26
Load a module specified by its name and arguments. For most
27
28
29
This command returns a *node variable*.
30
31
-destroy-node *node-var*
32
- Destroy a node.
33
-
34
export-node *node-id* *remote-var*
35
Export a node from the local instance to the specified instance.
36
When no instance is specified, the node will be exported to the current
37
instance.
38
39
+DEVICE MANAGEMENT
40
+=================
41
+
42
+create-device *factory-name* *properties...*
43
+ Create a device from a factory in the current instance.
44
+
45
+ Properties are key=value pairs separated by whitespace.
46
+
47
+ This command returns a *device variable*.
48
+
49
+
50
LINK MANAGEMENT
51
===============
52
53
54
55
This command returns a *link variable*.
56
57
-destroy-link *link-var*
58
- Destroy a link.
59
+GLOBALS MANAGEMENT
60
+==================
61
+
62
+destroy *object-id*
63
+ Destroy a global object.
64
+
65
+
66
+PARAMETER MANAGEMENT
67
+====================
68
+
69
+enum-params *object-id* *param-id*
70
+ Enumerate params of an object.
71
+
72
+ *param-id* can also be given as the param short name.
73
+
74
+set-param *object-id* *param-id* *param-json*
75
+ Set param of an object.
76
+
77
+ *param-id* can also be given as the param short name.
78
+
79
+PERMISSION MANAGEMENT
80
+=====================
81
+
82
+permissions *client-id* *object-id* *permission*
83
+ Set permissions for a client.
84
+
85
+ *object-id* can be *-1* to set the default permissions.
86
+
87
+get-permissions *client-id*
88
+ Get permissions of a client.
89
+
90
+
91
+COMMAND MANAGEMENT
92
+==================
93
+
94
+send-command *object-id*
95
+ Send a command to an object.
96
+
97
98
EXAMPLES
99
========
100
pipewire-0.3.56.tar.gz/meson.build -> pipewire-0.3.57.tar.gz/meson.build
Changed
43
1
2
project('pipewire', 'c' ,
3
- version : '0.3.56',
4
+ version : '0.3.57',
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
cap_lib = dependency('libcap', required : false)
10
cdata.set('HAVE_LIBCAP', cap_lib.found())
11
12
+glib2_dep = dependency('glib-2.0', required : get_option('flatpak'))
13
+summary({'GLib-2.0 (Flatpak support)': glib2_dep.found()}, bool_yn: true, section: 'Misc dependencies')
14
+flatpak_support = glib2_dep.found()
15
+cdata.set('HAVE_GLIB2', flatpak_support)
16
+
17
gst_option = get_option('gstreamer')
18
gst_deps_def = {
19
'glib-2.0': {'version': '>=2.32.0'},
20
21
cdata.set('HAVE_WEBRTC', webrtc_dep.found())
22
23
# On FreeBSD and MidnightBSD, epoll-shim library is required for eventfd() and timerfd()
24
-epoll_shim_dep = (build_machine.system() == 'freebsd' or build_machine.system() == 'midnightbsd'
25
+epoll_shim_dep = (host_machine.system() == 'freebsd' or host_machine.system() == 'midnightbsd'
26
? dependency('epoll-shim', required: true)
27
: dependency('', required: false))
28
29
-libinotify_dep = (build_machine.system() == 'freebsd' or build_machine.system() == 'midnightbsd'
30
+libinotify_dep = (host_machine.system() == 'freebsd' or host_machine.system() == 'midnightbsd'
31
? dependency('libinotify', required: true)
32
: dependency('', required: false))
33
34
35
alsa_dep = dependency('alsa', version : '>=1.1.7', required: need_alsa)
36
summary({'pipewire-alsa': alsa_dep.found()}, bool_yn: true)
37
38
-if build_machine.system() == 'freebsd' or build_machine.system() == 'midnightbsd'
39
+if host_machine.system() == 'freebsd' or host_machine.system() == 'midnightbsd'
40
# On FreeBSD and MidnightBSD the OpenSSL library may come from base or a package.
41
# Check for a package first and fallback to the base library if we can't find it via pkgconfig
42
openssl_lib = dependency('openssl', required: false)
43
pipewire-0.3.56.tar.gz/meson_options.txt -> pipewire-0.3.57.tar.gz/meson_options.txt
Changed
20
1
2
description: 'Enable LC3plus open source codec implementation',
3
type: 'feature',
4
value: 'auto')
5
+option('bluez5-codec-opus',
6
+ description: 'Enable Opus open source codec implementation',
7
+ type: 'feature',
8
+ value: 'auto')
9
option('control',
10
description: 'Enable control spa plugin integration',
11
type: 'feature',
12
13
description: 'Enable AVB code',
14
type: 'feature',
15
value: 'auto')
16
+option('flatpak',
17
+ description: 'Enable Flatpak support',
18
+ type: 'feature',
19
+ value: 'enabled')
20
pipewire-0.3.56.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c -> pipewire-0.3.57.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c
Changed
9
1
2
spa_pod_builder_add(&b,
3
SPA_PARAM_ROUTE_index, SPA_POD_Int(id),
4
SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id),
5
+ SPA_PARAM_ROUTE_save, SPA_POD_Bool(true),
6
0);
7
8
spa_pod_builder_prop(&b, SPA_PARAM_ROUTE_props, 0);
9
pipewire-0.3.56.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.57.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
92
1
2
3
#define DEFAULT_RT_MAX 88
4
5
-#define JACK_CLIENT_NAME_SIZE 128
6
+#define JACK_CLIENT_NAME_SIZE 256
7
#define JACK_PORT_NAME_SIZE 256
8
#define JACK_PORT_TYPE_SIZE 32
9
#define MONITOR_EXT " Monitor"
10
11
} else { \
12
if (c->active) \
13
(expr); \
14
- pw_log_debug("skip " #callback \
15
+ pw_log_debug("skip " #callback \
16
" cb:%p active:%d", c->callback, \
17
c->active); \
18
} \
19
20
res = c->callback(__VA_ARGS__); \
21
c->rt_locked = false; \
22
pthread_mutex_unlock(&c->rt_lock); \
23
+ } else { \
24
+ pw_log_debug("skip " #callback \
25
+ " cb:%p", c->callback); \
26
} \
27
} \
28
res; \
29
30
pw_log_warn("sync requested from callback");
31
return 0;
32
}
33
+ if (client->last_res == -EPIPE)
34
+ return -EPIPE;
35
36
client->last_res = 0;
37
client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync);
38
39
"jack.properties", client->props);
40
41
pw_context_conf_section_match_rules(client->context.context, "jack.rules",
42
- &client->props->dict, execute_match, client);
43
+ &client->context.context->properties->dict, execute_match, client);
44
45
support = pw_context_get_support(client->context.context, &n_support);
46
47
48
}
49
if (pw_properties_get(client->props, PW_KEY_NODE_NAME) == NULL)
50
pw_properties_set(client->props, PW_KEY_NODE_NAME, client_name);
51
+ if (pw_properties_get(client->props, PW_KEY_NODE_GROUP) == NULL)
52
+ pw_properties_setf(client->props, PW_KEY_NODE_GROUP, "jack-%d", getpid());
53
if (pw_properties_get(client->props, PW_KEY_NODE_DESCRIPTION) == NULL)
54
pw_properties_set(client->props, PW_KEY_NODE_DESCRIPTION, client_name);
55
if (pw_properties_get(client->props, PW_KEY_MEDIA_TYPE) == NULL)
56
57
58
res = jack_deactivate(client);
59
60
+ clean_transport(c);
61
+
62
if (c->context.loop)
63
pw_thread_loop_stop(c->context.loop);
64
65
66
SPA_EXPORT
67
int jack_client_name_size (void)
68
{
69
- pw_log_trace("%d", JACK_CLIENT_NAME_SIZE);
70
- return JACK_CLIENT_NAME_SIZE;
71
+ /* The JACK API specifies that this value includes the final NULL character. */
72
+ pw_log_trace("%d", JACK_CLIENT_NAME_SIZE+1);
73
+ return JACK_CLIENT_NAME_SIZE+1;
74
}
75
76
SPA_EXPORT
77
78
struct client *c = (struct client *) client;
79
void *thr;
80
81
- spa_return_val_if_fail(c != NULL, -EINVAL);
82
+ spa_return_val_if_fail(c != NULL, (pthread_t){0});
83
84
thr = pw_data_loop_get_thread(c->loop);
85
if (thr == NULL)
86
return pthread_self();
87
- return *(pthread_t*)thr;
88
+ return (pthread_t) thr;
89
}
90
91
SPA_EXPORT
92
pipewire-0.3.56.tar.gz/po/LINGUAS -> pipewire-0.3.57.tar.gz/po/LINGUAS
Changed
9
1
2
id
3
it
4
ja
5
+ka
6
kk
7
kn
8
ko
9
pipewire-0.3.56.tar.gz/po/ca.po -> pipewire-0.3.57.tar.gz/po/ca.po
Changed
201
1
2
# Xavier Conde Rueda <xavi.conde@gmail.com>, 2008.
3
# Agustí Grau <fletxa@gmail.com>, 2009.
4
# Judith Pintó Subirada <judithp@gmail.com>
5
+# Jordi Mas i Herǹandez, <jmas@softcatala.org>, 2022
6
#
7
# This file is translated according to the glossary and style guide of
8
# Softcatalà. If you plan to modify this file, please read first the page
9
10
msgid ""
11
msgstr ""
12
"Project-Id-Version: pipewire\n"
13
-"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
14
-"issues/new\n"
15
+"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/issues/new\n"
16
"POT-Creation-Date: 2021-04-18 16:54+0800\n"
17
-"PO-Revision-Date: 2012-01-30 09:52+0000\n"
18
-"Last-Translator: Josep Torné Llavall <josep.torne@gmail.com>\n"
19
+"PO-Revision-Date: 2022-09-01 19:24+0000\n"
20
+"Last-Translator: Jordi Mas i Herǹandez, <jmas@softcatala.org>,\n"
21
"Language-Team: Catalan <fedora@softcatala.net>\n"
22
"Language: ca\n"
23
"MIME-Version: 1.0\n"
24
25
" --version Show version\n"
26
" -c, --config Load config (Default %s)\n"
27
msgstr ""
28
+"%s opcions\n"
29
+" -h, --help Mostra aquesta ajuda\n"
30
+" --version Mostra la versió\n"
31
+" -c, --config Carrega la configuració (predeterminada %s)\n"
32
33
#: src/daemon/pipewire.desktop.in:4
34
msgid "PipeWire Media System"
35
-msgstr ""
36
+msgstr "Sistema multimèdia PipeWire"
37
38
#: src/daemon/pipewire.desktop.in:5
39
msgid "Start the PipeWire Media System"
40
-msgstr ""
41
+msgstr "Inicia el sistema multimèdia PipeWire"
42
43
#: src/examples/media-session/alsa-monitor.c:526
44
#: spa/plugins/alsa/acp/compat.c:187
45
46
47
#: src/examples/media-session/alsa-monitor.c:539
48
msgid "Unknown device"
49
-msgstr ""
50
+msgstr "Dispositiu desconegut"
51
52
#: src/tools/pw-cat.c:991
53
#, c-format
54
55
" -v, --verbose Enable verbose operations\n"
56
"\n"
57
msgstr ""
58
+"%s opcions <fitxer>\n"
59
+" -h, --help Mostra aquesta ajuda\n"
60
+" --version Mostra la versió\n"
61
+" -v, --verbose Habilita les operacions detallades\n"
62
63
#: src/tools/pw-cat.c:998
64
-#, c-format
65
+#, c-format, fuzzy
66
msgid ""
67
" -R, --remote Remote daemon name\n"
68
" --media-type Set media type (default %s)\n"
69
70
" --latency Set node latency (default %s)\n"
71
" Xunit (unit = s, ms, us, ns)\n"
72
" or direct samples (256)\n"
73
-" the rate is the one of the source "
74
-"file\n"
75
+" the rate is the one of the source file\n"
76
" --list-targets List available targets for --target\n"
77
"\n"
78
msgstr ""
79
+"-R, --remote Nom del dimoni remot\n"
80
+" --media-type Estableix el tipus de mitjà (per defecte %s)\n"
81
+" --media-category Estableix la categoria dels mitjans (per defecte %s)\n"
82
+" --media-role Estableix el rol del mitjà (per defecte %s)\n"
83
+" --target Estableix l'objectiu del node (per defecte %s)\n"
84
+" 0 vol dir que no enllaça\n"
85
+" --latency Estableix latència del node (per defecte %s)\n"
86
+" Xunit (unitat = s, ms, us, ns)\n"
87
+" o mostres directes (256)\n"
88
+" la taxa és la del fitxer d'origen\n"
89
+" --list-targets Llista d'objectius disponibles per a --target"
90
91
#: src/tools/pw-cat.c:1016
92
-#, c-format
93
+#, c-format, fuzzy
94
msgid ""
95
-" --rate Sample rate (req. for rec) (default "
96
-"%u)\n"
97
-" --channels Number of channels (req. for rec) "
98
-"(default %u)\n"
99
+" --rate Sample rate (req. for rec) (default %u)\n"
100
+" --channels Number of channels (req. for rec) (default %u)\n"
101
" --channel-map Channel map\n"
102
-" one of: \"stereo\", "
103
-"\"surround-51\",... or\n"
104
-" comma separated list of channel "
105
-"names: eg. \"FL,FR\"\n"
106
-" --format Sample format %s (req. for rec) "
107
-"(default %s)\n"
108
+" one of: \"stereo\", \"surround-51\",... or\n"
109
+" comma separated list of channel names: eg. \"FL,FR\"\n"
110
+" --format Sample format %s (req. for rec) (default %s)\n"
111
" --volume Stream volume 0-1.0 (default %.3f)\n"
112
-" -q --quality Resampler quality (0 - 15) (default "
113
-"%d)\n"
114
+" -q --quality Resampler quality (0 - 15) (default %d)\n"
115
"\n"
116
msgstr ""
117
+"--rate Freqüència de mostreig (req. per rec) (predeterminat %u)\n"
118
+" --channels Nombre de canals (req. per rec) (predeterminat %u)\n"
119
+" --channel-map Mapa de canals\n"
120
+" un dels següents: \"estèreo\", \"surround-51\",... o\n"
121
+" Llista separada per comes dels noms dels canals: per exemple. \"FL,FR\"\n"
122
+" --format Format de mostra %s (req. per a rec) (predeterminat %s)\n"
123
+" --volume Volum de flux 0-1.0 (predeterminat %.3f)\n"
124
+" -q --qualitat Remostrador de qualitat (0 - 15) (per defecte %d)"
125
126
#: src/tools/pw-cat.c:1033
127
+#, fuzzy
128
msgid ""
129
" -p, --playback Playback mode\n"
130
" -r, --record Recording mode\n"
131
" -m, --midi Midi mode\n"
132
"\n"
133
msgstr ""
134
+"-p, --playback Mode de reproducció\n"
135
+" -r, --record mode d'enregistrament\n"
136
+" -m, --midi Mode MIDI"
137
138
#: src/tools/pw-cli.c:2932
139
-#, c-format
140
+#, c-format, fuzzy
141
msgid ""
142
"%s options command\n"
143
" -h, --help Show this help\n"
144
145
" -r, --remote Remote daemon name\n"
146
"\n"
147
msgstr ""
148
+"%s opcions ordre\n"
149
+" -h, --help Mostra aquesta ajuda\n"
150
+" --version Mostra la versió\n"
151
+" -d, --daemon Inicia com a dimoni (fals predeterminat)\n"
152
+" -r, --remote Nom del dimoni remot"
153
154
#: spa/plugins/alsa/acp/acp.c:290
155
msgid "Pro Audio"
156
-msgstr ""
157
+msgstr "Pro Audio"
158
159
#: spa/plugins/alsa/acp/acp.c:411 spa/plugins/alsa/acp/alsa-mixer.c:4704
160
#: spa/plugins/bluez5/bluez5-device.c:1000
161
162
163
#: spa/plugins/alsa/acp/alsa-mixer.c:2801
164
msgid "Dock Microphone"
165
-msgstr ""
166
+msgstr "Micròfon de l'acoblador"
167
168
#: spa/plugins/alsa/acp/alsa-mixer.c:2803
169
msgid "Headset Microphone"
170
-msgstr ""
171
+msgstr "Micròfon d'auriculars"
172
173
#: spa/plugins/alsa/acp/alsa-mixer.c:2807
174
msgid "Analog Output"
175
msgstr "Sortida analògica"
176
177
#: spa/plugins/alsa/acp/alsa-mixer.c:2809
178
-#, fuzzy
179
msgid "Headphones 2"
180
-msgstr "Auriculars"
181
+msgstr "Auriculars 2"
182
183
#: spa/plugins/alsa/acp/alsa-mixer.c:2810
184
-#, fuzzy
185
msgid "Headphones Mono Output"
186
-msgstr "Sortida mono analògica"
187
+msgstr "Sortida mono dels auriculars"
188
189
#: spa/plugins/alsa/acp/alsa-mixer.c:2811
190
msgid "Line Out"
191
192
msgstr "Entrada digital (S/PDIF)"
193
194
#: spa/plugins/alsa/acp/alsa-mixer.c:2817
195
-#, fuzzy
196
msgid "Multichannel Input"
197
-msgstr "Multicanal"
198
+msgstr "Entrada multicanal"
199
200
#: spa/plugins/alsa/acp/alsa-mixer.c:2818
201
pipewire-0.3.56.tar.gz/po/gl.po -> pipewire-0.3.57.tar.gz/po/gl.po
Changed
201
1
2
# Translators:
3
# bassball93 <bassball93@gmail.com>, 2011.
4
# mbouzada <mbouzada@gmail.com>, 2011.
5
-# Fran Dieguez <frandieguez@gnome.org>, 2012, 2019.
6
# Marcos Lans <marcoslansgarza@gmail.com>, 2018.
7
+# Fran Dieguez <frandieguez@gnome.org>, 2012-2022.
8
+#
9
msgid ""
10
msgstr ""
11
"Project-Id-Version: PipeWire\n"
12
-"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
13
-"issues/new\n"
14
-"POT-Creation-Date: 2021-04-18 16:54+0800\n"
15
-"PO-Revision-Date: 2019-02-20 01:36+0200\n"
16
+"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
17
+"issues\n"
18
+"POT-Creation-Date: 2022-07-10 03:27+0000\n"
19
+"PO-Revision-Date: 2022-08-23 09:47+0200\n"
20
"Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n"
21
-"Language-Team: Galician\n"
22
+"Language-Team: Galician <Proxecto Trasno <proxecto@trasno.gal>>\n"
23
"Language: gl\n"
24
"MIME-Version: 1.0\n"
25
"Content-Type: text/plain; charset=UTF-8\n"
26
"Content-Transfer-Encoding: 8bit\n"
27
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
28
-"X-Generator: Virtaal 0.7.1\n"
29
-
30
-#: src/daemon/pipewire.c:43
31
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
32
+"X-Generator: Gtranslator 40.0\n"
33
+"X-DL-Team: gl\n"
34
+"X-DL-Module: PipeWire\n"
35
+"X-DL-Branch: master\n"
36
+"X-DL-Domain: po\n"
37
+"X-DL-State: Translating\n"
38
+
39
+#: src/daemon/pipewire.c:46
40
#, c-format
41
msgid ""
42
"%s options\n"
43
44
" --version Show version\n"
45
" -c, --config Load config (Default %s)\n"
46
msgstr ""
47
+"%s opcións\n"
48
+" -h, --help Mostra esta axuda\n"
49
+" --version Mostrar versión\n"
50
+" -c, --config Cargar configuración (Predeterminado "
51
+"%s)\n"
52
53
#: src/daemon/pipewire.desktop.in:4
54
msgid "PipeWire Media System"
55
56
msgid "Start the PipeWire Media System"
57
msgstr "Iniciar o Sistema multimedia PipeWire"
58
59
-#: src/examples/media-session/alsa-monitor.c:526
60
-#: spa/plugins/alsa/acp/compat.c:187
61
-msgid "Built-in Audio"
62
-msgstr "Audio interno"
63
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180
64
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
65
+#, c-format
66
+msgid "Tunnel to %s/%s"
67
+msgstr "Túnel a %s/%s"
68
69
-#: src/examples/media-session/alsa-monitor.c:530
70
-#: spa/plugins/alsa/acp/compat.c:192
71
-msgid "Modem"
72
-msgstr "Módem"
73
+#: src/modules/module-fallback-sink.c:51
74
+#| msgid "Game Output"
75
+msgid "Dummy Output"
76
+msgstr "Saída de proba"
77
78
-#: src/examples/media-session/alsa-monitor.c:539
79
+#: src/modules/module-pulse-tunnel.c:648
80
+#, c-format
81
+msgid "Tunnel for %s@%s"
82
+msgstr "Túnel para %s@%s"
83
+
84
+#: src/modules/module-zeroconf-discover.c:332
85
msgid "Unknown device"
86
-msgstr ""
87
+msgstr "Dispositivo descoñecido"
88
+
89
+#: src/modules/module-zeroconf-discover.c:344
90
+#, c-format
91
+msgid "%s on %s@%s"
92
+msgstr "%s en %s@%s"
93
+
94
+#: src/modules/module-zeroconf-discover.c:348
95
+#, c-format
96
+msgid "%s on %s"
97
+msgstr "%s en %s"
98
99
-#: src/tools/pw-cat.c:991
100
+#: src/tools/pw-cat.c:784
101
#, c-format
102
msgid ""
103
-"%s options <file>\n"
104
+"%s options <file>|-\n"
105
" -h, --help Show this help\n"
106
" --version Show version\n"
107
" -v, --verbose Enable verbose operations\n"
108
"\n"
109
msgstr ""
110
+"%s opcións <ficheiro>|-\n"
111
+" -h, --help Mostrar esta axuda\n"
112
+" --version Mostrar versión\n"
113
+" -v, --verbose Activar operacións verbosas\n"
114
+"\n"
115
116
-#: src/tools/pw-cat.c:998
117
+#: src/tools/pw-cat.c:791
118
#, c-format
119
msgid ""
120
" -R, --remote Remote daemon name\n"
121
122
" or direct samples (256)\n"
123
" the rate is the one of the source "
124
"file\n"
125
-" --list-targets List available targets for --target\n"
126
+" -P --properties Set node properties\n"
127
"\n"
128
msgstr ""
129
+" -R, --remote Nome do daemon remoto\n"
130
+" --media-type Estabelecer o tipo de medio (por "
131
+"omisión %s)\n"
132
+" --media-category Estabelecer a categoría multimedia "
133
+"(por omisión %s)\n"
134
+" --media-role Estabelecer o rol multimedia (por "
135
+"omisión %s)\n"
136
+" --target Estabelecer o nodo obxectivo (por "
137
+"omisión %s)\n"
138
+" 0 significa non ligar\n"
139
+" --latency Estabelecer a latencia do nodo (por "
140
+"omisión %s)\n"
141
+" Xunit (unidade = s, ms, us, ns)\n"
142
+" ou mostras directas samples (256)\n"
143
+" a taxa é un dos ficheiros de "
144
+"orixe\n"
145
+" -P --properties Estabelecer as propiedades do nodo\n"
146
+"\n"
147
148
-#: src/tools/pw-cat.c:1016
149
+#: src/tools/pw-cat.c:809
150
#, c-format
151
msgid ""
152
" --rate Sample rate (req. for rec) (default "
153
154
"%d)\n"
155
"\n"
156
msgstr ""
157
+" --rate Taxa de mostreo (solicitudes por "
158
+"segundo) (por omisión %u)\n"
159
+" --channels Número de canles (solicitudes por "
160
+"segundo) (por omisión %u)\n"
161
+" --channel-map Mapa de canles\n"
162
+" un de: \"stereo\", "
163
+"\"surround-51\",... or\n"
164
+" lista separada por comas dos "
165
+"nomes das canles: p.ex. \"FL,FR\"\n"
166
+" --format Formato de mostras %s (solicitudes "
167
+"por segundo) (por omisión %s)\n"
168
+" --volume Volume do fluxo 0-1.0 (por omisión "
169
+"%.3f)\n"
170
+" -q --quality Calidade do remostreador (0 - 15) "
171
+"(por omisión %d)\n"
172
+"\n"
173
174
-#: src/tools/pw-cat.c:1033
175
+#: src/tools/pw-cat.c:826
176
msgid ""
177
" -p, --playback Playback mode\n"
178
" -r, --record Recording mode\n"
179
" -m, --midi Midi mode\n"
180
+" -d, --dsd DSD mode\n"
181
"\n"
182
msgstr ""
183
+" -p, --playback Modo de reprodución\n"
184
+" -r, --record Modo de grabación\n"
185
+" -m, --midi Modo MIDI\n"
186
+" -d, --dsd Modo DSD\n"
187
+"\n"
188
189
-#: src/tools/pw-cli.c:2932
190
+#: src/tools/pw-cli.c:3165
191
#, c-format
192
msgid ""
193
"%s options command\n"
194
195
" -r, --remote Remote daemon name\n"
196
"\n"
197
msgstr ""
198
+"%s opcións orde\n"
199
+" -h, --help Mostrar esta axuda\n"
200
+" --version Mostrar versión\n"
201
pipewire-0.3.57.tar.gz/po/ka.po
Added
201
1
2
+# SOME DESCRIPTIVE TITLE.
3
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
4
+# This file is distributed under the same license as the pipewire package.
5
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
6
+#
7
+msgid ""
8
+msgstr ""
9
+"Project-Id-Version: pipewire\n"
10
+"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
11
+"issues/new\n"
12
+"POT-Creation-Date: 2022-06-30 12:50+0200\n"
13
+"PO-Revision-Date: 2022-07-25 13:11+0200\n"
14
+"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n"
15
+"Language-Team: Georgian <(nothing)>\n"
16
+"Language: ka\n"
17
+"MIME-Version: 1.0\n"
18
+"Content-Type: text/plain; charset=UTF-8\n"
19
+"Content-Transfer-Encoding: 8bit\n"
20
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
21
+"X-Generator: Poedit 3.1.1\n"
22
+
23
+#: src/daemon/pipewire.c:46
24
+#, c-format
25
+msgid ""
26
+"%s options\n"
27
+" -h, --help Show this help\n"
28
+" --version Show version\n"
29
+" -c, --config Load config (Default %s)\n"
30
+msgstr ""
31
+"%s პარამეტრები\n"
32
+" -h, --help ამ დახმარების ჩვენება\n"
33
+" --version ვერსიის ჩვენება\n"
34
+" -c, --config ჩატვირთვის კონფიგურაცია (ნაგულისხმები %s)\n"
35
+
36
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180
37
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
38
+#, c-format
39
+msgid "Tunnel to %s/%s"
40
+msgstr "გვირაბი %s/%s -მდე"
41
+
42
+#: src/modules/module-fallback-sink.c:51
43
+msgid "Dummy Output"
44
+msgstr "ნულოვანი გამოყვანა"
45
+
46
+#: src/modules/module-pulse-tunnel.c:648
47
+#, c-format
48
+msgid "Tunnel for %s@%s"
49
+msgstr "გვირაბი %s@%s-სთვის"
50
+
51
+#: src/modules/module-zeroconf-discover.c:332
52
+msgid "Unknown device"
53
+msgstr "უცნობი მოწყობილობა"
54
+
55
+#: src/modules/module-zeroconf-discover.c:344
56
+#, c-format
57
+msgid "%s on %s@%s"
58
+msgstr "%s %s@%s -ზე"
59
+
60
+#: src/modules/module-zeroconf-discover.c:348
61
+#, c-format
62
+msgid "%s on %s"
63
+msgstr "%s %s-ზე"
64
+
65
+#: src/tools/pw-cat.c:784
66
+#, c-format
67
+msgid ""
68
+"%s options <file>|-\n"
69
+" -h, --help Show this help\n"
70
+" --version Show version\n"
71
+" -v, --verbose Enable verbose operations\n"
72
+"\n"
73
+msgstr ""
74
+"%s პარამეტრები <ფაილი>|-\n"
75
+" -h, --help ამ დახმარების ჩვენება\n"
76
+" --version ვერსიის ჩვენება\n"
77
+" -v, --verbose დამატებითი შეტყობინებების გამოტანა\n"
78
+"\n"
79
+
80
+#: src/tools/pw-cat.c:791
81
+#, c-format
82
+msgid ""
83
+" -R, --remote Remote daemon name\n"
84
+" --media-type Set media type (default %s)\n"
85
+" --media-category Set media category (default %s)\n"
86
+" --media-role Set media role (default %s)\n"
87
+" --target Set node target (default %s)\n"
88
+" 0 means don't link\n"
89
+" --latency Set node latency (default %s)\n"
90
+" Xunit (unit = s, ms, us, ns)\n"
91
+" or direct samples (256)\n"
92
+" the rate is the one of the source "
93
+"file\n"
94
+" -P --properties Set node properties\n"
95
+"\n"
96
+msgstr ""
97
+" -R, --remote დაშორებული დემონის სახელი\n"
98
+" --media-type მედიის ტიპის დაყენება (ნაგულისხმები %s)\n"
99
+" --media-category მედია კატეგორიის დაყენება (ნაგულისხმები %s)\n"
100
+" --media-role მედიის როლის დაყენება (ნაგულისხმები %s)\n"
101
+" --target კვანძის სამიზნის დაყენება (ნაგულისხმები %s)\n"
102
+" 0 ნიშნავს არ მიბმა\n"
103
+" --latency კვანძის შეყოვნების დაყენება (ნაგულისხმები %s)\n"
104
+" Xunit (ერთეული = s, ms, us, ns)\n"
105
+" ან პირდაპირი ნიმუშები (256)\n"
106
+" მაჩვენებელი არის ერთ-ერთი წყაროს "
107
+"ფაილი\n"
108
+" -P --properties კვანძის თვისებების დაყენება\n"
109
+
110
+#: src/tools/pw-cat.c:809
111
+#, c-format
112
+msgid ""
113
+" --rate Sample rate (req. for rec) (default "
114
+"%u)\n"
115
+" --channels Number of channels (req. for rec) "
116
+"(default %u)\n"
117
+" --channel-map Channel map\n"
118
+" one of: \"stereo\", "
119
+"\"surround-51\",... or\n"
120
+" comma separated list of channel "
121
+"names: eg. \"FL,FR\"\n"
122
+" --format Sample format %s (req. for rec) "
123
+"(default %s)\n"
124
+" --volume Stream volume 0-1.0 (default %.3f)\n"
125
+" -q --quality Resampler quality (0 - 15) (default "
126
+"%d)\n"
127
+"\n"
128
+msgstr ""
129
+" --rate სემპლის_სიჩქარე (მოთხოვნილება rec.) (ნაგულისხმები %u)\n"
130
+" --channels არხების რაოდენობა (მოთხოვნილი ჩანაწერისთვის) (ნაგულისხმები "
131
+"%u)\n"
132
+" --channel-map არხის რუკა\n"
133
+" ერთ-ერთი: \"stereo\", "
134
+"\"surround-51\",... ან\n"
135
+" მძიმით გამოყოფილი არხის "
136
+"სახელების სია: მაგ. \"FL, FR\"\n"
137
+" --format ნიმუშის ფორმატი %s (მოთხოვნილება rec.) "
138
+"(ნაგულისხმები %s)\n"
139
+" --volume ნაკადის მოცულობა 0-1.0 (ნაგულისხმები %.3f)\n"
140
+" -q --quality Resampler ხარისხი (0 - 15) "
141
+"(ნაგულისხმები %d)\n"
142
+
143
+#: src/tools/pw-cat.c:826
144
+msgid ""
145
+" -p, --playback Playback mode\n"
146
+" -r, --record Recording mode\n"
147
+" -m, --midi Midi mode\n"
148
+" -d, --dsd DSD mode\n"
149
+"\n"
150
+msgstr ""
151
+" -p, --playback დაკვრის რეჟიმი\n"
152
+" -r, -- record ჩაწერის რეჟიმი\n"
153
+" -m, --midi Midi რეჟიმი\n"
154
+" -d, --dsd DSD რეჟიმი\n"
155
+"\n"
156
+
157
+#: src/tools/pw-cli.c:3165
158
+#, c-format
159
+msgid ""
160
+"%s options command\n"
161
+" -h, --help Show this help\n"
162
+" --version Show version\n"
163
+" -d, --daemon Start as daemon (Default false)\n"
164
+" -r, --remote Remote daemon name\n"
165
+"\n"
166
+msgstr ""
167
+"%s პარამეტრები ბრძანება\n"
168
+" -h, --help ამ დახმარების ჩვენება\n"
169
+" --version ვერსიის ჩვენება\n"
170
+" -d, --daemon დაწყება როგორც დემონი (ნაგულისხმები "
171
+"false)\n"
172
+" -r, --remote დაშორებული დემონის სახელი\n"
173
+
174
+#: spa/plugins/alsa/acp/acp.c:321
175
+msgid "Pro Audio"
176
+msgstr "Pro Audio"
177
+
178
+#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648
179
+#: spa/plugins/bluez5/bluez5-device.c:1161
180
+msgid "Off"
181
+msgstr "გამორთული"
182
+
183
+#: spa/plugins/alsa/acp/alsa-mixer.c:2652
184
+msgid "Input"
185
+msgstr "შეყვანა"
186
+
187
+#: spa/plugins/alsa/acp/alsa-mixer.c:2653
188
+msgid "Docking Station Input"
189
+msgstr "Docking Station-ის შეყვანა"
190
+
191
+#: spa/plugins/alsa/acp/alsa-mixer.c:2654
192
+msgid "Docking Station Microphone"
193
+msgstr "Docking Station-ის მიკროფონი"
194
+
195
+#: spa/plugins/alsa/acp/alsa-mixer.c:2655
196
+msgid "Docking Station Line In"
197
+msgstr "Docking Station Line In"
198
+
199
+#: spa/plugins/alsa/acp/alsa-mixer.c:2656
200
+#: spa/plugins/alsa/acp/alsa-mixer.c:2747
201
pipewire-0.3.56.tar.gz/po/pl.po -> pipewire-0.3.57.tar.gz/po/pl.po
Changed
201
1
2
"Project-Id-Version: pipewire\n"
3
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
4
"issues\n"
5
-"POT-Creation-Date: 2022-05-20 15:26+0000\n"
6
-"PO-Revision-Date: 2022-05-21 12:49+0200\n"
7
+"POT-Creation-Date: 2022-08-27 13:57+0000\n"
8
+"PO-Revision-Date: 2022-08-27 16:00+0200\n"
9
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
10
"Language-Team: Polish <community-poland@mozilla.org>\n"
11
"Language: pl\n"
12
13
msgid "Start the PipeWire Media System"
14
msgstr "Uruchomienie systemu multimediów PipeWire"
15
16
-#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:183
17
-#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:183
18
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180
19
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
20
#, c-format
21
msgid "Tunnel to %s/%s"
22
msgstr "Tunel do %s/%s"
23
24
msgid "Dummy Output"
25
msgstr "Głuche wyjście"
26
27
-#: src/modules/module-pulse-tunnel.c:639
28
+#: src/modules/module-pulse-tunnel.c:648
29
#, c-format
30
msgid "Tunnel for %s@%s"
31
msgstr "Tunel dla %s@%s"
32
33
msgid "%s on %s"
34
msgstr "%s na %s"
35
36
-#: src/tools/pw-cat.c:872
37
+#: src/tools/pw-cat.c:784
38
#, c-format
39
msgid ""
40
"%s options <file>|-\n"
41
42
" -v, --verbose Wyświetla więcej komunikatów\n"
43
"\n"
44
45
-#: src/tools/pw-cat.c:879
46
+#: src/tools/pw-cat.c:791
47
#, c-format
48
msgid ""
49
" -R, --remote Remote daemon name\n"
50
51
" -P --properties Ustawia właściwości węzła\n"
52
"\n"
53
54
-#: src/tools/pw-cat.c:897
55
+#: src/tools/pw-cat.c:809
56
#, c-format
57
msgid ""
58
" --rate Sample rate (req. for rec) (default "
59
60
"(domyślnie %d)\n"
61
"\n"
62
63
-#: src/tools/pw-cat.c:914
64
+#: src/tools/pw-cat.c:826
65
msgid ""
66
" -p, --playback Playback mode\n"
67
" -r, --record Recording mode\n"
68
69
" -d, --dsd Tryb DSD\n"
70
"\n"
71
72
-#: src/tools/pw-cli.c:3139
73
+#: src/tools/pw-cli.c:2255
74
#, c-format
75
msgid ""
76
"%s options command\n"
77
78
msgstr "Dźwięk w zastosowaniach profesjonalnych"
79
80
#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
81
-#: spa/plugins/bluez5/bluez5-device.c:1161
82
+#: spa/plugins/bluez5/bluez5-device.c:1188
83
msgid "Off"
84
msgstr "Wyłączone"
85
86
87
88
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
89
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
90
-#: spa/plugins/bluez5/bluez5-device.c:1330
91
+#: spa/plugins/bluez5/bluez5-device.c:1360
92
msgid "Microphone"
93
msgstr "Mikrofon"
94
95
96
msgstr "Brak podbicia basów"
97
98
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
99
-#: spa/plugins/bluez5/bluez5-device.c:1335
100
+#: spa/plugins/bluez5/bluez5-device.c:1366
101
msgid "Speaker"
102
msgstr "Głośnik"
103
104
105
106
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
107
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
108
-#: spa/plugins/bluez5/bluez5-device.c:1320
109
+#: spa/plugins/bluez5/bluez5-device.c:1348
110
msgid "Headset"
111
msgstr "Słuchawki z mikrofonem"
112
113
114
msgid "%s Input"
115
msgstr "Wejście %s"
116
117
-#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267
118
+#: spa/plugins/alsa/acp/alsa-util.c:1187 spa/plugins/alsa/acp/alsa-util.c:1281
119
#, c-format
120
msgid ""
121
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
122
123
"Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem "
124
"programistom usługi ALSA."
125
126
-#: spa/plugins/alsa/acp/alsa-util.c:1239
127
+#: spa/plugins/alsa/acp/alsa-util.c:1253
128
#, c-format
129
msgid ""
130
"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
131
132
"Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem "
133
"programistom usługi ALSA."
134
135
-#: spa/plugins/alsa/acp/alsa-util.c:1286
136
+#: spa/plugins/alsa/acp/alsa-util.c:1300
137
#, c-format
138
msgid ""
139
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
140
141
"Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem "
142
"programistom usługi ALSA."
143
144
-#: spa/plugins/alsa/acp/alsa-util.c:1329
145
+#: spa/plugins/alsa/acp/alsa-util.c:1343
146
#, c-format
147
msgid ""
148
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
149
150
"Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem "
151
"programistom usługi ALSA."
152
153
-#: spa/plugins/alsa/acp/channelmap.h:464
154
+#: spa/plugins/alsa/acp/channelmap.h:457
155
msgid "(invalid)"
156
msgstr "(nieprawidłowe)"
157
158
159
msgid "Modem"
160
msgstr "Modem"
161
162
-#: spa/plugins/bluez5/bluez5-device.c:1172
163
+#: spa/plugins/bluez5/bluez5-device.c:1199
164
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
165
msgstr "Bramka dźwięku (źródło A2DP i AG HSP/HFP)"
166
167
-#: spa/plugins/bluez5/bluez5-device.c:1197
168
+#: spa/plugins/bluez5/bluez5-device.c:1224
169
#, c-format
170
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
171
msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP, kodek %s)"
172
173
-#: spa/plugins/bluez5/bluez5-device.c:1200
174
+#: spa/plugins/bluez5/bluez5-device.c:1227
175
#, c-format
176
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
177
msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP, kodek %s)"
178
179
-#: spa/plugins/bluez5/bluez5-device.c:1208
180
+#: spa/plugins/bluez5/bluez5-device.c:1235
181
msgid "High Fidelity Playback (A2DP Sink)"
182
msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP)"
183
184
-#: spa/plugins/bluez5/bluez5-device.c:1210
185
+#: spa/plugins/bluez5/bluez5-device.c:1237
186
msgid "High Fidelity Duplex (A2DP Source/Sink)"
187
msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP)"
188
189
-#: spa/plugins/bluez5/bluez5-device.c:1238
190
+#: spa/plugins/bluez5/bluez5-device.c:1265
191
#, c-format
192
msgid "Headset Head Unit (HSP/HFP, codec %s)"
193
msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP, kodek %s)"
194
195
-#: spa/plugins/bluez5/bluez5-device.c:1243
196
+#: spa/plugins/bluez5/bluez5-device.c:1270
197
msgid "Headset Head Unit (HSP/HFP)"
198
msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP)"
199
200
-#: spa/plugins/bluez5/bluez5-device.c:1325
201
pipewire-0.3.56.tar.gz/po/sv.po -> pipewire-0.3.57.tar.gz/po/sv.po
Changed
201
1
2
"Project-Id-Version: pipewire\n"
3
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
4
"issues\n"
5
-"POT-Creation-Date: 2022-05-20 15:26+0000\n"
6
-"PO-Revision-Date: 2022-05-23 11:01+0200\n"
7
+"POT-Creation-Date: 2022-07-19 15:27+0000\n"
8
+"PO-Revision-Date: 2022-07-10 10:22+0200\n"
9
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
10
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
11
"Language: sv\n"
12
13
"Content-Type: text/plain; charset=UTF-8\n"
14
"Content-Transfer-Encoding: 8bit\n"
15
"Plural-Forms: nplurals=2; plural=n != 1;\n"
16
-"X-Generator: Poedit 3.0.1\n"
17
+"X-Generator: Poedit 3.1\n"
18
19
#: src/daemon/pipewire.c:46
20
#, c-format
21
22
msgid "Start the PipeWire Media System"
23
msgstr "Starta mediasystemet 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:180
28
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
29
#, c-format
30
msgid "Tunnel to %s/%s"
31
msgstr "Tunnel till %s/%s"
32
33
msgid "Dummy Output"
34
msgstr "Attrapputgång"
35
36
-#: src/modules/module-pulse-tunnel.c:639
37
+#: src/modules/module-pulse-tunnel.c:648
38
#, c-format
39
msgid "Tunnel for %s@%s"
40
msgstr "Tunnel för %s@%s"
41
42
msgid "%s on %s"
43
msgstr "%s på %s"
44
45
-#: src/tools/pw-cat.c:872
46
+#: src/tools/pw-cat.c:784
47
#, c-format
48
msgid ""
49
"%s options <file>|-\n"
50
51
" -v, --verbose Aktivera utförliga operationer\n"
52
"\n"
53
54
-#: src/tools/pw-cat.c:879
55
+#: src/tools/pw-cat.c:791
56
#, c-format
57
msgid ""
58
" -R, --remote Remote daemon name\n"
59
60
" -P --properties Sätt nodegenskaper\n"
61
"\n"
62
63
-#: src/tools/pw-cat.c:897
64
+#: src/tools/pw-cat.c:809
65
#, c-format
66
msgid ""
67
" --rate Sample rate (req. for rec) (default "
68
69
"%d)\n"
70
"\n"
71
72
-#: src/tools/pw-cat.c:914
73
+#: src/tools/pw-cat.c:826
74
msgid ""
75
" -p, --playback Playback mode\n"
76
" -r, --record Recording mode\n"
77
78
" -d, --dsd DSD-läge\n"
79
"\n"
80
81
-#: src/tools/pw-cli.c:3139
82
+#: src/tools/pw-cli.c:3165
83
#, c-format
84
msgid ""
85
"%s options command\n"
86
87
msgid "Pro Audio"
88
msgstr "Professionellt ljud"
89
90
-#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
91
-#: spa/plugins/bluez5/bluez5-device.c:1161
92
+#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648
93
+#: spa/plugins/bluez5/bluez5-device.c:1188
94
msgid "Off"
95
msgstr "Av"
96
97
98
99
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
100
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
101
-#: spa/plugins/bluez5/bluez5-device.c:1330
102
+#: spa/plugins/bluez5/bluez5-device.c:1360
103
msgid "Microphone"
104
msgstr "Mikrofon"
105
106
107
msgstr "Ingen basökning"
108
109
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
110
-#: spa/plugins/bluez5/bluez5-device.c:1335
111
+#: spa/plugins/bluez5/bluez5-device.c:1366
112
msgid "Speaker"
113
msgstr "Högtalare"
114
115
116
117
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
118
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
119
-#: spa/plugins/bluez5/bluez5-device.c:1320
120
+#: spa/plugins/bluez5/bluez5-device.c:1348
121
msgid "Headset"
122
msgstr "Headset"
123
124
125
#: spa/plugins/alsa/acp/alsa-util.c:1239
126
#, c-format
127
msgid ""
128
-"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
129
-"(%s%lu ms).\n"
130
+"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
131
+"%lu ms).\n"
132
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
133
"to the ALSA developers."
134
msgid_plural ""
135
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
136
-"(%s%lu ms).\n"
137
+"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
138
+"%lu ms).\n"
139
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
140
"to the ALSA developers."
141
msgstr0 ""
142
143
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
144
"problemet till ALSA-utvecklarna."
145
146
-#: spa/plugins/alsa/acp/channelmap.h:464
147
+#: spa/plugins/alsa/acp/channelmap.h:457
148
msgid "(invalid)"
149
msgstr "(ogiltig)"
150
151
152
msgid "Modem"
153
msgstr "Modem"
154
155
-#: spa/plugins/bluez5/bluez5-device.c:1172
156
+#: spa/plugins/bluez5/bluez5-device.c:1199
157
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
158
msgstr "Audio gateway (A2DP-källa & HSP/HFP AG)"
159
160
-#: spa/plugins/bluez5/bluez5-device.c:1197
161
+#: spa/plugins/bluez5/bluez5-device.c:1224
162
#, c-format
163
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
164
msgstr "High fidelity-uppspelning (A2DP-utgång, kodek %s)"
165
166
-#: spa/plugins/bluez5/bluez5-device.c:1200
167
+#: spa/plugins/bluez5/bluez5-device.c:1227
168
#, c-format
169
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
170
msgstr "High fidelity duplex (A2DP-källa/utgång, kodek %s)"
171
172
-#: spa/plugins/bluez5/bluez5-device.c:1208
173
+#: spa/plugins/bluez5/bluez5-device.c:1235
174
msgid "High Fidelity Playback (A2DP Sink)"
175
msgstr "High fidelity-uppspelning (A2DP-utgång)"
176
177
-#: spa/plugins/bluez5/bluez5-device.c:1210
178
+#: spa/plugins/bluez5/bluez5-device.c:1237
179
msgid "High Fidelity Duplex (A2DP Source/Sink)"
180
msgstr "High fidelity duplex (A2DP-källa/utgång)"
181
182
-#: spa/plugins/bluez5/bluez5-device.c:1238
183
+#: spa/plugins/bluez5/bluez5-device.c:1265
184
#, c-format
185
msgid "Headset Head Unit (HSP/HFP, codec %s)"
186
msgstr "Headset-huvudenhet (HSP/HFP, kodek %s)"
187
188
-#: spa/plugins/bluez5/bluez5-device.c:1243
189
+#: spa/plugins/bluez5/bluez5-device.c:1270
190
msgid "Headset Head Unit (HSP/HFP)"
191
msgstr "Headset-huvudenhet (HSP/HFP)"
192
193
-#: spa/plugins/bluez5/bluez5-device.c:1325
194
+#: spa/plugins/bluez5/bluez5-device.c:1349
195
+#: spa/plugins/bluez5/bluez5-device.c:1354
196
+#: spa/plugins/bluez5/bluez5-device.c:1361
197
+#: spa/plugins/bluez5/bluez5-device.c:1367
198
+#: spa/plugins/bluez5/bluez5-device.c:1373
199
+#: spa/plugins/bluez5/bluez5-device.c:1379
200
+#: spa/plugins/bluez5/bluez5-device.c:1385
201
pipewire-0.3.56.tar.gz/spa/include/spa/interfaces/audio/aec.h -> pipewire-0.3.57.tar.gz/spa/include/spa/interfaces/audio/aec.h
Changed
14
1
2
const struct spa_audio_aec_events *events,
3
void *data);
4
5
- int (*init) (void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info);
6
- int (*run) (void *data, const float *rec, const float *play, float *out, uint32_t n_samples);
7
- int (*set_props) (void *data, const struct spa_dict *args);
8
+ int (*init) (void *object, const struct spa_dict *args, const struct spa_audio_info_raw *info);
9
+ int (*run) (void *object, const float *rec, const float *play, float *out, uint32_t n_samples);
10
+ int (*set_props) (void *object, const struct spa_dict *args);
11
};
12
13
#define spa_audio_aec_method(o,method,version,...) \
14
pipewire-0.3.56.tar.gz/spa/include/spa/param/bluetooth/audio.h -> pipewire-0.3.57.tar.gz/spa/include/spa/param/bluetooth/audio.h
Changed
13
1
2
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM,
3
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX,
4
SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR,
5
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05,
6
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51,
7
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71,
8
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX,
9
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO,
10
11
/* HFP */
12
SPA_BLUETOOTH_AUDIO_CODEC_CVSD = 0x100,
13
pipewire-0.3.56.tar.gz/spa/include/spa/param/bluetooth/type-info.h -> pipewire-0.3.57.tar.gz/spa/include/spa/param/bluetooth/type-info.h
Changed
13
1
2
{ SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "faststream", NULL },
3
{ SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "faststream_duplex", NULL },
4
{ SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "lc3plus_hr", NULL },
5
+ { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05", NULL },
6
+ { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_51", NULL },
7
+ { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_71", NULL },
8
+ { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_duplex", NULL },
9
+ { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_pro", NULL },
10
11
{ SPA_BLUETOOTH_AUDIO_CODEC_CVSD, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "cvsd", NULL },
12
{ SPA_BLUETOOTH_AUDIO_CODEC_MSBC, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "msbc", NULL },
13
pipewire-0.3.56.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.57.tar.gz/spa/include/spa/utils/defs.h
Changed
30
1
2
SPA_MIN(SPA_MAX(_v, _low), _high); \
3
})
4
5
+#define SPA_CLAMPF(v,low,high) \
6
+({ \
7
+ fminf(fmaxf(v, low), high); \
8
+})
9
+
10
+
11
#define SPA_SWAP(a,b) \
12
({ \
13
__typeof__(a) _t = (a); \
14
15
#define SPA_SENTINEL __attribute__((__sentinel__))
16
#define SPA_UNUSED __attribute__ ((unused))
17
#define SPA_NORETURN __attribute__ ((noreturn))
18
+#define SPA_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
19
#else
20
#define SPA_PRINTF_FUNC(fmt, arg1)
21
#define SPA_FORMAT_ARG_FUNC(arg1)
22
23
#define SPA_SENTINEL
24
#define SPA_UNUSED
25
#define SPA_NORETURN
26
+#define SPA_WARN_UNUSED_RESULT
27
#endif
28
29
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
30
pipewire-0.3.56.tar.gz/spa/include/spa/utils/hook.h -> pipewire-0.3.57.tar.gz/spa/include/spa/utils/hook.h
Changed
11
1
2
/** Remove a hook */
3
static inline void spa_hook_remove(struct spa_hook *hook)
4
{
5
- spa_list_remove(&hook->link);
6
+ if (spa_list_is_initialized(&hook->link))
7
+ spa_list_remove(&hook->link);
8
if (hook->removed)
9
hook->removed(hook);
10
}
11
pipewire-0.3.56.tar.gz/spa/include/spa/utils/list.h -> pipewire-0.3.57.tar.gz/spa/include/spa/utils/list.h
Changed
13
1
2
*list = SPA_LIST_INIT(list);
3
}
4
5
+static inline int spa_list_is_initialized(struct spa_list *list)
6
+{
7
+ return !!list->prev;
8
+}
9
+
10
#define spa_list_is_empty(l) ((l)->next == (l))
11
12
static inline void spa_list_insert(struct spa_list *list, struct spa_list *elem)
13
pipewire-0.3.56.tar.gz/spa/meson.build -> pipewire-0.3.57.tar.gz/spa/meson.build
Changed
10
1
2
endif
3
endif
4
summary({'LC3plus': lc3plus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
5
+ opus_dep = dependency('opus', required : get_option('bluez5-codec-opus'))
6
+ summary({'Opus': opus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
7
endif
8
avcodec_dep = dependency('libavcodec', required: get_option('ffmpeg'))
9
jack_dep = dependency('jack', version : '>= 1.9.10', required: get_option('jack'))
10
pipewire-0.3.56.tar.gz/spa/plugins/aec/aec-null.c -> pipewire-0.3.57.tar.gz/spa/plugins/aec/aec-null.c
Changed
67
1
2
return 0;
3
}
4
5
-static struct spa_audio_aec_methods impl_aec = {
6
+static const struct spa_audio_aec_methods impl_aec = {
7
+ SPA_VERSION_AUDIO_AEC,
8
.init = null_init,
9
.run = null_run,
10
};
11
12
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
13
{
14
- struct impl *impl;
15
-
16
spa_return_val_if_fail(handle != NULL, -EINVAL);
17
spa_return_val_if_fail(interface != NULL, -EINVAL);
18
19
- impl = (struct impl *) handle;
20
+ struct impl *impl = (struct impl *) handle;
21
22
if (spa_streq(type, SPA_TYPE_INTERFACE_AUDIO_AEC))
23
*interface = &impl->aec;
24
25
const struct spa_support *support,
26
uint32_t n_support)
27
{
28
- struct impl *impl;
29
-
30
spa_return_val_if_fail(factory != NULL, -EINVAL);
31
spa_return_val_if_fail(handle != NULL, -EINVAL);
32
33
handle->get_interface = impl_get_interface;
34
handle->clear = impl_clear;
35
36
- impl = (struct impl *) handle;
37
+ struct impl *impl = (struct impl *) handle;
38
39
impl->aec.iface = SPA_INTERFACE_INIT(
40
SPA_TYPE_INTERFACE_AUDIO_AEC,
41
42
impl->aec.info = NULL;
43
impl->aec.latency = NULL;
44
45
- impl->log = (struct spa_log*)spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
46
+ impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
47
spa_log_topic_init(impl->log, &log_topic);
48
49
spa_hook_list_init(&impl->hooks_list);
50
51
return 1;
52
}
53
54
-const struct spa_handle_factory spa_aec_null_factory = {
55
+static const struct spa_handle_factory spa_aec_null_factory = {
56
SPA_VERSION_HANDLE_FACTORY,
57
SPA_NAME_AEC,
58
NULL,
59
60
impl_enum_interface_info,
61
};
62
63
-
64
SPA_EXPORT
65
int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
66
{
67
pipewire-0.3.56.tar.gz/spa/plugins/aec/aec-webrtc.cpp -> pipewire-0.3.57.tar.gz/spa/plugins/aec/aec-webrtc.cpp
Changed
76
1
2
#undef SPA_LOG_TOPIC_DEFAULT
3
#define SPA_LOG_TOPIC_DEFAULT &log_topic
4
5
-static bool webrtc_get_spa_bool(const struct spa_dict *args, const char *key, bool default_value) {
6
- const char *str_val;
7
- bool value = default_value;
8
- str_val = spa_dict_lookup(args, key);
9
- if (str_val != NULL)
10
- value =spa_atob(str_val);
11
-
12
- return value;
13
+static bool webrtc_get_spa_bool(const struct spa_dict *args, const char *key, bool default_value)
14
+{
15
+ if (auto str = spa_dict_lookup(args, key))
16
+ return spa_atob(str);
17
+
18
+ return default_value;
19
}
20
21
-static int webrtc_init(void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info)
22
+static int webrtc_init(void *object, const struct spa_dict *args, const struct spa_audio_info_raw *info)
23
{
24
- auto impl = reinterpret_cast<struct impl_data*>(data);
25
+ auto impl = static_cast<struct impl_data*>(object);
26
27
bool extended_filter = webrtc_get_spa_bool(args, "webrtc.extended_filter", true);
28
bool delay_agnostic = webrtc_get_spa_bool(args, "webrtc.delay_agnostic", true);
29
30
return 0;
31
}
32
33
-static int webrtc_run(void *data, const float *rec, const float *play, float *out, uint32_t n_samples)
34
+static int webrtc_run(void *object, const float *rec, const float *play, float *out, uint32_t n_samples)
35
{
36
- auto impl = reinterpret_cast<struct impl_data*>(data);
37
+ auto impl = static_cast<struct impl_data*>(object);
38
webrtc::StreamConfig config =
39
webrtc::StreamConfig(impl->info.rate, impl->info.channels, false);
40
unsigned int num_blocks = n_samples * 1000 / impl->info.rate / 10;
41
42
return 0;
43
}
44
45
-static struct spa_audio_aec_methods impl_aec = {
46
+static const struct spa_audio_aec_methods impl_aec = {
47
SPA_VERSION_AUDIO_AEC_METHODS,
48
.add_listener = NULL,
49
.init = webrtc_init,
50
51
impl->aec.info = NULL;
52
impl->aec.latency = "480/48000",
53
54
- impl->log = (struct spa_log*)spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
55
+ impl->log = static_cast<struct spa_log *>(spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log));
56
spa_log_topic_init(impl->log, &log_topic);
57
58
return 0;
59
60
return 1;
61
}
62
63
-const struct spa_handle_factory spa_aec_webrtc_factory = {
64
+static const struct spa_handle_factory spa_aec_webrtc_factory = {
65
SPA_VERSION_HANDLE_FACTORY,
66
SPA_NAME_AEC,
67
NULL,
68
69
impl_enum_interface_info,
70
};
71
72
-
73
SPA_EXPORT
74
int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
75
{
76
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
72
1
2
0, NULL, NULL, false))) {
3
pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm);
4
pa_proplist_setf(m->output_proplist, "clock.name", "api.alsa.%u", index);
5
- snd_pcm_close(m->output_pcm);
6
- m->output_pcm = NULL;
7
+ pa_alsa_close(&m->output_pcm);
8
m->supported = true;
9
pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX);
10
}
11
12
0, NULL, NULL, false))) {
13
pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm);
14
pa_proplist_setf(m->input_proplist, "clock.name", "api.alsa.%u", index);
15
- snd_pcm_close(m->input_pcm);
16
- m->input_pcm = NULL;
17
+ pa_alsa_close(&m->input_pcm);
18
m->supported = true;
19
pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX);
20
}
21
22
uint32_t i;
23
int res;
24
25
+ if (!dev->mixer_handle)
26
+ return 0;
27
+
28
if ((res = pa_alsa_path_get_volume(dev->mixer_path, dev->mixer_handle, &dev->mapping->channel_map, &r)) < 0)
29
return res;
30
31
32
33
dev->real_volume = *v;
34
35
+ if (!dev->mixer_handle)
36
+ return;
37
+
38
/* Shift up by the base volume */
39
pa_sw_cvolume_divide_scalar(&r, &dev->real_volume, dev->base_volume);
40
41
42
bool mute;
43
int res;
44
45
+ if (!dev->mixer_handle)
46
+ return 0;
47
+
48
if ((res = pa_alsa_path_get_mute(dev->mixer_path, dev->mixer_handle, &mute)) < 0)
49
return res;
50
51
52
static void set_mute(pa_alsa_device *dev, bool mute)
53
{
54
dev->muted = mute;
55
+
56
+ if (!dev->mixer_handle)
57
+ return;
58
+
59
pa_alsa_path_set_mute(dev->mixer_path, dev->mixer_handle, mute);
60
}
61
62
63
setting = data->setting;
64
}
65
66
- pa_alsa_path_select(d->mixer_path, setting, d->mixer_handle, d->muted);
67
+ if (d->mixer_handle)
68
+ pa_alsa_path_select(d->mixer_path, setting, d->mixer_handle, d->muted);
69
70
if (d->set_mute)
71
d->set_mute(d, d->muted);
72
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-mixer.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-mixer.c
Changed
21
1
2
continue;
3
4
pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm);
5
- snd_pcm_close(m->output_pcm);
6
- m->output_pcm = NULL;
7
+ pa_alsa_close(&m->output_pcm);
8
}
9
10
if (to_be_finalized->input_mappings)
11
12
continue;
13
14
pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm);
15
- snd_pcm_close(m->input_pcm);
16
- m->input_pcm = NULL;
17
+ pa_alsa_close(&m->input_pcm);
18
}
19
}
20
21
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-ucm.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-ucm.c
Changed
21
1
2
continue;
3
4
pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm);
5
- snd_pcm_close(m->output_pcm);
6
- m->output_pcm = NULL;
7
+ pa_alsa_close(&m->output_pcm);
8
}
9
10
PA_IDXSET_FOREACH(m, p->input_mappings, idx) {
11
12
continue;
13
14
pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm);
15
- snd_pcm_close(m->input_pcm);
16
- m->input_pcm = NULL;
17
+ pa_alsa_close(&m->input_pcm);
18
}
19
}
20
21
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-util.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-util.c
Changed
66
1
2
return pcm_handle;
3
}
4
5
+int pa_alsa_close(snd_pcm_t **pcm)
6
+{
7
+ int err;
8
+ pa_assert(pcm);
9
+ pa_log_info("ALSA device close %p", *pcm);
10
+ if (*pcm == NULL)
11
+ return 0;
12
+ if ((err = snd_pcm_close(*pcm)) < 0) {
13
+ pa_log_warn("ALSA close failed: %s", snd_strerror(err));
14
+ }
15
+ *pcm = NULL;
16
+ return err;
17
+}
18
+
19
snd_pcm_t *pa_alsa_open_by_device_string(
20
const char *device,
21
char **dev,
22
23
pa_log_info("Error opening PCM device %s: %s", d, pa_alsa_strerror(err));
24
goto fail;
25
}
26
-
27
- pa_log_debug("Managed to open %s", d);
28
+ pa_log_info("ALSA device open '%s' %s: %p", d,
29
+ mode == SND_PCM_STREAM_CAPTURE ? "capture" : "playback", pcm_handle);
30
31
if ((err = pa_alsa_set_hw_params(
32
pcm_handle,
33
34
if (!reformat) {
35
reformat = true;
36
37
- snd_pcm_close(pcm_handle);
38
+ pa_alsa_close(&pcm_handle);
39
continue;
40
}
41
42
43
44
reformat = false;
45
46
- snd_pcm_close(pcm_handle);
47
+ pa_alsa_close(&pcm_handle);
48
continue;
49
}
50
51
pa_log_info("Failed to set hardware parameters on %s: %s", d, pa_alsa_strerror(err));
52
- snd_pcm_close(pcm_handle);
53
+ pa_alsa_close(&pcm_handle);
54
55
goto fail;
56
}
57
58
if (ss->channels > PA_CHANNELS_MAX) {
59
pa_log("Device %s has %u channels, but PulseAudio supports only %u channels. Unable to use the device.",
60
d, ss->channels, PA_CHANNELS_MAX);
61
- snd_pcm_close(pcm_handle);
62
+ pa_alsa_close(&pcm_handle);
63
goto fail;
64
}
65
66
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-util.h -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-util.h
Changed
9
1
2
void pa_alsa_dump(pa_log_level_t level, snd_pcm_t *pcm);
3
void pa_alsa_dump_status(snd_pcm_t *pcm);
4
#endif
5
+int pa_alsa_close(snd_pcm_t **pcm);
6
7
void pa_alsa_refcnt_inc(void);
8
void pa_alsa_refcnt_dec(void);
9
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
54
1
2
static int impl_node_process(void *object)
3
{
4
struct state *this = object;
5
- struct spa_io_buffers *input;
6
+ struct spa_io_buffers *io;
7
8
spa_return_val_if_fail(this != NULL, -EINVAL);
9
10
- input = this->io;
11
- spa_return_val_if_fail(input != NULL, -EIO);
12
+ if ((io = this->io) == NULL)
13
+ return -EIO;
14
15
- spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, input->status,
16
- input->buffer_id, this->n_buffers);
17
+ spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, io->status,
18
+ io->buffer_id, this->n_buffers);
19
20
if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) {
21
- input->status = SPA_STATUS_NEED_DATA;
22
+ io->status = SPA_STATUS_NEED_DATA;
23
return SPA_STATUS_HAVE_DATA;
24
}
25
- if (input->status == SPA_STATUS_HAVE_DATA &&
26
- input->buffer_id < this->n_buffers) {
27
- struct buffer *b = &this->buffersinput->buffer_id;
28
+ if (io->status == SPA_STATUS_HAVE_DATA &&
29
+ io->buffer_id < this->n_buffers) {
30
+ struct buffer *b = &this->buffersio->buffer_id;
31
32
if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_OUT)) {
33
spa_log_warn(this->log, "%p: buffer %u in use",
34
- this, input->buffer_id);
35
- input->status = -EINVAL;
36
+ this, io->buffer_id);
37
+ io->status = -EINVAL;
38
return -EINVAL;
39
}
40
- spa_log_trace_fp(this->log, "%p: queue buffer %u", this, input->buffer_id);
41
+ spa_log_trace_fp(this->log, "%p: queue buffer %u", this, io->buffer_id);
42
spa_list_append(&this->ready, &b->link);
43
SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT);
44
- input->buffer_id = SPA_ID_INVALID;
45
+ io->buffer_id = SPA_ID_INVALID;
46
47
spa_alsa_write(this);
48
49
- input->status = SPA_STATUS_OK;
50
+ io->status = SPA_STATUS_OK;
51
}
52
return SPA_STATUS_HAVE_DATA;
53
}
54
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
12
1
2
3
spa_return_val_if_fail(this != NULL, -EINVAL);
4
5
- io = this->io;
6
- spa_return_val_if_fail(io != NULL, -EIO);
7
+ if ((io = this->io) == NULL)
8
+ return -EIO;
9
10
spa_log_trace_fp(this->log, "%p; status %d", this, io->status);
11
12
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
201
1
2
3
#include <spa/pod/filter.h>
4
#include <spa/utils/string.h>
5
+#include <spa/utils/result.h>
6
#include <spa/support/system.h>
7
#include <spa/utils/keys.h>
8
9
10
return changed;
11
}
12
13
+#define CHECK(s,msg,...) if ((err = (s)) < 0) { spa_log_error(state->log, msg ": %s", ##__VA_ARGS__, snd_strerror(err)); return err; }
14
+
15
+static ssize_t log_write(void *cookie, const char *buf, size_t size)
16
+{
17
+ struct state *state = cookie;
18
+ int len;
19
+
20
+ while (size > 0) {
21
+ len = strcspn(buf, "\n");
22
+ if (len > 0)
23
+ spa_log_debug(state->log, "%.*s", (int)len, buf);
24
+ buf += len + 1;
25
+ size -= len + 1;
26
+ }
27
+ return size;
28
+}
29
+
30
+static cookie_io_functions_t io_funcs = {
31
+ .write = log_write,
32
+};
33
+
34
int spa_alsa_init(struct state *state, const struct spa_dict *info)
35
{
36
uint32_t i;
37
+ int err;
38
39
snd_config_update_free_global();
40
41
42
spa_log_error(state->log, "can't create card %u", state->card_index);
43
return -errno;
44
}
45
+ state->log_file = fopencookie(state, "w", io_funcs);
46
+ if (state->log_file == NULL) {
47
+ spa_log_error(state->log, "can't create log file");
48
+ return -errno;
49
+ }
50
+ CHECK(snd_output_stdio_attach(&state->output, state->log_file, 0), "attach failed");
51
+
52
return 0;
53
}
54
55
int spa_alsa_clear(struct state *state)
56
{
57
+ int err;
58
+
59
release_card(state->card);
60
61
state->card = NULL;
62
state->card_index = SPA_ID_INVALID;
63
64
- return 0;
65
-}
66
+ if ((err = snd_output_close(state->output)) < 0)
67
+ spa_log_warn(state->log, "output close failed: %s", snd_strerror(err));
68
+ fclose(state->log_file);
69
70
-#define CHECK(s,msg,...) if ((err = (s)) < 0) { spa_log_error(state->log, msg ": %s", ##__VA_ARGS__, snd_strerror(err)); return err; }
71
+ return err;
72
+}
73
74
int spa_alsa_open(struct state *state, const char *params)
75
{
76
77
if (state->opened)
78
return 0;
79
80
- CHECK(snd_output_stdio_attach(&state->output, stderr, 0), "attach failed");
81
-
82
spa_scnprintf(device_name, sizeof(device_name), "%s%s%s",
83
state->card->ucm_prefix ? state->card->ucm_prefix : "",
84
props->device, params ? params : "");
85
86
return 0;
87
88
error_exit_close:
89
+ spa_log_info(state->log, "%p: Device '%s' closing: %s", state, state->props.device,
90
+ spa_strerror(err));
91
snd_pcm_close(state->hndl);
92
return err;
93
}
94
95
spa_log_warn(state->log, "%s: close failed: %s", state->props.device,
96
snd_strerror(err));
97
98
- if ((err = snd_output_close(state->output)) < 0)
99
- spa_log_warn(state->log, "output close failed: %s", snd_strerror(err));
100
-
101
spa_system_close(state->data_system, state->timerfd);
102
103
if (state->have_format)
104
105
CHECK(snd_pcm_hw_params_get_rate_min(params, &min, &dir), "get_rate_min");
106
CHECK(snd_pcm_hw_params_get_rate_max(params, &max, &dir), "get_rate_max");
107
108
+ spa_log_debug(state->log, "min:%u max:%u min-allowed:%u scale:%u all:%d",
109
+ min, max, min_allowed_rate, scale, all);
110
+
111
min_allowed_rate /= scale;
112
min = SPA_MAX(min_allowed_rate, min);
113
114
115
116
rate = SPA_CLAMP(rate, min, max);
117
118
+ spa_log_debug(state->log, "rate:%u multi:%d card:%d def:%d",
119
+ rate, state->multi_rate, state->card->rate, state->default_rate);
120
+
121
spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_rate, 0);
122
123
spa_pod_builder_push_choice(b, &f0, SPA_CHOICE_None, 0);
124
125
126
CHECK(snd_pcm_hw_params_get_channels_min(params, &min), "get_channels_min");
127
CHECK(snd_pcm_hw_params_get_channels_max(params, &max), "get_channels_max");
128
- spa_log_debug(state->log, "channels (%d %d)", min, max);
129
+ spa_log_debug(state->log, "channels (%d %d) default:%d all:%d",
130
+ min, max, state->default_channels, all);
131
132
if (state->default_channels != 0 && !all) {
133
if (min < state->default_channels)
134
135
return 1;
136
}
137
138
+static void debug_hw_params(struct state *state, const char *prefix, snd_pcm_hw_params_t *params)
139
+{
140
+ if (SPA_UNLIKELY(spa_log_level_topic_enabled(state->log, SPA_LOG_TOPIC_DEFAULT, SPA_LOG_LEVEL_DEBUG))) {
141
+ spa_log_debug(state->log, "%s:", prefix);
142
+ snd_pcm_hw_params_dump(params, state->output);
143
+ fflush(state->log_file);
144
+ }
145
+}
146
static int enum_pcm_formats(struct state *state, uint32_t index, uint32_t *next,
147
struct spa_pod **result, struct spa_pod_builder *b)
148
{
149
150
snd_pcm_hw_params_alloca(¶ms);
151
CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available");
152
153
+ debug_hw_params(state, __func__, params);
154
+
155
CHECK(snd_pcm_hw_params_set_rate_resample(hndl, params, 0), "set_rate_resample");
156
157
if (state->default_channels != 0) {
158
159
snd_pcm_hw_params_alloca(¶ms);
160
CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available");
161
162
+ debug_hw_params(state, __func__, params);
163
+
164
CHECK(snd_pcm_hw_params_set_rate_resample(hndl, params, 0), "set_rate_resample");
165
166
spa_pod_builder_push_object(b, &f0, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
167
168
snd_pcm_hw_params_alloca(¶ms);
169
CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available");
170
171
+ debug_hw_params(state, __func__, params);
172
+
173
snd_pcm_format_mask_alloca(&fmask);
174
snd_pcm_hw_params_get_format_mask(params, fmask);
175
176
177
struct spa_result_node_params result;
178
uint32_t count = 0;
179
180
+ spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened,
181
+ state->have_format, state->started);
182
+
183
opened = state->opened;
184
+ if (!state->started && state->have_format)
185
+ spa_alsa_close(state);
186
if ((err = spa_alsa_open(state, NULL)) < 0)
187
return err;
188
189
190
bool match = true, planar = false, is_batch;
191
char spdif_params128 = "";
192
193
+ spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened,
194
+ state->have_format, state->started);
195
+
196
state->use_mmap = !state->disable_mmap;
197
198
switch (fmt->media_subtype) {
199
200
return -EINVAL;
201
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
10
1
2
struct spa_system *data_system;
3
struct spa_loop *data_loop;
4
5
+ FILE *log_file;
6
+
7
uint32_t card_index;
8
struct card *card;
9
snd_pcm_stream_t stream;
10
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-seq.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-seq.c
Changed
10
1
2
3
static void debug_event(struct seq_state *state, snd_seq_event_t *ev)
4
{
5
- if (SPA_LIKELY(!spa_log_level_enabled(state->log, SPA_LOG_LEVEL_TRACE)))
6
+ if (SPA_LIKELY(!spa_log_level_topic_enabled(state->log, SPA_LOG_TOPIC_DEFAULT, SPA_LOG_LEVEL_TRACE)))
7
return;
8
9
spa_log_trace(state->log, "event type:%d flags:0x%x", ev->type, ev->flags);
10
pipewire-0.3.56.tar.gz/spa/plugins/alsa/meson.build -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/meson.build
Changed
21
1
2
install : true,
3
)
4
5
-
6
executable('test-timer',
7
'test-timer.c' ,
8
dependencies : spa_dep, alsa_dep, mathlib, epoll_shim_dep ,
9
install : false,
10
)
11
12
+executable('test-hw-params',
13
+ 'test-hw-params.c' ,
14
+ dependencies : spa_dep, alsa_dep, mathlib ,
15
+ install : false,
16
+)
17
+
18
if libudev_dep.found()
19
install_data(alsa_udevrules,
20
install_dir : udevrulesdir,
21
pipewire-0.3.57.tar.gz/spa/plugins/alsa/test-hw-params.c
Added
175
1
2
+/* Spa
3
+ *
4
+ * Copyright © 2022 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <stdio.h>
27
+#include <stdbool.h>
28
+#include <limits.h>
29
+#include <getopt.h>
30
+#include <math.h>
31
+
32
+#include <alsa/asoundlib.h>
33
+
34
+#include <spa/utils/defs.h>
35
+
36
+#define DEFAULT_DEVICE "default"
37
+
38
+
39
+struct state {
40
+ const char *device;
41
+ snd_output_t *output;
42
+ snd_pcm_t *hndl;
43
+};
44
+
45
+#define CHECK(s,msg,...) { \
46
+ int __err; \
47
+ if ((__err = (s)) < 0) { \
48
+ fprintf(stderr, msg ": %s\n", ##__VA_ARGS__, snd_strerror(__err)); \
49
+ return __err; \
50
+ } \
51
+}
52
+
53
+static const char *get_class(snd_pcm_class_t c)
54
+{
55
+ switch (c) {
56
+ case SND_PCM_CLASS_GENERIC:
57
+ return "generic";
58
+ case SND_PCM_CLASS_MULTI:
59
+ return "multichannel";
60
+ case SND_PCM_CLASS_MODEM:
61
+ return "modem";
62
+ case SND_PCM_CLASS_DIGITIZER:
63
+ return "digitizer";
64
+ default:
65
+ return "unknown";
66
+ }
67
+}
68
+
69
+static const char *get_subclass(snd_pcm_subclass_t c)
70
+{
71
+ switch (c) {
72
+ case SND_PCM_SUBCLASS_GENERIC_MIX:
73
+ return "generic-mix";
74
+ case SND_PCM_SUBCLASS_MULTI_MIX:
75
+ return "multichannel-mix";
76
+ default:
77
+ return "unknown";
78
+ }
79
+}
80
+
81
+static void show_help(const char *name, bool error)
82
+{
83
+ fprintf(error ? stderr : stdout, "%s options\n"
84
+ " -h, --help Show this help\n"
85
+ " -D, --device device name (default '%s')\n"
86
+ " -C, --capture capture mode (default playback)\n",
87
+ name, DEFAULT_DEVICE);
88
+}
89
+
90
+int main(int argc, char *argv)
91
+{
92
+ struct state state = { 0, };
93
+ snd_pcm_hw_params_t *hparams;
94
+ snd_pcm_info_t *info;
95
+ snd_pcm_sync_id_t sync;
96
+ snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
97
+ snd_pcm_chmap_query_t **maps;
98
+ int c, i;
99
+ static const struct option long_options = {
100
+ { "help", no_argument, NULL, 'h' },
101
+ { "device", required_argument, NULL, 'D' },
102
+ { "capture", no_argument, NULL, 'C' },
103
+ { NULL, 0, NULL, 0}
104
+ };
105
+ state.device = DEFAULT_DEVICE;
106
+
107
+ while ((c = getopt_long(argc, argv, "hD:C", long_options, NULL)) != -1) {
108
+ switch (c) {
109
+ case 'h':
110
+ show_help(argv0, false);
111
+ return 0;
112
+ case 'D':
113
+ state.device = optarg;
114
+ break;
115
+ case 'C':
116
+ stream = SND_PCM_STREAM_CAPTURE;
117
+ break;
118
+ default:
119
+ show_help(argv0, true);
120
+ return -1;
121
+ }
122
+ }
123
+
124
+ CHECK(snd_output_stdio_attach(&state.output, stdout, 0), "attach failed");
125
+
126
+ fprintf(stdout, "opening device: '%s'\n", state.device);
127
+
128
+ CHECK(snd_pcm_open(&state.hndl, state.device, stream, 0),
129
+ "open %s failed", state.device);
130
+
131
+ snd_pcm_info_alloca(&info);
132
+ snd_pcm_info(state.hndl, info);
133
+
134
+ fprintf(stdout, "info:\n");
135
+ fprintf(stdout, " device: %u\n", snd_pcm_info_get_device(info));
136
+ fprintf(stdout, " subdevice: %u\n", snd_pcm_info_get_subdevice(info));
137
+ fprintf(stdout, " stream: %s\n", snd_pcm_stream_name(snd_pcm_info_get_stream(info)));
138
+ fprintf(stdout, " card: %d\n", snd_pcm_info_get_card(info));
139
+ fprintf(stdout, " id: '%s'\n", snd_pcm_info_get_id(info));
140
+ fprintf(stdout, " name: '%s'\n", snd_pcm_info_get_name(info));
141
+ fprintf(stdout, " subdevice name: '%s'\n", snd_pcm_info_get_subdevice_name(info));
142
+ fprintf(stdout, " class: %s\n", get_class(snd_pcm_info_get_class(info)));
143
+ fprintf(stdout, " subclass: %s\n", get_subclass(snd_pcm_info_get_subclass(info)));
144
+ fprintf(stdout, " subdevice count: %u\n", snd_pcm_info_get_subdevices_count(info));
145
+ fprintf(stdout, " subdevice avail: %u\n", snd_pcm_info_get_subdevices_avail(info));
146
+ sync = snd_pcm_info_get_sync(info);
147
+ fprintf(stdout, " sync: %08x:%08x:%08x:%08x\n",
148
+ sync.id320, sync.id321, sync.id322,sync.id323);
149
+
150
+ /* channel maps */
151
+ if ((maps = snd_pcm_query_chmaps(state.hndl)) != NULL) {
152
+ fprintf(stdout, "channels:\n");
153
+
154
+ for (i = 0; mapsi; i++) {
155
+ snd_pcm_chmap_t* map = &mapsi->map;
156
+ char buf2048;
157
+
158
+ snd_pcm_chmap_print(map, sizeof(buf), buf);
159
+
160
+ fprintf(stdout, " %d: %s\n", map->channels, buf);
161
+ }
162
+ snd_pcm_free_chmaps(maps);
163
+ }
164
+
165
+ /* hw params */
166
+ snd_pcm_hw_params_alloca(&hparams);
167
+ snd_pcm_hw_params_any(state.hndl, hparams);
168
+
169
+ snd_pcm_hw_params_dump(hparams, state.output);
170
+
171
+ snd_pcm_close(state.hndl);
172
+
173
+ return EXIT_SUCCESS;
174
+}
175
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
147
1
2
}
3
break;
4
case SPA_PROP_rate:
5
- if (spa_pod_get_double(&prop->value, &p->rate) == 0)
6
- changed++;
7
+ spa_pod_get_double(&prop->value, &p->rate);
8
break;
9
case SPA_PROP_params:
10
changed += parse_prop_params(this, &prop->value);
11
12
13
rate = this->io_position ? this->io_position->clock.rate.denom : DEFAULT_RATE;
14
15
- if (in->format.info.raw.rate == 0 && in->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp)
16
+ /* in DSP mode we always convert to the DSP rate */
17
+ if (in->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp)
18
in->format.info.raw.rate = rate;
19
- if (out->format.info.raw.rate == 0 && out->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp)
20
+ if (out->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp)
21
out->format.info.raw.rate = rate;
22
23
+ /* try to passthrough the rates */
24
if (in->format.info.raw.rate == 0)
25
in->format.info.raw.rate = out->format.info.raw.rate;
26
else if (out->format.info.raw.rate == 0)
27
out->format.info.raw.rate = in->format.info.raw.rate;
28
29
- if (in->format.info.raw.rate == 0 && out->format.info.raw.rate == 0)
30
- return -EINVAL;
31
- if (in->format.info.raw.channels == 0 && out->format.info.raw.channels == 0)
32
- return -EINVAL;
33
-
34
+ /* try to passthrough the channels */
35
if (in->format.info.raw.channels == 0)
36
in->format.info.raw.channels = out->format.info.raw.channels;
37
else if (out->format.info.raw.channels == 0)
38
out->format.info.raw.channels = in->format.info.raw.channels;
39
40
+ if (in->format.info.raw.rate == 0 || out->format.info.raw.rate == 0)
41
+ return -EINVAL;
42
+ if (in->format.info.raw.channels == 0 || out->format.info.raw.channels == 0)
43
+ return -EINVAL;
44
+
45
if ((res = setup_in_convert(this)) < 0)
46
return res;
47
if ((res = setup_channelmix(this)) < 0)
48
49
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
50
break;
51
case SPA_PARAM_Buffers:
52
+ {
53
+ uint32_t size;
54
+ struct dir *dir;
55
+
56
if (!port->have_format)
57
return -EIO;
58
if (result.index > 0)
59
return 0;
60
61
+ dir = &this->dirdirection;
62
+ if (dir->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp) {
63
+ /* DSP ports always use the quantum_limit as the buffer
64
+ * size. */
65
+ size = this->quantum_limit;
66
+ } else {
67
+ uint32_t irate, orate;
68
+ /* Convert ports are scaled so that they can always
69
+ * provide one quantum of data */
70
+ irate = dir->format.info.raw.rate;
71
+
72
+ /* collect the other port rate */
73
+ dir = &this->dirSPA_DIRECTION_REVERSE(direction);
74
+ if (dir->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp)
75
+ orate = this->io_position ? this->io_position->clock.rate.denom : DEFAULT_RATE;
76
+ else
77
+ orate = dir->format.info.raw.rate;
78
+
79
+ /* always keep some extra room for adaptive resampling */
80
+ size = this->quantum_limit * 2;
81
+ /* scale the buffer size when we can. */
82
+ if (irate != 0 && orate != 0)
83
+ size = size * (irate + orate - 1) / orate;
84
+ }
85
+
86
param = spa_pod_builder_add_object(&b,
87
SPA_TYPE_OBJECT_ParamBuffers, id,
88
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS),
89
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(port->blocks),
90
SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int(
91
- this->quantum_limit * port->stride,
92
+ size * port->stride,
93
16 * port->stride,
94
INT32_MAX),
95
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(port->stride));
96
break;
97
+ }
98
case SPA_PARAM_Meta:
99
switch (result.index) {
100
case 0:
101
102
return end ? 1 : 0;
103
}
104
105
+static uint32_t resample_get_in_size(struct impl *this, bool passthrough, uint32_t out_size)
106
+{
107
+ uint32_t match_size = passthrough ? out_size : resample_in_len(&this->resample, out_size);
108
+ spa_log_trace_fp(this->log, "%p: current match %u", this, match_size);
109
+ return match_size;
110
+}
111
+
112
static uint32_t resample_update_rate_match(struct impl *this, bool passthrough, uint32_t out_size, uint32_t in_queued)
113
{
114
- double rate = this->rate_scale / this->props.rate;
115
uint32_t delay, match_size;
116
117
if (passthrough) {
118
delay = 0;
119
match_size = out_size;
120
} else {
121
+ double rate = this->rate_scale / this->props.rate;
122
if (this->io_rate_match &&
123
SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE))
124
rate *= this->io_rate_match->rate;
125
126
127
/* calculate how many samples we are going to consume. */
128
if (this->direction == SPA_DIRECTION_INPUT) {
129
- uint32_t n_in;
130
- /* then figure out how much input samples we need to consume */
131
- n_in = resample_update_rate_match(this, resample_passthrough, n_out, 0);
132
if (!in_avail || this->drained) {
133
+ /* no input, ask for more, update rate-match first */
134
+ resample_update_rate_match(this, resample_passthrough, n_out, 0);
135
spa_log_trace_fp(this->log, "%p: no input drained:%d", this, this->drained);
136
- /* no input, ask for more */
137
res |= this->drained ? SPA_STATUS_DRAINED : SPA_STATUS_NEED_DATA;
138
return res;
139
}
140
- n_samples = SPA_MIN(n_samples, n_in);
141
+ /* else figure out how much input samples we need to consume */
142
+ n_samples = SPA_MIN(n_samples,
143
+ resample_get_in_size(this, resample_passthrough, n_out));
144
} else {
145
/* in merge mode we consume one duration of samples */
146
n_samples = SPA_MIN(n_samples, quant_samples);
147
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/channelmix-ops.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/channelmix-ops.c
Changed
55
1
2
matrixii= 1.0f;
3
}
4
src_mask = dst_mask = ~0LU;
5
+ filter_fc = filter_lfe = true;
6
goto done;
7
} else {
8
spa_log_debug(mix->log, "matching channels");
9
10
spa_log_debug(mix->log, "unassigned upmix %08"PRIx64" lfe:%f",
11
unassigned, mix->lfe_cutoff);
12
13
+ if (unassigned & STEREO) {
14
+ if ((src_mask & FRONT) == FRONT) {
15
+ spa_log_debug(mix->log, "produce STEREO from FC");
16
+ _MATRIX(FL,FC) += clev;
17
+ _MATRIX(FR,FC) += clev;
18
+ } else {
19
+ spa_log_warn(mix->log, "can't produce STEREO");
20
+ }
21
+ }
22
if (unassigned & FRONT) {
23
if ((src_mask & STEREO) == STEREO) {
24
spa_log_debug(mix->log, "produce FC from STEREO");
25
26
spa_log_debug(mix->log, "produce SIDE from STEREO");
27
_MATRIX(SL,FL) += slev;
28
_MATRIX(SR,FR) += slev;
29
- } else if ((src_mask & FRONT) == FRONT) {
30
+ } else if ((src_mask & FRONT) == FRONT &&
31
+ mix->upmix == CHANNELMIX_UPMIX_SIMPLE) {
32
spa_log_debug(mix->log, "produce SIDE from FC");
33
_MATRIX(SL,FC) += clev;
34
_MATRIX(SR,FC) += clev;
35
+ } else {
36
+ spa_log_debug(mix->log, "won't produce SIDE");
37
}
38
}
39
if (unassigned & REAR) {
40
41
spa_log_debug(mix->log, "produce REAR from STEREO");
42
_MATRIX(RL,FL) += slev;
43
_MATRIX(RR,FR) += slev;
44
- } else if ((src_mask & FRONT) == FRONT) {
45
+ } else if ((src_mask & FRONT) == FRONT &&
46
+ mix->upmix == CHANNELMIX_UPMIX_SIMPLE) {
47
spa_log_debug(mix->log, "produce REAR from FC");
48
_MATRIX(RL,FC) += clev;
49
_MATRIX(RR,FC) += clev;
50
+ } else {
51
+ spa_log_debug(mix->log, "won't produce SIDE");
52
}
53
}
54
55
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c
Changed
101
1
2
float *d0 = dst0, *d1 = dst1, *d2 = dst2, *d3 = dst3;
3
uint32_t n, unrolled;
4
__m256i in4, t4;
5
- __m256 out4, factor = _mm256_set1_ps(1.0f / S32_SCALE);
6
+ __m256 out4, factor = _mm256_set1_ps(1.0f / S24_SCALE);
7
__m256i mask1 = _mm256_setr_epi64x(0*n_channels, 0*n_channels+2, 4*n_channels, 4*n_channels+2);
8
__m256i mask2 = _mm256_setr_epi64x(1*n_channels, 1*n_channels+2, 5*n_channels, 5*n_channels+2);
9
__m256i mask3 = _mm256_setr_epi64x(2*n_channels, 2*n_channels+2, 6*n_channels, 6*n_channels+2);
10
11
in2 = _mm256_unpacklo_epi64(t1, t3); /* c0 c1 c2 c3 c4 c5 c6 c7 */
12
in3 = _mm256_unpackhi_epi64(t1, t3); /* d0 d1 d2 d3 d4 d5 d6 d7 */
13
14
+ in0 = _mm256_srai_epi32(in0, 8);
15
+ in1 = _mm256_srai_epi32(in1, 8);
16
+ in2 = _mm256_srai_epi32(in2, 8);
17
+ in3 = _mm256_srai_epi32(in3, 8);
18
+
19
out0 = _mm256_cvtepi32_ps(in0);
20
out1 = _mm256_cvtepi32_ps(in1);
21
out2 = _mm256_cvtepi32_ps(in2);
22
23
s += 8*n_channels;
24
}
25
for(; n < n_samples; n++) {
26
- __m128 out4, factor = _mm_set1_ps(1.0f / S32_SCALE);
27
- out0 = _mm_cvtsi32_ss(factor, s0);
28
- out1 = _mm_cvtsi32_ss(factor, s1);
29
- out2 = _mm_cvtsi32_ss(factor, s2);
30
- out3 = _mm_cvtsi32_ss(factor, s3);
31
+ __m128 out4, factor = _mm_set1_ps(1.0f / S24_SCALE);
32
+ out0 = _mm_cvtsi32_ss(factor, s0 >> 8);
33
+ out1 = _mm_cvtsi32_ss(factor, s1 >> 8);
34
+ out2 = _mm_cvtsi32_ss(factor, s2 >> 8);
35
+ out3 = _mm_cvtsi32_ss(factor, s3 >> 8);
36
out0 = _mm_mul_ss(out0, factor);
37
out1 = _mm_mul_ss(out1, factor);
38
out2 = _mm_mul_ss(out2, factor);
39
40
float *d0 = dst0, *d1 = dst1;
41
uint32_t n, unrolled;
42
__m256i in4, t4;
43
- __m256 out4, factor = _mm256_set1_ps(1.0f / S32_SCALE);
44
+ __m256 out4, factor = _mm256_set1_ps(1.0f / S24_SCALE);
45
__m256i perm = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7);
46
__m256i mask1 = _mm256_setr_epi64x(0*n_channels, 1*n_channels, 2*n_channels, 3*n_channels);
47
__m256i mask2 = _mm256_setr_epi64x(4*n_channels, 5*n_channels, 6*n_channels, 7*n_channels);
48
49
in0 = _mm256_permute2x128_si256(t0, t1, 0 | (2 << 4));
50
in1 = _mm256_permute2x128_si256(t0, t1, 1 | (3 << 4));
51
52
+ in0 = _mm256_srai_epi32(in0, 8);
53
+ in1 = _mm256_srai_epi32(in1, 8);
54
+
55
out0 = _mm256_cvtepi32_ps(in0);
56
out1 = _mm256_cvtepi32_ps(in1);
57
58
59
s += 8*n_channels;
60
}
61
for(; n < n_samples; n++) {
62
- __m128 out2, factor = _mm_set1_ps(1.0f / S32_SCALE);
63
- out0 = _mm_cvtsi32_ss(factor, s0);
64
- out1 = _mm_cvtsi32_ss(factor, s1);
65
+ __m128 out2, factor = _mm_set1_ps(1.0f / S24_SCALE);
66
+ out0 = _mm_cvtsi32_ss(factor, s0 >> 8);
67
+ out1 = _mm_cvtsi32_ss(factor, s1 >> 8);
68
out0 = _mm_mul_ss(out0, factor);
69
out1 = _mm_mul_ss(out1, factor);
70
_mm_store_ss(&d0n, out0);
71
72
float *d0 = dst0;
73
uint32_t n, unrolled;
74
__m256i in2;
75
- __m256 out2, factor = _mm256_set1_ps(1.0f / S32_SCALE);
76
+ __m256 out2, factor = _mm256_set1_ps(1.0f / S24_SCALE);
77
__m256i mask1 = _mm256_setr_epi64x(0*n_channels, 1*n_channels, 2*n_channels, 3*n_channels);
78
__m256i mask2 = _mm256_setr_epi64x(4*n_channels, 5*n_channels, 6*n_channels, 7*n_channels);
79
80
81
_mm256_i64gather_epi32(&s 8*n_channels, mask1, 4),
82
_mm256_i64gather_epi32(&s 8*n_channels, mask2, 4));
83
84
+ in0 = _mm256_srai_epi32(in0, 8);
85
+ in1 = _mm256_srai_epi32(in1, 8);
86
+
87
out0 = _mm256_cvtepi32_ps(in0);
88
out1 = _mm256_cvtepi32_ps(in1);
89
90
91
s += 16*n_channels;
92
}
93
for(; n < n_samples; n++) {
94
- __m128 out, factor = _mm_set1_ps(1.0f / S32_SCALE);
95
- out = _mm_cvtsi32_ss(factor, s0);
96
+ __m128 out, factor = _mm_set1_ps(1.0f / S24_SCALE);
97
+ out = _mm_cvtsi32_ss(factor, s0 >> 8);
98
out = _mm_mul_ss(out, factor);
99
_mm_store_ss(&d0n, out);
100
s += n_channels;
101
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/fmt-ops-neon.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/fmt-ops-neon.c
Changed
200
1
2
#include <stdio.h>
3
#include <math.h>
4
5
+#include <arm_neon.h>
6
+
7
#include "fmt-ops.h"
8
9
void
10
11
12
#ifdef __aarch64__
13
asm volatile(
14
+ " dup v2.4s, %wscale\n"
15
" cmp %n_samples, #0\n"
16
" beq 2f\n"
17
"1:"
18
" ld1 { v0.4s }, %s0, #16\n"
19
" ld1 { v1.4s }, %s1, #16\n"
20
" subs %n_samples, %n_samples, #4\n"
21
- " fcvtzs v0.4s, v0.4s, #31\n"
22
- " fcvtzs v1.4s, v1.4s, #31\n"
23
- " sqrshrn v0.4h, v0.4s, #16\n"
24
- " sqrshrn v1.4h, v1.4s, #16\n"
25
+ " sqadd v0.4s, v0.4s, v2.4s\n"
26
+ " sqadd v1.4s, v1.4s, v2.4s\n"
27
+ " fcvtns v0.4s, v0.4s\n"
28
+ " fcvtns v1.4s, v1.4s\n"
29
+ " sqxtn v0.4h, v0.4s\n"
30
+ " sqxtn v1.4h, v1.4s\n"
31
" st2 { v0.h, v1.h }0, %d, %stride\n"
32
" st2 { v0.h, v1.h }1, %d, %stride\n"
33
" st2 { v0.h, v1.h }2, %d, %stride\n"
34
35
" ld1 { v0.s }0, %s0, #4\n"
36
" ld1 { v2.s }0, %s1, #4\n"
37
" subs %remainder, %remainder, #1\n"
38
- " fcvtzs v0.4s, v0.4s, #31\n"
39
- " fcvtzs v1.4s, v1.4s, #31\n"
40
- " sqrshrn v0.4h, v0.4s, #16\n"
41
- " sqrshrn v1.4h, v1.4s, #16\n"
42
+ " sqadd v0.4s, v0.4s, v2.4s\n"
43
+ " sqadd v1.4s, v1.4s, v2.4s\n"
44
+ " fcvtns v0.4s, v0.4s\n"
45
+ " fcvtns v1.4s, v1.4s\n"
46
+ " sqxtn v0.4h, v0.4s\n"
47
+ " sqxtn v1.4h, v1.4s\n"
48
" st2 { v0.h, v1.h }0, %d, %stride\n"
49
" bne 3b\n"
50
"4:"
51
: d "+r" (d), s0 "+r" (s0), s1 "+r" (s1), n_samples "+r" (n_samples),
52
remainder "+r" (remainder)
53
- : stride "r" (stride)
54
+ : stride "r" (stride),
55
+ scale "r" (15 << 23)
56
: "cc", "v0", "v1");
57
#else
58
+ float32x4_t pos = vdupq_n_f32(0.4999999f / S16_SCALE);
59
+ float32x4_t neg = vdupq_n_f32(-0.4999999f / S16_SCALE);
60
+
61
asm volatile(
62
+ " veor q2, q2, q2\n"
63
" cmp %n_samples, #0\n"
64
" beq 2f\n"
65
"1:"
66
" vld1.32 { q0 }, %s0!\n"
67
" vld1.32 { q1 }, %s1!\n"
68
" subs %n_samples, %n_samples, #4\n"
69
- " vcvt.s32.f32 q0, q0, #31\n"
70
- " vcvt.s32.f32 q1, q1, #31\n"
71
- " vqrshrn.s32 d0, q0, #16\n"
72
- " vqrshrn.s32 d1, q1, #16\n"
73
+ " vcgt.f32 q3, q0, q2\n"
74
+ " vcgt.f32 q4, q0, q2\n"
75
+ " vbsl q3, %qpos, %qneg\n"
76
+ " vbsl q4, %qpos, %qneg\n"
77
+ " vadd.f32 q0, q0, q3\n"
78
+ " vadd.f32 q1, q1, q4\n"
79
+ " vcvt.s32.f32 q0, q0, #15\n"
80
+ " vcvt.s32.f32 q1, q1, #15\n"
81
+ " vqmovn.s32 d0, q0\n"
82
+ " vqmovn.s32 d1, q1\n"
83
" vst2.16 { d00, d10 }, %d, %stride\n"
84
" vst2.16 { d01, d11 }, %d, %stride\n"
85
" vst2.16 { d02, d12 }, %d, %stride\n"
86
87
" vld1.32 { d00 }, %s0!\n"
88
" vld1.32 { d20 }, %s1!\n"
89
" subs %remainder, %remainder, #1\n"
90
- " vcvt.s32.f32 q0, q0, #31\n"
91
- " vcvt.s32.f32 q1, q1, #31\n"
92
- " vqrshrn.s32 d0, q0, #16\n"
93
- " vqrshrn.s32 d1, q1, #16\n"
94
+ " vcgt.f32 q3, q0, q2\n"
95
+ " vcgt.f32 q4, q0, q2\n"
96
+ " vbsl q3, %qpos, %qneg\n"
97
+ " vbsl q4, %qpos, %qneg\n"
98
+ " vadd.f32 q0, q0, q3\n"
99
+ " vadd.f32 q1, q1, q4\n"
100
+ " vcvt.s32.f32 q0, q0, #15\n"
101
+ " vcvt.s32.f32 q1, q1, #15\n"
102
+ " vqmovn.s32 d0, q0\n"
103
+ " vqmovn.s32 d1, q1\n"
104
" vst2.16 { d00, d10 }, %d, %stride\n"
105
" bne 3b\n"
106
"4:"
107
: d "+r" (d), s0 "+r" (s0), s1 "+r" (s1), n_samples "+r" (n_samples),
108
remainder "+r" (remainder)
109
- : stride "r" (stride)
110
- : "cc", "q0", "q1");
111
+ : stride "r" (stride),
112
+ pos"w"(pos),
113
+ neg"w"(neg)
114
+ : "cc", "q0", "q1", "q2", "q3", "q4");
115
#endif
116
}
117
118
119
120
#ifdef __aarch64__
121
asm volatile(
122
+ " dup v2.4s, %wscale\n"
123
" cmp %n_samples, #0\n"
124
" beq 2f\n"
125
"1:"
126
" ld1 { v0.4s }, %s, #16\n"
127
" subs %n_samples, %n_samples, #4\n"
128
- " fcvtzs v0.4s, v0.4s, #31\n"
129
- " sqrshrn v0.4h, v0.4s, #16\n"
130
+ " sqadd v0.4s, v0.4s, v2.4s\n"
131
+ " fcvtns v0.4s, v0.4s\n"
132
+ " sqxtn v0.4h, v0.4s\n"
133
" st1 { v0.h }0, %d, %stride\n"
134
" st1 { v0.h }1, %d, %stride\n"
135
" st1 { v0.h }2, %d, %stride\n"
136
137
"3:"
138
" ld1 { v0.s }0, %s, #4\n"
139
" subs %remainder, %remainder, #1\n"
140
- " fcvtzs v0.4s, v0.4s, #31\n"
141
- " sqrshrn v0.4h, v0.4s, #16\n"
142
+ " sqadd v0.4s, v0.4s, v2.4s\n"
143
+ " fcvtns v0.4s, v0.4s\n"
144
+ " sqxtn v0.4h, v0.4s\n"
145
" st1 { v0.h }0, %d, %stride\n"
146
" bne 3b\n"
147
"4:"
148
: d "+r" (d), s "+r" (s), n_samples "+r" (n_samples),
149
remainder "+r" (remainder)
150
- : stride "r" (stride)
151
+ : stride "r" (stride),
152
+ scale "r" (15 << 23)
153
: "cc", "v0");
154
#else
155
+ float32x4_t pos = vdupq_n_f32(0.4999999f / S16_SCALE);
156
+ float32x4_t neg = vdupq_n_f32(-0.4999999f / S16_SCALE);
157
+
158
asm volatile(
159
+ " veor q1, q1, q1\n"
160
" cmp %n_samples, #0\n"
161
" beq 2f\n"
162
"1:"
163
" vld1.32 { q0 }, %s!\n"
164
" subs %n_samples, %n_samples, #4\n"
165
- " vcvt.s32.f32 q0, q0, #31\n"
166
- " vqrshrn.s32 d0, q0, #16\n"
167
+ " vcgt.f32 q2, q0, q1\n"
168
+ " vbsl q2, %qpos, %qneg\n"
169
+ " vadd.f32 q0, q0, q2\n"
170
+ " vcvt.s32.f32 q0, q0, #15\n"
171
+ " vqmovn.s32 d0, q0\n"
172
" vst1.16 { d00 }, %d, %stride\n"
173
" vst1.16 { d01 }, %d, %stride\n"
174
" vst1.16 { d02 }, %d, %stride\n"
175
176
"3:"
177
" vld1.32 { d00 }, %s!\n"
178
" subs %remainder, %remainder, #1\n"
179
- " vcvt.s32.f32 q0, q0, #31\n"
180
- " vqrshrn.s32 d0, q0, #16\n"
181
+ " vcgt.f32 q2, q0, q1\n"
182
+ " vbsl q2, %qpos, %qneg\n"
183
+ " vadd.f32 q0, q0, q2\n"
184
+ " vcvt.s32.f32 q0, q0, #15\n"
185
+ " vqmovn.s32 d0, q0\n"
186
" vst1.16 { d00 }, %d, %stride\n"
187
" bne 3b\n"
188
"4:"
189
: d "+r" (d), s "+r" (s), n_samples "+r" (n_samples),
190
remainder "+r" (remainder)
191
- : stride "r" (stride)
192
- : "cc", "q0");
193
+ : stride "r" (stride),
194
+ pos"w"(pos),
195
+ neg"w"(neg)
196
+ : "cc", "q0", "q1", "q2");
197
#endif
198
}
199
200
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/fmt-ops.h -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/fmt-ops.h
Changed
22
1
2
#define ITOF(type,v,scale,offs) \
3
(((type)(v)) * (1.0f / (scale)) - (offs))
4
#define FTOI(type,v,scale,offs,noise,min,max) \
5
- (type)f32_round(SPA_CLAMP((v) * (scale) + (offs) + (noise), min, max))
6
+ (type)f32_round(SPA_CLAMPF((v) * (scale) + (offs) + (noise), min, max))
7
8
#define FMT_OPS_MAX_ALIGN 32
9
10
11
#define F32_TO_S24_32S(v) bswap_32(F32_TO_S24_32(v))
12
#define F32_TO_S24_32S_D(v,d) bswap_32(F32_TO_S24_32_D(v,d))
13
14
-#define S32_MIN -2147483648
15
-#define S32_MAX 2147483647
16
-#define S32_SCALE 2147483648.f
17
+#define S32_MIN (S24_MIN * 256)
18
+#define S32_MAX (S24_MAX * 256)
19
#define S32_TO_F32(v) ITOF(int32_t, (v) >> 8, S24_SCALE, 0.0f)
20
#define S32S_TO_F32(v) S32_TO_F32(bswap_32(v))
21
#define F32_TO_S32(v) (F32_TO_S24_32(v) << 8)
22
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/resample-native.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/resample-native.c
Changed
20
1
2
}
3
static inline double window_cosh(double x, double n_taps)
4
{
5
- double R = 190.0, r;
6
- double A = (-325.1E-6 * R + 0.1677) * R - 3.149;
7
+ double r;
8
+ double A = 16.97789;
9
double x2;
10
x = 2.0 * x / n_taps;
11
x2 = x * x;
12
if (x2 >= 1.0)
13
return 0.0;
14
- r = cosh(A * sqrt(1 - x2)) / cosh(A);
15
+ /* doi:10.1109/RME.2008.4595727 with tweak */
16
+ r = (exp(A * sqrt(1 - x2)) - 1) / (exp(A) - 1);
17
return r;
18
}
19
20
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/test-fmt-ops.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/test-fmt-ops.c
Changed
27
1
2
false, true, conv_f32d_to_s16_avx2);
3
}
4
#endif
5
+#if defined(HAVE_NEON)
6
+ if (cpu_flags & SPA_CPU_FLAG_NEON) {
7
+ run_test("test_f32d_s16_neon", in, sizeof(in0), out, sizeof(out0), SPA_N_ELEMENTS(out),
8
+ false, true, conv_f32d_to_s16_neon);
9
+ }
10
+#endif
11
}
12
13
static void test_s16_f32(void)
14
15
true, false, conv_s16_to_f32d_avx2);
16
}
17
#endif
18
+#if defined(HAVE_NEON)
19
+ if (cpu_flags & SPA_CPU_FLAG_NEON) {
20
+ run_test("test_s16_f32d_neon", in, sizeof(in0), out, sizeof(out0), SPA_N_ELEMENTS(out),
21
+ true, false, conv_s16_to_f32d_neon);
22
+ }
23
+#endif
24
}
25
26
static void test_f32_u32(void)
27
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/test-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/test-source.c
Changed
13
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = GET_OUT_PORT(this, 0);
5
-
6
- io = port->io;
7
- spa_return_val_if_fail(io != NULL, -EIO);
8
+ if ((io = port->io) == NULL)
9
+ return -EIO;
10
11
spa_log_trace_fp(this->log, NAME " %p: status %d", this, io->status);
12
13
pipewire-0.3.56.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.57.tar.gz/spa/plugins/audiomixer/audiomixer.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
outport = GET_OUT_PORT(this, 0);
5
- outio = outport->io;
6
- spa_return_val_if_fail(outio != NULL, -EIO);
7
+ if ((outio = outport->io) == NULL)
8
+ return -EIO;
9
10
spa_log_trace_fp(this->log, "%p: status %p %d %d",
11
this, outio, outio->status, outio->buffer_id);
12
pipewire-0.3.56.tar.gz/spa/plugins/audiomixer/mixer-dsp.c -> pipewire-0.3.57.tar.gz/spa/plugins/audiomixer/mixer-dsp.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
outport = GET_OUT_PORT(this, 0);
5
- outio = outport->io;
6
- spa_return_val_if_fail(outio != NULL, -EIO);
7
+ if ((outio = outport->io) == NULL)
8
+ return -EIO;
9
10
spa_log_trace_fp(this->log, "%p: status %p %d %d",
11
this, outio, outio->status, outio->buffer_id);
12
pipewire-0.3.56.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c -> pipewire-0.3.57.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c
Changed
11
1
2
port = &this->port;
3
4
io = port->io;
5
- spa_return_val_if_fail(io != NULL, -EIO);
6
+ if ((io = port->io) == NULL)
7
+ return -EIO;
8
9
if (port->io_control)
10
process_control(this, &port->io_control->sequence);
11
pipewire-0.3.56.tar.gz/spa/plugins/avb/avb-pcm-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/avb/avb-pcm-sink.c
Changed
56
1
2
{
3
struct state *this = object;
4
struct port *port;
5
- struct spa_io_buffers *input;
6
+ struct spa_io_buffers *io;
7
8
spa_return_val_if_fail(this != NULL, -EINVAL);
9
10
port = GET_PORT(this, SPA_DIRECTION_INPUT, 0);
11
+ if ((io = port->io) == NULL)
12
+ return -EIO;
13
14
- input = port->io;
15
- spa_return_val_if_fail(input != NULL, -EIO);
16
-
17
- spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, input->status,
18
- input->buffer_id, port->n_buffers);
19
+ spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, io->status,
20
+ io->buffer_id, port->n_buffers);
21
22
if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) {
23
- input->status = SPA_STATUS_NEED_DATA;
24
+ io->status = SPA_STATUS_NEED_DATA;
25
return SPA_STATUS_HAVE_DATA;
26
}
27
- if (input->status == SPA_STATUS_HAVE_DATA &&
28
- input->buffer_id < port->n_buffers) {
29
- struct buffer *b = &port->buffersinput->buffer_id;
30
+ if (io->status == SPA_STATUS_HAVE_DATA &&
31
+ io->buffer_id < port->n_buffers) {
32
+ struct buffer *b = &port->buffersio->buffer_id;
33
34
if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_OUT)) {
35
spa_log_warn(this->log, "%p: buffer %u in use",
36
- this, input->buffer_id);
37
- input->status = -EINVAL;
38
+ this, io->buffer_id);
39
+ io->status = -EINVAL;
40
return -EINVAL;
41
}
42
- spa_log_trace_fp(this->log, "%p: queue buffer %u", this, input->buffer_id);
43
+ spa_log_trace_fp(this->log, "%p: queue buffer %u", this, io->buffer_id);
44
spa_list_append(&port->ready, &b->link);
45
SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT);
46
- input->buffer_id = SPA_ID_INVALID;
47
+ io->buffer_id = SPA_ID_INVALID;
48
49
spa_avb_write(this);
50
51
- input->status = SPA_STATUS_OK;
52
+ io->status = SPA_STATUS_OK;
53
}
54
return SPA_STATUS_HAVE_DATA;
55
}
56
pipewire-0.3.56.tar.gz/spa/plugins/avb/avb-pcm-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/avb/avb-pcm-source.c
Changed
13
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = GET_PORT(this, SPA_DIRECTION_OUTPUT, 0);
5
-
6
- io = port->io;
7
- spa_return_val_if_fail(io != NULL, -EIO);
8
+ if ((io = port->io) == NULL)
9
+ return -EIO;
10
11
spa_log_trace_fp(this->log, "%p: process %d %d/%d %d", this, io->status,
12
io->buffer_id, port->n_buffers, this->following);
13
pipewire-0.3.56.tar.gz/spa/plugins/avb/avbtp/packets.h -> pipewire-0.3.57.tar.gz/spa/plugins/avb/avbtp/packets.h
Changed
10
1
2
unsigned gv:1;
3
unsigned tv:1;
4
5
- uint8_t seq_number;
6
+ uint8_t seq_num;
7
8
unsigned _r2:7;
9
unsigned tu:1;
10
pipewire-0.3.57.tar.gz/spa/plugins/bluez5/README-OPUS-A2DP.md
Added
201
1
2
+---
3
+title: OPUS-A2DP-0.5 specification
4
+author: Pauli Virtanen <pav@iki.fi>
5
+date: Jun 4, 2022
6
+---
7
+
8
+# OPUS-A2DP-0.5 specification
9
+
10
+DRAFT
11
+
12
+In this file, we specify how to use Opus as an A2DP vendor codec. We
13
+will call this "OPUS-A2DP-0.5". There is no previous public
14
+specification for using Opus as an A2DP vendor codec (to my
15
+knowledge), which is why we need this one.
16
+
17
+_TOC_
18
+
19
+# A2DP Codec Capabilities
20
+
21
+The A2DP capability structure is as follows.
22
+
23
+Integer fields and multi-byte bitfields are laid out in **little
24
+endian** order. All integer fields are unsigned.
25
+
26
+Each entry may have different meaning when present as a capability.
27
+Below, we indicate this by abbreviations CAP/SNK for sink capability,
28
+CAP/SRC for source capability, CAP for capability as either, and SEL
29
+for the selected value by SRC.
30
+
31
+Bits in fields marked RFA (Reserved For Additions) shall be set to
32
+zero.
33
+
34
+The capability and configuration structure is as follows:
35
+
36
+| Octet | Bits | Meaning |
37
+|-------|------|-----------------------------------------------|
38
+| 0-5 | 0-7 | Vendor ID Part |
39
+| 6-7 | 0-7 | Channel Configuration |
40
+| 8-11 | 0-7 | Audio Location Configuration |
41
+| 12-14 | 0-7 | Limits Configuration |
42
+| 15-16 | 0-7 | Return Direction Channel Configuration |
43
+| 17-20 | 0-7 | Return Direction Audio Location Configuration |
44
+| 21-23 | 0-7 | Return Direction Limits Configuration |
45
+
46
+See `a2dp-codec-caps.h` for definition as C structs.
47
+
48
+## Vendor ID Part
49
+
50
+The fixed value
51
+
52
+| Octet | Bits | Meaning |
53
+|-------|------|-------------------------------|
54
+| 0-3 | 0-7 | A2DP Vendor ID (0x05F1) |
55
+| 4-5 | 0-7 | A2DP Vendor Codec ID (0x1005) |
56
+
57
+The Vendor ID is that of the Linux Foundation, and we are using it
58
+here unofficially.
59
+
60
+## Channel Configuration
61
+
62
+The channel configuration consists of the channel count and a bitfield
63
+indicating which of them are encoded in coupled streams.
64
+
65
+| Octet | Bits | Meaning |
66
+|-------|------|------------------------------------------------------------|
67
+| 6 | 0-7 | Channel Count. CAP: maximum number supported. SEL: actual. |
68
+| 7 | 0-7 | Coupled Stream Count. CAP: 0. SEL: actual. |
69
+
70
+The Channel Count indicates the number of logical channels encoded in
71
+the data stream.
72
+
73
+The Coupled Stream Count indicates the number of streams that encode a
74
+coupled (left & right) channel pair. The count shall satisfy
75
+`(Channel Count) >= 2*(Coupled Stream Count)`.
76
+The Stream Count is `(Channel Count) - (Coupled Stream Count)`.
77
+
78
+Streams and Coupled Streams have the same meaning as in Sec. 5.1.1 of
79
+Opus Multistream RFC7845.
80
+
81
+The logical Channels are identified by a Channel Index *j* such that `0 <= j
82
+< (Channel Count)`. The channels `0 <= j < 2*(Coupled Stream Count)`
83
+are encoded in the *k*-th stream of the payload, where `k = floor(j/2)` and
84
+`j mod 2` determines which of the two channels of the stream the logical
85
+channel is. The channels `2*(Coupled Stream Count) <= j < (Channel Count)`
86
+are encoded in the *k*-th stream of the payload, where `k = j - (Coupled Stream Count)`.
87
+The prescription here is identical to RFC7845 with channel mapping
88
+`mappingj = j`.
89
+
90
+The semantic meaning for each channel is determined by their Audio
91
+Location.
92
+
93
+## Audio Location Configuration
94
+
95
+The channel audio location specification is similar to the location
96
+bitfield of the `Audio_Channel_Allocation` LTV structure in Bluetooth
97
+SIG Assigned Numbers, Generic Audio used in the LE Audio.
98
+
99
+| Octet | Bits | Meaning |
100
+|-------|------|------------------------------------------------------|
101
+| 8-11 | 0-7 | Audio Location bitfield. CAP: available. SEL: actual |
102
+
103
+The values specified in CAP are informative, and SEL may contain bits
104
+that were not set in CAP. SNK shall handle unsupported audio
105
+locations. It may do this for example by ignoring unsupported channels
106
+or via suitable up/downmixing. Hence, SRC may transmit channels with
107
+audio locations that are not marked supported by SNK. The maximum
108
+Channel Count however shall not be exceeded.
109
+
110
+The audio location bitfield values defined in Assigned Numbers,
111
+Generic Audio are:
112
+
113
+| Channel Order | Bitmask | Audio Location |
114
+|---------------|------------|-------------------------|
115
+| 0 | 0x00000001 | Front Left |
116
+| 1 | 0x00000002 | Front Right |
117
+| 2 | 0x00000400 | Side Left |
118
+| 3 | 0x00000800 | Side Right |
119
+| 4 | 0x00000010 | Back Left |
120
+| 5 | 0x00000020 | Back Right |
121
+| 6 | 0x00000040 | Front Left of Center |
122
+| 7 | 0x00000080 | Front Right of Center |
123
+| 8 | 0x00001000 | Top Front Left |
124
+| 9 | 0x00002000 | Top Front Right |
125
+| 10 | 0x00040000 | Top Side Left |
126
+| 11 | 0x00080000 | Top Side Right |
127
+| 12 | 0x00010000 | Top Back Left |
128
+| 13 | 0x00020000 | Top Back Right |
129
+| 14 | 0x00400000 | Bottom Front Left |
130
+| 15 | 0x00800000 | Bottom Front Right |
131
+| 16 | 0x01000000 | Front Left Wide |
132
+| 17 | 0x02000000 | Front Right Wide |
133
+| 18 | 0x04000000 | Left Surround |
134
+| 19 | 0x08000000 | Right Surround |
135
+| 20 | 0x00000004 | Front Center |
136
+| 21 | 0x00000100 | Back Center |
137
+| 22 | 0x00004000 | Top Front Center |
138
+| 23 | 0x00008000 | Top Center |
139
+| 24 | 0x00100000 | Top Back Center |
140
+| 25 | 0x00200000 | Bottom Front Center |
141
+| 26 | 0x00000008 | Low Frequency Effects 1 |
142
+| 27 | 0x00000200 | Low Frequency Effects 2 |
143
+| 28 | 0x10000000 | RFA |
144
+| 29 | 0x20000000 | RFA |
145
+| 30 | 0x40000000 | RFA |
146
+| 31 | 0x80000000 | RFA |
147
+
148
+In addition, we define a specific Channel Order for each. The bits
149
+set in the bitfield define audio locations for the streams present in the
150
+payload. The set bit with the smallest Channel Order value defines the
151
+audio location for the Channel Index *j=0*, the bit with the next
152
+lowest Channel Order value defines the audio location for the Channel
153
+Index *j=1*, and so forth.
154
+
155
+When the Channel Count is larger than the number of bits set in the
156
+Audio Location bitfield, the audio locations of the remaining channels
157
+are unspecified. Implementations may handle them as appropriate for
158
+their use case, considering them as AUX0-AUXN, or in the case of
159
+Channel Count = 1, as the single mono audio channel.
160
+
161
+When the Channel Count is smaller than the number of bits set in the
162
+Audio Location bitfield, the audio locations for the channels are
163
+assigned as above, and remaining excess bits shall be ignored.
164
+
165
+The channel ordering defined here is compatible with the internal
166
+stream ordering in the reference Opus Multistream surround encoder
167
+Mapping Family 0 and 1 output. This allows making use of its surround
168
+masking and LFE handling capabilities. The stream ordering of the
169
+reference Opus surround encoder, although being unchanged since its
170
+addition in 2013, is an internal detail of the
171
+encoder. Implementations using the surround encoder shall check that
172
+the mapping table used by the encoder corresponds to the above channel
173
+ordering.
174
+
175
+For reference, we list the Audio Location bitfield values
176
+corresponding to the different channel counts in Opus Mapping Family 0
177
+and 1 surround encoder output, and the expected mapping table:
178
+
179
+| Mapping Family | Channel Count | Audio Location Value | Stream Ordering | Mapping Table |
180
+|----------------|---------------|----------------------|---------------------------------|--------------------------|
181
+| 0 | 1 | 0x00000000 | mono | {0} |
182
+| 0 | 2 | 0x00000003 | FL, FR | {0, 1} |
183
+| 1 | 1 | 0x00000000 | mono | {0} |
184
+| 1 | 2 | 0x00000003 | FL, FR | {0, 1} |
185
+| 1 | 3 | 0x00000007 | FL, FR, FC | {0, 2, 1} |
186
+| 1 | 4 | 0x00000033 | FL, FR, BL, BR | {0, 1, 2, 3} |
187
+| 1 | 5 | 0x00000037 | FL, FR, BL, BR, FC | {0, 4, 1, 2, 3} |
188
+| 1 | 6 | 0x0000003f | FL, FR, BL, BR, FC, LFE | {0, 4, 1, 2, 3, 5} |
189
+| 1 | 7 | 0x00000d0f | FL, FR, SL, SR, FC, BC, LFE | {0, 4, 1, 2, 3, 5, 6} |
190
+| 1 | 8 | 0x00000c3f | FL, FR, SL, SR, BL, BR, FC, LFE | {0, 6, 1, 2, 3, 4, 5, 7} |
191
+
192
+The Mapping Table in the table indicates the mapping table selected by
193
+`opus_multistream_surround_encoder_create` (Opus 1.3.1). If the
194
+encoder outputs a different mapping table in a future Opus encoder
195
+release, the channel ordering will be incorrect, and the surround
196
+encoder can not be used. We expect that the probability of the Opus
197
+encoder authors making such changes is negligible.
198
+
199
+## Limits Configuration
200
+
201
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c
Changed
175
1
2
#include <spa/utils/dict.h>
3
4
#include <fdk-aac/aacenc_lib.h>
5
+#include <fdk-aac/aacdecoder_lib.h>
6
7
#include "rtp.h"
8
#include "a2dp-codecs.h"
9
10
+static struct spa_log *log;
11
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.aac");
12
+#undef SPA_LOG_TOPIC_DEFAULT
13
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
14
+
15
#define DEFAULT_AAC_BITRATE 320000
16
#define MIN_AAC_BITRATE 64000
17
18
19
20
struct impl {
21
HANDLE_AACENCODER aacenc;
22
+ HANDLE_AACDECODER aacdec;
23
24
struct rtp_header *header;
25
26
27
return sizeof(conf);
28
}
29
30
-static int codec_enum_config(const struct a2dp_codec *codec,
31
+static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
32
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
33
struct spa_pod_builder *b, struct spa_pod **param)
34
{
35
36
return 0;
37
}
38
39
-static void *codec_init_props(const struct a2dp_codec *codec, const struct spa_dict *settings)
40
+static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings)
41
{
42
struct props *p = calloc(1, sizeof(struct props));
43
const char *str;
44
45
46
this->codesize = enc_info.frameLength * this->channels * this->samplesize;
47
48
+ this->aacdec = aacDecoder_Open(TT_MP4_LATM_MCP1, 1);
49
+ if (!this->aacdec) {
50
+ res = -EINVAL;
51
+ goto error;
52
+ }
53
+
54
+#ifdef AACDECODER_LIB_VL0
55
+ res = aacDecoder_SetParam(this->aacdec, AAC_PCM_MIN_OUTPUT_CHANNELS, this->channels);
56
+ if (res != AAC_DEC_OK) {
57
+ spa_log_debug(log, "Couldn't set min output channels: 0x%04X", res);
58
+ goto error;
59
+ }
60
+
61
+ res = aacDecoder_SetParam(this->aacdec, AAC_PCM_MAX_OUTPUT_CHANNELS, this->channels);
62
+ if (res != AAC_DEC_OK) {
63
+ spa_log_debug(log, "Couldn't set max output channels: 0x%04X", res);
64
+ goto error;
65
+ }
66
+#else
67
+ res = aacDecoder_SetParam(this->aacdec, AAC_PCM_OUTPUT_CHANNELS, this->channels);
68
+ if (res != AAC_DEC_OK) {
69
+ spa_log_debug(log, "Couldn't set output channels: 0x%04X", res);
70
+ goto error;
71
+ }
72
+#endif
73
+
74
return this;
75
76
error:
77
if (this && this->aacenc)
78
aacEncClose(&this->aacenc);
79
+ if (this && this->aacdec)
80
+ aacDecoder_Close(this->aacdec);
81
free(this);
82
errno = -res;
83
return NULL;
84
85
struct impl *this = data;
86
if (this->aacenc)
87
aacEncClose(&this->aacenc);
88
+ if (this->aacdec)
89
+ aacDecoder_Close(this->aacdec);
90
free(this);
91
}
92
93
94
return out_args.numInSamples * this->samplesize;
95
}
96
97
+static int codec_start_decode (void *data,
98
+ const void *src, size_t src_size, uint16_t *seqnum, uint32_t *timestamp)
99
+{
100
+ const struct rtp_header *header = src;
101
+ size_t header_size = sizeof(struct rtp_header);
102
+
103
+ spa_return_val_if_fail (src_size > header_size, -EINVAL);
104
+
105
+ if (seqnum)
106
+ *seqnum = ntohs(header->sequence_number);
107
+ if (timestamp)
108
+ *timestamp = ntohl(header->timestamp);
109
+
110
+ return header_size;
111
+}
112
+
113
+static int codec_decode(void *data,
114
+ const void *src, size_t src_size,
115
+ void *dst, size_t dst_size,
116
+ size_t *dst_out)
117
+{
118
+ struct impl *this = data;
119
+ uint data_size = (uint)src_size;
120
+ uint bytes_valid = data_size;
121
+ CStreamInfo *aacinf;
122
+ int res;
123
+
124
+ res = aacDecoder_Fill(this->aacdec, (UCHAR **)&src, &data_size, &bytes_valid);
125
+ if (res != AAC_DEC_OK) {
126
+ spa_log_debug(log, "AAC buffer fill error: 0x%04X", res);
127
+ return -EINVAL;
128
+ }
129
+
130
+ res = aacDecoder_DecodeFrame(this->aacdec, dst, dst_size, 0);
131
+ if (res != AAC_DEC_OK) {
132
+ spa_log_debug(log, "AAC decode frame error: 0x%04X", res);
133
+ return -EINVAL;
134
+ }
135
+
136
+ aacinf = aacDecoder_GetStreamInfo(this->aacdec);
137
+ if (!aacinf) {
138
+ spa_log_debug(log, "AAC get stream info failed");
139
+ return -EINVAL;
140
+ }
141
+ *dst_out = aacinf->frameSize * aacinf->numChannels * this->samplesize;
142
+
143
+ return src_size - bytes_valid;
144
+}
145
+
146
static int codec_abr_process (void *data, size_t unsent)
147
{
148
return -ENOTSUP;
149
150
return codec_change_bitrate(this, (this->cur_bitrate * 4) / 3);
151
}
152
153
+static void codec_set_log(struct spa_log *global_log)
154
+{
155
+ log = global_log;
156
+ spa_log_topic_init(log, &log_topic);
157
+}
158
+
159
const struct a2dp_codec a2dp_codec_aac = {
160
.id = SPA_BLUETOOTH_AUDIO_CODEC_AAC,
161
.codec_id = A2DP_CODEC_MPEG24,
162
163
.get_block_size = codec_get_block_size,
164
.start_encode = codec_start_encode,
165
.encode = codec_encode,
166
+ .start_decode = codec_start_decode,
167
+ .decode = codec_decode,
168
.abr_process = codec_abr_process,
169
.reduce_bitpool = codec_reduce_bitpool,
170
.increase_bitpool = codec_increase_bitpool,
171
+ .set_log = codec_set_log,
172
};
173
174
A2DP_CODEC_EXPORT_DEF(
175
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-aptx.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-aptx.c
Changed
47
1
2
return actual_conf_size;
3
}
4
5
-static int codec_enum_config(const struct a2dp_codec *codec,
6
+static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
7
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
8
struct spa_pod_builder *b, struct spa_pod **param)
9
{
10
11
* When connected as SRC to SNK, aptX-LL sink may send back mSBC data.
12
*/
13
14
-static int msbc_enum_config(const struct a2dp_codec *codec,
15
+static int msbc_enum_config(const struct a2dp_codec *codec, uint32_t flags,
16
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
17
struct spa_pod_builder *b, struct spa_pod **param)
18
{
19
20
.increase_bitpool = msbc_increase_bitpool,
21
};
22
23
+static const struct spa_dict_item duplex_info_items = {
24
+ { "duplex.boost", "true" },
25
+};
26
+static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items);
27
+
28
const struct a2dp_codec a2dp_codec_aptx_ll_duplex_0 = {
29
APTX_LL_COMMON_DEFS,
30
.id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX,
31
32
.name = "aptx_ll_duplex",
33
.endpoint_name = "aptx_ll_duplex_0",
34
.duplex_codec = &aptx_ll_msbc,
35
+ .info = &duplex_info,
36
};
37
38
const struct a2dp_codec a2dp_codec_aptx_ll_duplex_1 = {
39
40
.name = "aptx_ll_duplex",
41
.endpoint_name = "aptx_ll_duplex_1",
42
.duplex_codec = &aptx_ll_msbc,
43
+ .info = &duplex_info,
44
};
45
46
A2DP_CODEC_EXPORT_DEF(
47
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-caps.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-caps.h
Changed
79
1
2
#define LC3PLUS_HR_SAMPLING_FREQ_48000 (1 << 8)
3
#define LC3PLUS_HR_SAMPLING_FREQ_96000 (1 << 7)
4
5
+#define OPUS_05_VENDOR_ID 0x000005f1
6
+#define OPUS_05_CODEC_ID 0x1005
7
+
8
+#define OPUS_05_MAPPING_FAMILY_0 (1 << 0)
9
+#define OPUS_05_MAPPING_FAMILY_1 (1 << 1)
10
+#define OPUS_05_MAPPING_FAMILY_255 (1 << 2)
11
+
12
+#define OPUS_05_FRAME_DURATION_25 (1 << 0)
13
+#define OPUS_05_FRAME_DURATION_50 (1 << 1)
14
+#define OPUS_05_FRAME_DURATION_100 (1 << 2)
15
+#define OPUS_05_FRAME_DURATION_200 (1 << 3)
16
+#define OPUS_05_FRAME_DURATION_400 (1 << 4)
17
+
18
+#define OPUS_05_GET_UINT16(a, field) \
19
+ (((a).field ## 2 << 8) | (a).field ## 1)
20
+#define OPUS_05_INIT_UINT16(field, v) \
21
+ .field ## 1 = ((v) & 0xff), \
22
+ .field ## 2 = (((v) >> 8) & 0xff),
23
+#define OPUS_05_SET_UINT16(a, field, v) \
24
+ do { \
25
+ (a).field ## 1 = ((v) & 0xff); \
26
+ (a).field ## 2 = (((v) >> 8) & 0xff); \
27
+ } while (0)
28
+#define OPUS_05_GET_UINT32(a, field) \
29
+ (((a).field ## 4 << 24) | ((a).field ## 3 << 16) | \
30
+ ((a).field ## 2 << 8) | (a).field ## 1)
31
+#define OPUS_05_INIT_UINT32(field, v) \
32
+ .field ## 1 = ((v) & 0xff), \
33
+ .field ## 2 = (((v) >> 8) & 0xff), \
34
+ .field ## 3 = (((v) >> 16) & 0xff), \
35
+ .field ## 4 = (((v) >> 24) & 0xff),
36
+#define OPUS_05_SET_UINT32(a, field, v) \
37
+ do { \
38
+ (a).field ## 1 = ((v) & 0xff); \
39
+ (a).field ## 2 = (((v) >> 8) & 0xff); \
40
+ (a).field ## 3 = (((v) >> 16) & 0xff); \
41
+ (a).field ## 4 = (((v) >> 24) & 0xff); \
42
+ } while (0)
43
+
44
+#define OPUS_05_GET_LOCATION(a) OPUS_05_GET_UINT32(a, location)
45
+#define OPUS_05_INIT_LOCATION(v) OPUS_05_INIT_UINT32(location, v)
46
+#define OPUS_05_SET_LOCATION(a, v) OPUS_05_SET_UINT32(a, location, v)
47
+
48
+#define OPUS_05_GET_BITRATE(a) OPUS_05_GET_UINT16(a, bitrate)
49
+#define OPUS_05_INIT_BITRATE(v) OPUS_05_INIT_UINT16(bitrate, v)
50
+#define OPUS_05_SET_BITRATE(a, v) OPUS_05_SET_UINT16(a, bitrate, v)
51
+
52
+
53
typedef struct {
54
uint32_t vendor_id;
55
uint16_t codec_id;
56
57
uint8_t frequency2;
58
} __attribute__ ((packed)) a2dp_lc3plus_hr_t;
59
60
+typedef struct {
61
+ uint8_t channels;
62
+ uint8_t coupled_streams;
63
+ uint8_t location1;
64
+ uint8_t location2;
65
+ uint8_t location3;
66
+ uint8_t location4;
67
+ uint8_t frame_duration;
68
+ uint8_t bitrate1;
69
+ uint8_t bitrate2;
70
+} __attribute__ ((packed)) a2dp_opus_05_direction_t;
71
+
72
+typedef struct {
73
+ a2dp_vendor_codec_t info;
74
+ a2dp_opus_05_direction_t main;
75
+ a2dp_opus_05_direction_t bidi;
76
+} __attribute__ ((packed)) a2dp_opus_05_t;
77
+
78
#endif
79
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-faststream.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-faststream.c
Changed
44
1
2
return sizeof(conf);
3
}
4
5
-static int codec_enum_config(const struct a2dp_codec *codec,
6
+static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
7
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
8
struct spa_pod_builder *b, struct spa_pod **param)
9
{
10
11
* When connected as SRC to SNK, FastStream sink may send back SBC data.
12
*/
13
14
-static int duplex_enum_config(const struct a2dp_codec *codec,
15
+static int duplex_enum_config(const struct a2dp_codec *codec, uint32_t flags,
16
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
17
struct spa_pod_builder *b, struct spa_pod **param)
18
{
19
20
.reduce_bitpool = codec_reduce_bitpool, \
21
.increase_bitpool = codec_increase_bitpool
22
23
-const struct a2dp_codec a2dp_codec_faststream = {
24
+static const struct a2dp_codec a2dp_codec_faststream = {
25
FASTSTREAM_COMMON_DEFS,
26
.id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM,
27
.name = "faststream",
28
};
29
30
+static const struct spa_dict_item duplex_info_items = {
31
+ { "duplex.boost", "true" },
32
+};
33
+static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items);
34
+
35
const struct a2dp_codec a2dp_codec_faststream_duplex = {
36
FASTSTREAM_COMMON_DEFS,
37
.id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX,
38
.name = "faststream_duplex",
39
.duplex_codec = &duplex_codec,
40
+ .info = &duplex_info,
41
};
42
43
A2DP_CODEC_EXPORT_DEF(
44
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c
Changed
30
1
2
return sizeof(conf);
3
}
4
5
-static int codec_caps_preference_cmp(const struct a2dp_codec *codec, const void *caps1, size_t caps1_size,
6
- const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info)
7
+static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
8
+ const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings)
9
{
10
a2dp_lc3plus_hr_t conf1, conf2;
11
a2dp_lc3plus_hr_t *conf;
12
13
14
/* Order selected configurations by preference */
15
res1 = codec->select_config(codec, 0, caps1, caps1_size, info, NULL, (uint8_t *)&conf1);
16
- res2 = codec->select_config(codec, 0, caps2, caps2_size, info , NULL, (uint8_t *)&conf2);
17
+ res2 = codec->select_config(codec, 0, caps2, caps2_size, info, NULL, (uint8_t *)&conf2);
18
19
#define PREFER_EXPR(expr) \
20
do { \
21
22
#undef PREFER_BOOL
23
}
24
25
-static int codec_enum_config(const struct a2dp_codec *codec,
26
+static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
27
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
28
struct spa_pod_builder *b, struct spa_pod **param)
29
{
30
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c
Changed
32
1
2
return sizeof(conf);
3
}
4
5
-static int codec_enum_config(const struct a2dp_codec *codec,
6
+static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
7
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
8
struct spa_pod_builder *b, struct spa_pod **param)
9
{
10
11
return LDACBT_EQMID_AUTO;
12
}
13
14
-static void *codec_init_props(const struct a2dp_codec *codec, const struct spa_dict *settings)
15
+static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings)
16
{
17
struct props *p = calloc(1, sizeof(struct props));
18
const char *str;
19
20
error_errno:
21
res = -errno;
22
error:
23
- if (this->ldac)
24
+ if (this && this->ldac)
25
ldacBT_free_handle(this->ldac);
26
#ifdef ENABLE_LDAC_ABR
27
- if (this->ldac_abr)
28
+ if (this && this->ldac_abr)
29
ldac_ABR_free_handle(this->ldac_abr);
30
#endif
31
free(this);
32
pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c
Added
201
1
2
+/* Spa A2DP Opus Codec
3
+ *
4
+ * Copyright © 2020 Wim Taymans
5
+ * Copyright © 2022 Pauli Virtanen
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a
8
+ * copy of this software and associated documentation files (the "Software"),
9
+ * to deal in the Software without restriction, including without limitation
10
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ * and/or sell copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice (including the next
15
+ * paragraph) shall be included in all copies or substantial portions of the
16
+ * Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ * DEALINGS IN THE SOFTWARE.
25
+ */
26
+
27
+#include <unistd.h>
28
+#include <string.h>
29
+#include <stddef.h>
30
+#include <errno.h>
31
+#include <arpa/inet.h>
32
+#if __BYTE_ORDER != __LITTLE_ENDIAN
33
+#include <byteswap.h>
34
+#endif
35
+
36
+#include <spa/debug/types.h>
37
+#include <spa/param/audio/type-info.h>
38
+#include <spa/param/audio/raw.h>
39
+#include <spa/utils/string.h>
40
+#include <spa/utils/dict.h>
41
+#include <spa/param/audio/format.h>
42
+#include <spa/param/audio/format-utils.h>
43
+
44
+#include <opus.h>
45
+#include <opus_multistream.h>
46
+
47
+#include "rtp.h"
48
+#include "a2dp-codecs.h"
49
+
50
+static struct spa_log *log;
51
+static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.opus");
52
+#undef SPA_LOG_TOPIC_DEFAULT
53
+#define SPA_LOG_TOPIC_DEFAULT &log_topic
54
+
55
+#define BUFSIZE_FROM_BITRATE(frame_dms,bitrate) ((bitrate)/8 * (frame_dms) / 10000 * 5/4) /* estimate */
56
+
57
+/*
58
+ * Opus CVBR target bitrate. When connecting, it is set to the INITIAL
59
+ * value, and after that adjusted according to link quality between the MIN and
60
+ * MAX values. The bitrate adjusts up to either MAX or the value at
61
+ * which the socket buffer starts filling up, whichever is lower.
62
+ *
63
+ * With perfect connection quality, the target bitrate converges to the MAX
64
+ * value. Under realistic conditions, the upper limit may often be as low as
65
+ * 300-500kbit/s, so the INITIAL values are not higher than this.
66
+ *
67
+ * The MAX is here set to 2-2.5x and INITIAL to 1.5x the upper Opus recommended
68
+ * values 1, to be safer quality-wise for CVBR, and MIN to the lower
69
+ * recommended value.
70
+ *
71
+ * 1 https://wiki.xiph.org/Opus_Recommended_Settings
72
+ */
73
+#define BITRATE_INITIAL 192000
74
+#define BITRATE_MAX 320000
75
+#define BITRATE_MIN 96000
76
+
77
+#define BITRATE_INITIAL_51 384000
78
+#define BITRATE_MAX_51 600000
79
+#define BITRATE_MIN_51 128000
80
+
81
+#define BITRATE_INITIAL_71 450000
82
+#define BITRATE_MAX_71 900000
83
+#define BITRATE_MIN_71 256000
84
+
85
+#define BITRATE_DUPLEX_BIDI 160000
86
+
87
+#define OPUS_05_MAX_BYTES (15 * 1024)
88
+
89
+struct props {
90
+ uint32_t channels;
91
+ uint32_t coupled_streams;
92
+ uint32_t location;
93
+ uint32_t max_bitrate;
94
+ uint8_t frame_duration;
95
+ int application;
96
+
97
+ uint32_t bidi_channels;
98
+ uint32_t bidi_coupled_streams;
99
+ uint32_t bidi_location;
100
+ uint32_t bidi_max_bitrate;
101
+ uint32_t bidi_frame_duration;
102
+ int bidi_application;
103
+};
104
+
105
+struct dec_data {
106
+ int fragment_size;
107
+ int fragment_count;
108
+ uint8_t fragmentOPUS_05_MAX_BYTES;
109
+};
110
+
111
+struct abr {
112
+ uint64_t now;
113
+ uint64_t last_update;
114
+
115
+ uint32_t buffer_level;
116
+ uint32_t packet_size;
117
+ uint32_t total_size;
118
+ bool bad;
119
+
120
+ uint64_t last_change;
121
+ uint64_t retry_interval;
122
+
123
+ bool prev_bad;
124
+};
125
+
126
+struct enc_data {
127
+ struct rtp_header *header;
128
+ struct rtp_payload *payload;
129
+
130
+ struct abr abr;
131
+
132
+ int samples;
133
+ int codesize;
134
+
135
+ int packet_size;
136
+ int fragment_size;
137
+ int fragment_count;
138
+ void *fragment;
139
+
140
+ int bitrate_min;
141
+ int bitrate_max;
142
+
143
+ int bitrate;
144
+ int next_bitrate;
145
+
146
+ int frame_dms;
147
+ int application;
148
+};
149
+
150
+struct impl {
151
+ OpusMSEncoder *enc;
152
+ OpusMSDecoder *dec;
153
+
154
+ int mtu;
155
+ int samplerate;
156
+ int application;
157
+
158
+ uint8_t channels;
159
+ uint8_t streams;
160
+ uint8_t coupled_streams;
161
+
162
+ bool is_bidi;
163
+
164
+ struct dec_data d;
165
+ struct enc_data e;
166
+};
167
+
168
+struct audio_location {
169
+ uint32_t mask;
170
+ enum spa_audio_channel position;
171
+};
172
+
173
+struct surround_encoder_mapping {
174
+ uint8_t channels;
175
+ uint8_t coupled_streams;
176
+ uint32_t location;
177
+ uint8_t mapping8; /**< permutation streams -> vorbis order */
178
+ uint8_t inv_mapping8; /**< permutation vorbis order -> streams */
179
+};
180
+
181
+/* Bluetooth SIG, Assigned Numbers, Generic Audio, Audio Location Definitions */
182
+#define BT_AUDIO_LOCATION_FL 0x00000001 /* Front Left */
183
+#define BT_AUDIO_LOCATION_FR 0x00000002 /* Front Right */
184
+#define BT_AUDIO_LOCATION_FC 0x00000004 /* Front Center */
185
+#define BT_AUDIO_LOCATION_LFE 0x00000008 /* Low Frequency Effects 1 */
186
+#define BT_AUDIO_LOCATION_RL 0x00000010 /* Back Left */
187
+#define BT_AUDIO_LOCATION_RR 0x00000020 /* Back Right */
188
+#define BT_AUDIO_LOCATION_FLC 0x00000040 /* Front Left of Center */
189
+#define BT_AUDIO_LOCATION_FRC 0x00000080 /* Front Right of Center */
190
+#define BT_AUDIO_LOCATION_RC 0x00000100 /* Back Center */
191
+#define BT_AUDIO_LOCATION_LFE2 0x00000200 /* Low Frequency Effects 2 */
192
+#define BT_AUDIO_LOCATION_SL 0x00000400 /* Side Left */
193
+#define BT_AUDIO_LOCATION_SR 0x00000800 /* Side Right */
194
+#define BT_AUDIO_LOCATION_TFL 0x00001000 /* Top Front Left */
195
+#define BT_AUDIO_LOCATION_TFR 0x00002000 /* Top Front Right */
196
+#define BT_AUDIO_LOCATION_TFC 0x00004000 /* Top Front Center */
197
+#define BT_AUDIO_LOCATION_TC 0x00008000 /* Top Center */
198
+#define BT_AUDIO_LOCATION_TRL 0x00010000 /* Top Back Left */
199
+#define BT_AUDIO_LOCATION_TRR 0x00020000 /* Top Back Right */
200
+#define BT_AUDIO_LOCATION_TSL 0x00040000 /* Top Side Left */
201
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-sbc.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-sbc.c
Changed
21
1
2
return sizeof(conf);
3
}
4
5
-static int codec_caps_preference_cmp(const struct a2dp_codec *codec, const void *caps1, size_t caps1_size,
6
- const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info)
7
+static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
8
+ const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings)
9
{
10
a2dp_sbc_t conf1, conf2;
11
a2dp_sbc_t *conf;
12
13
return this->sbc.bitpool;
14
}
15
16
-static int codec_enum_config(const struct a2dp_codec *codec,
17
+static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags,
18
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
19
struct spa_pod_builder *b, struct spa_pod **param)
20
{
21
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codecs.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codecs.c
Changed
20
1
2
3
bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id,
4
const void *caps, size_t caps_size,
5
- const struct a2dp_codec_audio_info *info)
6
+ const struct a2dp_codec_audio_info *info,
7
+ const struct spa_dict *global_settings)
8
{
9
uint8_t configA2DP_MAX_CAPS_SIZE;
10
int res;
11
12
if (caps == NULL)
13
return false;
14
15
- res = codec->select_config(codec, 0, caps, caps_size, info, NULL, config);
16
+ res = codec->select_config(codec, 0, caps, caps_size, info, global_settings, config);
17
if (res < 0)
18
return false;
19
20
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codecs.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codecs.h
Changed
70
1
2
#include <spa/support/plugin.h>
3
#include <spa/pod/pod.h>
4
#include <spa/pod/builder.h>
5
+#include <spa/support/log.h>
6
7
#include "a2dp-codec-caps.h"
8
9
10
11
#define SPA_TYPE_INTERFACE_Bluez5CodecA2DP SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:A2DP:Private"
12
13
-#define SPA_VERSION_BLUEZ5_CODEC_A2DP 1
14
+#define SPA_VERSION_BLUEZ5_CODEC_A2DP 5
15
16
struct spa_bluez5_codec_a2dp {
17
struct spa_interface iface;
18
19
extern const char *codec_plugin_factory_name;
20
#endif
21
22
+#define A2DP_CODEC_FLAG_SINK (1 << 0)
23
24
#define A2DP_CODEC_DEFAULT_RATE 48000
25
#define A2DP_CODEC_DEFAULT_CHANNELS 2
26
27
int (*select_config) (const struct a2dp_codec *codec, uint32_t flags,
28
const void *caps, size_t caps_size,
29
const struct a2dp_codec_audio_info *info,
30
- const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE);
31
- int (*enum_config) (const struct a2dp_codec *codec,
32
+ const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE);
33
+ int (*enum_config) (const struct a2dp_codec *codec, uint32_t flags,
34
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
35
struct spa_pod_builder *builder, struct spa_pod **param);
36
int (*validate_config) (const struct a2dp_codec *codec, uint32_t flags,
37
38
* The caps handed in correspond to this codec_id, but are
39
* otherwise not checked beforehand.
40
*/
41
- int (*caps_preference_cmp) (const struct a2dp_codec *codec, const void *caps1, size_t caps1_size,
42
- const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info);
43
+ int (*caps_preference_cmp) (const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size,
44
+ const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info,
45
+ const struct spa_dict *global_settings);
46
47
- void *(*init_props) (const struct a2dp_codec *codec, const struct spa_dict *settings);
48
+ void *(*init_props) (const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings);
49
void (*clear_props) (void *);
50
int (*enum_props) (void *props, const struct spa_dict *settings, uint32_t id, uint32_t idx,
51
struct spa_pod_builder *builder, struct spa_pod **param);
52
53
54
int (*reduce_bitpool) (void *data);
55
int (*increase_bitpool) (void *data);
56
+
57
+ void (*set_log) (struct spa_log *global_log);
58
};
59
60
struct a2dp_codec_config {
61
62
uint32_t cap, int preferred_value);
63
64
bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id,
65
- const void *caps, size_t caps_size, const struct a2dp_codec_audio_info *info);
66
+ const void *caps, size_t caps_size, const struct a2dp_codec_audio_info *info,
67
+ const struct spa_dict *global_settings);
68
69
#endif
70
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-sink.c
Changed
70
1
2
unsigned int started:1;
3
unsigned int following:1;
4
5
+ unsigned int is_duplex:1;
6
+
7
struct spa_source source;
8
int timerfd;
9
struct spa_source flush_source;
10
11
for (i = 0; i < size; i++)
12
spa_log_debug(this->log, " %d: %02x", i, confi);
13
14
- this->codec_data = this->codec->init(this->codec, 0,
15
+ this->codec_data = this->codec->init(this->codec,
16
+ this->is_duplex ? A2DP_CODEC_FLAG_SINK : 0,
17
this->transport->configuration,
18
this->transport->configuration_len,
19
&port->current_format,
20
21
return -EIO;
22
23
if ((res = this->codec->enum_config(this->codec,
24
+ this->is_duplex ? A2DP_CODEC_FLAG_SINK : 0,
25
this->transport->configuration,
26
this->transport->configuration_len,
27
id, result.index, &b, ¶m)) != 1)
28
29
spa_return_val_if_fail(this != NULL, -EINVAL);
30
31
port = &this->port;
32
- io = port->io;
33
- spa_return_val_if_fail(io != NULL, -EIO);
34
+ if ((io = port->io) == NULL)
35
+ return -EIO;
36
37
if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) {
38
io->status = SPA_STATUS_NEED_DATA;
39
40
41
spa_list_init(&port->ready);
42
43
+ if (info && (str = spa_dict_lookup(info, "api.bluez5.a2dp-duplex")) != NULL)
44
+ this->is_duplex = spa_atob(str);
45
+
46
if (info && (str = spa_dict_lookup(info, SPA_KEY_API_BLUEZ5_TRANSPORT)))
47
sscanf(str, "pointer:%p", &this->transport);
48
49
50
spa_log_error(this->log, "a transport codec is needed");
51
return -EINVAL;
52
}
53
+
54
this->codec = this->transport->a2dp_codec;
55
+
56
+ if (this->is_duplex) {
57
+ if (!this->codec->duplex_codec) {
58
+ spa_log_error(this->log, "transport codec doesn't support duplex");
59
+ return -EINVAL;
60
+ }
61
+ this->codec = this->codec->duplex_codec;
62
+ }
63
+
64
if (this->codec->init_props != NULL)
65
this->codec_props = this->codec->init_props(this->codec,
66
+ this->is_duplex ? A2DP_CODEC_FLAG_SINK : 0,
67
this->transport->device->settings);
68
69
reset_props(this, &this->props);
70
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-source.c
Changed
103
1
2
3
unsigned int is_input:1;
4
unsigned int is_duplex:1;
5
+ unsigned int use_duplex_source:1;
6
7
int fd;
8
struct spa_source source;
9
10
11
this->transport_acquired = true;
12
13
- this->codec_data = this->codec->init(this->codec, 0,
14
+ this->codec_data = this->codec->init(this->codec,
15
+ this->is_duplex ? 0 : A2DP_CODEC_FLAG_SINK,
16
this->transport->configuration,
17
this->transport->configuration_len,
18
&port->current_format,
19
20
21
this->source.data = this;
22
23
- if (!this->is_duplex) {
24
+ if (!this->use_duplex_source) {
25
this->source.fd = this->transport->fd;
26
this->source.func = a2dp_on_ready_read;
27
this->source.mask = SPA_IO_IN;
28
29
* XXX: The reason for this should be found and fixed.
30
* XXX: To work around this, for now we just do the stupid thing and poll
31
* XXX: on a timer, chosen so that it's fast enough for the aptX-LL codec
32
- * XXX: we currently support (which sends mSBC data).
33
+ * XXX: we currently support (which sends mSBC data), and also for Opus
34
+ * XXX: forward stream.
35
*/
36
this->source.fd = this->duplex_timerfd;
37
this->source.func = a2dp_on_duplex_timeout;
38
39
this->source.rmask = 0;
40
spa_loop_add_source(this->data_loop, &this->source);
41
42
- this->duplex_timeout = SPA_NSEC_PER_MSEC * 75/10;
43
+ this->duplex_timeout = SPA_NSEC_PER_MSEC * 25/10;
44
set_duplex_timeout(this, this->duplex_timeout);
45
}
46
47
48
if (this->started)
49
return 0;
50
51
+ spa_return_val_if_fail(this->transport != NULL, -EIO);
52
+
53
this->following = is_following(this);
54
55
spa_log_debug(this->log, "%p: start state:%d following:%d",
56
this, this->transport->state, this->following);
57
58
- spa_return_val_if_fail(this->transport != NULL, -EIO);
59
-
60
if (this->transport->state >= SPA_BT_TRANSPORT_STATE_PENDING ||
61
this->is_duplex)
62
res = transport_start(this);
63
64
return -EIO;
65
66
if ((res = this->codec->enum_config(this->codec,
67
+ this->is_duplex ? 0 : A2DP_CODEC_FLAG_SINK,
68
this->transport->configuration,
69
this->transport->configuration_len,
70
id, result.index, &b, ¶m)) != 1)
71
72
spa_return_val_if_fail(this != NULL, -EINVAL);
73
74
port = &this->port;
75
- io = port->io;
76
- spa_return_val_if_fail(io != NULL, -EIO);
77
+ if ((io = port->io) == NULL)
78
+ return -EIO;
79
80
spa_log_trace(this->log, "%p status:%d", this, io->status);
81
82
83
this->codec = this->codec->duplex_codec;
84
this->is_input = true;
85
}
86
+ this->use_duplex_source = this->is_duplex || (this->codec->duplex_codec != NULL);
87
88
if (this->codec->init_props != NULL)
89
this->codec_props = this->codec->init_props(this->codec,
90
+ this->is_duplex ? 0 : A2DP_CODEC_FLAG_SINK,
91
this->transport->device->settings);
92
93
spa_bt_transport_add_listener(this->transport,
94
95
this->timerfd = spa_system_timerfd_create(this->data_system,
96
CLOCK_MONOTONIC, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
97
98
- if (this->is_duplex) {
99
+ if (this->use_duplex_source) {
100
this->duplex_timerfd = spa_system_timerfd_create(this->data_system,
101
CLOCK_MONOTONIC, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
102
} else {
103
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/bluez-hardware.conf -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/bluez-hardware.conf
Changed
9
1
2
{ name = "Motorola DC800", no-features = sbc-xq }, # #pipewire-1590
3
{ name = "Motorola S305", no-features = sbc-xq }, # #pipewire-1590
4
{ name = "Soundcore Life P2-L", no-features = msbc-alt1, msbc-alt1-rtl },
5
+ { name = "Soundcore Motion B", no-features = hw-volume },
6
{ name = "SoundCore mini", no-features = hw-volume }, # #pipewire-1686
7
{ name = "SoundCore 2", no-features = sbc-xq }, # #pipewire-2291
8
{ name = "Tribit MAXSound Plus", no-features = hw-volume }, # #pipewire-1592
9
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
201
1
2
3
struct spa_bt_quirks *quirks;
4
5
+#define MAX_SETTINGS 128
6
+ struct spa_dict_item global_setting_itemsMAX_SETTINGS;
7
+ struct spa_dict global_settings;
8
+
9
/* A reference audio info for A2DP codec configuration. */
10
struct a2dp_codec_audio_info default_audio_info;
11
};
12
13
return 0;
14
}
15
16
-static const struct a2dp_codec *a2dp_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint)
17
+static const struct a2dp_codec *a2dp_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink)
18
{
19
const char *ep_name;
20
const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs;
21
int i;
22
23
- if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/"))
24
+ if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) {
25
ep_name = endpoint + strlen(A2DP_SINK_ENDPOINT "/");
26
- else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/"))
27
+ *sink = true;
28
+ } else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/")) {
29
ep_name = endpoint + strlen(A2DP_SOURCE_ENDPOINT "/");
30
- else
31
+ *sink = false;
32
+ } else {
33
return NULL;
34
+ }
35
36
for (i = 0; a2dp_codecsi; i++) {
37
const struct a2dp_codec *codec = a2dp_codecsi;
38
39
DBusError err;
40
int i, size, res;
41
const struct a2dp_codec *codec;
42
+ bool sink;
43
44
dbus_error_init(&err);
45
46
47
for (i = 0; i < size; i++)
48
spa_log_debug(monitor->log, " %d: %02x", i, capi);
49
50
- codec = a2dp_endpoint_to_codec(monitor, path);
51
+ codec = a2dp_endpoint_to_codec(monitor, path, &sink);
52
if (codec != NULL)
53
/* FIXME: We can't determine which device the SelectConfiguration()
54
* call is associated with, therefore device settings are not passed.
55
* This causes inconsistency with SelectConfiguration() triggered
56
* by codec switching.
57
*/
58
- res = codec->select_config(codec, 0, cap, size, &monitor->default_audio_info, NULL, config);
59
+ res = codec->select_config(codec, sink ? A2DP_CODEC_FLAG_SINK : 0, cap, size, &monitor->default_audio_info,
60
+ &monitor->global_settings, config);
61
else
62
res = -ENOTSUP;
63
64
65
return device->adapter && device->address;
66
}
67
68
-bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec)
69
+bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink)
70
{
71
struct spa_bt_monitor *monitor = device->monitor;
72
struct spa_bt_remote_endpoint *ep;
73
74
}
75
76
spa_list_for_each(ep, &device->remote_endpoint_list, device_link) {
77
+ const enum spa_bt_profile profile = spa_bt_profile_from_uuid(ep->uuid);
78
+ const enum spa_bt_profile expected = sink ?
79
+ SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
80
+
81
+ if (profile != expected)
82
+ continue;
83
+
84
if (a2dp_codec_check_caps(codec, ep->codec, ep->capabilities, ep->capabilities_len,
85
- &ep->monitor->default_audio_info))
86
+ &ep->monitor->default_audio_info, &monitor->global_settings))
87
return true;
88
}
89
90
return false;
91
}
92
93
-const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count)
94
+const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink)
95
{
96
struct spa_bt_monitor *monitor = device->monitor;
97
const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs;
98
99
100
j = 0;
101
for (i = 0; a2dp_codecsi != NULL; ++i) {
102
- if (spa_bt_device_supports_a2dp_codec(device, a2dp_codecsi)) {
103
+ if (spa_bt_device_supports_a2dp_codec(device, a2dp_codecsi, sink)) {
104
supported_codecsj = a2dp_codecsi;
105
++j;
106
}
107
108
.set_volume = transport_set_volume,
109
};
110
111
-static void append_basic_array_variant_dict_entry(DBusMessageIter *dict, int key_type_int, void* key, const char* variant_type_str, const char* array_type_str, int array_type_int, void* data, int data_size);
112
+static void append_basic_array_variant_dict_entry(DBusMessageIter *dict, const char* key, const char* variant_type_str, const char* array_type_str, int array_type_int, void* data, int data_size);
113
114
static void a2dp_codec_switch_reply(DBusPendingCall *pending, void *userdata);
115
116
117
char *local_endpoint = NULL;
118
int res, config_size;
119
dbus_bool_t dbus_ret;
120
- const char *str;
121
DBusMessage *m;
122
DBusMessageIter iter, d;
123
int i;
124
+ bool sink;
125
126
/* Try setting configuration for current codec on current endpoint in list */
127
128
129
130
if (sw->profile & SPA_BT_PROFILE_A2DP_SINK) {
131
local_endpoint_base = A2DP_SOURCE_ENDPOINT;
132
+ sink = false;
133
} else if (sw->profile & SPA_BT_PROFILE_A2DP_SOURCE) {
134
local_endpoint_base = A2DP_SINK_ENDPOINT;
135
+ sink = true;
136
} else {
137
spa_log_debug(sw->device->monitor->log, "a2dp codec switch %p: bad profile (%d), try next",
138
sw, sw->profile);
139
140
}
141
}
142
143
- res = codec->select_config(codec, 0, ep->capabilities, ep->capabilities_len,
144
+ res = codec->select_config(codec, sink ? A2DP_CODEC_FLAG_SINK : 0, ep->capabilities, ep->capabilities_len,
145
&sw->device->monitor->default_audio_info,
146
- sw->device->settings, config);
147
+ &sw->device->monitor->global_settings, config);
148
if (res < 0) {
149
spa_log_debug(sw->device->monitor->log, "a2dp codec switch %p: incompatible capabilities (%d), try next",
150
sw, res);
151
152
dbus_message_iter_init_append(m, &iter);
153
dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &local_endpoint);
154
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &d);
155
- str = "Capabilities";
156
- append_basic_array_variant_dict_entry(&d, DBUS_TYPE_STRING, &str, "ay", "y", DBUS_TYPE_BYTE, config, config_size);
157
+ append_basic_array_variant_dict_entry(&d, "Capabilities", "ay", "y", DBUS_TYPE_BYTE, config, config_size);
158
dbus_message_iter_close_container(&iter, &d);
159
160
spa_assert(sw->pending == NULL);
161
162
const struct a2dp_codec *codec = *sw->codec_iter;
163
const char *path1 = *(char **)a, *path2 = *(char **)b;
164
struct spa_bt_remote_endpoint *ep1, *ep2;
165
+ uint32_t flags;
166
167
ep1 = device_remote_endpoint_find(sw->device, path1);
168
ep2 = device_remote_endpoint_find(sw->device, path2);
169
170
ep1 = NULL;
171
if (ep2 != NULL && (ep2->uuid == NULL || ep2->codec != codec->codec_id || ep2->capabilities == NULL))
172
ep2 = NULL;
173
+ if (ep1 && ep2 && !spa_streq(ep1->uuid, ep2->uuid)) {
174
+ ep1 = NULL;
175
+ ep2 = NULL;
176
+ }
177
178
if (ep1 == NULL && ep2 == NULL)
179
return 0;
180
181
else if (ep2 == NULL)
182
return -1;
183
184
- return codec->caps_preference_cmp(codec, ep1->capabilities, ep1->capabilities_len,
185
- ep2->capabilities, ep2->capabilities_len, &sw->device->monitor->default_audio_info);
186
+ flags = spa_streq(ep1->uuid, SPA_BT_UUID_A2DP_SOURCE) ? A2DP_CODEC_FLAG_SINK : 0;
187
+
188
+ return codec->caps_preference_cmp(codec, flags, ep1->capabilities, ep1->capabilities_len,
189
+ ep2->capabilities, ep2->capabilities_len, &sw->device->monitor->default_audio_info,
190
+ &sw->device->monitor->global_settings);
191
}
192
193
/* Ensure there's a transport for at least one of the listed codecs */
194
195
}
196
197
for (i = 0; codecsi != NULL; ++i) {
198
- if (spa_bt_device_supports_a2dp_codec(device, codecsi)) {
199
+ if (spa_bt_device_supports_a2dp_codec(device, codecsi, true)) {
200
preferred_codec = codecsi;
201
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
38
1
2
3
static float get_soft_volume_boost(struct node *node)
4
{
5
+ const struct a2dp_codec *codec = node->transport ? node->transport->a2dp_codec : NULL;
6
+
7
/*
8
* For A2DP duplex, the duplex microphone channel sometimes does not appear
9
* to have hardware gain, and input volume is very low.
10
11
* If this causes clipping, the user can just reduce the mic volume to
12
* bring SW gain below 1.
13
*/
14
- if (node->a2dp_duplex && node->transport &&
15
+ if (node->a2dp_duplex && node->transport && codec && codec->info &&
16
+ spa_atob(spa_dict_lookup(codec->info, "duplex.boost")) &&
17
node->id == DEVICE_ID_SOURCE &&
18
!node->transport->volumesSPA_BT_VOLUME_ID_RX.active)
19
return 10.0f; /* 20 dB boost */
20
21
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) {
22
free(this->supported_codecs);
23
this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs(
24
- this->bt_dev, &this->supported_codec_count);
25
+ this->bt_dev, &this->supported_codec_count, true);
26
}
27
28
switch (this->profile) {
29
30
if (this->supported_codecs)
31
free(this->supported_codecs);
32
this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs(
33
- this->bt_dev, &this->supported_codec_count);
34
+ this->bt_dev, &this->supported_codec_count, true);
35
36
/* Prefer A2DP, then HFP, then null, but select AG if the device
37
appears not to have A2DP_SINK or any HEAD_UNIT profile */
38
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/codec-loader.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/codec-loader.c
Changed
33
1
2
SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX,
3
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM,
4
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX,
5
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05,
6
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51,
7
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71,
8
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX,
9
+ SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO,
10
};
11
size_t i;
12
for (i = 0; i < SPA_N_ELEMENTS(order); ++i)
13
14
15
spa_log_debug(impl->log, "loaded A2DP codec %s from %s", c->name, factory_name);
16
17
+ if (c->set_log)
18
+ c->set_log(impl->log);
19
+
20
impl->codecsimpl->n_codecs++ = c;
21
++n_codecs;
22
23
24
A2DP_CODEC_FACTORY_LIB("faststream"),
25
A2DP_CODEC_FACTORY_LIB("ldac"),
26
A2DP_CODEC_FACTORY_LIB("sbc"),
27
- A2DP_CODEC_FACTORY_LIB("lc3plus")
28
+ A2DP_CODEC_FACTORY_LIB("lc3plus"),
29
+ A2DP_CODEC_FACTORY_LIB("opus")
30
#undef A2DP_CODEC_FACTORY_LIB
31
};
32
33
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/decode-buffer.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/decode-buffer.h
Changed
31
1
2
static void spa_bt_decode_buffer_process(struct spa_bt_decode_buffer *this, uint32_t samples, uint32_t duration)
3
{
4
const uint32_t data_size = samples * this->frame_size;
5
- const int32_t max_level = SPA_MAX(8 * this->packet_size.max, (int32_t)duration);
6
+ const int32_t packet_size = SPA_CLAMP(this->packet_size.max, 0, INT32_MAX/8);
7
+ const int32_t max_level = SPA_MAX(8 * packet_size, (int32_t)duration);
8
uint32_t avail;
9
10
if (SPA_UNLIKELY(duration != this->prev_duration)) {
11
12
spa_log_trace(this->log, "%p buffering size:%d", this, (int)size);
13
14
if (this->received &&
15
- this->packet_size.max > 0 &&
16
- size >= SPA_MAX(3*this->packet_size.max, (int32_t)duration))
17
+ packet_size > 0 &&
18
+ size >= SPA_MAX(3*packet_size, (int32_t)duration))
19
this->buffering = false;
20
else
21
return;
22
23
spa_bt_ptp_update(&this->spike, this->ctl.avg - level, this->prev_consumed);
24
25
/* Update target level */
26
- target = BUFFERING_TARGET(this->spike.max, this->packet_size.max);
27
+ target = BUFFERING_TARGET(this->spike.max, packet_size);
28
29
if (level > SPA_MAX(4 * target, 2*(int32_t)duration) &&
30
avail > data_size) {
31
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/defs.h
Changed
33
1
2
3
#define BLUEZ_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported"
4
5
-#define SPA_BT_UUID_A2DP_SOURCE "0000110A-0000-1000-8000-00805F9B34FB"
6
-#define SPA_BT_UUID_A2DP_SINK "0000110B-0000-1000-8000-00805F9B34FB"
7
-#define SPA_BT_UUID_HSP_HS "00001108-0000-1000-8000-00805F9B34FB"
8
-#define SPA_BT_UUID_HSP_HS_ALT "00001131-0000-1000-8000-00805F9B34FB"
9
-#define SPA_BT_UUID_HSP_AG "00001112-0000-1000-8000-00805F9B34FB"
10
-#define SPA_BT_UUID_HFP_HF "0000111E-0000-1000-8000-00805F9B34FB"
11
-#define SPA_BT_UUID_HFP_AG "0000111F-0000-1000-8000-00805F9B34FB"
12
+#define SPA_BT_UUID_A2DP_SOURCE "0000110a-0000-1000-8000-00805f9b34fb"
13
+#define SPA_BT_UUID_A2DP_SINK "0000110b-0000-1000-8000-00805f9b34fb"
14
+#define SPA_BT_UUID_HSP_HS "00001108-0000-1000-8000-00805f9b34fb"
15
+#define SPA_BT_UUID_HSP_HS_ALT "00001131-0000-1000-8000-00805f9b34fb"
16
+#define SPA_BT_UUID_HSP_AG "00001112-0000-1000-8000-00805f9b34fb"
17
+#define SPA_BT_UUID_HFP_HF "0000111e-0000-1000-8000-00805f9b34fb"
18
+#define SPA_BT_UUID_HFP_AG "0000111f-0000-1000-8000-00805f9b34fb"
19
20
#define PROFILE_HSP_AG "/Profile/HSPAG"
21
#define PROFILE_HSP_HS "/Profile/HSPHS"
22
23
int spa_bt_device_connect_profile(struct spa_bt_device *device, enum spa_bt_profile profile);
24
int spa_bt_device_check_profiles(struct spa_bt_device *device, bool force);
25
int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec * const *codecs);
26
-bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec);
27
-const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count);
28
+bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink);
29
+const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink);
30
int spa_bt_device_ensure_hfp_codec(struct spa_bt_device *device, unsigned int codec);
31
int spa_bt_device_supports_hfp_codec(struct spa_bt_device *device, unsigned int codec);
32
int spa_bt_device_release_transports(struct spa_bt_device *device);
33
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/meson.build
Changed
26
1
2
endif
3
4
if get_option('bluez5-codec-lc3plus').allowed() and lc3plus_dep.found()
5
- lc3plus_args = codec_args
6
- lc3plus_dep = lc3plus_dep
7
bluez_codec_lc3plus = shared_library('spa-codec-bluez5-lc3plus',
8
'a2dp-codec-lc3plus.c', 'a2dp-codecs.c' ,
9
include_directories : configinc ,
10
11
install : true,
12
install_dir : spa_plugindir / 'bluez5')
13
endif
14
+
15
+if get_option('bluez5-codec-opus').allowed() and opus_dep.found()
16
+ opus_args = codec_args
17
+ opus_dep = opus_dep
18
+ bluez_codec_opus = shared_library('spa-codec-bluez5-opus',
19
+ 'a2dp-codec-opus.c', 'a2dp-codecs.c' ,
20
+ include_directories : configinc ,
21
+ c_args : opus_args,
22
+ dependencies : spa_dep, opus_dep, mathlib ,
23
+ install : true,
24
+ install_dir : spa_plugindir / 'bluez5')
25
+endif
26
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = &this->port;
5
- io = port->io;
6
- spa_return_val_if_fail(io != NULL, -EIO);
7
+ if ((io = port->io) == NULL)
8
+ return -EIO;
9
10
if (io->status == SPA_STATUS_HAVE_DATA && io->buffer_id < port->n_buffers) {
11
struct buffer *b = &port->buffersio->buffer_id;
12
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/sco-source.c
Changed
28
1
2
return 0;
3
}
4
5
+ if (size_read % port->frame_size != 0) {
6
+ /* Unaligned data: reception or adapter problem.
7
+ * Consider the whole packet lost and report.
8
+ */
9
+ spa_log_debug(this->log,
10
+ "received bad Bluetooth SCO CVSD packet");
11
+ return 0;
12
+ }
13
+
14
packet = spa_bt_decode_buffer_get_write(&port->buffer, &avail);
15
avail = SPA_MIN(avail, (uint32_t)size_read);
16
spa_memmove(packet, read_data, avail);
17
18
spa_return_val_if_fail(this != NULL, -EINVAL);
19
20
port = &this->port;
21
- io = port->io;
22
- spa_return_val_if_fail(io != NULL, -EIO);
23
+ if ((io = port->io) == NULL)
24
+ return -EIO;
25
26
/* Return if we already have a buffer */
27
if (io->status == SPA_STATUS_HAVE_DATA)
28
pipewire-0.3.56.tar.gz/spa/plugins/control/mixer.c -> pipewire-0.3.57.tar.gz/spa/plugins/control/mixer.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
outport = GET_OUT_PORT(this, 0);
5
- outio = outport->io;
6
- spa_return_val_if_fail(outio != NULL, -EIO);
7
+ if ((outio = outport->io) == NULL)
8
+ return -EIO;
9
10
spa_log_trace_fp(this->log, NAME " %p: status %p %d %d",
11
this, outio, outio->status, outio->buffer_id);
12
pipewire-0.3.56.tar.gz/spa/plugins/libcamera/libcamera-device.cpp -> pipewire-0.3.57.tar.gz/spa/plugins/libcamera/libcamera-device.cpp
Changed
76
1
2
std::shared_ptr<Camera> camera;
3
};
4
5
-std::string cameraModel(const Camera *camera)
6
+static std::string cameraModel(const Camera *camera)
7
{
8
const ControlList &props = camera->properties();
9
- std::string name;
10
- if (props.contains(properties::Model))
11
- name = props.get(properties::Model);
12
- else
13
- name = camera->id();
14
- return name;
15
+
16
+ if (auto model = props.get(properties::Model))
17
+ return std::move(model.value());
18
+
19
+ return camera->id();
20
}
21
22
-std::string cameraLoc(const Camera *camera)
23
+static const char *cameraLoc(const Camera *camera)
24
{
25
const ControlList &props = camera->properties();
26
- std::string location;
27
- if (props.contains(properties::Location)) {
28
- switch (props.get(properties::Location)) {
29
+
30
+ if (auto location = props.get(properties::Location)) {
31
+ switch (location.value()) {
32
case properties::CameraLocationFront:
33
- location = "front";
34
- break;
35
+ return "front";
36
case properties::CameraLocationBack:
37
- location = "back";
38
- break;
39
+ return "back";
40
case properties::CameraLocationExternal:
41
- location = "external";
42
- break;
43
+ return "external";
44
}
45
}
46
- return location;
47
+
48
+ return nullptr;
49
}
50
51
static int emit_info(struct impl *impl, bool full)
52
53
uint32_t n_items = 0;
54
struct spa_device_info info;
55
struct spa_param_info params2;
56
- char path256, location10, model256, name256;
57
+ char path256, model256, name256;
58
59
info = SPA_DEVICE_INFO_INIT();
60
61
62
ADD_ITEM(SPA_KEY_OBJECT_PATH, path);
63
ADD_ITEM(SPA_KEY_DEVICE_API, "libcamera");
64
ADD_ITEM(SPA_KEY_MEDIA_CLASS, "Video/Device");
65
- ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, (char *)impl->props.device);
66
- snprintf(location, sizeof(location), "%s", cameraLoc(impl->camera.get()).c_str());
67
- ADD_ITEM(SPA_KEY_API_LIBCAMERA_LOCATION, location);
68
+ ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, impl->props.device);
69
+
70
+ if (auto location = cameraLoc(impl->camera.get()))
71
+ ADD_ITEM(SPA_KEY_API_LIBCAMERA_LOCATION, location);
72
+
73
snprintf(model, sizeof(model), "%s", cameraModel(impl->camera.get()).c_str());
74
ADD_ITEM(SPA_KEY_DEVICE_PRODUCT_NAME, model);
75
ADD_ITEM(SPA_KEY_DEVICE_DESCRIPTION, model);
76
pipewire-0.3.56.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.57.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
12
1
2
spa_return_val_if_fail(impl != NULL, -EINVAL);
3
4
port = GET_OUT_PORT(impl, 0);
5
- io = port->io;
6
- spa_return_val_if_fail(io != NULL, -EIO);
7
+ if ((io = port->io) == NULL)
8
+ return -EIO;
9
10
if (port->control)
11
process_control(impl, &port->control->sequence);
12
pipewire-0.3.56.tar.gz/spa/plugins/meson.build -> pipewire-0.3.57.tar.gz/spa/plugins/meson.build
Changed
17
1
2
if alsa_dep.found()
3
subdir('alsa')
4
endif
5
-if get_option('avb').allowed()
6
+if get_option('avb').require(host_machine.system() == 'linux', error_message: 'AVB support is only available on Linux').allowed()
7
subdir('avb')
8
endif
9
if get_option('audioconvert').allowed()
10
11
subdir('libcamera')
12
endif
13
14
-subdir('aec')
15
\ No newline at end of file
16
+subdir('aec')
17
pipewire-0.3.56.tar.gz/spa/plugins/support/loop.c -> pipewire-0.3.57.tar.gz/spa/plugins/support/loop.c
Changed
9
1
2
3
if (--impl->enter_count == 0) {
4
impl->thread = 0;
5
+ flush_items(impl);
6
impl->polling = false;
7
}
8
}
9
pipewire-0.3.56.tar.gz/spa/plugins/support/null-audio-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/support/null-audio-sink.c
Changed
13
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = &this->port;
5
-
6
- io = port->io;
7
- spa_return_val_if_fail(io != NULL, -EIO);
8
+ if ((io = port->io) == NULL)
9
+ return -EIO;
10
11
if (io->status != SPA_STATUS_HAVE_DATA)
12
return io->status;
13
pipewire-0.3.56.tar.gz/spa/plugins/test/fakesink.c -> pipewire-0.3.57.tar.gz/spa/plugins/test/fakesink.c
Changed
13
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = &this->port;
5
-
6
- io = port->io;
7
- spa_return_val_if_fail(io != NULL, -EIO);
8
+ if ((io = port->io) == NULL)
9
+ return -EIO;
10
11
if (io->status == SPA_STATUS_HAVE_DATA && io->buffer_id < port->n_buffers) {
12
struct buffer *b = &port->buffersio->buffer_id;
13
pipewire-0.3.56.tar.gz/spa/plugins/test/fakesrc.c -> pipewire-0.3.57.tar.gz/spa/plugins/test/fakesrc.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = &this->port;
5
- io = port->io;
6
- spa_return_val_if_fail(io != NULL, -EIO);
7
+ if ((io = port->io) == NULL)
8
+ return -EIO;
9
10
if (io->status == SPA_STATUS_HAVE_DATA)
11
return SPA_STATUS_HAVE_DATA;
12
pipewire-0.3.56.tar.gz/spa/plugins/v4l2/v4l2-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/v4l2/v4l2-source.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = GET_OUT_PORT(this, 0);
5
- io = port->io;
6
- spa_return_val_if_fail(io != NULL, -EIO);
7
+ if ((io = port->io) == NULL)
8
+ return -EIO;
9
10
if (port->control)
11
process_control(this, &port->control->sequence);
12
pipewire-0.3.56.tar.gz/spa/plugins/videotestsrc/videotestsrc.c -> pipewire-0.3.57.tar.gz/spa/plugins/videotestsrc/videotestsrc.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = &this->port;
5
- io = port->io;
6
- spa_return_val_if_fail(io != NULL, -EIO);
7
+ if ((io = port->io) == NULL)
8
+ return -EIO;
9
10
if (io->status == SPA_STATUS_HAVE_DATA)
11
return SPA_STATUS_HAVE_DATA;
12
pipewire-0.3.56.tar.gz/spa/plugins/volume/volume.c -> pipewire-0.3.57.tar.gz/spa/plugins/volume/volume.c
Changed
23
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
out_port = GET_OUT_PORT(this, 0);
5
- output = out_port->io;
6
- spa_return_val_if_fail(output != NULL, -EIO);
7
+ if ((output = out_port->io) == NULL)
8
+ return -EIO;
9
10
if (output->status == SPA_STATUS_HAVE_DATA)
11
return SPA_STATUS_HAVE_DATA;
12
13
}
14
15
in_port = GET_IN_PORT(this, 0);
16
- input = in_port->io;
17
- spa_return_val_if_fail(input != NULL, -EIO);
18
+ if ((input = in_port->io) == NULL)
19
+ return -EIO;
20
21
if (input->status != SPA_STATUS_HAVE_DATA)
22
return SPA_STATUS_NEED_DATA;
23
pipewire-0.3.56.tar.gz/spa/plugins/vulkan/vulkan-compute-filter.c -> pipewire-0.3.57.tar.gz/spa/plugins/vulkan/vulkan-compute-filter.c
Changed
23
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
inport = &this->portSPA_DIRECTION_INPUT;
5
- inio = inport->io;
6
- spa_return_val_if_fail(inio != NULL, -EIO);
7
+ if ((inio = inport->io) == NULL)
8
+ return -EIO;
9
10
if (inio->status != SPA_STATUS_HAVE_DATA)
11
return inio->status;
12
13
}
14
15
outport = &this->portSPA_DIRECTION_OUTPUT;
16
- outio = outport->io;
17
- spa_return_val_if_fail(outio != NULL, -EIO);
18
+ if ((outio = outport->io) == NULL)
19
+ return -EIO;
20
21
if (outio->status == SPA_STATUS_HAVE_DATA)
22
return SPA_STATUS_HAVE_DATA;
23
pipewire-0.3.56.tar.gz/spa/plugins/vulkan/vulkan-compute-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/vulkan/vulkan-compute-source.c
Changed
12
1
2
spa_return_val_if_fail(this != NULL, -EINVAL);
3
4
port = &this->port;
5
- io = port->io;
6
- spa_return_val_if_fail(io != NULL, -EIO);
7
+ if ((io = port->io) == NULL)
8
+ return -EIO;
9
10
if (io->status == SPA_STATUS_HAVE_DATA)
11
return SPA_STATUS_HAVE_DATA;
12
pipewire-0.3.57.tar.gz/src/daemon/systemd/user/filter-chain.service.in
Added
23
1
2
+Unit
3
+Description=PipeWire filter chain daemon
4
+
5
+After=pipewire.service pipewire-session-manager.service
6
+BindsTo=pipewire.service
7
+
8
+Service
9
+LockPersonality=yes
10
+MemoryDenyWriteExecute=yes
11
+NoNewPrivileges=yes
12
+RestrictNamespaces=yes
13
+SystemCallArchitectures=native
14
+SystemCallFilter=@system-service
15
+Type=simple
16
+ExecStart=@PW_BINARY@ -c filter-chain.conf
17
+Restart=on-failure
18
+Slice=session.slice
19
+
20
+Install
21
+Also=pipewire.socket
22
+WantedBy=default.target
23
pipewire-0.3.56.tar.gz/src/daemon/systemd/user/meson.build -> pipewire-0.3.57.tar.gz/src/daemon/systemd/user/meson.build
Changed
10
1
2
output : 'pipewire-pulse.service',
3
configuration : systemd_config,
4
install_dir : systemd_user_services_dir)
5
+
6
+configure_file(input : 'filter-chain.service.in',
7
+ output : 'filter-chain.service',
8
+ configuration : systemd_config,
9
+ install_dir : systemd_user_services_dir)
10
pipewire-0.3.56.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.57.tar.gz/src/gst/gstpipewiresrc.c
Changed
43
1
2
meta->height = crop->region.size.height;
3
}
4
}
5
- gst_buffer_add_parent_buffer_meta (buf, data->buf);
6
- gst_buffer_unref (data->buf);
7
for (i = 0; i < b->buffer->n_datas; i++) {
8
struct spa_data *d = &b->buffer->datasi;
9
GstMemory *pmem = gst_buffer_peek_memory (data->buf, i);
10
if (pmem) {
11
- GstMemory *mem = gst_memory_share (pmem, d->chunk->offset, d->chunk->size);
12
+ GstMemory *mem;
13
+ if (!pwsrc->always_copy)
14
+ mem = gst_memory_share (pmem, d->chunk->offset, d->chunk->size);
15
+ else
16
+ mem = gst_memory_copy (pmem, d->chunk->offset, d->chunk->size);
17
gst_buffer_insert_memory (buf, i, mem);
18
- spa_assert_se(mem->size <= mem->maxsize);
19
}
20
if (d->chunk->flags & SPA_CHUNK_FLAG_CORRUPTED)
21
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_CORRUPTED);
22
}
23
+ if (!pwsrc->always_copy)
24
+ gst_buffer_add_parent_buffer_meta (buf, data->buf);
25
+ gst_buffer_unref (data->buf);
26
return buf;
27
}
28
29
30
}
31
pw_thread_loop_unlock (pwsrc->core->loop);
32
33
- if (pwsrc->always_copy) {
34
- *buffer = gst_buffer_copy_deep (buf);
35
- gst_buffer_unref (buf);
36
- }
37
- else
38
- *buffer = buf;
39
+ *buffer = buf;
40
41
if (pwsrc->is_live)
42
base_time = GST_ELEMENT_CAST (psrc)->base_time;
43
pipewire-0.3.57.tar.gz/src/modules/flatpak-utils.h
Added
158
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2018 Wim Taymans
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#ifndef FLATPAK_UTILS_H
27
+#define FLATPAK_UTILS_H
28
+
29
+#include <stdio.h>
30
+#include <string.h>
31
+#include <fcntl.h>
32
+#include <sys/mman.h>
33
+#include <sys/stat.h>
34
+#ifdef HAVE_SYS_VFS_H
35
+#include <sys/vfs.h>
36
+#endif
37
+
38
+#include "config.h"
39
+
40
+#ifdef HAVE_GLIB2
41
+#include <glib.h>
42
+#endif
43
+
44
+#include <spa/utils/result.h>
45
+#include <pipewire/log.h>
46
+
47
+static int pw_check_flatpak_parse_metadata(const char *buf, size_t size, char **app_id, char **devices)
48
+{
49
+#ifdef HAVE_GLIB2
50
+ /*
51
+ * See flatpak-metadata(5)
52
+ *
53
+ * The .flatpak-info file is in GLib key_file .ini format.
54
+ */
55
+ g_autoptr(GKeyFile) metadata = NULL;
56
+ char *s;
57
+
58
+ metadata = g_key_file_new();
59
+ if (!g_key_file_load_from_data(metadata, buf, size, G_KEY_FILE_NONE, NULL))
60
+ return -EINVAL;
61
+
62
+ if (app_id) {
63
+ s = g_key_file_get_value(metadata, "Application", "name", NULL);
64
+ *app_id = s ? strdup(s) : NULL;
65
+ g_free(s);
66
+ }
67
+
68
+ if (devices) {
69
+ s = g_key_file_get_value(metadata, "Context", "devices", NULL);
70
+ *devices = s ? strdup(s) : NULL;
71
+ g_free(s);
72
+ }
73
+
74
+ return 0;
75
+#else
76
+ return -ENOTSUP;
77
+#endif
78
+}
79
+
80
+static int pw_check_flatpak(pid_t pid, char **app_id, char **devices)
81
+{
82
+#if defined(__linux__)
83
+ char root_path2048;
84
+ int root_fd, info_fd, res;
85
+ struct stat stat_buf;
86
+
87
+ if (app_id)
88
+ *app_id = NULL;
89
+ if (devices)
90
+ *devices = NULL;
91
+
92
+ snprintf(root_path, sizeof(root_path), "/proc/%d/root", (int)pid);
93
+ root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
94
+ if (root_fd == -1) {
95
+ res = -errno;
96
+ if (res == -EACCES) {
97
+ struct statfs buf;
98
+ /* Access to the root dir isn't allowed. This can happen if the root is on a fuse
99
+ * filesystem, such as in a toolbox container. We will never have a fuse rootfs
100
+ * in the flatpak case, so in that case its safe to ignore this and
101
+ * continue to detect other types of apps. */
102
+ if (statfs(root_path, &buf) == 0 &&
103
+ buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */
104
+ return 0;
105
+ }
106
+ /* Not able to open the root dir shouldn't happen. Probably the app died and
107
+ * we're failing due to /proc/$pid not existing. In that case fail instead
108
+ * of treating this as privileged. */
109
+ pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res));
110
+ return res;
111
+ }
112
+ info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY);
113
+ close (root_fd);
114
+ if (info_fd == -1) {
115
+ if (errno == ENOENT) {
116
+ pw_log_debug("no .flatpak-info, client on the host");
117
+ /* No file => on the host */
118
+ return 0;
119
+ }
120
+ res = -errno;
121
+ pw_log_error("error opening .flatpak-info: %m");
122
+ return res;
123
+ }
124
+ if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) {
125
+ /* Some weird fd => failure, assume sandboxed */
126
+ pw_log_error("error fstat .flatpak-info: %m");
127
+ } else if (app_id || devices) {
128
+ /* Parse the application ID if needed */
129
+ const size_t size = stat_buf.st_size;
130
+
131
+ if (size > 0) {
132
+ void *buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, info_fd, 0);
133
+ if (buf != MAP_FAILED) {
134
+ res = pw_check_flatpak_parse_metadata(buf, size, app_id, devices);
135
+ munmap(buf, size);
136
+ } else {
137
+ res = -errno;
138
+ }
139
+ } else {
140
+ res = -EINVAL;
141
+ }
142
+
143
+ if (res == -EINVAL)
144
+ pw_log_error("PID %d .flatpak-info file is malformed",
145
+ (int)pid);
146
+ else if (res < 0)
147
+ pw_log_error("PID %d .flatpak-info parsing failed: %s",
148
+ (int)pid, spa_strerror(res));
149
+ }
150
+ close(info_fd);
151
+ return 1;
152
+#else
153
+ return 0;
154
+#endif
155
+}
156
+
157
+#endif /* FLATPAK_UTILS_H */
158
pipewire-0.3.56.tar.gz/src/modules/meson.build -> pipewire-0.3.57.tar.gz/src/modules/meson.build
Changed
49
1
2
'module-x11-bell.c',
3
4
5
+pipewire_module_access_deps = spa_dep, mathlib, dl_lib, pipewire_dep
6
+if flatpak_support
7
+ pipewire_module_access_deps += glib2_dep
8
+endif
9
+
10
pipewire_module_access = shared_library('pipewire-module-access', 'module-access.c' ,
11
include_directories : configinc,
12
install : true,
13
install_dir : modules_install_dir,
14
install_rpath: modules_install_dir,
15
- dependencies : spa_dep, mathlib, dl_lib, pipewire_dep,
16
+ dependencies : pipewire_module_access_deps
17
)
18
19
pipewire_module_loopback = shared_library('pipewire-module-loopback',
20
21
cdata.set('HAVE_AVAHI', true)
22
endif
23
24
+if flatpak_support
25
+ pipewire_module_protocol_pulse_deps += glib2_dep
26
+endif
27
+
28
pipewire_module_protocol_pulse = shared_library('pipewire-module-protocol-pulse',
29
pipewire_module_protocol_pulse_sources,
30
include_directories : configinc,
31
32
endif
33
summary({'raop-sink (requires OpenSSL)': build_module_raop}, bool_yn: true, section: 'Optional Modules')
34
35
-roc_lib = cc.find_library('roc', required: get_option('roc'))
36
+roc_lib = cc.find_library('roc', has_headers: 'roc/config.h' , required: get_option('roc'))
37
summary({'ROC': roc_lib.found()}, bool_yn: true, section: 'Streaming between daemons')
38
39
build_module_roc = roc_lib.found()
40
41
dependencies : mathlib, dl_lib, rt_lib, pipewire_dep,
42
)
43
44
-build_module_avb = get_option('avb').allowed()
45
+build_module_avb = get_option('avb').require(host_machine.system() == 'linux', error_message: 'AVB support is only available on Linux').allowed()
46
if build_module_avb
47
pipewire_module_avb = shared_library('pipewire-module-avb',
48
'module-avb.c',
49
pipewire-0.3.56.tar.gz/src/modules/module-access.c -> pipewire-0.3.57.tar.gz/src/modules/module-access.c
Changed
144
1
2
#include <pipewire/impl.h>
3
#include <pipewire/private.h>
4
5
+#include "flatpak-utils.h"
6
+
7
/** \page page_module_access PipeWire Module: Access
8
*
9
*
10
11
* on an external actor to update that property once permission is
12
* granted or rejected.
13
*
14
+ * For connections from applications running inside Flatpak not mediated
15
+ * by a portal, the `access` module itself sets the `pipewire.access.portal.app_id`
16
+ * property to the Flatpak application ID.
17
*
18
* ## Module Options
19
*
20
21
return res;
22
}
23
24
-#if defined(__linux__)
25
-static int check_flatpak(struct pw_impl_client *client, int pid)
26
-{
27
- char root_path2048;
28
- int root_fd, info_fd, res;
29
- struct stat stat_buf;
30
-
31
- sprintf(root_path, "/proc/%u/root", pid);
32
- root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
33
- if (root_fd == -1) {
34
- res = -errno;
35
- if (res == -EACCES) {
36
- struct statfs buf;
37
- /* Access to the root dir isn't allowed. This can happen if the root is on a fuse
38
- * filesystem, such as in a toolbox container. We will never have a fuse rootfs
39
- * in the flatpak case, so in that case its safe to ignore this and
40
- * continue to detect other types of apps. */
41
- if (statfs(root_path, &buf) == 0 &&
42
- buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */
43
- return 0;
44
- }
45
- /* Not able to open the root dir shouldn't happen. Probably the app died and
46
- * we're failing due to /proc/$pid not existing. In that case fail instead
47
- * of treating this as privileged. */
48
- pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res));
49
- return res;
50
- }
51
- info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY);
52
- close (root_fd);
53
- if (info_fd == -1) {
54
- if (errno == ENOENT) {
55
- pw_log_debug("no .flatpak-info, client on the host");
56
- /* No file => on the host */
57
- return 0;
58
- }
59
- res = -errno;
60
- pw_log_error("error opening .flatpak-info: %m");
61
- return res;
62
- }
63
- if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) {
64
- /* Some weird fd => failure, assume sandboxed */
65
- pw_log_error("error fstat .flatpak-info: %m");
66
- }
67
- close(info_fd);
68
- return 1;
69
-}
70
-#endif
71
-
72
static void
73
context_check_access(void *data, struct pw_impl_client *client)
74
{
75
76
struct spa_dict_item items2;
77
const struct pw_properties *props;
78
const char *str, *access;
79
+ char *flatpak_app_id = NULL;
80
+ int nitems = 0;
81
int pid, res;
82
83
pid = -EINVAL;
84
85
(access = pw_properties_get(impl->properties, "access.force")) != NULL)
86
goto wait_permissions;
87
88
-#if defined(__linux__)
89
- res = check_flatpak(client, pid);
90
+ res = pw_check_flatpak(pid, &flatpak_app_id, NULL);
91
if (res != 0) {
92
if (res < 0) {
93
if (res == -EACCES) {
94
95
pw_log_debug(" %p: flatpak client %p added", impl, client);
96
}
97
access = "flatpak";
98
+ itemsnitems++ = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id",
99
+ flatpak_app_id);
100
goto wait_permissions;
101
}
102
-#endif
103
+
104
if ((access = pw_properties_get(props, PW_KEY_CLIENT_ACCESS)) == NULL)
105
access = "unrestricted";
106
107
108
109
granted:
110
pw_log_info("%p: client %p '%s' access granted", impl, client, access);
111
- items0 = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access);
112
- pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1));
113
+ itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access);
114
+ pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems));
115
116
permissions0 = PW_PERMISSION_INIT(PW_ID_ANY, PW_PERM_ALL);
117
pw_impl_client_update_permissions(client, 1, permissions);
118
- return;
119
+ goto done;
120
121
wait_permissions:
122
pw_log_info("%p: client %p wait for '%s' permissions",
123
impl, client, access);
124
- items0 = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access);
125
- pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1));
126
- return;
127
+ itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access);
128
+ pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems));
129
+ goto done;
130
131
rejected:
132
pw_resource_error(pw_impl_client_get_core_resource(client), res, access);
133
- items0 = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access);
134
- pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1));
135
+ itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access);
136
+ pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems));
137
+ goto done;
138
+
139
+done:
140
+ free(flatpak_app_id);
141
return;
142
}
143
144
pipewire-0.3.56.tar.gz/src/modules/module-avb/aaf.h -> pipewire-0.3.57.tar.gz/src/modules/module-avb/aaf.h
Changed
10
1
2
unsigned gv:1;
3
unsigned tv:1;
4
5
- uint8_t seq_number;
6
+ uint8_t seq_num;
7
8
unsigned _r2:7;
9
unsigned tu:1;
10
pipewire-0.3.56.tar.gz/src/modules/module-avb/iec61883.h -> pipewire-0.3.57.tar.gz/src/modules/module-avb/iec61883.h
Changed
10
1
2
unsigned gv:1;
3
unsigned tv:1;
4
5
- uint8_t seq_number;
6
+ uint8_t seq_num;
7
8
unsigned _r2:7;
9
unsigned tu:1;
10
pipewire-0.3.56.tar.gz/src/modules/module-avb/maap.c -> pipewire-0.3.57.tar.gz/src/modules/module-avb/maap.c
Changed
13
1
2
maap->server = server;
3
pw_log_info("0x%"PRIx64" %d", server->entity_id, server->ifindex);
4
5
- pw_getrandom(maap->xsubi, sizeof(maap->xsubi), 0);
6
+ if (pw_getrandom(maap->xsubi, sizeof(maap->xsubi), 0) != sizeof(maap->xsubi)) {
7
+ res = -errno;
8
+ goto error_free;
9
+ }
10
load_state(maap);
11
12
maap->source = pw_loop_add_io(server->impl->loop, fd, SPA_IO_IN, true, on_socket_data, maap);
13
pipewire-0.3.56.tar.gz/src/modules/module-client-node/remote-node.c -> pipewire-0.3.57.tar.gz/src/modules/module-client-node/remote-node.c
Changed
26
1
2
{
3
struct link *link = user_data;
4
struct spa_system *data_system = link->data->context->data_system;
5
- struct timespec ts = { 0, 0 };
6
-
7
- pw_log_trace_fp("link %p: signal", link);
8
-
9
- spa_system_clock_gettime(data_system, CLOCK_MONOTONIC, &ts);
10
- link->target.activation->status = PW_NODE_ACTIVATION_TRIGGERED;
11
- link->target.activation->signal_time = SPA_TIMESPEC_TO_NSEC(&ts);
12
13
+ pw_log_trace_fp("link %p: signal %p", link, link->target.activation);
14
if (SPA_UNLIKELY(spa_system_eventfd_write(data_system, link->signalfd, 1) < 0))
15
pw_log_warn("link %p: write failed %m", link);
16
17
18
link->map = mm;
19
link->target.activation = ptr;
20
link->signalfd = signalfd;
21
- link->target.signal = link_signal_func;
22
+ link->target.signal_func = link_signal_func;
23
link->target.data = link;
24
link->target.node = NULL;
25
spa_list_append(&data->links, &link->link);
26
pipewire-0.3.56.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.57.tar.gz/src/modules/module-echo-cancel.c
Changed
10
1
2
goto error;
3
}
4
5
- (void)SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_AUDIO_AEC, (struct spa_audio_aec *)impl->aec);
6
-
7
pw_log_info("Using plugin AEC %s", impl->aec->name);
8
9
if ((str = pw_properties_get(props, "aec.args")) != NULL)
10
pipewire-0.3.56.tar.gz/src/modules/module-filter-chain/convolver.c -> pipewire-0.3.57.tar.gz/src/modules/module-filter-chain/convolver.c
Changed
17
1
2
fft_cpx_free(&conv->segmentsi);
3
fft_cpx_free(&conv->segmentsIri);
4
}
5
- fft_destroy(conv->fft);
6
- fft_destroy(conv->ifft);
7
- fft_free(conv->fft_buffer);
8
+ if (conv->fft)
9
+ fft_destroy(conv->fft);
10
+ if (conv->ifft)
11
+ fft_destroy(conv->ifft);
12
+ if (conv->fft_buffer)
13
+ fft_free(conv->fft_buffer);
14
free(conv->segments);
15
free(conv->segmentsIr);
16
fft_cpx_free(&conv->pre_mult);
17
pipewire-0.3.56.tar.gz/src/modules/module-filter-chain/lv2_plugin.c -> pipewire-0.3.57.tar.gz/src/modules/module-filter-chain/lv2_plugin.c
Changed
14
1
2
#include <lilv/lilv.h>
3
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
4
#include <lv2/lv2plug.in/ns/ext/buf-size/buf-size.h>
5
-#include "lv2/lv2plug.in/ns/ext/worker/worker.h"
6
-#include "lv2/lv2plug.in/ns/ext/options/options.h"
7
-#include "lv2/lv2plug.in/ns/ext/parameters/parameters.h"
8
+#include <lv2/lv2plug.in/ns/ext/worker/worker.h>
9
+#include <lv2/lv2plug.in/ns/ext/options/options.h>
10
+#include <lv2/lv2plug.in/ns/ext/parameters/parameters.h>
11
12
#include "plugin.h"
13
14
pipewire-0.3.56.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.57.tar.gz/src/modules/module-protocol-native.c
Changed
201
1
2
* - XDG_RUNTIME_DIR
3
* - USERPROFILE
4
*
5
+ * The socket address will be written into the notification file descriptor
6
+ * if the following environment variable is set:
7
+ *
8
+ * - PIPEWIRE_NOTIFICATION_FD
9
+ *
10
* When a client connect, the connection will be made to:
11
*
12
* - PIPEWIRE_REMOTE : the environment with the remote name
13
14
if (client == NULL)
15
goto exit;
16
17
-
18
this = pw_impl_client_get_user_data(client);
19
spa_list_append(&s->this.client_list, &this->protocol_link);
20
21
this->server = s;
22
this->client = client;
23
+ pw_map_init(&this->compat_v2.types, 0, 32);
24
+
25
+ pw_impl_client_add_listener(client, &this->client_listener, &client_events, this);
26
+
27
this->source = pw_loop_add_io(pw_context_get_main_loop(context),
28
fd, SPA_IO_ERR | SPA_IO_HUP, true,
29
connection_data, this);
30
31
goto cleanup_client;
32
}
33
34
- pw_map_init(&this->compat_v2.types, 0, 32);
35
-
36
pw_protocol_native_connection_add_listener(this->connection,
37
&this->conn_listener,
38
&server_conn_events,
39
this);
40
41
- pw_impl_client_add_listener(client, &this->client_listener, &client_events, this);
42
-
43
if ((res = pw_impl_client_register(client, NULL)) < 0)
44
goto cleanup_client;
45
46
47
}
48
}
49
50
+static int write_socket_address(struct server *s)
51
+{
52
+ long v;
53
+ int fd, res = 0;
54
+ char *endptr;
55
+ const char *env = getenv("PIPEWIRE_NOTIFICATION_FD");
56
+
57
+ if (env == NULL || env0 == '\0')
58
+ return 0;
59
+
60
+ errno = 0;
61
+ v = strtol(env, &endptr, 10);
62
+ if (endptr0 != '\0')
63
+ errno = EINVAL;
64
+ if (errno != 0) {
65
+ res = -errno;
66
+ pw_log_error("server %p: strtol() failed with error: %m", s);
67
+ goto error;
68
+ }
69
+ fd = (int)v;
70
+ if (v != fd) {
71
+ res = -ERANGE;
72
+ pw_log_error("server %p: invalid fd %ld: %s", s, v, spa_strerror(res));
73
+ goto error;
74
+ }
75
+ if (dprintf(fd, "%s\n", s->addr.sun_path) < 0) {
76
+ res = -errno;
77
+ pw_log_error("server %p: dprintf() failed with error: %m", s);
78
+ goto error;
79
+ }
80
+ close(fd);
81
+ unsetenv("PIPEWIRE_NOTIFICATION_FD");
82
+ return 0;
83
+
84
+error:
85
+ return res;
86
+}
87
+
88
static int add_socket(struct pw_protocol *protocol, struct server *s)
89
{
90
socklen_t size;
91
92
}
93
}
94
95
+ res = write_socket_address(s);
96
+ if (res < 0) {
97
+ pw_log_error("server %p: failed to write socket address: %s", s,
98
+ spa_strerror(res));
99
+ goto error_close;
100
+ }
101
s->activated = activated;
102
s->loop = pw_context_get_main_loop(protocol->context);
103
if (s->loop == NULL) {
104
105
goto done;
106
}
107
108
-static void on_client_connection_destroy(void *data)
109
-{
110
- struct client *impl = data;
111
- spa_hook_remove(&impl->conn_listener);
112
-}
113
-
114
-static void on_client_need_flush(void *data)
115
-{
116
- struct client *impl = data;
117
-
118
- pw_log_trace("need flush");
119
- impl->need_flush = true;
120
-
121
- if (impl->source && !(impl->source->mask & SPA_IO_OUT)) {
122
- pw_loop_update_io(impl->context->main_loop,
123
- impl->source, impl->source->mask | SPA_IO_OUT);
124
- }
125
-}
126
-
127
-static const struct pw_protocol_native_connection_events client_conn_events = {
128
- PW_VERSION_PROTOCOL_NATIVE_CONNECTION_EVENTS,
129
- .destroy = on_client_connection_destroy,
130
- .need_flush = on_client_need_flush,
131
-};
132
-
133
static int impl_connect_fd(struct pw_protocol_client *client, int fd, bool do_close)
134
{
135
struct client *impl = SPA_CONTAINER_OF(client, struct client, this);
136
- int res;
137
138
impl->connected = false;
139
impl->disconnecting = false;
140
141
fd,
142
SPA_IO_IN | SPA_IO_OUT | SPA_IO_HUP | SPA_IO_ERR,
143
do_close, on_remote_data, impl);
144
- if (impl->source == NULL) {
145
- res = -errno;
146
- goto error_cleanup;
147
- }
148
+ if (impl->source == NULL)
149
+ return -errno;
150
151
- pw_protocol_native_connection_add_listener(impl->connection,
152
- &impl->conn_listener,
153
- &client_conn_events,
154
- impl);
155
return 0;
156
-
157
-error_cleanup:
158
- if (impl->connection) {
159
- pw_protocol_native_connection_destroy(impl->connection);
160
- impl->connection = NULL;
161
- }
162
- return res;
163
}
164
165
static void impl_disconnect(struct pw_protocol_client *client)
166
167
pw_loop_destroy_source(impl->context->main_loop, impl->source);
168
impl->source = NULL;
169
170
- if (impl->connection)
171
- pw_protocol_native_connection_destroy(impl->connection);
172
- impl->connection = NULL;
173
+ pw_protocol_native_connection_set_fd(impl->connection, -1);
174
}
175
176
static void impl_destroy(struct pw_protocol_client *client)
177
178
179
impl_disconnect(client);
180
181
+ if (impl->connection)
182
+ pw_protocol_native_connection_destroy(impl->connection);
183
+ impl->connection = NULL;
184
+
185
spa_list_remove(&client->link);
186
client_unref(impl);
187
}
188
189
goto done;
190
}
191
192
+static void on_client_connection_destroy(void *data)
193
+{
194
+ struct client *impl = data;
195
+ spa_hook_remove(&impl->conn_listener);
196
+}
197
+
198
+static void on_client_need_flush(void *data)
199
+{
200
+ struct client *impl = data;
201
pipewire-0.3.56.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.57.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
26
1
2
attr->fragsize = SPA_ROUND_UP(attr->fragsize, frame_size);
3
attr->fragsize = SPA_MAX(attr->fragsize, minfrag);
4
5
- attr->tlength = attr->minreq = attr->prebuf = 0;
6
+ /* pulseaudio configures the source to half of the fragsize. It also
7
+ * immediately sends chunks to clients. Configure a 2/3 of the fragsize
8
+ * as the latency. */
9
+ latency = attr->fragsize * 2 / 3;
10
+
11
+ if (s->adjust_latency)
12
+ attr->fragsize = SPA_ROUND_UP(latency, frame_size);
13
+
14
+ attr->tlength = attr->prebuf = 0;
15
16
- if (s->early_requests) {
17
- latency = attr->fragsize;
18
- } else if (s->adjust_latency) {
19
- latency = attr->fragsize;
20
- } else {
21
- latency = attr->fragsize;
22
- }
23
/* make sure can queue at least to fragsize without overruns */
24
if (attr->maxlength < attr->fragsize * 4)
25
attr->maxlength = attr->fragsize * 4;
26
pipewire-0.3.56.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.57.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
58
1
2
#include "server.h"
3
#include "stream.h"
4
#include "utils.h"
5
+#include "flatpak-utils.h"
6
7
#define LISTEN_BACKLOG 32
8
#define MAX_CLIENTS 64
9
10
client_access = server->client_access;
11
12
if (server->addr.ss_family == AF_UNIX) {
13
+ char *app_id = NULL, *devices = NULL;
14
+
15
#ifdef SO_PRIORITY
16
val = 6;
17
if (setsockopt(client_fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val)) < 0)
18
pw_log_warn("setsockopt(SO_PRIORITY) failed: %m");
19
#endif
20
pid = get_client_pid(client, client_fd);
21
- if (pid != 0 && check_flatpak(client, pid) == 1)
22
+ if (pid != 0 && pw_check_flatpak(pid, &app_id, &devices) == 1) {
23
+ /*
24
+ * XXX: we should really use Portal client access here
25
+ *
26
+ * However, session managers currently support only camera
27
+ * permissions, and the XDG Portal doesn't have a "Sound Manager"
28
+ * permission defined. So for now, use access=flatpak, and determine
29
+ * extra permissions here.
30
+ *
31
+ * The application has access to the Pulseaudio socket,
32
+ * and with real PA it would always then have full sound access.
33
+ * We'll restrict the full access here behind devices=all;
34
+ * if the application can access all devices it can then
35
+ * also sound and camera devices directly, so granting also the
36
+ * Manager permissions here is reasonable.
37
+ *
38
+ * The "Manager" permission in any case is also currently not safe
39
+ * as the session manager does not check any permission store
40
+ * for it.
41
+ */
42
client_access = "flatpak";
43
+ pw_properties_set(client->props, "pipewire.access.portal.app_id",
44
+ app_id);
45
+
46
+ if (devices && (spa_streq(devices, "all") ||
47
+ spa_strstartswith(devices, "all;") ||
48
+ strstr(devices, ";all;")))
49
+ pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, "Manager");
50
+ else
51
+ pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, NULL);
52
+ }
53
+ free(devices);
54
+ free(app_id);
55
}
56
else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) {
57
58
pipewire-0.3.56.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.57.tar.gz/src/modules/module-pulse-tunnel.c
Changed
60
1
2
} else {
3
float error, corr;
4
5
- error = (float)(impl->current_latency) - (float)impl->target_latency;
6
+ error = (float)impl->target_latency - (float)impl->current_latency;
7
error = SPA_CLAMP(error, -impl->max_error, impl->max_error);
8
9
corr = spa_dll_update(&impl->dll, error);
10
11
static void context_state_cb(pa_context *c, void *userdata)
12
{
13
struct impl *impl = userdata;
14
+ bool do_destroy = false;
15
switch (pa_context_get_state(c)) {
16
- case PA_CONTEXT_READY:
17
case PA_CONTEXT_TERMINATED:
18
case PA_CONTEXT_FAILED:
19
+ do_destroy = true;
20
+ SPA_FALLTHROUGH;
21
+ case PA_CONTEXT_READY:
22
pa_threaded_mainloop_signal(impl->pa_mainloop, 0);
23
break;
24
case PA_CONTEXT_UNCONNECTED:
25
+ do_destroy = true;
26
+ break;
27
case PA_CONTEXT_CONNECTING:
28
case PA_CONTEXT_AUTHORIZING:
29
case PA_CONTEXT_SETTING_NAME:
30
break;
31
}
32
+ if (do_destroy)
33
+ pw_impl_module_schedule_destroy(impl->module);
34
}
35
36
static void stream_state_cb(pa_stream *s, void * userdata)
37
{
38
struct impl *impl = userdata;
39
+ bool do_destroy = false;
40
switch (pa_stream_get_state(s)) {
41
- case PA_STREAM_READY:
42
case PA_STREAM_FAILED:
43
case PA_STREAM_TERMINATED:
44
+ do_destroy = true;
45
+ SPA_FALLTHROUGH;
46
+ case PA_STREAM_READY:
47
pa_threaded_mainloop_signal(impl->pa_mainloop, 0);
48
break;
49
case PA_STREAM_UNCONNECTED:
50
+ do_destroy = true;
51
+ break;
52
case PA_STREAM_CREATING:
53
break;
54
}
55
+ if (do_destroy)
56
+ pw_impl_module_schedule_destroy(impl->module);
57
}
58
59
static void stream_read_request_cb(pa_stream *s, size_t length, void *userdata)
60
pipewire-0.3.56.tar.gz/src/modules/module-rt.c -> pipewire-0.3.57.tar.gz/src/modules/module-rt.c
Changed
201
1
2
#ifdef HAVE_DBUS
3
#define RTKIT_SERVICE_NAME "org.freedesktop.RealtimeKit1"
4
#define RTKIT_OBJECT_PATH "/org/freedesktop/RealtimeKit1"
5
+#define RTKIT_INTERFACE "org.freedesktop.RealtimeKit1"
6
+
7
+#define XDG_PORTAL_SERVICE_NAME "org.freedesktop.portal.Desktop"
8
+#define XDG_PORTAL_OBJECT_PATH "/org/freedesktop/portal/desktop"
9
+#define XDG_PORTAL_INTERFACE "org.freedesktop.portal.Realtime"
10
11
/** \cond */
12
struct pw_rtkit_bus {
13
14
15
#ifdef HAVE_DBUS
16
bool use_rtkit;
17
- struct pw_rtkit_bus *system_bus;
18
+ /* For D-Bus. These are const static. */
19
+ const char* service_name;
20
+ const char* object_path;
21
+ const char* interface;
22
+ struct pw_rtkit_bus *rtkit_bus;
23
24
/* These are only for the RTKit implementation to fill in the `thread`
25
* struct. Since there's barely any overhead here we'll do this
26
27
}
28
29
#ifdef HAVE_DBUS
30
-struct pw_rtkit_bus *pw_rtkit_bus_get_system(void)
31
+struct pw_rtkit_bus *pw_rtkit_bus_get(DBusBusType bus_type)
32
{
33
struct pw_rtkit_bus *bus;
34
DBusError error;
35
36
if (bus == NULL)
37
return NULL;
38
39
- bus->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
40
+ bus->bus = dbus_bus_get_private(bus_type, &error);
41
if (bus->bus == NULL)
42
goto error;
43
44
45
46
error:
47
free(bus);
48
- pw_log_error("Failed to connect to system bus: %s", error.message);
49
+ pw_log_error("Failed to connect to %s bus: %s",
50
+ bus_type == DBUS_BUS_SYSTEM ? "system" : "session", error.message);
51
dbus_error_free(&error);
52
errno = ECONNREFUSED;
53
return NULL;
54
}
55
56
+struct pw_rtkit_bus *pw_rtkit_bus_get_system(void)
57
+{
58
+ return pw_rtkit_bus_get(DBUS_BUS_SYSTEM);
59
+}
60
+
61
+struct pw_rtkit_bus *pw_rtkit_bus_get_session(void)
62
+{
63
+ return pw_rtkit_bus_get(DBUS_BUS_SESSION);
64
+}
65
+
66
+bool pw_rtkit_check_xdg_portal(struct pw_rtkit_bus *system_bus)
67
+{
68
+ DBusError error;
69
+ bool ret = true;
70
+
71
+ dbus_error_init(&error);
72
+
73
+ if (!dbus_bus_name_has_owner(system_bus->bus, XDG_PORTAL_SERVICE_NAME, &error)) {
74
+ pw_log_warn("Can't find xdg-portal: %s", error.name);
75
+ ret = false;
76
+ goto finish;
77
+ }
78
+finish:
79
+ dbus_error_free(&error);
80
+
81
+ return ret;
82
+}
83
+
84
void pw_rtkit_bus_free(struct pw_rtkit_bus *system_bus)
85
{
86
dbus_connection_close(system_bus->bus);
87
88
return -EIO;
89
}
90
91
-static long long rtkit_get_int_property(struct pw_rtkit_bus *connection, const char *propname,
92
+static long long rtkit_get_int_property(struct impl *impl, const char *propname,
93
long long *propval)
94
{
95
DBusMessage *m = NULL, *r = NULL;
96
97
DBusError error;
98
int current_type;
99
long long ret;
100
- const char *interfacestr = "org.freedesktop.RealtimeKit1";
101
+ struct pw_rtkit_bus *connection = impl->rtkit_bus;
102
103
dbus_error_init(&error);
104
105
- if (!(m = dbus_message_new_method_call(RTKIT_SERVICE_NAME,
106
- RTKIT_OBJECT_PATH,
107
+ if (!(m = dbus_message_new_method_call(impl->service_name,
108
+ impl->object_path,
109
"org.freedesktop.DBus.Properties", "Get"))) {
110
ret = -ENOMEM;
111
goto finish;
112
}
113
114
if (!dbus_message_append_args(m,
115
- DBUS_TYPE_STRING, &interfacestr,
116
+ DBUS_TYPE_STRING, &impl->interface,
117
DBUS_TYPE_STRING, &propname, DBUS_TYPE_INVALID)) {
118
ret = -ENOMEM;
119
goto finish;
120
121
return ret;
122
}
123
124
-int pw_rtkit_get_max_realtime_priority(struct pw_rtkit_bus *connection)
125
+int pw_rtkit_get_max_realtime_priority(struct impl *impl)
126
{
127
long long retval;
128
int err;
129
130
- err = rtkit_get_int_property(connection, "MaxRealtimePriority", &retval);
131
+ err = rtkit_get_int_property(impl, "MaxRealtimePriority", &retval);
132
return err < 0 ? err : retval;
133
}
134
135
-int pw_rtkit_get_min_nice_level(struct pw_rtkit_bus *connection, int *min_nice_level)
136
+int pw_rtkit_get_min_nice_level(struct impl *impl, int *min_nice_level)
137
{
138
long long retval;
139
int err;
140
141
- err = rtkit_get_int_property(connection, "MinNiceLevel", &retval);
142
+ err = rtkit_get_int_property(impl, "MinNiceLevel", &retval);
143
if (err >= 0)
144
*min_nice_level = retval;
145
return err;
146
}
147
148
-long long pw_rtkit_get_rttime_usec_max(struct pw_rtkit_bus *connection)
149
+long long pw_rtkit_get_rttime_usec_max(struct impl *impl)
150
{
151
long long retval;
152
int err;
153
154
- err = rtkit_get_int_property(connection, "RTTimeUSecMax", &retval);
155
+ err = rtkit_get_int_property(impl, "RTTimeUSecMax", &retval);
156
return err < 0 ? err : retval;
157
}
158
159
-int pw_rtkit_make_realtime(struct pw_rtkit_bus *connection, pid_t thread, int priority)
160
+int pw_rtkit_make_realtime(struct impl *impl, pid_t thread, int priority)
161
{
162
DBusMessage *m = NULL, *r = NULL;
163
+ dbus_uint64_t pid;
164
dbus_uint64_t u64;
165
dbus_uint32_t u32;
166
DBusError error;
167
int ret;
168
+ struct pw_rtkit_bus *connection = impl->rtkit_bus;
169
170
dbus_error_init(&error);
171
172
if (thread == 0)
173
thread = _gettid();
174
175
- if (!(m = dbus_message_new_method_call(RTKIT_SERVICE_NAME,
176
- RTKIT_OBJECT_PATH,
177
- "org.freedesktop.RealtimeKit1",
178
- "MakeThreadRealtime"))) {
179
+ if (!(m = dbus_message_new_method_call(impl->service_name,
180
+ impl->object_path, impl->interface,
181
+ "MakeThreadRealtimeWithPID"))) {
182
ret = -ENOMEM;
183
goto finish;
184
}
185
186
+ pid = (dbus_uint64_t) getpid();
187
u64 = (dbus_uint64_t) thread;
188
u32 = (dbus_uint32_t) priority;
189
190
if (!dbus_message_append_args(m,
191
+ DBUS_TYPE_UINT64, &pid,
192
DBUS_TYPE_UINT64, &u64,
193
DBUS_TYPE_UINT32, &u32, DBUS_TYPE_INVALID)) {
194
ret = -ENOMEM;
195
196
return ret;
197
}
198
199
-int pw_rtkit_make_high_priority(struct pw_rtkit_bus *connection, pid_t thread, int nice_level)
200
+int pw_rtkit_make_high_priority(struct impl *impl, pid_t thread, int nice_level)
201
pipewire-0.3.56.tar.gz/src/pipewire/conf.c -> pipewire-0.3.57.tar.gz/src/pipewire/conf.c
Changed
201
1
2
#include <pwd.h>
3
#endif
4
#if defined(__FreeBSD__) || defined(__MidnightBSD__)
5
+#ifndef O_PATH
6
#define O_PATH 0
7
#endif
8
+#endif
9
10
#include <spa/utils/result.h>
11
#include <spa/utils/string.h>
12
13
return -ENOENT;
14
}
15
16
+ if (pw_check_option("no-config", "true"))
17
+ goto no_config;
18
+
19
if ((res = get_envconf_path(path, size, prefix, name)) != 0) {
20
if ((*level)++ == 0)
21
return res;
22
23
24
if (*level == 0) {
25
(*level)++;
26
- if ((res = get_confdata_path(path, size, prefix, name)) != 0)
27
+ if ((res = get_homeconf_path(path, size, prefix, name)) != 0)
28
return res;
29
}
30
- if (pw_check_option("no-config", "true"))
31
- return 0;
32
-
33
if (*level == 1) {
34
(*level)++;
35
if ((res = get_configdir_path(path, size, prefix, name)) != 0)
36
return res;
37
}
38
if (*level == 2) {
39
+no_config:
40
(*level)++;
41
- if ((res = get_homeconf_path(path, size, prefix, name)) != 0)
42
+ if ((res = get_confdata_path(path, size, prefix, name)) != 0)
43
return res;
44
}
45
return 0;
46
47
48
if (fstat(fd, &sbuf) < 0)
49
goto error_close;
50
- if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
51
- goto error_close;
52
- close(fd);
53
54
- count = pw_properties_update_string(conf, data, sbuf.st_size);
55
- munmap(data, sbuf.st_size);
56
+ if (sbuf.st_size > 0) {
57
+ if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
58
+ goto error_close;
59
+
60
+ count = pw_properties_update_string(conf, data, sbuf.st_size);
61
+ munmap(data, sbuf.st_size);
62
+ } else {
63
+ count = 0;
64
+ }
65
+ close(fd);
66
67
pw_log_info("%p: loaded config '%s' with %d items", conf, path, count);
68
69
70
return -errno;
71
}
72
73
+static bool check_override(struct pw_properties *conf, const char *name, int level)
74
+{
75
+ const struct spa_dict_item *it;
76
+
77
+ spa_dict_for_each(it, &conf->dict) {
78
+ int lev, idx;
79
+
80
+ if (!spa_streq(name, it->value))
81
+ continue;
82
+ if (sscanf(it->key, "override.%d.%d.config.name", &lev, &idx) != 2)
83
+ continue;
84
+ if (lev < level)
85
+ return false;
86
+ }
87
+ return true;
88
+}
89
+
90
static void add_override(struct pw_properties *conf, struct pw_properties *override,
91
- const char *path, int level, int index)
92
+ const char *path, const char *name, int level, int index)
93
{
94
const struct spa_dict_item *it;
95
char key1024;
96
+
97
snprintf(key, sizeof(key), "override.%d.%d.config.path", level, index);
98
pw_properties_set(conf, key, path);
99
+ snprintf(key, sizeof(key), "override.%d.%d.config.name", level, index);
100
+ pw_properties_set(conf, key, name);
101
spa_dict_for_each(it, &override->dict) {
102
snprintf(key, sizeof(key), "override.%d.%d.%s", level, index, it->key);
103
pw_properties_set(conf, key, it->value);
104
105
return -errno;
106
107
for (i = 0; i < n; i++) {
108
- snprintf(fname, sizeof(fname), "%s/%s", path, entriesi->d_name);
109
- if (conf_load(fname, override) >= 0)
110
- add_override(conf, override, fname, level, i);
111
- pw_properties_clear(override);
112
+ const char *name = entriesi->d_name;
113
+
114
+ snprintf(fname, sizeof(fname), "%s/%s", path, name);
115
+ if (check_override(conf, name, level)) {
116
+ if (conf_load(fname, override) >= 0)
117
+ add_override(conf, override, fname, name, level, i);
118
+ pw_properties_clear(override);
119
+ } else {
120
+ pw_log_info("skip override %s with lower priority", fname);
121
+ }
122
free(entriesi);
123
}
124
free(entries);
125
126
return 0;
127
}
128
129
+static int try_load_conf(const char *conf_prefix, const char *conf_name,
130
+ struct pw_properties *conf)
131
+{
132
+ int res;
133
+
134
+ if (conf_name == NULL)
135
+ return -EINVAL;
136
+ if (spa_streq(conf_name, "null"))
137
+ return 0;
138
+ if ((res = pw_conf_load_conf(conf_prefix, conf_name, conf)) < 0) {
139
+ bool skip_prefix = conf_prefix == NULL || conf_name0 == '/';
140
+ pw_log_warn("can't load config %s%s%s: %s",
141
+ skip_prefix ? "" : conf_prefix,
142
+ skip_prefix ? "" : "/",
143
+ conf_name, spa_strerror(res));
144
+ }
145
+ return res;
146
+}
147
+
148
+SPA_EXPORT
149
+int pw_conf_load_conf_for_context(struct pw_properties *props, struct pw_properties *conf)
150
+{
151
+ const char *conf_prefix, *conf_name;
152
+ int res;
153
+
154
+ conf_prefix = getenv("PIPEWIRE_CONFIG_PREFIX");
155
+ if (conf_prefix == NULL)
156
+ conf_prefix = pw_properties_get(props, PW_KEY_CONFIG_PREFIX);
157
+
158
+ conf_name = getenv("PIPEWIRE_CONFIG_NAME");
159
+ if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) {
160
+ conf_name = pw_properties_get(props, PW_KEY_CONFIG_NAME);
161
+ if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) {
162
+ conf_name = "client.conf";
163
+ if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) {
164
+ pw_log_error("can't load default config %s: %s",
165
+ conf_name, spa_strerror(res));
166
+ return res;
167
+ }
168
+ }
169
+ }
170
+
171
+ conf_name = pw_properties_get(props, PW_KEY_CONFIG_OVERRIDE_NAME);
172
+ if (conf_name != NULL) {
173
+ struct pw_properties *override;
174
+ const char *path, *name;
175
+
176
+ override = pw_properties_new(NULL, NULL);
177
+ if (override == NULL) {
178
+ res = -errno;
179
+ return res;
180
+ }
181
+
182
+ conf_prefix = pw_properties_get(props, PW_KEY_CONFIG_OVERRIDE_PREFIX);
183
+ if ((res = try_load_conf(conf_prefix, conf_name, override)) < 0) {
184
+ pw_log_error("can't load default override config %s: %s",
185
+ conf_name, spa_strerror(res));
186
+ pw_properties_free (override);
187
+ return res;
188
+ }
189
+ path = pw_properties_get(override, "config.path");
190
+ name = pw_properties_get(override, "config.name");
191
+ add_override(conf, override, path, name, 0, 1);
192
+ pw_properties_free(override);
193
+ }
194
+
195
+ return res;
196
+}
197
+
198
SPA_EXPORT
199
int pw_context_conf_update_props(struct pw_context *context,
200
const char *section, struct pw_properties *props)
201
pipewire-0.3.56.tar.gz/src/pipewire/conf.h -> pipewire-0.3.57.tar.gz/src/pipewire/conf.h
Changed
9
1
2
* \{
3
*/
4
5
+int pw_conf_load_conf_for_context(struct pw_properties *props, struct pw_properties *conf);
6
int pw_conf_load_conf(const char *prefix, const char *name, struct pw_properties *conf);
7
int pw_conf_load_state(const char *prefix, const char *name, struct pw_properties *conf);
8
int pw_conf_save_state(const char *prefix, const char *name, const struct pw_properties *conf);
9
pipewire-0.3.56.tar.gz/src/pipewire/context.c -> pipewire-0.3.57.tar.gz/src/pipewire/context.c
Changed
172
1
2
pw_properties_set(properties, PW_KEY_CORE_NAME, context->core->info.name);
3
}
4
5
-static int try_load_conf(struct pw_context *this, const char *conf_prefix,
6
- const char *conf_name, struct pw_properties *conf)
7
-{
8
- int res;
9
-
10
- if (conf_name == NULL)
11
- return -EINVAL;
12
- if (spa_streq(conf_name, "null"))
13
- return 0;
14
- if ((res = pw_conf_load_conf(conf_prefix, conf_name, conf)) < 0) {
15
- bool skip_prefix = conf_prefix == NULL || conf_name0 == '/';
16
- pw_log_warn("%p: can't load config %s%s%s: %s",
17
- this,
18
- skip_prefix ? "" : conf_prefix,
19
- skip_prefix ? "" : "/",
20
- conf_name, spa_strerror(res));
21
- }
22
- return res;
23
-}
24
-
25
static int context_set_freewheel(struct pw_context *context, bool freewheel)
26
{
27
struct spa_thread *thr;
28
29
{
30
struct impl *impl;
31
struct pw_context *this;
32
- const char *lib, *str, *conf_prefix, *conf_name;
33
+ const char *lib, *str;
34
void *dbus_iface = NULL;
35
uint32_t n_support;
36
struct pw_properties *pr, *conf;
37
38
goto error_free;
39
}
40
this->conf = conf;
41
-
42
- conf_prefix = getenv("PIPEWIRE_CONFIG_PREFIX");
43
- if (conf_prefix == NULL)
44
- conf_prefix = pw_properties_get(properties, PW_KEY_CONFIG_PREFIX);
45
-
46
- conf_name = getenv("PIPEWIRE_CONFIG_NAME");
47
- if (try_load_conf(this, conf_prefix, conf_name, conf) < 0) {
48
- conf_name = pw_properties_get(properties, PW_KEY_CONFIG_NAME);
49
- if (try_load_conf(this, conf_prefix, conf_name, conf) < 0) {
50
- conf_name = "client.conf";
51
- if ((res = try_load_conf(this, conf_prefix, conf_name, conf)) < 0) {
52
- pw_log_error("%p: can't load config %s: %s",
53
- this, conf_name, spa_strerror(res));
54
- goto error_free;
55
- }
56
- }
57
- }
58
+ if ((res = pw_conf_load_conf_for_context (properties, conf)) < 0)
59
+ goto error_free;
60
61
n_support = pw_get_support(this->support, SPA_N_ELEMENTS(this->support) - 6);
62
cpu = spa_support_find(this->support, n_support, SPA_TYPE_INTERFACE_CPU);
63
64
return global;
65
}
66
67
-/** Find a port to link with
68
- *
69
- * \param context a context
70
- * \param other_port a port to find a link with
71
- * \param id the id of a port or PW_ID_ANY
72
- * \param props extra properties
73
- * \param n_format_filters number of filters
74
- * \param format_filters array of format filters
75
- * \paramout error an error when something is wrong
76
- * \return a port that can be used to link to \a otherport or NULL on error
77
- */
78
-struct pw_impl_port *pw_context_find_port(struct pw_context *context,
79
- struct pw_impl_port *other_port,
80
- uint32_t id,
81
- struct pw_properties *props,
82
- uint32_t n_format_filters,
83
- struct spa_pod **format_filters,
84
- char **error)
85
-{
86
- struct pw_impl_port *best = NULL;
87
- bool have_id;
88
- struct pw_impl_node *n;
89
-
90
- have_id = id != PW_ID_ANY;
91
-
92
- pw_log_debug("%p: id:%u", context, id);
93
-
94
- spa_list_for_each(n, &context->node_list, link) {
95
- if (n->global == NULL)
96
- continue;
97
-
98
- if (other_port->node == n)
99
- continue;
100
-
101
- if (!global_can_read(context, n->global))
102
- continue;
103
-
104
- pw_log_debug("%p: node id:%d", context, n->global->id);
105
-
106
- if (have_id) {
107
- if (n->global->id == id) {
108
- pw_log_debug("%p: id:%u matches node %p", context, id, n);
109
-
110
- best =
111
- pw_impl_node_find_port(n,
112
- pw_direction_reverse(other_port->direction),
113
- PW_ID_ANY);
114
- if (best)
115
- break;
116
- }
117
- } else {
118
- struct pw_impl_port *p, *pin, *pout;
119
- uint8_t buf4096;
120
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
121
- struct spa_pod *dummy;
122
-
123
- p = pw_impl_node_find_port(n,
124
- pw_direction_reverse(other_port->direction),
125
- PW_ID_ANY);
126
- if (p == NULL)
127
- continue;
128
-
129
- if (p->direction == PW_DIRECTION_OUTPUT) {
130
- pin = other_port;
131
- pout = p;
132
- } else {
133
- pin = p;
134
- pout = other_port;
135
- }
136
-
137
- if (pw_context_find_format(context,
138
- pout,
139
- pin,
140
- props,
141
- n_format_filters,
142
- format_filters,
143
- &dummy,
144
- &b,
145
- error) < 0) {
146
- free(*error);
147
- continue;
148
- }
149
- best = p;
150
- break;
151
- }
152
- }
153
- if (best == NULL) {
154
- *error = spa_aprintf("No matching Node found");
155
- }
156
- return best;
157
-}
158
-
159
SPA_PRINTF_FUNC(7, 8) int pw_context_debug_port_params(struct pw_context *this,
160
struct spa_node *node, enum spa_direction direction,
161
uint32_t port_id, uint32_t id, int err, const char *debug, ...)
162
163
* panding change. Apply the change to the position now so
164
* that we have the right values when we change the node
165
* states of the driver and followers to RUNNING below */
166
+ pw_log_debug("%p: apply duration:%"PRIu64" rate:%u/%u", context,
167
+ n->current_quantum, n->current_rate.num,
168
+ n->current_rate.denom);
169
n->rt.position->clock.duration = n->current_quantum;
170
n->rt.position->clock.rate = n->current_rate;
171
n->current_pending = false;
172
pipewire-0.3.56.tar.gz/src/pipewire/data-loop.c -> pipewire-0.3.57.tar.gz/src/pipewire/data-loop.c
Changed
15
1
2
spa_invoke_func_t func, uint32_t seq, const void *data, size_t size,
3
bool block, void *user_data)
4
{
5
- int res;
6
- if (loop->running)
7
- res = pw_loop_invoke(loop->loop, func, seq, data, size, block, user_data);
8
- else
9
- res = func(loop->loop->loop, false, seq, data, size, user_data);
10
- return res;
11
+ return pw_loop_invoke(loop->loop, func, seq, data, size, block, user_data);
12
}
13
14
/** Set a thread utils implementation.
15
pipewire-0.3.56.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.57.tar.gz/src/pipewire/impl-link.c
Changed
22
1
2
/* find a common format for the ports */
3
if ((res = pw_context_find_format(context,
4
output, input, NULL, 0, NULL,
5
- &format, &b, &error)) < 0)
6
+ &format, &b, &error)) < 0) {
7
+ format = NULL;
8
goto error;
9
+ }
10
11
format = spa_pod_copy(format);
12
spa_pod_fixate(format);
13
14
impl->inode = input_node;
15
}
16
17
- this->rt.target.signal = impl->inode->rt.target.signal;
18
+ this->rt.target.signal_func = impl->inode->rt.target.signal_func;
19
this->rt.target.data = impl->inode->rt.target.data;
20
21
pw_log_debug("%p: constructed out:%p:%d.%d -> in:%p:%d.%d", impl,
22
pipewire-0.3.56.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.57.tar.gz/src/pipewire/impl-node.c
Changed
40
1
2
if (pw_node_activation_state_dec(state, 1)) {
3
a->status = PW_NODE_ACTIVATION_TRIGGERED;
4
a->signal_time = nsec;
5
- t->signal(t->data);
6
+ t->signal_func(t->data);
7
}
8
}
9
return 0;
10
11
this->name, this->info.id, cmd - 1);
12
13
pw_log_trace_fp("%p: got process", this);
14
- this->rt.target.signal(this->rt.target.data);
15
+ this->rt.target.signal_func(this->rt.target.data);
16
}
17
}
18
19
20
this->rt.activation = this->activation->map->ptr;
21
this->rt.target.activation = this->rt.activation;
22
this->rt.target.node = this;
23
- this->rt.target.signal = process_node;
24
+ this->rt.target.signal_func = process_node;
25
this->rt.target.data = this;
26
- this->rt.driver_target.signal = process_node;
27
+ this->rt.driver_target.signal_func = process_node;
28
29
reset_position(this, &this->rt.activation->position);
30
this->rt.activation->sync_timeout = DEFAULT_SYNC_TIMEOUT;
31
32
state->pending, state->required);
33
dump_states(node);
34
}
35
- node->rt.target.signal(node->rt.target.data);
36
+ node->rt.target.signal_func(node->rt.target.data);
37
}
38
39
if (node->current_pending) {
40
pipewire-0.3.56.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.57.tar.gz/src/pipewire/impl-port.c
Changed
59
1
2
int pw_impl_port_init_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mix)
3
{
4
uint32_t port_id;
5
+ struct pw_impl_node *node = port->node;
6
int res = 0;
7
8
port_id = pw_map_insert_new(&port->mix_port_map, mix);
9
10
port->n_mix, port->port_id, mix->port.port_id,
11
mix->io, spa_strerror(res));
12
13
+ if (port->n_mix == 1) {
14
+ pw_log_debug("%p: setting port io", port);
15
+ spa_node_port_set_io(node->node,
16
+ port->direction, port->port_id,
17
+ SPA_IO_Buffers,
18
+ &port->rt.io, sizeof(port->rt.io));
19
+ }
20
return res;
21
22
error_remove_port:
23
24
{
25
int res = 0;
26
uint32_t port_id = mix->port.port_id;
27
+ struct pw_impl_node *node = port->node;
28
29
pw_map_remove(&port->mix_port_map, port_id);
30
spa_list_remove(&mix->link);
31
32
pw_log_debug("%p: release mix %d %d.%d", port,
33
port->n_mix, port->port_id, mix->port.port_id);
34
35
+ if (port->n_mix == 0) {
36
+ pw_log_debug("%p: clearing port io", port);
37
+ spa_node_port_set_io(node->node,
38
+ port->direction, port->port_id,
39
+ SPA_IO_Buffers,
40
+ NULL, sizeof(port->rt.io));
41
+ }
42
return res;
43
}
44
45
46
if (control) {
47
pw_log_debug("%p: setting node control", port);
48
} else {
49
- pw_log_debug("%p: setting node io", port);
50
- spa_node_port_set_io(node->node,
51
- port->direction, port->port_id,
52
- SPA_IO_Buffers,
53
- &port->rt.io, sizeof(port->rt.io));
54
-
55
+ pw_log_debug("%p: setting mixer io", port);
56
spa_node_port_set_io(port->mix,
57
pw_direction_reverse(port->direction), 0,
58
SPA_IO_Buffers,
59
pipewire-0.3.56.tar.gz/src/pipewire/keys.h -> pipewire-0.3.57.tar.gz/src/pipewire/keys.h
Changed
22
1
2
/* config */
3
#define PW_KEY_CONFIG_PREFIX "config.prefix" /**< a config prefix directory */
4
#define PW_KEY_CONFIG_NAME "config.name" /**< a config file name */
5
+#define PW_KEY_CONFIG_OVERRIDE_PREFIX "config.override.prefix" /**< a config override prefix directory */
6
+#define PW_KEY_CONFIG_OVERRIDE_NAME "config.override.name" /**< a config override file name */
7
8
/* context */
9
#define PW_KEY_CONTEXT_PROFILE_MODULES "context.profile.modules" /**< a context profile for modules, deprecated */
10
11
#define PW_KEY_NODE_FORCE_RATE "node.force-rate" /**< force a rate while the node is
12
* active */
13
14
-#define PW_KEY_NODE_DONT_RECONNECT "node.dont-reconnect" /**< don't reconnect this node */
15
+#define PW_KEY_NODE_DONT_RECONNECT "node.dont-reconnect" /**< don't reconnect this node. The node is
16
+ * initially linked to node.target or
17
+ * target.object or the default node. If the
18
+ * targets is removed, the node is destroyed */
19
#define PW_KEY_NODE_ALWAYS_PROCESS "node.always-process" /**< process even when unlinked */
20
#define PW_KEY_NODE_WANT_DRIVER "node.want-driver" /**< the node wants to be grouped with a driver
21
* node in order to schedule the graph. */
22
pipewire-0.3.56.tar.gz/src/pipewire/mem.c -> pipewire-0.3.57.tar.gz/src/pipewire/mem.c
Changed
28
1
2
spa_list_init(&b->memmaps);
3
4
#ifdef HAVE_MEMFD_CREATE
5
- b->this.fd = memfd_create("pipewire-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
6
+ char name128;
7
+ snprintf(name, sizeof(name),
8
+ "pipewire-memfd:flags=0x%08x,type=%" PRIu32 ",size=%zu",
9
+ (unsigned int) flags, type, size);
10
+
11
+ b->this.fd = memfd_create(name, MFD_CLOEXEC | MFD_ALLOW_SEALING);
12
if (b->this.fd == -1) {
13
res = -errno;
14
pw_log_error("%p: Failed to create memfd: %m", pool);
15
16
goto error_free;
17
}
18
#else
19
- char filename = "/dev/shm/pipewire-tmpfile.XXXXXX";
20
+ char filename128;
21
+ snprintf(filename, sizeof(filename),
22
+ "/dev/shm/pipewire-tmpfile:flags=0x%08x,type=%" PRIu32 ",size=%zu:XXXXXX",
23
+ (unsigned int) flags, type, size);
24
+
25
b->this.fd = mkostemp(filename, O_CLOEXEC);
26
if (b->this.fd == -1) {
27
res = -errno;
28
pipewire-0.3.56.tar.gz/src/pipewire/meson.build -> pipewire-0.3.57.tar.gz/src/pipewire/meson.build
Changed
10
1
2
'-DOLD_MEDIA_SESSION_WORKAROUND=1'
3
4
5
-if build_machine.system() != 'freebsd' and build_machine.system() != 'midnightbsd'
6
+if host_machine.system() != 'freebsd' and host_machine.system() != 'midnightbsd'
7
libpipewire_c_args +=
8
'-D_POSIX_C_SOURCE'
9
10
pipewire-0.3.56.tar.gz/src/pipewire/private.h -> pipewire-0.3.57.tar.gz/src/pipewire/private.h
Changed
27
1
2
struct spa_list link;
3
struct pw_impl_node *node;
4
struct pw_node_activation *activation;
5
- int (*signal) (void *data);
6
+ int (*signal_func) (void *data);
7
void *data;
8
unsigned int active:1;
9
};
10
11
struct spa_pod_builder *builder,
12
char **error);
13
14
-/** Find a ports compatible with \a other_port and the format filters */
15
-struct pw_impl_port *
16
-pw_context_find_port(struct pw_context *context,
17
- struct pw_impl_port *other_port,
18
- uint32_t id,
19
- struct pw_properties *props,
20
- uint32_t n_format_filters,
21
- struct spa_pod **format_filters,
22
- char **error);
23
-
24
int pw_context_debug_port_params(struct pw_context *context,
25
struct spa_node *node, enum spa_direction direction,
26
uint32_t port_id, uint32_t id, int err, const char *debug, ...);
27
pipewire-0.3.56.tar.gz/src/pipewire/stream.c -> pipewire-0.3.57.tar.gz/src/pipewire/stream.c
Changed
49
1
2
{
3
struct spa_pod_prop *prop;
4
struct spa_pod_object *obj = (struct spa_pod_object *) param;
5
- union {
6
- float f;
7
- double d;
8
- bool b;
9
- } value;
10
+ float value_f;
11
+ double value_d;
12
+ bool value_b;
13
float *values;
14
uint32_t i, n_values;
15
16
17
18
switch (c->container) {
19
case SPA_TYPE_Float:
20
- if (spa_pod_get_float(&prop->value, &value.f) < 0)
21
+ if (spa_pod_get_float(&prop->value, &value_f) < 0)
22
continue;
23
n_values = 1;
24
- values = &value.f;
25
+ values = &value_f;
26
break;
27
case SPA_TYPE_Double:
28
- if (spa_pod_get_double(&prop->value, &value.d) < 0)
29
+ if (spa_pod_get_double(&prop->value, &value_d) < 0)
30
continue;
31
n_values = 1;
32
- value.f = value.d;
33
- values = &value.f;
34
+ value_f = value_d;
35
+ values = &value_f;
36
break;
37
case SPA_TYPE_Bool:
38
- if (spa_pod_get_bool(&prop->value, &value.b) < 0)
39
+ if (spa_pod_get_bool(&prop->value, &value_b) < 0)
40
continue;
41
- value.f = value.b ? 1.0f : 0.0f;
42
+ value_f = value_b ? 1.0f : 0.0f;
43
n_values = 1;
44
- values = &value.f;
45
+ values = &value_f;
46
break;
47
case SPA_TYPE_Array:
48
if ((values = spa_pod_get_array(&prop->value, &n_values)) == NULL ||
49
pipewire-0.3.56.tar.gz/src/pipewire/utils.c -> pipewire-0.3.57.tar.gz/src/pipewire/utils.c
Changed
19
1
2
ssize_t pw_getrandom(void *buf, size_t buflen, unsigned int flags)
3
{
4
ssize_t bytes;
5
+ int read_errno;
6
7
#ifdef HAVE_GETRANDOM
8
bytes = getrandom(buf, buflen, flags);
9
10
if (fd < 0)
11
return -1;
12
bytes = read(fd, buf, buflen);
13
+ read_errno = errno;
14
close(fd);
15
+ errno = read_errno;
16
return bytes;
17
}
18
19
pipewire-0.3.56.tar.gz/src/pipewire/utils.h -> pipewire-0.3.57.tar.gz/src/pipewire/utils.h
Changed
9
1
2
})
3
#endif
4
5
+SPA_WARN_UNUSED_RESULT
6
ssize_t pw_getrandom(void *buf, size_t buflen, unsigned int flags);
7
8
void* pw_reallocarray(void *ptr, size_t nmemb, size_t size);
9
pipewire-0.3.56.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.57.tar.gz/src/tools/pw-cat.c
Changed
17
1
2
pw_stream_destroy(data.stream);
3
}
4
error_no_stream:
5
+error_bad_file:
6
spa_hook_remove(&data.core_listener);
7
pw_core_disconnect(data.core);
8
error_ctx_connect_failed:
9
10
pw_main_loop_destroy(data.loop);
11
error_no_props:
12
error_no_main_loop:
13
-error_bad_file:
14
pw_properties_free(data.props);
15
if (data.file)
16
sf_close(data.file);
17
pipewire-0.3.56.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.57.tar.gz/src/tools/pw-cli.c
Changed
201
1
2
static bool do_permissions(struct data *data, const char *cmd, char *args, char **error);
3
static bool do_get_permissions(struct data *data, const char *cmd, char *args, char **error);
4
static bool do_send_command(struct data *data, const char *cmd, char *args, char **error);
5
-static bool do_dump(struct data *data, const char *cmd, char *args, char **error);
6
static bool do_quit(struct data *data, const char *cmd, char *args, char **error);
7
8
#define DUMP_NAMES "Core|Module|Device|Node|Port|Factory|Client|Link|Session|Endpoint|EndpointStream"
9
10
{ "permissions", "sp", "Set permissions for a client <client-id> <object> <permission>", do_permissions },
11
{ "get-permissions", "gp", "Get permissions of a client <client-id>", do_get_permissions },
12
{ "send-command", "c", "Send a command <object-id>", do_send_command },
13
- { "dump", "D", "Dump objects in ways that are cleaner for humans to understand "
14
- "short|deep|resolve|notype -sdrt all|"DUMP_NAMES"|<id>", do_dump },
15
{ "quit", "q", "Quit", do_quit },
16
};
17
18
19
20
printf("Available commands:\n");
21
for (i = 0; i < SPA_N_ELEMENTS(command_list); i++) {
22
- printf("\t%-20.20s\t%s\n", command_listi.name, command_listi.description);
23
+ char cmd256;
24
+ snprintf(cmd, sizeof(cmd), "%s | %s",
25
+ command_listi.name, command_listi.alias);
26
+ printf("\t%-20.20s\t%s\n", cmd, command_listi.description);
27
}
28
return true;
29
}
30
31
return true;
32
}
33
34
-static const char *
35
-pw_interface_short(const char *type)
36
-{
37
- size_t ilen;
38
-
39
- ilen = strlen(PW_TYPE_INFO_INTERFACE_BASE);
40
-
41
- if (!type || strlen(type) <= ilen ||
42
- memcmp(type, PW_TYPE_INFO_INTERFACE_BASE, ilen))
43
- return NULL;
44
-
45
- return type + ilen;
46
-}
47
-
48
static struct global *
49
obj_global(struct remote_data *rd, uint32_t id)
50
{
51
52
return NULL;
53
}
54
55
-static struct spa_dict *
56
-obj_props(struct remote_data *rd, uint32_t id)
57
-{
58
- struct global *global;
59
-
60
- if (!rd)
61
- return NULL;
62
-
63
- global = obj_global(rd, id);
64
- if (!global)
65
- return NULL;
66
- return global_props(global);
67
-}
68
-
69
static const char *
70
global_lookup(struct global *global, const char *key)
71
{
72
73
return spa_dict_lookup(dict, key);
74
}
75
76
-static const char *
77
-obj_lookup(struct remote_data *rd, uint32_t id, const char *key)
78
-{
79
- struct spa_dict *dict;
80
-
81
- dict = obj_props(rd, id);
82
- if (!dict)
83
- return NULL;
84
- return spa_dict_lookup(dict, key);
85
-}
86
87
static int
88
children_of(struct remote_data *rd, uint32_t parent_id,
89
90
return count;
91
}
92
93
-#ifndef BIT
94
-#define BIT(x) (1U << (x))
95
-#endif
96
-
97
-enum dump_flags {
98
- is_default = 0,
99
- is_short = BIT(0),
100
- is_deep = BIT(1),
101
- is_resolve = BIT(2),
102
- is_notype = BIT(3)
103
-};
104
-
105
-static const char * const dump_types = {
106
- PW_TYPE_INTERFACE_Core,
107
- PW_TYPE_INTERFACE_Module,
108
- PW_TYPE_INTERFACE_Device,
109
- PW_TYPE_INTERFACE_Node,
110
- PW_TYPE_INTERFACE_Port,
111
- PW_TYPE_INTERFACE_Factory,
112
- PW_TYPE_INTERFACE_Client,
113
- PW_TYPE_INTERFACE_Link,
114
- PW_TYPE_INTERFACE_Session,
115
- PW_TYPE_INTERFACE_Endpoint,
116
- PW_TYPE_INTERFACE_EndpointStream,
117
-};
118
-
119
-int dump_type_index(const char *type)
120
-{
121
- unsigned int i;
122
-
123
- if (!type)
124
- return -1;
125
-
126
- for (i = 0; i < SPA_N_ELEMENTS(dump_types); i++) {
127
- if (spa_streq(dump_typesi, type))
128
- return (int)i;
129
- }
130
-
131
- return -1;
132
-}
133
-
134
-static inline unsigned int dump_type_count(void)
135
-{
136
- return SPA_N_ELEMENTS(dump_types);
137
-}
138
-
139
-static const char *name_to_dump_type(const char *name)
140
-{
141
- unsigned int i;
142
-
143
- if (!name)
144
- return NULL;
145
-
146
- for (i = 0; i < SPA_N_ELEMENTS(dump_types); i++) {
147
- if (!strcasecmp(name, pw_interface_short(dump_typesi)))
148
- return dump_typesi;
149
- }
150
-
151
- return NULL;
152
-}
153
-
154
#define INDENT(_level) \
155
({ \
156
int __level = (_level); \
157
158
(const char *)_indent; \
159
})
160
161
-static void
162
-dump(struct data *data, struct global *global,
163
- enum dump_flags flags, int level);
164
-
165
-static void
166
-dump_properties(struct data *data, struct global *global,
167
- enum dump_flags flags, int level)
168
-{
169
- struct remote_data *rd = data->current;
170
- struct spa_dict *props;
171
- const struct spa_dict_item *item;
172
- const char *ind;
173
- int id;
174
- const char *extra;
175
-
176
- if (!global)
177
- return;
178
-
179
- props = global_props(global);
180
- if (!props || !props->n_items)
181
- return;
182
-
183
- ind = INDENT(level + 2);
184
- spa_dict_for_each(item, props) {
185
- printf("%s%s = \"%s\"",
186
- ind, item->key, item->value);
187
-
188
- extra = NULL;
189
- if (spa_streq(global->type, PW_TYPE_INTERFACE_Port) && spa_streq(item->key, PW_KEY_NODE_ID)) {
190
- id = atoi(item->value);
191
- if (id >= 0)
192
- extra = obj_lookup(rd, id, PW_KEY_NODE_NAME);
193
- } else if (spa_streq(global->type, PW_TYPE_INTERFACE_Factory) && spa_streq(item->key, PW_KEY_MODULE_ID)) {
194
- id = atoi(item->value);
195
- if (id >= 0)
196
- extra = obj_lookup(rd, id, PW_KEY_MODULE_NAME);
197
- } else if (spa_streq(global->type, PW_TYPE_INTERFACE_Device) && spa_streq(item->key, PW_KEY_FACTORY_ID)) {
198
- id = atoi(item->value);
199
- if (id >= 0)
200
- extra = obj_lookup(rd, id, PW_KEY_FACTORY_NAME);
201
pipewire-0.3.56.tar.gz/test/test-spa-utils.c -> pipewire-0.3.57.tar.gz/test/test-spa-utils.c
Changed
14
1
2
}
3
pwtest_int_eq(count, 4);
4
pwtest_int_eq(hook_free_count, 4);
5
+
6
+ /* remove a zeroed hook */
7
+ struct spa_hook hook;
8
+ spa_zero(hook);
9
+ spa_hook_remove(&hook);
10
+
11
return PWTEST_PASS;
12
}
13
14