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 17
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Mon Nov 21 11:36:55 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.60
6
+
7
+-------------------------------------------------------------------
8
Sat Oct 15 16:39:17 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.59
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.59
6
+Version: 0.3.60
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.59.tar.gz/.gitlab-ci.yml -> pipewire-0.3.60.tar.gz/.gitlab-ci.yml
Changed
156
1
2
.fedora:
3
variables:
4
# Update this tag when you want to trigger a rebuild
5
- FDO_DISTRIBUTION_TAG: '2022-03-05.0'
6
+ FDO_DISTRIBUTION_TAG: '2022-11-07.0'
7
FDO_DISTRIBUTION_VERSION: '35'
8
FDO_DISTRIBUTION_PACKAGES: >-
9
alsa-lib-devel
10
11
libv4l-devel
12
libva-devel
13
libX11-devel
14
+ ModemManager-devel
15
openssl-devel
16
pulseaudio-libs-devel
17
python3-docutils
18
19
python3-pip
20
pulseaudio-utils
21
openal-soft
22
+ readline-devel
23
FDO_DISTRIBUTION_EXEC: >-
24
pip3 install meson
25
26
27
.alpine:
28
variables:
29
# Update this tag when you want to trigger a rebuild
30
- FDO_DISTRIBUTION_TAG: '2022-01-28.2'
31
+ FDO_DISTRIBUTION_TAG: '2022-09-07.0'
32
FDO_DISTRIBUTION_VERSION: '3.15'
33
FDO_DISTRIBUTION_PACKAGES: >-
34
alsa-lib-dev
35
36
libusb-dev
37
libx11-dev
38
meson
39
+ modemmanager-dev
40
ncurses-dev
41
pulseaudio-dev
42
readline-dev
43
44
- ninja $NINJA_ARGS -C "$BUILD_DIR"
45
- ninja $NINJA_ARGS -C "$BUILD_DIR" test
46
- ninja $NINJA_ARGS -C "$BUILD_DIR" install
47
- - ./check_missing_headers.sh
48
artifacts:
49
name: pipewire-$CI_COMMIT_SHA
50
when: always
51
52
- .fdo.distribution-image@ubuntu
53
- .build
54
stage: build
55
+ variables:
56
+ MESON_OPTIONS: "-Dsession-managers="
57
58
.build_on_fedora:
59
extends:
60
61
-Dvulkan=enabled
62
-Dsdl2=enabled
63
-Dsndfile=enabled
64
+ -Dsession-managers=
65
artifacts:
66
name: pipewire-$CI_COMMIT_SHA
67
when: always
68
69
- .fdo.distribution-image@alpine
70
- .build
71
stage: build
72
+ variables:
73
+ MESON_OPTIONS: "-Dsession-managers="
74
75
# build with all auto() options enabled
76
build_all:
77
78
variables:
79
# Fedora doesn't have libfreeaptx, lc3plus, lc3, or roc
80
# libcamera has no stable API, so let's not chase that target
81
- MESON_OPTIONS: "-Dauto_features=enabled -Dbluez5-codec-aptx=disabled -Dbluez5-codec-lc3plus=disabled -Dbluez5-codec-lc3=disabled -Droc=disabled -Dlibcamera=disabled"
82
+ MESON_OPTIONS: >-
83
+ -Dauto_features=enabled
84
+ -Dbluez5-codec-aptx=disabled
85
+ -Dbluez5-codec-lc3plus=disabled
86
+ -Dbluez5-codec-lc3=disabled
87
+ -Droc=disabled
88
+ -Dlibcamera=disabled
89
+ -Dsession-managers=
90
parallel:
91
matrix:
92
- CC: gcc, clang
93
94
extends:
95
- .build_on_fedora
96
variables:
97
- MESON_OPTIONS: ""
98
+ MESON_OPTIONS: "-Dsession-managers="
99
parallel:
100
matrix:
101
- CC: gcc, clang
102
103
MESON_OPTION_VALUE: enabled, disabled
104
script:
105
- echo "Building with -D$MESON_OPTION=$MESON_OPTION_VALUE"
106
- - meson "$BUILD_DIR" . --prefix="$PREFIX" "-D$MESON_OPTION=$MESON_OPTION_VALUE"
107
+ - meson "$BUILD_DIR" . --prefix="$PREFIX" "-D$MESON_OPTION=$MESON_OPTION_VALUE" -Dsession-managers=
108
- ninja $NINJA_ARGS -C "$BUILD_DIR"
109
- ninja $NINJA_ARGS -C "$BUILD_DIR" test
110
111
112
extends:
113
- .build_on_fedora
114
variables:
115
- MESON_OPTIONS: "-Dtest=enabled -Dbuildtype=release -Db_ndebug=true"
116
+ MESON_OPTIONS: "-Dtest=enabled -Dbuildtype=release -Db_ndebug=true -Dsession-managers="
117
parallel:
118
matrix:
119
- CC: gcc, clang
120
121
- echo "Building with meson options $MESON_OPTIONS"
122
- meson "$BUILD_DIR" . --prefix="$PREFIX" $MESON_OPTIONS
123
- meson test -C "$BUILD_DIR" --setup=valgrind
124
+ variables:
125
+ MESON_OPTIONS: "-Dsession-managers="
126
127
build_with_coverity:
128
extends:
129
130
-Dvulkan=enabled
131
-Dsdl2=enabled
132
-Dsndfile=enabled
133
+ -Dsession-managers=
134
- cov-configure --config coverity_conf.xml
135
--comptype gcc --compiler cc --template
136
--xml-option=append_arg@C:--ppp_translator
137
138
git grep -q -e "\\\subpage $page" || (echo "\\page $page is missing \\subpage entry in doc/pipewire-modules.dox" && false)
139
done
140
141
+check_missing_headers:
142
+ extends:
143
+ - .fedora
144
+ - .not_coverity
145
+ - .fdo.distribution-image@fedora
146
+ stage: analysis
147
+ dependencies:
148
+ - build_on_fedora
149
+ script:
150
+ - export PREFIX=`find -name prefix-*`
151
+ - ./.gitlab/ci/check_missing_headers.sh
152
+
153
pages:
154
extends:
155
- .not_coverity
156
pipewire-0.3.60.tar.gz/.gitlab/ci
Added
2
1
+(directory)
2
pipewire-0.3.60.tar.gz/.gitlab/ci/check_missing_headers.sh
Changed
2
1
(renamed from check_missing_headers.sh)
2
pipewire-0.3.59.tar.gz/NEWS -> pipewire-0.3.60.tar.gz/NEWS
Changed
163
1
2
+# PipeWire 0.3.60 (2022-11-10)
3
+
4
+This is a bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+ - The filter-chain now handles errors better and has fixes for many
9
+ crasher bugs.
10
+ - A new RTP module was added with a sender and receiver. It uses SAP
11
+ to announce and consume RTP streams and is compatible with the
12
+ PulseAudio RTP modules.
13
+ - Many small bluetooth improvements and fixes.
14
+ - The alsa plugin will now only start playback when there is data. This
15
+ results in better sync and lower latency between capture and playback.
16
+ - The v4l2 and libcamera plugins have seen a lot of improvements. They
17
+ support control properties now. Also pw-v4l2 has seen many improvements
18
+ and mostly passes the v4l2-compliance test now.
19
+ - Many more bugfixes and improvements.
20
+
21
+
22
+## PipeWire
23
+ - Code cleanups, compiler warning fixes.
24
+ - Add some extra checks to avoid scheduling an inactive node.
25
+ - Rework the sequence of events to start and stop nodes.
26
+ - Improve param enumeration.
27
+ - An option was added to give priority to the Buffer params of the
28
+ consumer. This makes it possible to use the default values of the
29
+ consumer (instead of the producer) when capturing from a source.
30
+ - The graph rate selection was improved to pick a rate closest to the
31
+ requested one (instead of picking the default).
32
+
33
+## Modules
34
+ - Fix some crashes in filter-chain. (#2737)
35
+ - X11 Bell module will now be loaded by default when available.
36
+ - A new RTP module was added with a sender and receiver. It uses SAP
37
+ to announce and consume RTP streams and is compatible with the
38
+ PulseAudio RTP modules.
39
+ - Improve RAOP compatibility.
40
+ - The echo-cancel module now uses the resampler prefill option to align
41
+ input and output samples without buffering. Better latency control
42
+ when starting and stopping has been implemented.
43
+ - The pulse tunnel will now write aligned samples to pulseaudio even
44
+ when the ringbuffer wraps around. This fixes playback issues with
45
+ multichannel sinks.
46
+ - Add a delay option to module-loopback using a ringbuffer.
47
+ - Implement echo-cancel params.
48
+ - The filter-chain module has better error reporting.
49
+ - The LADSPA search path was extended with some more common paths.
50
+ - The echo-canceler input can now also be a monitor of a sink. This
51
+ improves compatibility with some proton games that expect a real
52
+ sink instead of a virtual one.
53
+
54
+## Tools
55
+ - Better error reporting in pw-link.
56
+ - pw-top now also shows IEC958 passthrough formats and JPEG/H264 video
57
+ formats.
58
+ - pw-top refreshes the screen faster.
59
+ - pw-top now prints the state of the node and shows less info for
60
+ inactive nodes.
61
+ - pw-dump now uses the new seq field in the spa_param_info to discard
62
+ old param updates and avoid duplicate params in the output.
63
+
64
+## Bluetooth
65
+ - Add ModemManager support in the native backend.
66
+ - Clean up GetManagedObjects handling.
67
+ - Handle QoS from the endpoints in the codec.
68
+ - Increase the socket buffer to have more control over the rate and QoS.
69
+ - Simplify the packet flushing code.
70
+ - Stop processing nodes before destroying them.
71
+ - Fix timers when a source switches drivers.
72
+ - Codecs can now share endpoints. This reduces the amount of endpoints and
73
+ avoids problems with devices that can't handle a large amount of
74
+ codec endpoints.
75
+ - Report batery status to UPower for HFP AG.
76
+ - Fix bitpool increase.
77
+
78
+## SPA
79
+ - The audioresampler now avoids clicks and pops between activating and
80
+ deactivating the adaptive resampler when used by the stream API.
81
+ - Use default locale to parse float parameters.
82
+ - The upmix functions now have SSE optimizations.
83
+ - Avoid recalculating the complete channelmix setup when only the
84
+ volume changes.
85
+ - The alsa plugin will now only start playback when there is data. This
86
+ results in better sync and lower latency between capture and playback.
87
+ - The ALSA MIDI sequencer will now pull data from the graph even when it
88
+ did not output anything. Fixes some graph stalls with the sequencer in
89
+ some cases. (#2775)
90
+ - v4l2 and libcamera sources now recycle buffers when nothing is consuming
91
+ them. This avoids stalling the graph.
92
+ - libcamera now suggests a more appropriate frame size than the smallest
93
+ poster frame.
94
+ - Improve state changes in audioconvert. (#2764)
95
+ - A new seq field was added to spa_param_info to keep track of pending
96
+ param updates.
97
+ - Support speaker output only on RealTek ALC4080. (#2744)
98
+ - The v4l2 source now supports setting controls.
99
+ - The libcamera plugin now supports enumerating and setting controls.
100
+ - A new unit test for 6.1 channel mapping was added. (#2809) More debug
101
+ info was added to audioconvert for the channel matrix.
102
+ - Audioconvert will now also upmix a rear-center channel when needed.
103
+
104
+## pulse-server
105
+ - Add support for the RTP send and recv modules with the new native
106
+ RTP module.
107
+ - Add option to set latency for pulse-tunnel streams and
108
+ module-zeroconf-discover.
109
+ - The socket will now be given the same permissions as what pulseaudio
110
+ did (0777).
111
+ - Implement module-loopback latency_msec correctly with the new delay
112
+ parameter.
113
+ - sysfs.path is now filled with the same data as pulseaudio.
114
+ - The manager now uses the new seq field in the spa_param_info.
115
+ - Fix a bug where in some cases the read pointer would get out of sync
116
+ and cause too large requests. (#2799)
117
+
118
+## ALSA
119
+ - The alsa plugin now reuses the stream in prepare which results in
120
+ better performance.
121
+ - Some deadlocks have been fixed in the ALSA plugin.
122
+ - The ALSA plugin reports more accurate timing information in some cases.
123
+
124
+## V4l2
125
+ - The v4l2 compatibility layer has received a lot of updates.
126
+ - Improved node names and format enumeration.
127
+ - Support for multiple /dev/videoX devices, each mapped to a unique
128
+ PipeWire node.
129
+ - Passes the v4l2-compliance test now with both the v4l2 and libcamera
130
+ backend in PipeWire.
131
+ - Improved mmap support for inline buffer memory. This makes it possible to
132
+ consume PipeWire streams.
133
+ - Negotiation works more reliably now.
134
+
135
+## JACK
136
+ - Implement jack_acquire_real_time_scheduling() and
137
+ jack_drop_real_time_scheduling() by keeping the thread utils in a global
138
+ state.
139
+ - Fix jack_client_thread_id() to return NULL when the client is not active,
140
+ just like jack1 and jack2.
141
+ - An option was added to let the jack_set_buffer_size() function update the
142
+ global metadata. A quirk was added so that jack_bufsize uses this new feature
143
+ to make the buffer size settings persistent and global, just like jack.
144
+ - jack_port_register() and jack_port_unregister() can be called on an
145
+ active client so make this thread safe. (#2652)
146
+
147
+
148
+Older versions:
149
+
150
# PipeWire 0.3.59 (2022-09-30)
151
152
This is a bugfix release that is API and ABI compatible with previous
153
154
- PIPEWIRE_ALSA can now be used as an environment variable to restrict the
155
plugin formats and buffer size.
156
157
-Older versions:
158
-
159
-
160
# PipeWire 0.3.58 (2022-09-15)
161
162
This is a bugfix release that is API and ABI compatible with previous
163
pipewire-0.3.59.tar.gz/doc/pipewire-modules.dox -> pipewire-0.3.60.tar.gz/doc/pipewire-modules.dox
Changed
10
1
2
- \subpage page_module_raop_discover
3
- \subpage page_module_roc_sink
4
- \subpage page_module_roc_source
5
+- \subpage page_module_rtp_sink
6
+- \subpage page_module_rtp_source
7
- \subpage page_module_rt
8
- \subpage page_module_session_manager
9
- \subpage page_module_x11_bell
10
pipewire-0.3.59.tar.gz/man/pw-top.1.rst.in -> pipewire-0.3.60.tar.gz/man/pw-top.1.rst.in
Changed
31
1
2
The columns presented are as follows:
3
4
S
5
- Measurement status.
6
- ! representing inactive - no connections
7
-
8
- Blank representing active
9
+ Node status.
10
+ E = ERROR
11
+ C = CREATING
12
+ S = SUSPENDED
13
+ I = IDLE
14
+ R = RUNNING
15
16
ID
17
- The ID of the pipewire node/device, as found in *pw-dump*
18
+ The ID of the pipewire node/device, as found in *pw-dump* and *pw-cli*
19
20
QUANT
21
The current quantum (for drivers) and the suggested quantum for follower
22
23
24
For raw audio formats, the layout is <sampleformat> <channels> <samplerate>.
25
26
+ For IEC958 passthrough audio formats, the layout is IEC958 <codec> <samplerate>.
27
+
28
For DSD formats, the layout is <dsd-rate> <channels>.
29
30
For Video formats, the layout is <pixelformat> <width>x<height>.
31
pipewire-0.3.59.tar.gz/meson.build -> pipewire-0.3.60.tar.gz/meson.build
Changed
38
1
2
project('pipewire', 'c' ,
3
- version : '0.3.59',
4
+ version : '0.3.60',
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
10
common_flags =
11
'-fvisibility=hidden',
12
+ '-fno-strict-aliasing',
13
'-Werror=suggest-attribute=format',
14
'-Wsign-compare',
15
'-Wpointer-arith',
16
17
18
if have_cpp
19
cxx = meson.get_compiler('cpp')
20
- cxx_flags = common_flags
21
+ cxx_flags = common_flags + '-Wno-c99-designator'
22
add_project_arguments(cxx.get_supported_arguments(cxx_flags), language: 'cpp')
23
endif
24
25
26
sdl_dep = dependency('sdl2', required : get_option('sdl2'))
27
summary({'SDL2 (video examples)': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies')
28
drm_dep = dependency('libdrm', required : false)
29
-readline_dep = dependency('readline', required : false)
30
+readline_dep = dependency('readline', required : get_option('readline'))
31
32
if not readline_dep.found()
33
- readline_dep = cc.find_library('readline', required: false)
34
+ readline_dep = cc.find_library('readline', required : get_option('readline'))
35
endif
36
37
summary({'readline (for pw-cli)': readline_dep.found()}, bool_yn: true, section: 'Misc dependencies')
38
pipewire-0.3.59.tar.gz/meson_options.txt -> pipewire-0.3.60.tar.gz/meson_options.txt
Changed
29
1
2
description: 'Enable HFP in native backend in bluez5 spa plugin',
3
type: 'feature',
4
value: 'enabled')
5
+option('bluez5-backend-native-mm',
6
+ description: 'Enable ModemManager in native backend in bluez5 spa plugin',
7
+ type: 'feature',
8
+ value: 'disabled')
9
option('bluez5-backend-ofono',
10
description: 'Enable oFono HFP backend in bluez5 spa plugin (no dependency on oFono)',
11
type: 'feature',
12
13
option('session-managers',
14
description : 'Session managers to build (can be for none or an absolute path)',
15
type : 'array',
16
- value : 'media-session')
17
+ value : 'wireplumber')
18
option('raop',
19
description: 'Enable module for Remote Audio Output Protocol',
20
type: 'feature',
21
22
description: 'Enable Flatpak support',
23
type: 'feature',
24
value: 'enabled')
25
+option('readline',
26
+ description: 'Enable code that depends on libreadline',
27
+ type: 'feature',
28
+ value: 'auto')
29
pipewire-0.3.59.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.60.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
143
1
2
struct spa_hook stream_listener;
3
4
int64_t delay;
5
- uint64_t now;
6
+ uint64_t transfered;
7
+ uint64_t buffered;
8
+ int64_t now;
9
uintptr_t seq;
10
11
struct spa_audio_info_raw format;
12
13
static int update_active(snd_pcm_ioplug_t *io)
14
{
15
snd_pcm_pipewire_t *pw = io->private_data;
16
- bool active;
17
-
18
- active = check_active(io);
19
-
20
- if (pw->active != active) {
21
- uint64_t val;
22
+ pw->active = check_active(io);
23
+ uint64_t val;
24
25
- pw->active = active;
26
+ if (pw->active || pw->error < 0)
27
+ spa_system_eventfd_write(pw->system, io->poll_fd, 1);
28
+ else
29
+ spa_system_eventfd_read(pw->system, io->poll_fd, &val);
30
31
- if (active)
32
- spa_system_eventfd_write(pw->system, io->poll_fd, 1);
33
- else
34
- spa_system_eventfd_read(pw->system, io->poll_fd, &val);
35
- }
36
- return active;
37
+ return pw->active;
38
}
39
40
static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw)
41
42
return pw->error;
43
44
*revents = pfds0.revents & ~(POLLIN | POLLOUT);
45
- if (pfds0.revents & POLLIN && check_active(io))
46
+ if (pfds0.revents & POLLIN && check_active(io)) {
47
*revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN;
48
+ update_active(io);
49
+ }
50
51
return 0;
52
}
53
54
do {
55
seq1 = SEQ_READ(pw->seq);
56
57
- delay = pw->delay;
58
+ delay = pw->delay + pw->transfered;
59
now = pw->now;
60
if (io->stream == SND_PCM_STREAM_PLAYBACK)
61
avail = snd_pcm_ioplug_hw_avail(io, pw->hw_ptr, io->appl_ptr);
62
63
pw_stream_get_time_n(pw->stream, &pwt, sizeof(pwt));
64
65
delay = pwt.delay;
66
- if (pwt.rate.num != 0) {
67
+ if (pwt.rate.num != 0)
68
delay = delay * io->rate * pwt.rate.num / pwt.rate.denom;
69
- }
70
71
before = hw_avail = snd_pcm_ioplug_hw_avail(io, pw->hw_ptr, io->appl_ptr);
72
73
74
75
SEQ_WRITE(pw->seq);
76
77
+ if (pw->now != pwt.now) {
78
+ pw->transfered = pw->buffered;
79
+ pw->buffered = 0;
80
+ }
81
+
82
xfer = snd_pcm_pipewire_process(pw, b, &hw_avail, want);
83
84
pw->delay = delay;
85
/* the buffer is now queued in the stream and consumed */
86
if (io->stream == SND_PCM_STREAM_PLAYBACK)
87
- pw->delay += xfer;
88
+ pw->transfered += xfer;
89
+
90
+ /* more then requested data transfered, use them in next iteration */
91
+ pw->buffered = (want == 0 || pw->transfered < want) ? 0 : (pw->transfered % want);
92
93
pw->now = pwt.now;
94
SEQ_WRITE(pw->seq);
95
96
goto done;
97
pw->hw_params_changed = false;
98
99
- if (pw->stream != NULL) {
100
- pw_stream_destroy(pw->stream);
101
- pw->stream = NULL;
102
- }
103
-
104
props = pw_properties_new(NULL, NULL);
105
if (props == NULL)
106
goto error;
107
108
pw_properties_get(props, PW_KEY_MEDIA_ROLE) == NULL)
109
pw_properties_setf(props, PW_KEY_MEDIA_ROLE, "%s", pw->role);
110
111
+ params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &pw->format);
112
+
113
+ if (pw->stream != NULL) {
114
+ pw_stream_update_properties(pw->stream, &props->dict);
115
+ pw_stream_update_params(pw->stream, params, 1);
116
+ goto done;
117
+ }
118
+
119
pw->stream = pw_stream_new(pw->core, pw->node_name, props);
120
if (pw->stream == NULL)
121
goto error;
122
123
pw_stream_add_listener(pw->stream, &pw->stream_listener, &stream_events, pw);
124
125
- params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &pw->format);
126
pw->error = 0;
127
128
pw_stream_connect(pw->stream,
129
130
131
static enum snd_pcm_chmap_position channel_to_chmap(enum spa_audio_channel channel)
132
{
133
- uint32_t i;
134
- for (i = 0; i < SPA_N_ELEMENTS(chmap_info); i++)
135
- if (chmap_infoi.channel == channel)
136
- return chmap_infoi.pos;
137
+ SPA_FOR_EACH_ELEMENT_VAR(chmap_info, info)
138
+ if (info->channel == channel)
139
+ return info->pos;
140
return SND_CHMAP_UNKNOWN;
141
}
142
143
pipewire-0.3.59.tar.gz/pipewire-jack/jack/uuid.h -> pipewire-0.3.60.tar.gz/pipewire-jack/jack/uuid.h
Changed
33
1
2
/*
3
Copyright (C) 2013 Paul Davis
4
-
5
+
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU Lesser General Public License as published by
8
the Free Software Foundation; either version 2.1 of the License, or
9
(at your option) any later version.
10
-
11
+
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU Lesser General Public License for more details.
16
-
17
+
18
You should have received a copy of the GNU Lesser General Public License
19
- along with this program; if not, write to the Free Software
20
+ along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23
*/
24
25
#define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */
26
#define JACK_UUID_EMPTY_INITIALIZER 0
27
28
-extern jack_uuid_t jack_client_uuid_generate ();
29
+extern jack_uuid_t jack_client_uuid_generate (void);
30
extern jack_uuid_t jack_port_uuid_generate (uint32_t port_id);
31
32
extern uint32_t jack_uuid_to_index (jack_uuid_t);
33
pipewire-0.3.59.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.60.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
201
1
2
pthread_mutex_t lock;
3
struct pw_array descriptions;
4
struct spa_list free_objects;
5
+ struct spa_thread_utils *thread_utils;
6
};
7
8
static struct globals globals;
9
10
struct spa_hook proxy_listener;
11
12
struct metadata *metadata;
13
+ struct metadata *settings;
14
15
uint32_t node_id;
16
uint32_t serial;
17
18
int self_connect_mode;
19
int rt_max;
20
unsigned int fix_midi_events:1;
21
+ unsigned int global_buffer_size:1;
22
23
jack_position_t jack_position;
24
jack_transport_state_t jack_state;
25
26
{
27
struct mix *m;
28
29
- if (!p->valid)
30
- return;
31
-
32
spa_list_consume(m, &p->mix, port_link)
33
free_mix(c, m);
34
35
- p->valid = false;
36
pw_map_remove(&c->portsp->direction, p->port_id);
37
free_object(c, p->object);
38
pw_properties_free(p->props);
39
40
struct buffer *b;
41
struct spa_data *d;
42
43
- if (frames == 0)
44
+ if (frames == 0 || !p->valid)
45
return NULL;
46
47
if (SPA_UNLIKELY((mix = p->global_mix) == NULL))
48
49
return spa_thread_utils_acquire_rt(c->context.old_thread_utils, thread, priority);
50
}
51
52
+static int impl_drop_rt(void *object, struct spa_thread *thread)
53
+{
54
+ struct client *c = (struct client *) object;
55
+ return spa_thread_utils_drop_rt(c->context.old_thread_utils, thread);
56
+}
57
+
58
static struct spa_thread_utils_methods thread_utils_impl = {
59
SPA_VERSION_THREAD_UTILS_METHODS,
60
.create = impl_create,
61
.join = impl_join,
62
.acquire_rt = impl_acquire_rt,
63
+ .drop_rt = impl_drop_rt,
64
};
65
66
static jack_port_type_id_t string_to_type(const char *port_type)
67
68
.destroy = metadata_proxy_destroy,
69
};
70
71
+static void settings_proxy_removed(void *data)
72
+{
73
+ struct client *c = data;
74
+ pw_proxy_destroy((struct pw_proxy*)c->settings->proxy);
75
+}
76
+
77
+static void settings_proxy_destroy(void *data)
78
+{
79
+ struct client *c = data;
80
+ spa_hook_remove(&c->settings->proxy_listener);
81
+ c->settings = NULL;
82
+}
83
+
84
+static const struct pw_proxy_events settings_proxy_events = {
85
+ PW_VERSION_PROXY_EVENTS,
86
+ .removed = settings_proxy_removed,
87
+ .destroy = settings_proxy_destroy,
88
+};
89
static void proxy_removed(void *data)
90
{
91
struct object *o = data;
92
93
94
if (c->metadata != NULL)
95
goto exit;
96
- if ((str = spa_dict_lookup(props, PW_KEY_METADATA_NAME)) != NULL &&
97
- !spa_streq(str, "default"))
98
+ if ((str = spa_dict_lookup(props, PW_KEY_METADATA_NAME)) == NULL)
99
goto exit;
100
101
- proxy = pw_registry_bind(c->registry,
102
- id, type, PW_VERSION_METADATA, sizeof(struct metadata));
103
-
104
- c->metadata = pw_proxy_get_user_data(proxy);
105
- c->metadata->proxy = (struct pw_metadata*)proxy;
106
- c->metadata->default_audio_sink0 = '\0';
107
- c->metadata->default_audio_source0 = '\0';
108
-
109
- pw_proxy_add_listener(proxy,
110
- &c->metadata->proxy_listener,
111
- &metadata_proxy_events, c);
112
- pw_metadata_add_listener(proxy,
113
- &c->metadata->listener,
114
- &metadata_events, c);
115
+ if (spa_streq(str, "default")) {
116
+ proxy = pw_registry_bind(c->registry,
117
+ id, type, PW_VERSION_METADATA, sizeof(struct metadata));
118
+
119
+ c->metadata = pw_proxy_get_user_data(proxy);
120
+ c->metadata->proxy = (struct pw_metadata*)proxy;
121
+ c->metadata->default_audio_sink0 = '\0';
122
+ c->metadata->default_audio_source0 = '\0';
123
+
124
+ pw_proxy_add_listener(proxy,
125
+ &c->metadata->proxy_listener,
126
+ &metadata_proxy_events, c);
127
+ pw_metadata_add_listener(proxy,
128
+ &c->metadata->listener,
129
+ &metadata_events, c);
130
+ } else if (spa_streq(str, "settings")) {
131
+ proxy = pw_registry_bind(c->registry,
132
+ id, type, PW_VERSION_METADATA, sizeof(struct metadata));
133
+
134
+ c->settings = pw_proxy_get_user_data(proxy);
135
+ c->settings->proxy = (struct pw_metadata*)proxy;
136
+ pw_proxy_add_listener(proxy,
137
+ &c->settings->proxy_listener,
138
+ &settings_proxy_events, c);
139
+ }
140
goto exit;
141
}
142
else {
143
144
if (client->context.old_thread_utils == NULL)
145
client->context.old_thread_utils = pw_thread_utils_get();
146
147
+ globals.thread_utils = client->context.old_thread_utils;
148
+
149
client->context.thread_utils.iface = SPA_INTERFACE_INIT(
150
SPA_TYPE_INTERFACE_ThreadUtils,
151
SPA_VERSION_THREAD_UTILS,
152
153
client->locked_process = pw_properties_get_bool(client->props, "jack.locked-process", true);
154
client->default_as_system = pw_properties_get_bool(client->props, "jack.default-as-system", false);
155
client->fix_midi_events = pw_properties_get_bool(client->props, "jack.fix-midi-events", true);
156
+ client->global_buffer_size = pw_properties_get_bool(client->props, "jack.global-buffer-size", false);
157
158
client->self_connect_mode = SELF_CONNECT_ALLOW;
159
if ((str = pw_properties_get(client->props, "jack.self-connect-mode")) != NULL) {
160
161
pw_proxy_destroy((struct pw_proxy*)c->registry);
162
}
163
if (c->metadata && c->metadata->proxy) {
164
- spa_hook_remove(&c->metadata->listener);
165
- spa_hook_remove(&c->metadata->proxy_listener);
166
pw_proxy_destroy((struct pw_proxy*)c->metadata->proxy);
167
}
168
+ if (c->settings && c->settings->proxy) {
169
+ pw_proxy_destroy((struct pw_proxy*)c->settings->proxy);
170
+ }
171
172
if (c->core) {
173
spa_hook_remove(&c->core_listener);
174
175
jack_native_thread_t jack_client_thread_id (jack_client_t *client)
176
{
177
struct client *c = (struct client *) client;
178
- void *thr;
179
180
spa_return_val_if_fail(c != NULL, (pthread_t){0});
181
182
- thr = pw_data_loop_get_thread(c->loop);
183
- if (thr == NULL)
184
- return pthread_self();
185
- return (pthread_t) thr;
186
+ return (jack_native_thread_t)pw_data_loop_get_thread(c->loop);
187
}
188
189
SPA_EXPORT
190
191
pw_log_info("%p: buffer-size %u", client, nframes);
192
193
pw_thread_loop_lock(c->context.loop);
194
- pw_properties_setf(c->props, PW_KEY_NODE_FORCE_QUANTUM, "%u", nframes);
195
+ if (c->global_buffer_size && c->settings && c->settings->proxy) {
196
+ char val256;
197
+ snprintf(val, sizeof(val), "%u", nframes == 1 ? 0: nframes);
198
+ pw_metadata_set_property(c->settings->proxy, 0,
199
+ "clock.force-quantum", "", val);
200
+ } else {
201
pipewire-0.3.59.tar.gz/pipewire-jack/src/uuid.c -> pipewire-0.3.60.tar.gz/pipewire-jack/src/uuid.c
Changed
10
1
2
#include <pipewire/pipewire.h>
3
4
SPA_EXPORT
5
-jack_uuid_t jack_client_uuid_generate ()
6
+jack_uuid_t jack_client_uuid_generate (void)
7
{
8
static uint32_t uuid_cnt = 0;
9
jack_uuid_t uuid = 0x2; /* JackUUIDClient */;
10
pipewire-0.3.59.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c -> pipewire-0.3.60.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c
Changed
201
1
2
#define DEFAULT_CARD "PipeWire Camera"
3
#define DEFAULT_BUS_INFO "PipeWire"
4
5
+#define MAX_DEV 32
6
struct file_map {
7
void *addr;
8
struct file *file;
9
10
11
struct fd_map {
12
int fd;
13
+#define FD_MAP_DUP (1<<0)
14
+ uint32_t flags;
15
struct file *file;
16
};
17
18
19
pthread_mutex_t lock;
20
struct pw_array fd_maps;
21
struct pw_array file_maps;
22
+ uint32_t dev_mapMAX_DEV;
23
};
24
25
static struct globals globals;
26
27
struct file {
28
int ref;
29
30
+ uint32_t dev_id;
31
+ uint32_t serial;
32
+
33
struct pw_properties *props;
34
struct pw_thread_loop *loop;
35
struct pw_loop *l;
36
37
struct pw_stream *stream;
38
struct spa_hook stream_listener;
39
40
+ enum v4l2_priority priority;
41
+
42
struct v4l2_format v4l2_format;
43
uint32_t reqbufs;
44
45
+ int reqbufs_fd;
46
struct buffer buffersMAX_BUFFERS;
47
uint32_t n_buffers;
48
uint32_t size;
49
50
+ uint32_t sequence;
51
+
52
struct pw_array buffer_maps;
53
54
uint32_t last_fourcc;
55
56
unsigned int running:1;
57
+ unsigned int closed:1;
58
int fd;
59
};
60
61
-#define MAX_PARAMS 32
62
-
63
struct global_info {
64
const char *type;
65
uint32_t version;
66
67
68
int changed;
69
void *info;
70
+ struct spa_list pending_list;
71
struct spa_list param_list;
72
- int param_seqMAX_PARAMS;
73
74
union {
75
struct {
76
77
struct param {
78
struct spa_list link;
79
uint32_t id;
80
+ int32_t seq;
81
struct spa_pod *param;
82
};
83
84
85
}
86
87
static struct param *add_param(struct spa_list *params,
88
- int seq, int *param_seq, uint32_t id, const struct spa_pod *param)
89
+ int seq, uint32_t id, const struct spa_pod *param)
90
{
91
struct param *p;
92
93
94
id = SPA_POD_OBJECT_ID(param);
95
}
96
97
- if (id >= MAX_PARAMS) {
98
- pw_log_error("too big param id %d", id);
99
- errno = EINVAL;
100
- return NULL;
101
- }
102
-
103
- if (seq != param_seqid) {
104
- pw_log_debug("ignoring param %d, seq:%d != current_seq:%d",
105
- id, seq, param_seqid);
106
- errno = EBUSY;
107
- return NULL;
108
- }
109
-
110
p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0));
111
if (p == NULL)
112
return NULL;
113
114
p->id = id;
115
+ p->seq = seq;
116
if (param != NULL) {
117
p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod);
118
memcpy(p->param, param, SPA_POD_SIZE(param));
119
120
return p;
121
}
122
123
+static void update_params(struct file *file)
124
+{
125
+ struct param *p, *t;
126
+ struct global *node;
127
+ struct pw_node_info *info;
128
+ uint32_t i;
129
+
130
+ if ((node = file->node) == NULL)
131
+ return;
132
+ if ((info = node->info) == NULL)
133
+ return;
134
+
135
+ for (i = 0; i < info->n_params; i++) {
136
+ spa_list_for_each_safe(p, t, &node->pending_list, link) {
137
+ if (p->id == info->paramsi.id &&
138
+ p->seq != info->paramsi.seq &&
139
+ p->param != NULL) {
140
+ spa_list_remove(&p->link);
141
+ free(p);
142
+ }
143
+ }
144
+ }
145
+
146
+ spa_list_consume(p, &node->pending_list, link) {
147
+ spa_list_remove(&p->link);
148
+ if (p->param == NULL) {
149
+ clear_params(&node->param_list, p->id);
150
+ free(p);
151
+ } else {
152
+ spa_list_append(&node->param_list, &p->link);
153
+ }
154
+ }
155
+}
156
#define ATOMIC_DEC(s) __atomic_sub_fetch(&(s), 1, __ATOMIC_SEQ_CST)
157
#define ATOMIC_INC(s) __atomic_add_fetch(&(s), 1, __ATOMIC_SEQ_CST)
158
159
160
161
file->ref = 1;
162
file->fd = -1;
163
+ file->reqbufs_fd = -1;
164
+ file->priority = V4L2_PRIORITY_DEFAULT;
165
spa_list_init(&file->globals);
166
pw_array_init(&file->buffer_maps, sizeof(struct buffer_map) * MAX_BUFFERS);
167
return file;
168
169
170
static void free_file(struct file *file)
171
{
172
+ pw_log_info("file:%d", file->fd);
173
+
174
if (file->loop)
175
pw_thread_loop_stop(file->loop);
176
177
178
179
static void unref_file(struct file *file)
180
{
181
+ pw_log_debug("file:%d ref:%d", file->fd, file->ref);
182
if (ATOMIC_DEC(file->ref) <= 0)
183
free_file(file);
184
}
185
186
-static int add_fd_map(int fd, struct file *file)
187
+static int add_fd_map(int fd, struct file *file, uint32_t flags)
188
{
189
struct fd_map *map;
190
pthread_mutex_lock(&globals.lock);
191
map = pw_array_add(&globals.fd_maps, sizeof(*map));
192
if (map != NULL) {
193
map->fd = fd;
194
+ map->flags = flags;
195
map->file = file;
196
ATOMIC_INC(file->ref);
197
+ pw_log_debug("fd:%d -> file:%d ref:%d", fd, file->fd, file->ref);
198
}
199
pthread_mutex_unlock(&globals.lock);
200
return 0;
201
pipewire-0.3.59.tar.gz/pipewire-v4l2/src/pw-v4l2.in -> pipewire-0.3.60.tar.gz/pipewire-v4l2/src/pw-v4l2.in
Changed
20
1
2
3
shift $(( OPTIND - 1 ))
4
5
+if "$PW_UNINSTALLED" = 1 ; then
6
+ PW_V4L2_LD_PRELOAD="$PW_BUILDDIR"'/pipewire-v4l2/src/libpw-v4l2.so'
7
+else
8
+ PW_V4L2_LD_PRELOAD='@LIBV4L2_PATH@/libpw-v4l2.so'
9
+fi
10
+
11
if "$LD_PRELOAD" = "" ; then
12
- LD_PRELOAD='@LIBV4L2_PATH@/libpw-v4l2.so'
13
+ LD_PRELOAD="$PW_V4L2_LD_PRELOAD"
14
else
15
- LD_PRELOAD="$LD_PRELOAD "'@LIBV4L2_PATH@/libpw-v4l2.so'
16
+ LD_PRELOAD="$LD_PRELOAD $PW_V4L2_LD_PRELOAD"
17
fi
18
19
export LD_PRELOAD
20
pipewire-0.3.59.tar.gz/po/cs.po -> pipewire-0.3.60.tar.gz/po/cs.po
Changed
201
1
2
msgid ""
3
msgstr ""
4
"Project-Id-Version: pipewire.master-tx\n"
5
-"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
6
-"issues/new\n"
7
-"POT-Creation-Date: 2021-04-18 16:54+0800\n"
8
-"PO-Revision-Date: 2021-10-12 14:18+0200\n"
9
+"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
10
+"issues\n"
11
+"POT-Creation-Date: 2022-09-15 15:26+0000\n"
12
+"PO-Revision-Date: 2022-10-21 16:44+0200\n"
13
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
14
"Language-Team: čeština <gnome-cs-list@gnome.org>\n"
15
"Language: cs\n"
16
17
"Content-Type: text/plain; charset=UTF-8\n"
18
"Content-Transfer-Encoding: 8bit\n"
19
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
20
-"X-Generator: Poedit 3.0\n"
21
+"X-Generator: Poedit 3.1.1\n"
22
23
-#: src/daemon/pipewire.c:43
24
+#: src/daemon/pipewire.c:46
25
#, c-format
26
msgid ""
27
"%s options\n"
28
29
msgid "Start the PipeWire Media System"
30
msgstr "Spustit multimediální systém PipeWire"
31
32
-#: src/examples/media-session/alsa-monitor.c:526
33
-#: spa/plugins/alsa/acp/compat.c:187
34
-msgid "Built-in Audio"
35
-msgstr "Vnitřní zvukový systém"
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 "Tunel do %s/%s"
41
42
-#: src/examples/media-session/alsa-monitor.c:530
43
-#: spa/plugins/alsa/acp/compat.c:192
44
-msgid "Modem"
45
-msgstr "Modem"
46
+#: src/modules/module-fallback-sink.c:51
47
+#| msgid "Game Output"
48
+msgid "Dummy Output"
49
+msgstr "Předstíraný výstup"
50
51
-#: src/examples/media-session/alsa-monitor.c:539
52
+#: src/modules/module-pulse-tunnel.c:662
53
+#, c-format
54
+msgid "Tunnel for %s@%s"
55
+msgstr "Tunel pro %s@%s"
56
+
57
+#: src/modules/module-zeroconf-discover.c:332
58
msgid "Unknown device"
59
msgstr "Neznámé zařízení"
60
61
-#: src/tools/pw-cat.c:991
62
+#: src/modules/module-zeroconf-discover.c:344
63
+#, c-format
64
+msgid "%s on %s@%s"
65
+msgstr "%s na %s@%s"
66
+
67
+#: src/modules/module-zeroconf-discover.c:348
68
+#, c-format
69
+msgid "%s on %s"
70
+msgstr "%s na %s"
71
+
72
+#: src/tools/pw-cat.c:784
73
#, c-format
74
msgid ""
75
-"%s options <file>\n"
76
+"%s options <file>|-\n"
77
" -h, --help Show this help\n"
78
" --version Show version\n"
79
" -v, --verbose Enable verbose operations\n"
80
"\n"
81
msgstr ""
82
-"%s volby <soubor>\n"
83
+"%s volby <soubor>|-\n"
84
" -h, --help Zobrazit tuto nápovědu\n"
85
" --version Zobrazit verzi\n"
86
" -v, --verbose Povolit podrobné operace\n"
87
"\n"
88
89
-#: src/tools/pw-cat.c:998
90
+#: src/tools/pw-cat.c:791
91
#, c-format
92
msgid ""
93
" -R, --remote Remote daemon name\n"
94
95
" or direct samples (256)\n"
96
" the rate is the one of the source "
97
"file\n"
98
-" --list-targets List available targets for --target\n"
99
+" -P --properties Set node properties\n"
100
"\n"
101
msgstr ""
102
" -R, --remote Název vzdáleného démonu\n"
103
104
" nebo přímé vzorky (256)\n"
105
" frekvence je stejná jako u "
106
"zdrojového souboru\n"
107
-" --list-targets Zobrazit dostupné cíle pro --target\n"
108
+" -P --properties Nastavit vlastnosti uzlu\n"
109
"\n"
110
111
-#: src/tools/pw-cat.c:1016
112
+#: src/tools/pw-cat.c:809
113
#, c-format
114
msgid ""
115
" --rate Sample rate (req. for rec) (default "
116
117
"je %d)\n"
118
"\n"
119
120
-#: src/tools/pw-cat.c:1033
121
+#: src/tools/pw-cat.c:826
122
msgid ""
123
" -p, --playback Playback mode\n"
124
" -r, --record Recording mode\n"
125
" -m, --midi Midi mode\n"
126
+" -d, --dsd DSD mode\n"
127
"\n"
128
msgstr ""
129
" -p, --playback Playback mód\n"
130
" -r, --record Recording mód\n"
131
" -m, --midi Midi mód\n"
132
+" -d, --dsd DSD mód\n"
133
"\n"
134
135
-#: src/tools/pw-cli.c:2932
136
+#: src/tools/pw-cli.c:2255
137
#, c-format
138
msgid ""
139
"%s options command\n"
140
141
" -r, --remote Název vzdáleného démonu\n"
142
"\n"
143
144
-#: spa/plugins/alsa/acp/acp.c:290
145
+#: spa/plugins/alsa/acp/acp.c:321
146
msgid "Pro Audio"
147
msgstr "Pro Audio"
148
149
-#: spa/plugins/alsa/acp/acp.c:411 spa/plugins/alsa/acp/alsa-mixer.c:4704
150
-#: spa/plugins/bluez5/bluez5-device.c:1000
151
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
152
+#: spa/plugins/bluez5/bluez5-device.c:1236
153
msgid "Off"
154
msgstr "Vypnuto"
155
156
-#: spa/plugins/alsa/acp/channelmap.h:466
157
-msgid "(invalid)"
158
-msgstr "(neplatné)"
159
-
160
-#: spa/plugins/alsa/acp/alsa-mixer.c:2709
161
+#: spa/plugins/alsa/acp/alsa-mixer.c:2652
162
msgid "Input"
163
msgstr "Vstup"
164
165
-#: spa/plugins/alsa/acp/alsa-mixer.c:2710
166
+#: spa/plugins/alsa/acp/alsa-mixer.c:2653
167
msgid "Docking Station Input"
168
msgstr "Vstup dokovací stanice"
169
170
-#: spa/plugins/alsa/acp/alsa-mixer.c:2711
171
+#: spa/plugins/alsa/acp/alsa-mixer.c:2654
172
msgid "Docking Station Microphone"
173
msgstr "Mikrofon dokovací stanice"
174
175
-#: spa/plugins/alsa/acp/alsa-mixer.c:2712
176
+#: spa/plugins/alsa/acp/alsa-mixer.c:2655
177
msgid "Docking Station Line In"
178
msgstr "Linkový vstup dokovací stanice"
179
180
-#: spa/plugins/alsa/acp/alsa-mixer.c:2713
181
-#: spa/plugins/alsa/acp/alsa-mixer.c:2804
182
+#: spa/plugins/alsa/acp/alsa-mixer.c:2656
183
+#: spa/plugins/alsa/acp/alsa-mixer.c:2747
184
msgid "Line In"
185
msgstr "Linkový vstup"
186
187
-#: spa/plugins/alsa/acp/alsa-mixer.c:2714
188
-#: spa/plugins/alsa/acp/alsa-mixer.c:2798
189
-#: spa/plugins/bluez5/bluez5-device.c:1145
190
+#: spa/plugins/alsa/acp/alsa-mixer.c:2657
191
+#: spa/plugins/alsa/acp/alsa-mixer.c:2741
192
+#: spa/plugins/bluez5/bluez5-device.c:1454
193
msgid "Microphone"
194
msgstr "Mikrofon"
195
196
-#: spa/plugins/alsa/acp/alsa-mixer.c:2715
197
-#: spa/plugins/alsa/acp/alsa-mixer.c:2799
198
+#: spa/plugins/alsa/acp/alsa-mixer.c:2658
199
+#: spa/plugins/alsa/acp/alsa-mixer.c:2742
200
msgid "Front Microphone"
201
pipewire-0.3.59.tar.gz/po/hr.po -> pipewire-0.3.60.tar.gz/po/hr.po
Changed
201
1
2
msgstr ""
3
"Project-Id-Version: pipewire\n"
4
"Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2022-06-30 12:50+0200\n"
6
-"PO-Revision-Date: 2022-06-30 13:14+0200\n"
7
+"POT-Creation-Date: 2022-10-01 14:01+0200\n"
8
+"PO-Revision-Date: 2022-10-01 14:12+0200\n"
9
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
10
"Language-Team: Croatian <https://translate.fedoraproject.org/projects/"
11
"pipewire/pipewire/hr/>\n"
12
13
"MIME-Version: 1.0\n"
14
"Content-Type: text/plain; charset=UTF-8\n"
15
"Content-Transfer-Encoding: 8bit\n"
16
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
17
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
18
-"X-Generator: Poedit 2.3\n"
19
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
20
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
21
+"X-Generator: Poedit 3.0.1\n"
22
"X-Launchpad-Export-Date: 2017-04-20 21:04+0000\n"
23
24
#: src/daemon/pipewire.c:46
25
26
msgid "Dummy Output"
27
msgstr "Lažni izlaz"
28
29
-#: src/modules/module-pulse-tunnel.c:648
30
+#: src/modules/module-pulse-tunnel.c:662
31
#, c-format
32
msgid "Tunnel for %s@%s"
33
msgstr "Tunel za %s@%s"
34
35
" -d, --dsd DSD način\n"
36
"\n"
37
38
-#: src/tools/pw-cli.c:3165
39
+#: src/tools/pw-cli.c:2250
40
#, c-format
41
msgid ""
42
"%s options command\n"
43
44
msgid "Pro Audio"
45
msgstr "Pro Audio"
46
47
-#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648
48
-#: spa/plugins/bluez5/bluez5-device.c:1161
49
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
50
+#: spa/plugins/bluez5/bluez5-device.c:1236
51
msgid "Off"
52
msgstr "Isključeno"
53
54
55
56
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
57
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
58
-#: spa/plugins/bluez5/bluez5-device.c:1330
59
+#: spa/plugins/bluez5/bluez5-device.c:1454
60
msgid "Microphone"
61
msgstr "Mikrofon"
62
63
64
msgstr "Bez pojačanja basa"
65
66
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
67
-#: spa/plugins/bluez5/bluez5-device.c:1335
68
+#: spa/plugins/bluez5/bluez5-device.c:1460
69
msgid "Speaker"
70
msgstr "Zvučnik"
71
72
73
74
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
75
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
76
-#: spa/plugins/bluez5/bluez5-device.c:1320
77
+#: spa/plugins/bluez5/bluez5-device.c:1442
78
msgid "Headset"
79
msgstr "Slušalice s mikrofonom"
80
81
82
msgid "%s Input"
83
msgstr "%s ulaz"
84
85
-#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267
86
+#: spa/plugins/alsa/acp/alsa-util.c:1187
87
+#: spa/plugins/alsa/acp/alsa-util.c:1281
88
#, c-format
89
msgid ""
90
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
91
92
"Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite "
93
"problem ALSA razvijateljima."
94
95
-#: spa/plugins/alsa/acp/alsa-util.c:1239
96
+#: spa/plugins/alsa/acp/alsa-util.c:1253
97
#, c-format
98
msgid ""
99
-"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
100
-"%lu ms).\n"
101
+"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
102
+"(%s%lu ms).\n"
103
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
104
"to the ALSA developers."
105
msgid_plural ""
106
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
107
-"%lu ms).\n"
108
+"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
109
+"(%s%lu ms).\n"
110
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
111
"to the ALSA developers."
112
msgstr0 ""
113
114
"Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite "
115
"problem ALSA razvijateljima."
116
msgstr1 ""
117
-"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta (%s"
118
-"%lu ms).\n"
119
+"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta "
120
+"(%s%lu ms).\n"
121
"Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite "
122
"problem ALSA razvijateljima."
123
msgstr2 ""
124
-"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta (%s"
125
-"%lu ms).\n"
126
+"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta "
127
+"(%s%lu ms).\n"
128
"Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite "
129
"problem ALSA razvijateljima."
130
131
-#: spa/plugins/alsa/acp/alsa-util.c:1286
132
+#: spa/plugins/alsa/acp/alsa-util.c:1300
133
#, c-format
134
msgid ""
135
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
136
137
"Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite "
138
"problem ALSA razvijateljima."
139
140
-#: spa/plugins/alsa/acp/alsa-util.c:1329
141
+#: spa/plugins/alsa/acp/alsa-util.c:1343
142
#, c-format
143
msgid ""
144
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
145
146
msgid "Modem"
147
msgstr "Modem"
148
149
-#: spa/plugins/bluez5/bluez5-device.c:1172
150
+#: spa/plugins/bluez5/bluez5-device.c:1247
151
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
152
msgstr "Zvučni pristupnik (A2DP izvor i HSP/HFP AG)"
153
154
-#: spa/plugins/bluez5/bluez5-device.c:1197
155
+#: spa/plugins/bluez5/bluez5-device.c:1272
156
#, c-format
157
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
158
msgstr "Reprodukcija visoke autentičnosti (A2DP slivnik, kôdek %s)"
159
160
-#: spa/plugins/bluez5/bluez5-device.c:1200
161
+#: spa/plugins/bluez5/bluez5-device.c:1275
162
#, c-format
163
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
164
msgstr "Telefonija visoke autentičnosti (A2DP slivnik, kôdek %s)"
165
166
-#: spa/plugins/bluez5/bluez5-device.c:1208
167
+#: spa/plugins/bluez5/bluez5-device.c:1283
168
msgid "High Fidelity Playback (A2DP Sink)"
169
msgstr "Reprodukcija visoke autentičnosti (A2DP slivnik)"
170
171
-#: spa/plugins/bluez5/bluez5-device.c:1210
172
+#: spa/plugins/bluez5/bluez5-device.c:1285
173
msgid "High Fidelity Duplex (A2DP Source/Sink)"
174
msgstr "Telefonija visoke autentičnosti (A2DP izvor/slivnik)"
175
176
-#: spa/plugins/bluez5/bluez5-device.c:1238
177
+#: spa/plugins/bluez5/bluez5-device.c:1322
178
+#, c-format
179
+msgid "High Fidelity Playback (BAP Sink, codec %s)"
180
+msgstr "Reprodukcija visoke autentičnosti (BAP slivnik, kôdek %s)"
181
+
182
+#: spa/plugins/bluez5/bluez5-device.c:1326
183
+#, c-format
184
+msgid "High Fidelity Input (BAP Source, codec %s)"
185
+msgstr "Ulaz visoke autentičnosti (BAP izvor, kôdek %s)"
186
+
187
+#: spa/plugins/bluez5/bluez5-device.c:1330
188
+#, c-format
189
+msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
190
+msgstr "Telefonija visoke autentičnosti (BAP izvor/slivnik, kôdek %s)"
191
+
192
+#: spa/plugins/bluez5/bluez5-device.c:1359
193
#, c-format
194
msgid "Headset Head Unit (HSP/HFP, codec %s)"
195
msgstr "Jedinica slušalice s mikrofonom (HSP/HFP, kôdek %s)"
196
197
-#: spa/plugins/bluez5/bluez5-device.c:1243
198
+#: spa/plugins/bluez5/bluez5-device.c:1364
199
msgid "Headset Head Unit (HSP/HFP)"
200
msgstr "Jedinica slušalice s mikrofonom (HSP/HFP)"
201
pipewire-0.3.59.tar.gz/po/pipewire.pot -> pipewire-0.3.60.tar.gz/po/pipewire.pot
Changed
201
1
2
msgid "Dummy Output"
3
msgstr ""
4
5
-#: src/modules/module-pulse-tunnel.c:648
6
+#: src/modules/module-pulse-tunnel.c:662
7
#, c-format
8
msgid "Tunnel for %s@%s"
9
msgstr ""
10
11
"\n"
12
msgstr ""
13
14
-#: src/tools/pw-cli.c:3165
15
+#: src/tools/pw-cli.c:2250
16
#, c-format
17
msgid ""
18
"%s options command\n"
19
20
msgid "Pro Audio"
21
msgstr ""
22
23
-#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648
24
-#: spa/plugins/bluez5/bluez5-device.c:1161
25
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
26
+#: spa/plugins/bluez5/bluez5-device.c:1236
27
msgid "Off"
28
msgstr ""
29
30
31
32
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
33
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
34
-#: spa/plugins/bluez5/bluez5-device.c:1330
35
+#: spa/plugins/bluez5/bluez5-device.c:1454
36
msgid "Microphone"
37
msgstr ""
38
39
40
msgstr ""
41
42
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
43
-#: spa/plugins/bluez5/bluez5-device.c:1335
44
+#: spa/plugins/bluez5/bluez5-device.c:1460
45
msgid "Speaker"
46
msgstr ""
47
48
49
50
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
51
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
52
-#: spa/plugins/bluez5/bluez5-device.c:1320
53
+#: spa/plugins/bluez5/bluez5-device.c:1442
54
msgid "Headset"
55
msgstr ""
56
57
58
msgid "%s Input"
59
msgstr ""
60
61
-#: spa/plugins/alsa/acp/alsa-util.c:1173
62
-#: spa/plugins/alsa/acp/alsa-util.c:1267
63
+#: spa/plugins/alsa/acp/alsa-util.c:1187
64
+#: spa/plugins/alsa/acp/alsa-util.c:1281
65
#, c-format
66
msgid ""
67
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
68
69
msgstr0 ""
70
msgstr1 ""
71
72
-#: spa/plugins/alsa/acp/alsa-util.c:1239
73
+#: spa/plugins/alsa/acp/alsa-util.c:1253
74
#, c-format
75
msgid ""
76
-"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
77
-"%lu ms).\n"
78
+"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
79
+"(%s%lu ms).\n"
80
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
81
"to the ALSA developers."
82
msgid_plural ""
83
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
84
-"%lu ms).\n"
85
+"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
86
+"(%s%lu ms).\n"
87
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
88
"to the ALSA developers."
89
msgstr0 ""
90
msgstr1 ""
91
92
-#: spa/plugins/alsa/acp/alsa-util.c:1286
93
+#: spa/plugins/alsa/acp/alsa-util.c:1300
94
#, c-format
95
msgid ""
96
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
97
98
"to the ALSA developers."
99
msgstr ""
100
101
-#: spa/plugins/alsa/acp/alsa-util.c:1329
102
+#: spa/plugins/alsa/acp/alsa-util.c:1343
103
#, c-format
104
msgid ""
105
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
106
107
msgid "Modem"
108
msgstr ""
109
110
-#: spa/plugins/bluez5/bluez5-device.c:1172
111
+#: spa/plugins/bluez5/bluez5-device.c:1247
112
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
113
msgstr ""
114
115
-#: spa/plugins/bluez5/bluez5-device.c:1197
116
+#: spa/plugins/bluez5/bluez5-device.c:1272
117
#, c-format
118
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
119
msgstr ""
120
121
-#: spa/plugins/bluez5/bluez5-device.c:1200
122
+#: spa/plugins/bluez5/bluez5-device.c:1275
123
#, c-format
124
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
125
msgstr ""
126
127
-#: spa/plugins/bluez5/bluez5-device.c:1208
128
+#: spa/plugins/bluez5/bluez5-device.c:1283
129
msgid "High Fidelity Playback (A2DP Sink)"
130
msgstr ""
131
132
-#: spa/plugins/bluez5/bluez5-device.c:1210
133
+#: spa/plugins/bluez5/bluez5-device.c:1285
134
msgid "High Fidelity Duplex (A2DP Source/Sink)"
135
msgstr ""
136
137
-#: spa/plugins/bluez5/bluez5-device.c:1238
138
+#: spa/plugins/bluez5/bluez5-device.c:1322
139
+#, c-format
140
+msgid "High Fidelity Playback (BAP Sink, codec %s)"
141
+msgstr ""
142
+
143
+#: spa/plugins/bluez5/bluez5-device.c:1326
144
+#, c-format
145
+msgid "High Fidelity Input (BAP Source, codec %s)"
146
+msgstr ""
147
+
148
+#: spa/plugins/bluez5/bluez5-device.c:1330
149
+#, c-format
150
+msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
151
+msgstr ""
152
+
153
+#: spa/plugins/bluez5/bluez5-device.c:1359
154
#, c-format
155
msgid "Headset Head Unit (HSP/HFP, codec %s)"
156
msgstr ""
157
158
-#: spa/plugins/bluez5/bluez5-device.c:1243
159
+#: spa/plugins/bluez5/bluez5-device.c:1364
160
msgid "Headset Head Unit (HSP/HFP)"
161
msgstr ""
162
163
-#: spa/plugins/bluez5/bluez5-device.c:1325
164
+#: spa/plugins/bluez5/bluez5-device.c:1443
165
+#: spa/plugins/bluez5/bluez5-device.c:1448
166
+#: spa/plugins/bluez5/bluez5-device.c:1455
167
+#: spa/plugins/bluez5/bluez5-device.c:1461
168
+#: spa/plugins/bluez5/bluez5-device.c:1467
169
+#: spa/plugins/bluez5/bluez5-device.c:1473
170
+#: spa/plugins/bluez5/bluez5-device.c:1479
171
+#: spa/plugins/bluez5/bluez5-device.c:1485
172
+#: spa/plugins/bluez5/bluez5-device.c:1491
173
msgid "Handsfree"
174
msgstr ""
175
176
-#: spa/plugins/bluez5/bluez5-device.c:1340
177
+#: spa/plugins/bluez5/bluez5-device.c:1449
178
+msgid "Handsfree (HFP)"
179
+msgstr ""
180
+
181
+#: spa/plugins/bluez5/bluez5-device.c:1466
182
msgid "Headphone"
183
msgstr ""
184
185
-#: spa/plugins/bluez5/bluez5-device.c:1345
186
+#: spa/plugins/bluez5/bluez5-device.c:1472
187
msgid "Portable"
188
msgstr ""
189
190
-#: spa/plugins/bluez5/bluez5-device.c:1350
191
+#: spa/plugins/bluez5/bluez5-device.c:1478
192
msgid "Car"
193
msgstr ""
194
195
-#: spa/plugins/bluez5/bluez5-device.c:1355
196
+#: spa/plugins/bluez5/bluez5-device.c:1484
197
msgid "HiFi"
198
msgstr ""
199
200
-#: spa/plugins/bluez5/bluez5-device.c:1360
201
pipewire-0.3.59.tar.gz/po/pt_BR.po -> pipewire-0.3.60.tar.gz/po/pt_BR.po
Changed
201
1
2
# Brazilian Portuguese translation for pipewire
3
-# Copyright (C) 2021 Rafael Fontenelle <rafaelff@gnome.org>
4
+# Copyright (C) 2022 Rafael Fontenelle <rafaelff@gnome.org>
5
# This file is distributed under the same license as the pipewire package.
6
# Fabian Affolter <fab@fedoraproject.org>, 2008.
7
# Igor Pires Soares <igor@projetofedora.org>, 2009, 2012.
8
# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2021.
9
+# Matheus Barbosa <mdpb.matheus@gmail.com>, 2022.
10
#
11
msgid ""
12
msgstr ""
13
"Project-Id-Version: pipewire\n"
14
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
15
"issues\n"
16
-"POT-Creation-Date: 2021-08-01 15:31+0000\n"
17
-"PO-Revision-Date: 2021-08-01 17:02-0300\n"
18
-"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
19
+"POT-Creation-Date: 2022-09-30 03:27+0000\n"
20
+"PO-Revision-Date: 2022-01-25 19:49-0300\n"
21
+"Last-Translator: Matheus Barbosa <mdpb.matheus@gmail.com>\n"
22
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
23
"Language: pt_BR\n"
24
"MIME-Version: 1.0\n"
25
26
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
27
"X-Generator: Gtranslator 40.0\n"
28
29
-#: src/daemon/pipewire.c:45
30
+#: src/daemon/pipewire.c:46
31
#, c-format
32
msgid ""
33
"%s options\n"
34
35
msgid "Start the PipeWire Media System"
36
msgstr "Inicia o Sistema de Mídia PipeWire"
37
38
-#: src/examples/media-session/alsa-monitor.c:586
39
-#: spa/plugins/alsa/acp/compat.c:189
40
-msgid "Built-in Audio"
41
-msgstr "Áudio interno"
42
-
43
-#: src/examples/media-session/alsa-monitor.c:590
44
-#: spa/plugins/alsa/acp/compat.c:194
45
-msgid "Modem"
46
-msgstr "Modem"
47
-
48
-#: src/examples/media-session/alsa-monitor.c:599
49
-#: src/modules/module-zeroconf-discover.c:296
50
-msgid "Unknown device"
51
-msgstr "Dispositivo desconhecido"
52
-
53
-#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:173
54
-#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:173
55
+#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180
56
+#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180
57
#, c-format
58
msgid "Tunnel to %s/%s"
59
msgstr "Túnel para %s/%s"
60
61
-#: src/modules/module-pulse-tunnel.c:534
62
+#: src/modules/module-fallback-sink.c:51
63
+msgid "Dummy Output"
64
+msgstr "Saída de falsa"
65
+
66
+#: src/modules/module-pulse-tunnel.c:662
67
#, c-format
68
msgid "Tunnel for %s@%s"
69
msgstr "Túnel para %s@%s"
70
71
-#: src/modules/module-zeroconf-discover.c:308
72
+#: src/modules/module-zeroconf-discover.c:332
73
+msgid "Unknown device"
74
+msgstr "Dispositivo desconhecido"
75
+
76
+#: src/modules/module-zeroconf-discover.c:344
77
#, c-format
78
msgid "%s on %s@%s"
79
msgstr "%s em %s@%s"
80
81
-#: src/modules/module-zeroconf-discover.c:312
82
+#: src/modules/module-zeroconf-discover.c:348
83
#, c-format
84
msgid "%s on %s"
85
msgstr "%s em %s"
86
87
-#: src/tools/pw-cat.c:1000
88
+#: src/tools/pw-cat.c:784
89
#, c-format
90
msgid ""
91
-"%s options <file>\n"
92
+"%s options <file>|-\n"
93
" -h, --help Show this help\n"
94
" --version Show version\n"
95
" -v, --verbose Enable verbose operations\n"
96
"\n"
97
msgstr ""
98
-"%s opções <arquivo>\n"
99
+"%s opções <arquivo>|-\n"
100
" -h, --help Mostra esta ajuda\n"
101
" --version Mostra a versão\n"
102
" -v, --verbose Habilita operações verbosas\n"
103
"\n"
104
105
-#: src/tools/pw-cat.c:1007
106
+#: src/tools/pw-cat.c:791
107
#, c-format
108
msgid ""
109
" -R, --remote Remote daemon name\n"
110
111
" or direct samples (256)\n"
112
" the rate is the one of the source "
113
"file\n"
114
-" --list-targets List available targets for --target\n"
115
+" -P --properties Set node properties\n"
116
"\n"
117
msgstr ""
118
" -R, --remote Nome do daemon remoto\n"
119
120
" Xunit (unidade = s, ms, us, ns)\n"
121
" ou amostras diretas (256)\n"
122
" a taxa é um dos arquivos fontes\n"
123
-" --list-targets Lista alvos disponíveis para --"
124
-"target\n"
125
+" --properties Define as propriedades do nó\n"
126
"\n"
127
128
-#: src/tools/pw-cat.c:1025
129
+#: src/tools/pw-cat.c:809
130
#, c-format
131
msgid ""
132
" --rate Sample rate (req. for rec) (default "
133
134
"(padrão: %d)\n"
135
"\n"
136
137
-#: src/tools/pw-cat.c:1042
138
+#: src/tools/pw-cat.c:826
139
msgid ""
140
" -p, --playback Playback mode\n"
141
" -r, --record Recording mode\n"
142
" -m, --midi Midi mode\n"
143
+" -d, --dsd DSD mode\n"
144
"\n"
145
msgstr ""
146
" -p, --playback Modo de reprodução\n"
147
" -r, --record Modo de gravação\n"
148
-" -m, --midi Modo midi\n"
149
+" -m, --midi Modo Midi\n"
150
+" -d, --dsd Modo DSD\n"
151
"\n"
152
153
-#: src/tools/pw-cli.c:2954
154
+#: src/tools/pw-cli.c:2255
155
#, c-format
156
msgid ""
157
"%s options command\n"
158
159
" -r, --remote Nome do daemon remoto\n"
160
"\n"
161
162
-#: spa/plugins/alsa/acp/acp.c:306
163
+#: spa/plugins/alsa/acp/acp.c:321
164
msgid "Pro Audio"
165
msgstr "Pro Audio"
166
167
-#: spa/plugins/alsa/acp/acp.c:429 spa/plugins/alsa/acp/alsa-mixer.c:4648
168
-#: spa/plugins/bluez5/bluez5-device.c:1043
169
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
170
+#: spa/plugins/bluez5/bluez5-device.c:1236
171
msgid "Off"
172
msgstr "Desligado"
173
174
175
176
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
177
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
178
-#: spa/plugins/bluez5/bluez5-device.c:1198
179
+#: spa/plugins/bluez5/bluez5-device.c:1454
180
msgid "Microphone"
181
msgstr "Microfone"
182
183
184
msgstr "Sem reforço de graves"
185
186
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
187
-#: spa/plugins/bluez5/bluez5-device.c:1203
188
+#: spa/plugins/bluez5/bluez5-device.c:1460
189
msgid "Speaker"
190
msgstr "Auto-falante"
191
192
193
# Fone de ouvido não se encaixa como tradução aqui, pois há ou pode haver microfone junto.
194
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
195
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
196
-#: spa/plugins/bluez5/bluez5-device.c:1188
197
+#: spa/plugins/bluez5/bluez5-device.c:1442
198
msgid "Headset"
199
msgstr "Headset"
200
201
pipewire-0.3.59.tar.gz/po/sv.po -> pipewire-0.3.60.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-07-19 15:27+0000\n"
6
-"PO-Revision-Date: 2022-07-10 10:22+0200\n"
7
+"POT-Creation-Date: 2022-10-20 15:27+0000\n"
8
+"PO-Revision-Date: 2022-09-16 12:58+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.1\n"
17
+"X-Generator: Poedit 3.1.1\n"
18
19
#: src/daemon/pipewire.c:46
20
#, c-format
21
22
msgid "Dummy Output"
23
msgstr "Attrapputgång"
24
25
-#: src/modules/module-pulse-tunnel.c:648
26
+#: src/modules/module-pulse-tunnel.c:681
27
#, c-format
28
msgid "Tunnel for %s@%s"
29
msgstr "Tunnel för %s@%s"
30
31
-#: src/modules/module-zeroconf-discover.c:332
32
+#: src/modules/module-zeroconf-discover.c:335
33
msgid "Unknown device"
34
msgstr "Okänd enhet"
35
36
-#: src/modules/module-zeroconf-discover.c:344
37
+#: src/modules/module-zeroconf-discover.c:347
38
#, c-format
39
msgid "%s on %s@%s"
40
msgstr "%s på %s@%s"
41
42
-#: src/modules/module-zeroconf-discover.c:348
43
+#: src/modules/module-zeroconf-discover.c:351
44
#, c-format
45
msgid "%s on %s"
46
msgstr "%s på %s"
47
48
-#: src/tools/pw-cat.c:784
49
+#: src/tools/pw-cat.c:782
50
#, c-format
51
msgid ""
52
"%s options <file>|-\n"
53
54
" -v, --verbose Aktivera utförliga operationer\n"
55
"\n"
56
57
-#: src/tools/pw-cat.c:791
58
+#: src/tools/pw-cat.c:789
59
#, c-format
60
msgid ""
61
" -R, --remote Remote daemon name\n"
62
63
" -P --properties Sätt nodegenskaper\n"
64
"\n"
65
66
-#: src/tools/pw-cat.c:809
67
+#: src/tools/pw-cat.c:807
68
#, c-format
69
msgid ""
70
" --rate Sample rate (req. for rec) (default "
71
72
"%d)\n"
73
"\n"
74
75
-#: src/tools/pw-cat.c:826
76
+#: src/tools/pw-cat.c:824
77
msgid ""
78
" -p, --playback Playback mode\n"
79
" -r, --record Recording mode\n"
80
81
" -d, --dsd DSD-läge\n"
82
"\n"
83
84
-#: src/tools/pw-cli.c:3165
85
+#: src/tools/pw-cli.c:2250
86
#, c-format
87
msgid ""
88
"%s options command\n"
89
90
msgid "Pro Audio"
91
msgstr "Professionellt ljud"
92
93
-#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648
94
-#: spa/plugins/bluez5/bluez5-device.c:1188
95
+#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
96
+#: spa/plugins/bluez5/bluez5-device.c:1237
97
msgid "Off"
98
msgstr "Av"
99
100
101
102
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
103
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
104
-#: spa/plugins/bluez5/bluez5-device.c:1360
105
+#: spa/plugins/bluez5/bluez5-device.c:1455
106
msgid "Microphone"
107
msgstr "Mikrofon"
108
109
110
msgstr "Ingen basökning"
111
112
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
113
-#: spa/plugins/bluez5/bluez5-device.c:1366
114
+#: spa/plugins/bluez5/bluez5-device.c:1461
115
msgid "Speaker"
116
msgstr "Högtalare"
117
118
119
120
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
121
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
122
-#: spa/plugins/bluez5/bluez5-device.c:1348
123
+#: spa/plugins/bluez5/bluez5-device.c:1443
124
msgid "Headset"
125
msgstr "Headset"
126
127
128
msgid "%s Input"
129
msgstr "%s-ingång"
130
131
-#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267
132
+#: spa/plugins/alsa/acp/alsa-util.c:1187 spa/plugins/alsa/acp/alsa-util.c:1281
133
#, c-format
134
msgid ""
135
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
136
137
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
138
"problemet till ALSA-utvecklarna."
139
140
-#: spa/plugins/alsa/acp/alsa-util.c:1239
141
+#: spa/plugins/alsa/acp/alsa-util.c:1253
142
#, c-format
143
msgid ""
144
"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
145
146
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
147
"problemet till ALSA-utvecklarna."
148
149
-#: spa/plugins/alsa/acp/alsa-util.c:1286
150
+#: spa/plugins/alsa/acp/alsa-util.c:1300
151
#, c-format
152
msgid ""
153
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
154
155
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
156
"problemet till ALSA-utvecklarna."
157
158
-#: spa/plugins/alsa/acp/alsa-util.c:1329
159
+#: spa/plugins/alsa/acp/alsa-util.c:1343
160
#, c-format
161
msgid ""
162
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
163
164
msgid "Modem"
165
msgstr "Modem"
166
167
-#: spa/plugins/bluez5/bluez5-device.c:1199
168
+#: spa/plugins/bluez5/bluez5-device.c:1248
169
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
170
msgstr "Audio gateway (A2DP-källa & HSP/HFP AG)"
171
172
-#: spa/plugins/bluez5/bluez5-device.c:1224
173
+#: spa/plugins/bluez5/bluez5-device.c:1273
174
#, c-format
175
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
176
msgstr "High fidelity-uppspelning (A2DP-utgång, kodek %s)"
177
178
-#: spa/plugins/bluez5/bluez5-device.c:1227
179
+#: spa/plugins/bluez5/bluez5-device.c:1276
180
#, c-format
181
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
182
msgstr "High fidelity duplex (A2DP-källa/utgång, kodek %s)"
183
184
-#: spa/plugins/bluez5/bluez5-device.c:1235
185
+#: spa/plugins/bluez5/bluez5-device.c:1284
186
msgid "High Fidelity Playback (A2DP Sink)"
187
msgstr "High fidelity-uppspelning (A2DP-utgång)"
188
189
-#: spa/plugins/bluez5/bluez5-device.c:1237
190
+#: spa/plugins/bluez5/bluez5-device.c:1286
191
msgid "High Fidelity Duplex (A2DP Source/Sink)"
192
msgstr "High fidelity duplex (A2DP-källa/utgång)"
193
194
-#: spa/plugins/bluez5/bluez5-device.c:1265
195
+#: spa/plugins/bluez5/bluez5-device.c:1323
196
+#, c-format
197
+msgid "High Fidelity Playback (BAP Sink, codec %s)"
198
+msgstr "High fidelity-uppspelning (BAP-utgång, kodek %s)"
199
+
200
+#: spa/plugins/bluez5/bluez5-device.c:1327
201
pipewire-0.3.59.tar.gz/po/tr.po -> pipewire-0.3.60.tar.gz/po/tr.po
Changed
201
1
2
"Project-Id-Version: PipeWire master\n"
3
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/"
4
"issues/new\n"
5
-"POT-Creation-Date: 2022-04-03 12:56+0200\n"
6
-"PO-Revision-Date: 2022-05-14 18:35+0300\n"
7
+"POT-Creation-Date: 2022-06-30 12:50+0200\n"
8
+"PO-Revision-Date: 2022-10-23 10:40+0300\n"
9
"Last-Translator: Oğuz Ersen <oguz@ersen.moe>\n"
10
"Language-Team: Turkish <tr>\n"
11
"Language: tr\n"
12
13
" --version Sürümü göster\n"
14
" -c, --config Yapılandırmayı yükle (Öntanımlı %s)\n"
15
16
-#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:190
17
-#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:190
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 "%s/%s tüneli"
23
24
msgid "Dummy Output"
25
msgstr "Temsili Çıkış"
26
27
-#: src/modules/module-pulse-tunnel.c:545
28
+#: src/modules/module-pulse-tunnel.c:662
29
#, c-format
30
msgid "Tunnel for %s@%s"
31
msgstr "%s@%s için tünel"
32
33
-#: src/modules/module-zeroconf-discover.c:313
34
+#: src/modules/module-zeroconf-discover.c:332
35
msgid "Unknown device"
36
msgstr "Bilinmeyen aygıt"
37
38
-#: src/modules/module-zeroconf-discover.c:325
39
+#: src/modules/module-zeroconf-discover.c:344
40
#, c-format
41
msgid "%s on %s@%s"
42
msgstr "%s, %s@%s"
43
44
-#: src/modules/module-zeroconf-discover.c:329
45
+#: src/modules/module-zeroconf-discover.c:348
46
#, c-format
47
msgid "%s on %s"
48
msgstr "%s, %s"
49
50
-#: src/tools/pw-cat.c:1087
51
+#: src/tools/pw-cat.c:784
52
#, c-format
53
msgid ""
54
-"%s options <file>\n"
55
+"%s options <file>|-\n"
56
" -h, --help Show this help\n"
57
" --version Show version\n"
58
" -v, --verbose Enable verbose operations\n"
59
"\n"
60
msgstr ""
61
-"%s seçenekler <dosya>\n"
62
+"%s seçenekler <dosya>|-\n"
63
" -h, --help Bu yardımı göster\n"
64
" --version Sürümü göster\n"
65
" -v, --verbose Ayrıntılı işlemleri etkinleştir\n"
66
"\n"
67
68
-#: src/tools/pw-cat.c:1094
69
+#: src/tools/pw-cat.c:791
70
#, c-format
71
msgid ""
72
" -R, --remote Remote daemon name\n"
73
74
" or direct samples (256)\n"
75
" the rate is the one of the source "
76
"file\n"
77
-" --list-targets List available targets for --target\n"
78
+" -P --properties Set node properties\n"
79
"\n"
80
msgstr ""
81
" -R, --remote Uzak arka plan programı adı\n"
82
83
" Xbirim (birim = s, ms, us, ns)\n"
84
" veya doğrudan örneklemeler (256)\n"
85
" oran kaynak dosyadan biridir\n"
86
-" --list-targets --target için kullanılabilir "
87
-"hedefleri listele\n"
88
+" -P --properties Düğüm özelliklerini ayarla\n"
89
"\n"
90
91
-#: src/tools/pw-cat.c:1112
92
+#: src/tools/pw-cat.c:809
93
#, c-format
94
msgid ""
95
" --rate Sample rate (req. for rec) (default "
96
97
"15) (öntanımlı %d)\n"
98
"\n"
99
100
-#: src/tools/pw-cat.c:1129
101
+#: src/tools/pw-cat.c:826
102
msgid ""
103
" -p, --playback Playback mode\n"
104
" -r, --record Recording mode\n"
105
106
" -d, --dsd DSD modu\n"
107
"\n"
108
109
-#: src/tools/pw-cli.c:3051
110
+#: src/tools/pw-cli.c:2250
111
#, c-format
112
msgid ""
113
"%s options command\n"
114
115
msgstr "Profesyonel Ses"
116
117
#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648
118
-#: spa/plugins/bluez5/bluez5-device.c:1159
119
+#: spa/plugins/bluez5/bluez5-device.c:1236
120
msgid "Off"
121
msgstr "Kapalı"
122
123
124
125
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
126
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
127
-#: spa/plugins/bluez5/bluez5-device.c:1328
128
+#: spa/plugins/bluez5/bluez5-device.c:1454
129
msgid "Microphone"
130
msgstr "Mikrofon"
131
132
133
msgstr "Bas Artırma Yok"
134
135
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
136
-#: spa/plugins/bluez5/bluez5-device.c:1333
137
+#: spa/plugins/bluez5/bluez5-device.c:1460
138
msgid "Speaker"
139
msgstr "Hoparlör"
140
141
142
143
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
144
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
145
-#: spa/plugins/bluez5/bluez5-device.c:1318
146
+#: spa/plugins/bluez5/bluez5-device.c:1442
147
msgid "Headset"
148
msgstr "Kulaklık"
149
150
151
msgid "%s Input"
152
msgstr "%s Girişi"
153
154
-#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267
155
+#: spa/plugins/alsa/acp/alsa-util.c:1187 spa/plugins/alsa/acp/alsa-util.c:1281
156
#, c-format
157
msgid ""
158
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
159
160
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
161
"geliştiricilerine bildirin."
162
163
-#: spa/plugins/alsa/acp/alsa-util.c:1239
164
+#: spa/plugins/alsa/acp/alsa-util.c:1253
165
#, c-format
166
msgid ""
167
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
168
169
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
170
"geliştiricilerine bildirin."
171
172
-#: spa/plugins/alsa/acp/alsa-util.c:1286
173
+#: spa/plugins/alsa/acp/alsa-util.c:1300
174
#, c-format
175
msgid ""
176
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
177
178
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
179
"geliştiricilerine bildirin."
180
181
-#: spa/plugins/alsa/acp/alsa-util.c:1329
182
+#: spa/plugins/alsa/acp/alsa-util.c:1343
183
#, c-format
184
msgid ""
185
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
186
187
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
188
"geliştiricilerine bildirin."
189
190
-#: spa/plugins/alsa/acp/channelmap.h:464
191
+#: spa/plugins/alsa/acp/channelmap.h:457
192
msgid "(invalid)"
193
msgstr "(geçersiz)"
194
195
196
msgid "Modem"
197
msgstr "Modem"
198
199
-#: spa/plugins/bluez5/bluez5-device.c:1170
200
+#: spa/plugins/bluez5/bluez5-device.c:1247
201
pipewire-0.3.59.tar.gz/pw-uninstalled.sh -> pipewire-0.3.60.tar.gz/pw-uninstalled.sh
Changed
18
1
2
export SPA_DATA_DIR="${SCRIPT_DIR}/spa/plugins"
3
# the directory with pipewire modules
4
export PIPEWIRE_MODULE_DIR="${BUILDDIR}/src/modules"
5
-export PATH="${BUILDDIR}/src/daemon:${BUILDDIR}/src/tools:${BUILDDIR}/src/media-session:${BUILDDIR}/src/examples:${PATH}"
6
+export PATH="${BUILDDIR}/src/daemon:${BUILDDIR}/src/tools:${BUILDDIR}/src/media-session:${BUILDDIR}/src/examples:${BUILDDIR}/pipewire-v4l2/src:${PATH}"
7
export LD_LIBRARY_PATH="${BUILDDIR}/src/pipewire/:${BUILDDIR}/pipewire-jack/src/${LD_LIBRARY_PATH+":$LD_LIBRARY_PATH"}"
8
export GST_PLUGIN_PATH="${BUILDDIR}/src/gst/${GST_PLUGIN_PATH+":${GST_PLUGIN_PATH}"}"
9
# the directory with card profiles and paths
10
11
# ALSA plugin directory
12
export ALSA_PLUGIN_DIR="${BUILDDIR}/pipewire-alsa/alsa-plugins"
13
14
+export PW_BUILDDIR=$BUILDDIR
15
export PW_UNINSTALLED=1
16
export PKG_CONFIG_PATH="${BUILDDIR}/meson-uninstalled/:${PKG_CONFIG_PATH}"
17
18
pipewire-0.3.59.tar.gz/spa/include/spa/interfaces/audio/aec.h -> pipewire-0.3.60.tar.gz/spa/include/spa/interfaces/audio/aec.h
Changed
40
1
2
*/
3
4
5
+#include <spa/pod/builder.h>
6
#include <spa/utils/dict.h>
7
#include <spa/utils/hook.h>
8
#include <spa/param/audio/raw.h>
9
10
};
11
12
struct spa_audio_aec_methods {
13
-#define SPA_VERSION_AUDIO_AEC_METHODS 1
14
+#define SPA_VERSION_AUDIO_AEC_METHODS 2
15
uint32_t version;
16
17
int (*add_listener) (void *object,
18
19
int (*activate) (void *object);
20
/* since 0.3.58, version 1:1 */
21
int (*deactivate) (void *object);
22
+
23
+ /* version 1:2 */
24
+ int (*enum_props) (void* object, int index, struct spa_pod_builder* builder);
25
+ int (*get_params) (void* object, struct spa_pod_builder* builder);
26
+ int (*set_params) (void *object, const struct spa_pod *args);
27
};
28
29
#define spa_audio_aec_method(o,method,version,...) \
30
31
#define spa_audio_aec_set_props(o,...) spa_audio_aec_method(o, set_props, 0, __VA_ARGS__)
32
#define spa_audio_aec_activate(o) spa_audio_aec_method(o, activate, 1)
33
#define spa_audio_aec_deactivate(o) spa_audio_aec_method(o, deactivate, 1)
34
+#define spa_audio_aec_enum_props(o,...) spa_audio_aec_method(o, enum_props, 2, __VA_ARGS__)
35
+#define spa_audio_aec_get_params(o,...) spa_audio_aec_method(o, get_params, 2, __VA_ARGS__)
36
+#define spa_audio_aec_set_params(o,...) spa_audio_aec_method(o, set_params, 2, __VA_ARGS__)
37
38
#ifdef __cplusplus
39
} /* extern "C" */
40
pipewire-0.3.59.tar.gz/spa/include/spa/param/audio/format-utils.h -> pipewire-0.3.60.tar.gz/spa/include/spa/param/audio/format-utils.h
Changed
49
1
2
info->flags = 0;
3
res = spa_pod_parse_object(format,
4
SPA_TYPE_OBJECT_Format, NULL,
5
- SPA_FORMAT_AUDIO_format, SPA_POD_Id(&info->format),
6
- SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info->rate),
7
- SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info->channels),
8
+ SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format),
9
+ SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate),
10
+ SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels),
11
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
12
if (position == NULL ||
13
!spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS))
14
15
int res;
16
res = spa_pod_parse_object(format,
17
SPA_TYPE_OBJECT_Format, NULL,
18
- SPA_FORMAT_AUDIO_format, SPA_POD_Id(&info->format));
19
+ SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format));
20
return res;
21
}
22
23
24
int res;
25
res = spa_pod_parse_object(format,
26
SPA_TYPE_OBJECT_Format, NULL,
27
- SPA_FORMAT_AUDIO_iec958Codec, SPA_POD_Id(&info->codec),
28
- SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info->rate));
29
+ SPA_FORMAT_AUDIO_iec958Codec, SPA_POD_OPT_Id(&info->codec),
30
+ SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate));
31
return res;
32
}
33
34
35
info->flags = 0;
36
res = spa_pod_parse_object(format,
37
SPA_TYPE_OBJECT_Format, NULL,
38
- SPA_FORMAT_AUDIO_bitorder, SPA_POD_Id(&info->bitorder),
39
- SPA_FORMAT_AUDIO_interleave, SPA_POD_Int(&info->interleave),
40
- SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info->rate),
41
- SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info->channels),
42
+ SPA_FORMAT_AUDIO_bitorder, SPA_POD_OPT_Id(&info->bitorder),
43
+ SPA_FORMAT_AUDIO_interleave, SPA_POD_OPT_Int(&info->interleave),
44
+ SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate),
45
+ SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels),
46
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
47
if (position == NULL ||
48
!spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS))
49
pipewire-0.3.59.tar.gz/spa/include/spa/param/param.h -> pipewire-0.3.60.tar.gz/spa/include/spa/param/param.h
Changed
12
1
2
uint32_t flags;
3
uint32_t user; /**< private user field. You can use this to keep
4
* state. */
5
- uint32_t padding5;
6
+ int32_t seq; /**< private seq field. You can use this to keep
7
+ * state of a pending update. */
8
+ uint32_t padding4;
9
};
10
11
#define SPA_PARAM_INFO(id,flags) ((struct spa_param_info){ (id), (flags) })
12
pipewire-0.3.59.tar.gz/spa/include/spa/param/video/format-utils.h -> pipewire-0.3.60.tar.gz/spa/include/spa/param/video/format-utils.h
Changed
24
1
2
{
3
return spa_pod_parse_object(format,
4
SPA_TYPE_OBJECT_Format, NULL,
5
- SPA_FORMAT_VIDEO_format, SPA_POD_Id(&info->format),
6
+ SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format),
7
SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier),
8
- SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&info->size),
9
- SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate),
10
+ SPA_FORMAT_VIDEO_size, SPA_POD_OPT_Rectangle(&info->size),
11
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_OPT_Fraction(&info->framerate),
12
SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_OPT_Fraction(&info->max_framerate),
13
SPA_FORMAT_VIDEO_views, SPA_POD_OPT_Int(&info->views),
14
SPA_FORMAT_VIDEO_interlaceMode, SPA_POD_OPT_Id(&info->interlace_mode),
15
16
{
17
return spa_pod_parse_object(format,
18
SPA_TYPE_OBJECT_Format, NULL,
19
- SPA_FORMAT_VIDEO_format, SPA_POD_Id(&info->format),
20
+ SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format),
21
SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier));
22
}
23
24
pipewire-0.3.59.tar.gz/spa/include/spa/pod/event.h -> pipewire-0.3.60.tar.gz/spa/include/spa/pod/event.h
Changed
14
1
2
#define SPA_EVENT_ID(ev,type) (SPA_EVENT_TYPE(ev) == (type) ? \
3
(ev)->body.body.id : SPA_ID_INVALID)
4
5
-#define SPA_EVENT_INIT_FULL(t,size,type,id,...) (t) \
6
- { { size, SPA_TYPE_OBJECT }, \
7
- { { type, id }, ##__VA_ARGS__ } } \
8
+#define SPA_EVENT_INIT_FULL(t,size,type,id,...) ((t) \
9
+ { { (size), SPA_TYPE_OBJECT }, \
10
+ { { (type), (id) }, ##__VA_ARGS__ } }) \
11
12
#define SPA_EVENT_INIT(type,id) \
13
SPA_EVENT_INIT_FULL(struct spa_event, \
14
pipewire-0.3.59.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.60.tar.gz/spa/include/spa/utils/defs.h
Changed
88
1
2
#endif
3
4
#define SPA_FLAG_MASK(field,mask,flag) (((field) & (mask)) == (flag))
5
-#define SPA_FLAG_IS_SET(field,flag) SPA_FLAG_MASK(field,flag,flag)
6
+#define SPA_FLAG_IS_SET(field,flag) SPA_FLAG_MASK(field, flag, flag)
7
+
8
#define SPA_FLAG_SET(field,flag) ((field) |= (flag))
9
#define SPA_FLAG_CLEAR(field, flag) \
10
({ \
11
12
#define SPA_FOR_EACH_ELEMENT(arr, ptr) \
13
for ((ptr) = arr; (void*)(ptr) < SPA_PTROFF(arr, sizeof(arr), void); (ptr)++)
14
15
+#define SPA_FOR_EACH_ELEMENT_VAR(arr, var) \
16
+ for (__typeof__((arr)0)* (var) = arr; (void*)(var) < SPA_PTROFF(arr, sizeof(arr), void); (var)++)
17
+
18
#define SPA_ABS(a) \
19
({ \
20
__typeof__(a) _a = (a); \
21
SPA_LIKELY(_a >= 0) ? _a : -_a; \
22
})
23
-#define SPA_MIN(a,b) \
24
-({ \
25
- __typeof__(a) _min_a = (a); \
26
- __typeof__(b) _min_b = (b); \
27
+#define SPA_MIN(a,b) \
28
+({ \
29
+ __typeof__(a) _min_a = (a); \
30
+ __typeof__(b) _min_b = (b); \
31
SPA_LIKELY(_min_a <= _min_b) ? _min_a : _min_b; \
32
})
33
-#define SPA_MAX(a,b) \
34
-({ \
35
- __typeof__(a) _max_a = (a); \
36
- __typeof__(b) _max_b = (b); \
37
+#define SPA_MAX(a,b) \
38
+({ \
39
+ __typeof__(a) _max_a = (a); \
40
+ __typeof__(b) _max_b = (b); \
41
SPA_LIKELY(_max_a >= _max_b) ? _max_a : _max_b; \
42
})
43
#define SPA_CLAMP(v,low,high) \
44
45
#define SPA_SWAP(a,b) \
46
({ \
47
__typeof__(a) _t = (a); \
48
- (a) = b; (b) = _t; \
49
+ (a) = b; (b) = _t; \
50
})
51
52
#define SPA_TYPECHECK(type,x) \
53
54
#define SPA_RESTRICT
55
#endif
56
57
-#define SPA_ROUND_DOWN(num,value) ((num) - ((num) % (value)))
58
-#define SPA_ROUND_UP(num,value) ((((num) + (value) - 1) / (value)) * (value))
59
-
60
-#define SPA_MASK_NEGATED(num1, num2) \
61
-({ \
62
- SPA_STATIC_ASSERT(__builtin_constant_p(num2) ? \
63
- (__typeof__(num2))(__typeof__(num1))(__typeof__(num2))(num2) == (num2) : \
64
- sizeof(num1) >= sizeof(num2), \
65
- "truncation problem when masking " #num1 \
66
- " with ~" #num2); \
67
- ((num1) & ~(__typeof__(num1))(num2)); \
68
+#define SPA_ROUND_DOWN(num,value) \
69
+({ \
70
+ __typeof__(num) _num = (num); \
71
+ ((_num) - ((_num) % (value))); \
72
})
73
+#define SPA_ROUND_UP(num,value) \
74
+({ \
75
+ __typeof__(value) _v = (value); \
76
+ ((((num) + (_v) - 1) / (_v)) * (_v)); \
77
+})
78
+
79
+#define SPA_ROUND_MASK(num,mask) ((__typeof__(num))((mask)-1))
80
81
-#define SPA_ROUND_DOWN_N(num,align) SPA_MASK_NEGATED((num), (align) - 1)
82
-#define SPA_ROUND_UP_N(num,align) SPA_ROUND_DOWN_N((num) + ((align) - 1),align)
83
+#define SPA_ROUND_DOWN_N(num,align) ((num) & ~SPA_ROUND_MASK(num, align))
84
+#define SPA_ROUND_UP_N(num,align) ((((num)-1) | SPA_ROUND_MASK(num, align))+1)
85
86
#define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1))
87
#define SPA_IS_ALIGNED(p,align) (SPA_PTR_ALIGNMENT(p,align) == 0)
88
pipewire-0.3.59.tar.gz/spa/include/spa/utils/hook.h -> pipewire-0.3.60.tar.gz/spa/include/spa/utils/hook.h
Changed
10
1
2
*
3
*/
4
#define SPA_INTERFACE_INIT(_type,_version,_funcs,_data) \
5
- (struct spa_interface){ _type, _version, SPA_CALLBACKS_INIT(_funcs,_data), }
6
+ ((struct spa_interface){ (_type), (_version), SPA_CALLBACKS_INIT(_funcs,_data), })
7
8
/**
9
* Invoke method named \a method in the \a callbacks.
10
pipewire-0.3.59.tar.gz/spa/meson.build -> pipewire-0.3.60.tar.gz/spa/meson.build
Changed
12
1
2
summary({'Opus': opus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
3
lc3_dep = dependency('lc3', required : get_option('bluez5-codec-lc3'))
4
summary({'LC3': lc3_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs')
5
+ if get_option('bluez5-backend-hsp-native').allowed() or get_option('bluez5-backend-hfp-native').allowed()
6
+ mm_dep = dependency('ModemManager', version : '>= 1.10.0', required : get_option('bluez5-backend-native-mm'))
7
+ summary({'ModemManager': mm_dep.found()}, bool_yn: true, section: 'Bluetooth backends')
8
+ endif
9
endif
10
avcodec_dep = dependency('libavcodec', required: get_option('ffmpeg'))
11
jack_dep = dependency('jack', version : '>= 1.9.10', required: get_option('jack'))
12
pipewire-0.3.59.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
51
1
2
pa_card *impl = snd_mixer_elem_get_callback_private(melem);
3
snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem);
4
snd_ctl_elem_value_t *elem_value;
5
- bool plugged_in;
6
+ bool plugged_in, any_input_port_available;
7
void *state;
8
pa_alsa_jack *jack;
9
struct temp_port_avail *tp, *tports;
10
11
if (impl->card.active_profile_index != ACP_INVALID_INDEX)
12
active_available = impl->card.profilesimpl->card.active_profile_index->available;
13
14
+ /* First round - detect, if we have any input port available.
15
+ If the hardware can report the state for all I/O jacks, only speakers
16
+ may be plugged in. */
17
+ any_input_port_available = false;
18
+ PA_HASHMAP_FOREACH(profile, impl->profiles, state) {
19
+ pa_device_port *port;
20
+ void *state2;
21
+
22
+ if (profile->profile.flags & ACP_PROFILE_OFF)
23
+ continue;
24
+
25
+ PA_HASHMAP_FOREACH(port, impl->ports, state2) {
26
+ if (!pa_hashmap_get(port->profiles, profile->profile.name))
27
+ continue;
28
+
29
+ if (port->port.direction == ACP_DIRECTION_CAPTURE &&
30
+ port->port.available != ACP_AVAILABLE_NO) {
31
+ any_input_port_available = true;
32
+ goto input_port_found;
33
+ }
34
+ }
35
+ }
36
+input_port_found:
37
+
38
+ /* Second round */
39
PA_HASHMAP_FOREACH(profile, impl->profiles, state) {
40
pa_device_port *port;
41
void *state2;
42
43
44
if (has_input_port && !has_output_port && found_available_input_port)
45
available = ACP_AVAILABLE_YES;
46
- if (has_output_port && !has_input_port && found_available_output_port)
47
+ if (has_output_port && (!has_input_port || !any_input_port_available) && found_available_output_port)
48
available = ACP_AVAILABLE_YES;
49
if (has_output_port && has_input_port && found_available_output_port && found_available_input_port)
50
available = ACP_AVAILABLE_YES;
51
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-acp-device.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-acp-device.c
Changed
25
1
2
{
3
int err = 0;
4
struct spa_dict_item *items;
5
- uint32_t i, n_items;
6
+ uint32_t n_items;
7
const struct acp_dict_item *it;
8
struct acp_card *card = this->card;
9
char path128;
10
11
#undef ADD_ITEM
12
13
if (this->info.change_mask & SPA_DEVICE_CHANGE_MASK_PARAMS) {
14
- for (i = 0; i < SPA_N_ELEMENTS(this->params); i++) {
15
- if (this->paramsi.user > 0) {
16
- this->paramsi.flags ^= SPA_PARAM_INFO_SERIAL;
17
- this->paramsi.user = 0;
18
+ SPA_FOR_EACH_ELEMENT_VAR(this->params, p) {
19
+ if (p->user > 0) {
20
+ p->flags ^= SPA_PARAM_INFO_SERIAL;
21
+ p->user = 0;
22
}
23
}
24
}
25
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
72
1
2
3
static snd_pcm_format_t spa_format_to_alsa(uint32_t format, bool *planar)
4
{
5
- size_t i;
6
-
7
- for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) {
8
- *planar = format_infoi.spa_pformat == format;
9
- if (format_infoi.spa_format == format || *planar)
10
- return format_infoi.format;
11
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, i) {
12
+ *planar = i->spa_pformat == format;
13
+ if (i->spa_format == format || *planar)
14
+ return i->format;
15
}
16
return SND_PCM_FORMAT_UNKNOWN;
17
}
18
19
struct spa_pod **result, struct spa_pod_builder *b)
20
{
21
int res, err;
22
- size_t i, j;
23
+ size_t j;
24
snd_pcm_t *hndl;
25
snd_pcm_hw_params_t *params;
26
struct spa_pod_frame f2;
27
28
spa_pod_builder_push_choice(b, &f1, SPA_CHOICE_None, 0);
29
choice = (struct spa_pod_choice*)spa_pod_builder_frame(b, &f1);
30
31
- for (i = 1, j = 0; i < SPA_N_ELEMENTS(format_info); i++) {
32
- const struct format_info *fi = &format_infoi;
33
+ j = 0;
34
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, fi) {
35
+ if (fi->format == SND_PCM_FORMAT_UNKNOWN)
36
+ continue;
37
38
if (snd_pcm_format_mask_test(fmask, fi->format)) {
39
if ((snd_pcm_access_mask_test(amask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED) ||
40
41
state->alsa_started = false;
42
43
if (state->stream == SND_PCM_STREAM_PLAYBACK)
44
- spa_alsa_silence(state, state->start_delay + state->threshold * 2 + state->headroom);
45
+ spa_alsa_silence(state, state->start_delay + state->threshold + state->headroom);
46
47
return do_start(state);
48
}
49
50
{
51
int res;
52
53
- if (SPA_UNLIKELY(delay > target + state->max_error)) {
54
+ if (state->alsa_started && SPA_UNLIKELY(delay > target + state->max_error)) {
55
spa_log_trace(state->log, "%p: early wakeup %lu %lu", state, delay, target);
56
if (delay > target * 3)
57
delay = target * 3;
58
59
state->alsa_recovering = false;
60
state->alsa_started = false;
61
62
+ /* start capture now, playback will start after first write */
63
if (state->stream == SND_PCM_STREAM_PLAYBACK)
64
- spa_alsa_silence(state, state->start_delay + state->threshold * 2 + state->headroom);
65
-
66
- if ((err = do_start(state)) < 0)
67
+ spa_alsa_silence(state, state->start_delay + state->threshold + state->headroom);
68
+ else if ((err = do_start(state)) < 0)
69
return err;
70
71
set_timers(state);
72
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c
Changed
10
1
2
if (result.index > 0)
3
return 0;
4
param = spa_pod_builder_add_object(&b,
5
- SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
6
+ SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
7
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
8
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
9
break;
10
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-seq.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-seq.c
Changed
94
1
2
continue;
3
4
if (prepare_buffer(state, port) >= 0) {
5
- port->buffer->buf->datas0.chunk->offset = 0;
6
- port->buffer->buf->datas0.chunk->size = port->builder.state.offset,
7
-
8
spa_pod_builder_pop(&port->builder, &port->frame);
9
10
+ port->buffer->buf->datas0.chunk->offset = 0;
11
+ port->buffer->buf->datas0.chunk->size = port->builder.state.offset;
12
+
13
/* move buffer to ready queue */
14
spa_list_remove(&port->buffer->link);
15
SPA_FLAG_SET(port->buffer->flags, BUFFER_FLAG_OUT);
16
17
return res;
18
}
19
20
-static int update_time(struct seq_state *state, uint64_t nsec, bool follower)
21
+static void update_position(struct seq_state *state)
22
{
23
- snd_seq_queue_status_t *status;
24
- const snd_seq_real_time_t* queue_time;
25
- uint64_t queue_real;
26
- double err, corr;
27
- uint64_t queue_elapsed;
28
-
29
if (state->position) {
30
struct spa_io_clock *clock = &state->position->clock;
31
state->rate = clock->rate;
32
+ if (state->rate.num == 0 || state->rate.denom == 0)
33
+ state->rate = SPA_FRACTION(1, 48000);
34
state->duration = clock->duration;
35
} else {
36
state->rate = SPA_FRACTION(1, 48000);
37
state->duration = 1024;
38
}
39
state->threshold = state->duration;
40
+}
41
+
42
+static int update_time(struct seq_state *state, uint64_t nsec, bool follower)
43
+{
44
+ snd_seq_queue_status_t *status;
45
+ const snd_seq_real_time_t* queue_time;
46
+ uint64_t queue_real;
47
+ double err, corr;
48
+ uint64_t queue_elapsed;
49
50
corr = 1.0 - (state->dll.z2 + state->dll.z3);
51
52
53
{
54
int res;
55
56
+ update_position(state);
57
+
58
res = process_recycle(state);
59
60
if (state->following && state->position) {
61
62
63
spa_log_trace(state->log, "timeout %"PRIu64, state->current_time);
64
65
+ update_position(state);
66
+
67
update_time(state, state->current_time, false);
68
69
res = process_read(state);
70
- if (res > 0)
71
- spa_node_call_ready(&state->callbacks, res);
72
+ if (res >= 0)
73
+ spa_node_call_ready(&state->callbacks, res | SPA_STATUS_NEED_DATA);
74
75
set_timeout(state, state->next_time);
76
}
77
78
while (snd_seq_drain_output(state->event.hndl) > 0)
79
sleep(1);
80
81
- if (state->position) {
82
- struct spa_io_clock *clock = &state->position->clock;
83
- state->rate = clock->rate;
84
- state->duration = clock->duration;
85
- } else {
86
- state->rate = SPA_FRACTION(1, 48000);
87
- state->duration = 1024;
88
- }
89
- state->threshold = state->duration;
90
+ update_position(state);
91
92
state->started = true;
93
94
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-udev.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-udev.c
Changed
45
1
2
if (str && *str) {
3
itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS_PATH, str);
4
}
5
- if ((str = udev_device_get_syspath(dev)) && *str) {
6
+ if ((str = udev_device_get_devpath(dev)) && *str) {
7
itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_SYSFS_PATH, str);
8
}
9
if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) {
10
11
{
12
bool deleted = false;
13
struct impl *this = source->data;
14
- struct {
15
+ union {
16
struct inotify_event e;
17
- char nameNAME_MAX+1;
18
+ char nameNAME_MAX+1+sizeof(struct inotify_event);
19
} buf;
20
21
while (true) {
22
23
e = SPA_PTROFF(&buf, len, void);
24
25
for (p = &buf; p < e;
26
- p = SPA_PTROFF(p, sizeof(struct inotify_event) + event->len, void)) {
27
+ p = SPA_PTROFF(p, sizeof(struct inotify_event) + event->len, void)) {
28
unsigned int id;
29
struct device *device;
30
31
event = (const struct inotify_event *) p;
32
+ spa_assert_se(SPA_PTRDIFF(e, p) >= (ptrdiff_t)sizeof(struct inotify_event) &&
33
+ SPA_PTRDIFF(e, p) - sizeof(struct inotify_event) >= event->len &&
34
+ "bad event from kernel");
35
36
/* Device becomes accessible or not busy */
37
if ((event->mask & (IN_ATTRIB | IN_CLOSE_WRITE))) {
38
bool access;
39
if (sscanf(event->name, "controlC%u", &id) != 1 &&
40
- sscanf(event->name, "pcmC%uD", &id) != 1)
41
+ sscanf(event->name, "pcmC%uD", &id) != 1)
42
continue;
43
if ((device = find_device(this, id)) == NULL)
44
continue;
45
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/audioadapter.c
Changed
112
1
2
return 0;
3
}
4
5
-static int format_audio_raw_parse_opt(const struct spa_pod *format, struct spa_audio_info_raw *info)
6
-{
7
- struct spa_pod *position = NULL;
8
- uint32_t media_type, media_subtype;
9
- int res;
10
- if ((res = spa_format_parse(format, &media_type, &media_subtype)) < 0)
11
- return res;
12
- if (media_type != SPA_MEDIA_TYPE_audio ||
13
- media_subtype != SPA_MEDIA_SUBTYPE_raw)
14
- return -ENOTSUP;
15
-
16
- spa_zero(*info);
17
- res = spa_pod_parse_object(format,
18
- SPA_TYPE_OBJECT_Format, NULL,
19
- SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format),
20
- SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels),
21
- SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
22
- if (position == NULL ||
23
- !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS))
24
- SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED);
25
-
26
- return res;
27
-}
28
-
29
static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
30
const struct spa_pod *param)
31
{
32
33
34
if (format) {
35
struct spa_audio_info info;
36
- if (format_audio_raw_parse_opt(format, &info.info.raw) >= 0)
37
+
38
+ spa_zero(info);
39
+ if ((res = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0)
40
+ return res;
41
+ if (info.media_type != SPA_MEDIA_TYPE_audio ||
42
+ info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
43
+ return -ENOTSUP;
44
+
45
+ if (spa_format_audio_raw_parse(format, &info.info.raw) >= 0) {
46
+ info.info.raw.rate = 0;
47
this->default_format = info;
48
+ }
49
}
50
51
switch (mode) {
52
53
54
switch (SPA_NODE_COMMAND_ID(command)) {
55
case SPA_NODE_COMMAND_Start:
56
+ spa_log_debug(this->log, "%p: starting %d", this, this->started);
57
if (this->started)
58
return 0;
59
if ((res = negotiate_format(this)) < 0)
60
return res;
61
if ((res = negotiate_buffers(this)) < 0)
62
return res;
63
+ this->started = true;
64
break;
65
case SPA_NODE_COMMAND_Suspend:
66
- configure_format(this, 0, NULL);
67
- SPA_FALLTHROUGH
68
+ spa_log_debug(this->log, "%p: suspending", this);
69
+ break;
70
case SPA_NODE_COMMAND_Pause:
71
- this->started = false;
72
- spa_log_debug(this->log, "%p: stopped", this);
73
+ spa_log_debug(this->log, "%p: pausing", this);
74
break;
75
case SPA_NODE_COMMAND_Flush:
76
+ spa_log_debug(this->log, "%p: flushing", this);
77
this->io_buffers.status = SPA_STATUS_OK;
78
break;
79
default:
80
81
}
82
switch (SPA_NODE_COMMAND_ID(command)) {
83
case SPA_NODE_COMMAND_Start:
84
- this->started = true;
85
spa_log_debug(this->log, "%p: started", this);
86
break;
87
+ case SPA_NODE_COMMAND_Suspend:
88
+ configure_format(this, 0, NULL);
89
+ SPA_FALLTHROUGH
90
+ case SPA_NODE_COMMAND_Pause:
91
+ this->started = false;
92
+ spa_log_debug(this->log, "%p: stopped", this);
93
+ break;
94
+ case SPA_NODE_COMMAND_Flush:
95
+ spa_log_debug(this->log, "%p: flushed", this);
96
+ break;
97
}
98
return res;
99
}
100
101
102
spa_log_trace_fp(this->log, "%p: ready %d", this, status);
103
104
+ if (!this->started) {
105
+ spa_log_warn(this->log, "%p: ready stopped node", this);
106
+ return -EIO;
107
+ }
108
+
109
if (this->target != this->follower) {
110
this->driver = true;
111
112
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
201
1
2
unsigned int resample_peaks:1;
3
unsigned int is_passthrough:1;
4
unsigned int drained:1;
5
+ unsigned int rate_adjust:1;
6
7
uint32_t empty_size;
8
float *empty;
9
10
static void emit_node_info(struct impl *this, bool full)
11
{
12
uint64_t old = full ? this->info.change_mask : 0;
13
- uint32_t i;
14
15
if (full)
16
this->info.change_mask = this->info_all;
17
if (this->info.change_mask) {
18
if (this->info.change_mask & SPA_NODE_CHANGE_MASK_PARAMS) {
19
- for (i = 0; i < SPA_N_ELEMENTS(this->params); i++) {
20
- if (this->paramsi.user > 0) {
21
- this->paramsi.flags ^= SPA_PARAM_INFO_SERIAL;
22
- this->paramsi.user = 0;
23
+ SPA_FOR_EACH_ELEMENT_VAR(this->params, p) {
24
+ if (p->user > 0) {
25
+ p->flags ^= SPA_PARAM_INFO_SERIAL;
26
+ p->user = 0;
27
}
28
}
29
}
30
31
static void emit_port_info(struct impl *this, struct port *port, bool full)
32
{
33
uint64_t old = full ? port->info.change_mask : 0;
34
- uint32_t i;
35
36
if (full)
37
port->info.change_mask = port->info_all;
38
39
port->info.props = &SPA_DICT_INIT(items, n_items);
40
41
if (port->info.change_mask & SPA_PORT_CHANGE_MASK_PARAMS) {
42
- for (i = 0; i < SPA_N_ELEMENTS(port->params); i++) {
43
- if (port->paramsi.user > 0) {
44
- port->paramsi.flags ^= SPA_PARAM_INFO_SERIAL;
45
- port->paramsi.user = 0;
46
+ SPA_FOR_EACH_ELEMENT_VAR(port->params, p) {
47
+ if (p->user > 0) {
48
+ p->flags ^= SPA_PARAM_INFO_SERIAL;
49
+ p->user = 0;
50
}
51
}
52
}
53
54
{
55
struct props *p = &this->props;
56
struct spa_pod_frame f2;
57
- uint32_t i;
58
59
switch (result.index) {
60
case 0:
61
62
63
spa_pod_builder_prop(&b, SPA_PROP_INFO_labels, 0);
64
spa_pod_builder_push_struct(&b, &f1);
65
- for (i = 0; i < SPA_N_ELEMENTS(channelmix_upmix_info); i++) {
66
- spa_pod_builder_string(&b, channelmix_upmix_infoi.label);
67
- spa_pod_builder_string(&b, channelmix_upmix_infoi.description);
68
+ SPA_FOR_EACH_ELEMENT_VAR(channelmix_upmix_info, i) {
69
+ spa_pod_builder_string(&b, i->label);
70
+ spa_pod_builder_string(&b, i->description);
71
}
72
spa_pod_builder_pop(&b, &f1);
73
param = spa_pod_builder_pop(&b, &f0);
74
75
0);
76
spa_pod_builder_prop(&b, SPA_PROP_INFO_labels, 0);
77
spa_pod_builder_push_struct(&b, &f1);
78
- for (i = 0; i < SPA_N_ELEMENTS(dither_method_info); i++) {
79
- spa_pod_builder_string(&b, dither_method_infoi.label);
80
- spa_pod_builder_string(&b, dither_method_infoi.description);
81
+ SPA_FOR_EACH_ELEMENT_VAR(dither_method_info, i) {
82
+ spa_pod_builder_string(&b, i->label);
83
+ spa_pod_builder_string(&b, i->description);
84
}
85
spa_pod_builder_pop(&b, &f1);
86
param = spa_pod_builder_pop(&b, &f0);
87
88
if (spa_pod_is_string(pod)) {
89
spa_pod_copy_string(pod, sizeof(value), value);
90
} else if (spa_pod_is_float(pod)) {
91
- snprintf(value, sizeof(value), "%f",
92
+ spa_dtoa(value, sizeof(value),
93
SPA_POD_VALUE(struct spa_pod_float, pod));
94
+ } else if (spa_pod_is_double(pod)) {
95
+ spa_dtoa(value, sizeof(value),
96
+ SPA_POD_VALUE(struct spa_pod_double, pod));
97
} else if (spa_pod_is_int(pod)) {
98
snprintf(value, sizeof(value), "%d",
99
SPA_POD_VALUE(struct spa_pod_int, pod));
100
101
spa_log_info(this->log, "key:'%s' val:'%s'", name, value);
102
changed += audioconvert_set_param(this, name, value);
103
}
104
+ if (changed) {
105
+ channelmix_init(&this->mix);
106
+ }
107
return changed;
108
}
109
110
111
break;
112
case SPA_PROP_rate:
113
spa_pod_get_double(&prop->value, &p->rate);
114
+ if (!this->rate_adjust && p->rate != 1.0) {
115
+ this->rate_adjust = true;
116
+ spa_log_info(this->log, "%p: activating adaptive resampler",
117
+ this);
118
+ }
119
break;
120
case SPA_PROP_params:
121
changed += parse_prop_params(this, &prop->value);
122
123
else if (have_channel_volume)
124
p->have_soft_volume = false;
125
126
- channelmix_init(&this->mix);
127
set_volume(this);
128
}
129
return changed;
130
131
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
132
return -EINVAL;
133
134
- if (info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS)
135
+ if (info.info.raw.format == 0 ||
136
+ info.info.raw.rate == 0 ||
137
+ info.info.raw.channels == 0 ||
138
+ info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS)
139
return -EINVAL;
140
141
infop = &info;
142
143
this->paramsIDX_Props.user++;
144
}
145
146
+static char *format_position(char *str, size_t len, uint32_t channels, uint32_t *position)
147
+{
148
+ uint32_t i, idx = 0;
149
+ for (i = 0; i < channels; i++)
150
+ idx += snprintf(str + idx, len - idx, "%s%s", i == 0 ? "" : " ",
151
+ spa_debug_type_find_short_name(spa_type_audio_channel,
152
+ positioni));
153
+ return str;
154
+}
155
+
156
static int setup_channelmix(struct impl *this)
157
{
158
struct dir *in = &this->dirSPA_DIRECTION_INPUT;
159
struct dir *out = &this->dirSPA_DIRECTION_OUTPUT;
160
uint32_t i, src_chan, dst_chan, p;
161
uint64_t src_mask, dst_mask;
162
+ char str1024;
163
int res;
164
165
src_chan = in->format.info.raw.channels;
166
167
dst_mask |= 1ULL << (p < 64 ? p : 0);
168
}
169
170
+ spa_log_info(this->log, "in %s (%016"PRIx64")", format_position(str, sizeof(str),
171
+ src_chan, in->format.info.raw.position), src_mask);
172
+ spa_log_info(this->log, "out %s (%016"PRIx64")", format_position(str, sizeof(str),
173
+ dst_chan, out->format.info.raw.position), dst_mask);
174
+
175
if (src_mask & 1)
176
src_mask = default_mask(src_chan);
177
if (dst_mask & 1)
178
179
this->resample.quality = this->props.resample_quality;
180
this->resample.cpu_flags = this->cpu_flags;
181
182
+ this->rate_adjust = this->props.rate != 1.0;
183
+
184
if (this->resample_peaks)
185
res = resample_peaks_init(&this->resample);
186
else
187
188
spa_log_error(this->log, "can't parse format %s", spa_strerror(res));
189
return res;
190
}
191
- if (info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) {
192
- spa_log_error(this->log, "too many channels %d > %d",
193
- info.info.raw.channels, SPA_AUDIO_MAX_CHANNELS);
194
+ if (info.info.raw.format == 0 ||
195
+ info.info.raw.rate == 0 ||
196
+ info.info.raw.channels == 0 ||
197
+ info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) {
198
+ spa_log_error(this->log, "invalid format:%d rate:%d channels:%d",
199
+ info.info.raw.format, info.info.raw.rate,
200
+ info.info.raw.channels);
201
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/benchmark-fmt-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/benchmark-fmt-ops.c
Changed
28
1
2
static void run_testc(const char *name, const char *impl, bool in_packed, bool out_packed, convert_func_t func,
3
int channel_count)
4
{
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(sample_sizes); i++) {
7
+ SPA_FOR_EACH_ELEMENT_VAR(sample_sizes, s) {
8
run_test1(name, impl, in_packed, out_packed, func, channel_count,
9
- (sample_sizesi + (channel_count -1)) / channel_count);
10
+ (*s + (channel_count -1)) / channel_count);
11
}
12
}
13
14
static void run_test(const char *name, const char *impl, bool in_packed, bool out_packed, convert_func_t func)
15
{
16
- size_t i, j;
17
-
18
- for (i = 0; i < SPA_N_ELEMENTS(sample_sizes); i++) {
19
- for (j = 0; j < SPA_N_ELEMENTS(channel_counts); j++) {
20
- run_test1(name, impl, in_packed, out_packed, func, channel_countsj,
21
- (sample_sizesi + (channel_countsj -1)) / channel_countsj);
22
+ SPA_FOR_EACH_ELEMENT_VAR(sample_sizes, s) {
23
+ SPA_FOR_EACH_ELEMENT_VAR(channel_counts, c) {
24
+ run_test1(name, impl, in_packed, out_packed, func, *c, (*s + (*c -1)) / *c);
25
}
26
}
27
}
28
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops-sse.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/channelmix-ops-sse.c
Changed
200
1
2
}
3
}
4
5
+static inline void avg_sse(float *d, const float *s0, const float *s1, uint32_t n_samples)
6
+{
7
+ uint32_t n, unrolled;
8
+ __m128 half = _mm_set1_ps(0.5f);
9
+
10
+ if (SPA_IS_ALIGNED(d, 16) &&
11
+ SPA_IS_ALIGNED(s0, 16) &&
12
+ SPA_IS_ALIGNED(s1, 16))
13
+ unrolled = n_samples & ~7;
14
+ else
15
+ unrolled = 0;
16
+
17
+ for (n = 0; n < unrolled; n += 8) {
18
+ _mm_store_ps(&dn + 0,
19
+ _mm_mul_ps(
20
+ _mm_add_ps(
21
+ _mm_load_ps(&s0n + 0),
22
+ _mm_load_ps(&s1n + 0)),
23
+ half));
24
+ _mm_store_ps(&dn + 4,
25
+ _mm_mul_ps(
26
+ _mm_add_ps(
27
+ _mm_load_ps(&s0n + 4),
28
+ _mm_load_ps(&s1n + 4)),
29
+ half));
30
+ }
31
+
32
+ for (; n < n_samples; n++)
33
+ _mm_store_ss(&dn,
34
+ _mm_mul_ss(
35
+ _mm_add_ss(
36
+ _mm_load_ss(&s0n),
37
+ _mm_load_ss(&s1n)),
38
+ half));
39
+}
40
+
41
+static inline void sub_sse(float *d, const float *s0, const float *s1, uint32_t n_samples)
42
+{
43
+ uint32_t n, unrolled;
44
+
45
+ if (SPA_IS_ALIGNED(d, 16) &&
46
+ SPA_IS_ALIGNED(s0, 16) &&
47
+ SPA_IS_ALIGNED(s1, 16))
48
+ unrolled = n_samples & ~7;
49
+ else
50
+ unrolled = 0;
51
+
52
+ for (n = 0; n < unrolled; n += 8) {
53
+ _mm_store_ps(&dn + 0,
54
+ _mm_sub_ps(_mm_load_ps(&s0n + 0), _mm_load_ps(&s1n + 0)));
55
+ _mm_store_ps(&dn + 4,
56
+ _mm_sub_ps(_mm_load_ps(&s0n + 4), _mm_load_ps(&s1n + 4)));
57
+ }
58
+ for (; n < n_samples; n++)
59
+ _mm_store_ss(&dn,
60
+ _mm_sub_ss(_mm_load_ss(&s0n), _mm_load_ss(&s1n)));
61
+}
62
+
63
void channelmix_copy_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
64
const void * SPA_RESTRICT src, uint32_t n_samples)
65
{
66
67
}
68
}
69
70
+void
71
+channelmix_f32_2_3p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
72
+ const void * SPA_RESTRICT src, uint32_t n_samples)
73
+{
74
+ uint32_t i, n, unrolled, n_dst = mix->dst_chan;
75
+ float **d = (float **)dst;
76
+ const float **s = (const float **)src;
77
+ const float v0 = mix->matrix00;
78
+ const float v1 = mix->matrix11;
79
+ const float v2 = (mix->matrix20 + mix->matrix21) * 0.5f;
80
+ const float v3 = (mix->matrix30 + mix->matrix31) * 0.5f;
81
+
82
+ if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) {
83
+ for (i = 0; i < n_dst; i++)
84
+ clear_sse(di, n_samples);
85
+ }
86
+ else {
87
+ if (mix->widen == 0.0f) {
88
+ vol_sse(d0, s0, v0, n_samples);
89
+ vol_sse(d1, s1, v1, n_samples);
90
+ avg_sse(d2, s0, s1, n_samples);
91
+ } else {
92
+ const __m128 mv0 = _mm_set1_ps(mix->matrix00);
93
+ const __m128 mv1 = _mm_set1_ps(mix->matrix11);
94
+ const __m128 mw = _mm_set1_ps(mix->widen);
95
+ const __m128 mh = _mm_set1_ps(0.5f);
96
+ __m128 t01, t11, w1, c1;
97
+
98
+ if (SPA_IS_ALIGNED(s0, 16) &&
99
+ SPA_IS_ALIGNED(s1, 16) &&
100
+ SPA_IS_ALIGNED(d0, 16) &&
101
+ SPA_IS_ALIGNED(d1, 16) &&
102
+ SPA_IS_ALIGNED(d2, 16))
103
+ unrolled = n_samples & ~3;
104
+ else
105
+ unrolled = 0;
106
+
107
+ for(n = 0; n < unrolled; n += 4) {
108
+ t00 = _mm_load_ps(&s0n);
109
+ t10 = _mm_load_ps(&s1n);
110
+ c0 = _mm_add_ps(t00, t10);
111
+ w0 = _mm_mul_ps(c0, mw);
112
+ _mm_store_ps(&d0n, _mm_mul_ps(_mm_sub_ps(t00, w0), mv0));
113
+ _mm_store_ps(&d1n, _mm_mul_ps(_mm_sub_ps(t10, w0), mv1));
114
+ _mm_store_ps(&d2n, _mm_mul_ps(c0, mh));
115
+ }
116
+ for (; n < n_samples; n++) {
117
+ t00 = _mm_load_ss(&s0n);
118
+ t10 = _mm_load_ss(&s1n);
119
+ c0 = _mm_add_ss(t00, t10);
120
+ w0 = _mm_mul_ss(c0, mw);
121
+ _mm_store_ss(&d0n, _mm_mul_ss(_mm_sub_ss(t00, w0), mv0));
122
+ _mm_store_ss(&d1n, _mm_mul_ss(_mm_sub_ss(t10, w0), mv1));
123
+ _mm_store_ss(&d2n, _mm_mul_ss(c0, mh));
124
+ }
125
+ }
126
+ lr4_process(&mix->lr43, d3, d2, v3, n_samples);
127
+ lr4_process(&mix->lr42, d2, d2, v2, n_samples);
128
+ }
129
+}
130
+
131
+void
132
+channelmix_f32_2_5p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
133
+ const void * SPA_RESTRICT src, uint32_t n_samples)
134
+{
135
+ uint32_t i, n_dst = mix->dst_chan;
136
+ float **d = (float **)dst;
137
+ const float **s = (const float **)src;
138
+ const float v4 = mix->matrix40;
139
+ const float v5 = mix->matrix51;
140
+
141
+ if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) {
142
+ for (i = 0; i < n_dst; i++)
143
+ clear_sse(di, n_samples);
144
+ }
145
+ else {
146
+ channelmix_f32_2_3p1_sse(mix, dst, src, n_samples);
147
+
148
+ if (mix->upmix != CHANNELMIX_UPMIX_PSD) {
149
+ vol_sse(d4, s0, v4, n_samples);
150
+ vol_sse(d5, s1, v5, n_samples);
151
+ } else {
152
+ sub_sse(d4, s0, s1, n_samples);
153
+
154
+ delay_convolve_run(mix->buffer1, &mix->pos1, BUFFER_SIZE, mix->delay,
155
+ mix->taps, mix->n_taps, d5, d4, -v5, n_samples);
156
+ delay_convolve_run(mix->buffer0, &mix->pos0, BUFFER_SIZE, mix->delay,
157
+ mix->taps, mix->n_taps, d4, d4, v4, n_samples);
158
+ }
159
+ }
160
+}
161
+
162
+void
163
+channelmix_f32_2_7p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
164
+ const void * SPA_RESTRICT src, uint32_t n_samples)
165
+{
166
+ uint32_t i, n_dst = mix->dst_chan;
167
+ float **d = (float **)dst;
168
+ const float **s = (const float **)src;
169
+ const float v4 = mix->matrix40;
170
+ const float v5 = mix->matrix51;
171
+ const float v6 = mix->matrix60;
172
+ const float v7 = mix->matrix71;
173
+
174
+ if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) {
175
+ for (i = 0; i < n_dst; i++)
176
+ clear_sse(di, n_samples);
177
+ }
178
+ else {
179
+ channelmix_f32_2_3p1_sse(mix, dst, src, n_samples);
180
+
181
+ vol_sse(d4, s0, v4, n_samples);
182
+ vol_sse(d5, s1, v5, n_samples);
183
+
184
+ if (mix->upmix != CHANNELMIX_UPMIX_PSD) {
185
+ vol_sse(d6, s0, v6, n_samples);
186
+ vol_sse(d7, s1, v7, n_samples);
187
+ } else {
188
+ sub_sse(d6, s0, s1, n_samples);
189
+
190
+ delay_convolve_run(mix->buffer1, &mix->pos1, BUFFER_SIZE, mix->delay,
191
+ mix->taps, mix->n_taps, d7, d6, -v7, n_samples);
192
+ delay_convolve_run(mix->buffer0, &mix->pos0, BUFFER_SIZE, mix->delay,
193
+ mix->taps, mix->n_taps, d6, d6, v6, n_samples);
194
+ }
195
+ }
196
+}
197
/* FL+FR+FC+LFE -> FL+FR */
198
void
199
channelmix_f32_3p1_2_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
200
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/channelmix-ops.c
Changed
142
1
2
#include <spa/support/cpu.h>
3
#include <spa/support/log.h>
4
#include <spa/utils/defs.h>
5
+#include <spa/debug/types.h>
6
7
#include "channelmix-ops.h"
8
#include "hilbert.h"
9
10
MAKE(4, MASK_QUAD, 1, MASK_MONO, channelmix_f32_4_1_c),
11
MAKE(4, MASK_3_1, 1, MASK_MONO, channelmix_f32_4_1_c),
12
MAKE(2, MASK_STEREO, 4, MASK_QUAD, channelmix_f32_2_4_c),
13
+#if defined (HAVE_SSE)
14
+ MAKE(2, MASK_STEREO, 4, MASK_3_1, channelmix_f32_2_3p1_sse, SPA_CPU_FLAG_SSE),
15
+#endif
16
MAKE(2, MASK_STEREO, 4, MASK_3_1, channelmix_f32_2_3p1_c),
17
+#if defined (HAVE_SSE)
18
+ MAKE(2, MASK_STEREO, 6, MASK_5_1, channelmix_f32_2_5p1_sse, SPA_CPU_FLAG_SSE),
19
+#endif
20
MAKE(2, MASK_STEREO, 6, MASK_5_1, channelmix_f32_2_5p1_c),
21
+#if defined (HAVE_SSE)
22
+ MAKE(2, MASK_STEREO, 8, MASK_7_1, channelmix_f32_2_7p1_sse, SPA_CPU_FLAG_SSE),
23
+#endif
24
MAKE(2, MASK_STEREO, 8, MASK_7_1, channelmix_f32_2_7p1_c),
25
#if defined (HAVE_SSE)
26
MAKE(4, MASK_3_1, 2, MASK_STEREO, channelmix_f32_3p1_2_sse, SPA_CPU_FLAG_SSE),
27
28
MAKE(8, MASK_7_1, 4, MASK_3_1, channelmix_f32_7p1_3p1_c),
29
30
#if defined (HAVE_SSE)
31
- MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_sse),
32
+ MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_sse, SPA_CPU_FLAG_SSE),
33
#endif
34
MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_c),
35
};
36
37
static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uint64_t src_mask,
38
uint32_t dst_chan, uint64_t dst_mask, uint32_t cpu_flags)
39
{
40
- size_t i;
41
- for (i = 0; i < SPA_N_ELEMENTS(channelmix_table); i++) {
42
- if (!MATCH_CPU_FLAGS(channelmix_tablei.cpu_flags, cpu_flags))
43
+ SPA_FOR_EACH_ELEMENT_VAR(channelmix_table, info) {
44
+ if (!MATCH_CPU_FLAGS(info->cpu_flags, cpu_flags))
45
continue;
46
47
if (src_chan == dst_chan && src_mask == dst_mask)
48
- return &channelmix_tablei;
49
+ return info;
50
51
- if (MATCH_CHAN(channelmix_tablei.src_chan, src_chan) &&
52
- MATCH_CHAN(channelmix_tablei.dst_chan, dst_chan) &&
53
- MATCH_MASK(channelmix_tablei.src_mask, src_mask) &&
54
- MATCH_MASK(channelmix_tablei.dst_mask, dst_mask))
55
- return &channelmix_tablei;
56
+ if (MATCH_CHAN(info->src_chan, src_chan) &&
57
+ MATCH_CHAN(info->dst_chan, dst_chan) &&
58
+ MATCH_MASK(info->src_mask, src_mask) &&
59
+ MATCH_MASK(info->dst_mask, dst_mask))
60
+ return info;
61
}
62
return NULL;
63
}
64
65
_MATRIX(SL,RL) += 1.0f;
66
_MATRIX(SR,RR) += 1.0f;
67
}
68
+ keep &= ~SIDE;
69
} else if (dst_mask & STEREO) {
70
spa_log_debug(mix->log, "assign RL+RR to FL+FR (%f)", slev);
71
if (matrix_encoding == MATRIX_DOLBY) {
72
73
_MATRIX(RL,SL) += 1.0f;
74
_MATRIX(RR,SR) += 1.0f;
75
}
76
+ keep &= ~REAR;
77
} else if (dst_mask & _MASK(RC)) {
78
spa_log_debug(mix->log, "assign SL+SR to RC (%f)", SQRT1_2);
79
_MATRIX(RC,SL)+= SQRT1_2;
80
81
spa_log_debug(mix->log, "won't produce SIDE");
82
}
83
}
84
+ if (unassigned & _MASK(RC)) {
85
+ if ((src_mask & REAR) == REAR) {
86
+ spa_log_debug(mix->log, "produce RC from REAR (%f)", 0.5f);
87
+ _MATRIX(RC,RL) += 0.5f;
88
+ _MATRIX(RC,RR) += 0.5f;
89
+ } else if ((src_mask & SIDE) == SIDE) {
90
+ spa_log_debug(mix->log, "produce RC from SIDE (%f)", 0.5f);
91
+ _MATRIX(RC,SL) += 0.5f;
92
+ _MATRIX(RC,SR) += 0.5f;
93
+ } else if ((src_mask & STEREO) == STEREO) {
94
+ spa_log_debug(mix->log, "produce RC from STEREO (%f)", 0.5f);
95
+ _MATRIX(RC,FL) += 0.5f;
96
+ _MATRIX(RC,FR) += 0.5f;
97
+ } else if ((src_mask & FRONT) == FRONT &&
98
+ mix->upmix == CHANNELMIX_UPMIX_SIMPLE) {
99
+ spa_log_debug(mix->log, "produce RC from FC (%f)", slev);
100
+ _MATRIX(RC,FC) += slev;
101
+ } else {
102
+ spa_log_debug(mix->log, "won't produce RC");
103
+ }
104
+ }
105
106
done:
107
for (jc = 0, ic = 0, i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) {
108
float sum = 0.0f;
109
+ char str1024, str21024;
110
+ int idx = 0, idx2 = 0;
111
if ((dst_mask & (1UL << i)) == 0)
112
continue;
113
for (jc = 0, j = 0; j < SPA_AUDIO_MAX_CHANNELS; j++) {
114
115
continue;
116
if (ic >= dst_chan || jc >= src_chan)
117
continue;
118
+
119
+ if (i == 0)
120
+ idx2 += snprintf(str2 + idx2, sizeof(str2) - idx2, "%-4.4s ",
121
+ spa_debug_type_find_short_name(spa_type_audio_channel, j + 3));
122
+
123
mix->matrix_origicjc++ = matrixij;
124
sum += fabs(matrixij);
125
+
126
+ if (matrixij == 0.0f)
127
+ idx += snprintf(str + idx, sizeof(str) - idx, " ");
128
+ else
129
+ idx += snprintf(str + idx, sizeof(str) - idx, "%1.3f ", matrixij);
130
}
131
+ if (dst_mask != 0 && src_mask != 0 && sum > 0.0f) {
132
+ if (i == 0)
133
+ spa_log_info(mix->log, " %s", str2);
134
+ spa_log_info(mix->log, "%-4.4s %s %f",
135
+ spa_debug_type_find_short_name(spa_type_audio_channel, i + 3),
136
+ str, sum);
137
+ }
138
+
139
maxsum = SPA_MAX(maxsum, sum);
140
if (i == _CH(LFE) && mix->lfe_cutoff > 0.0f && filter_lfe) {
141
spa_log_info(mix->log, "channel %d is LFE cutoff:%f", ic, mix->lfe_cutoff);
142
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops.h -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/channelmix-ops.h
Changed
25
1
2
3
static inline uint32_t channelmix_upmix_from_label(const char *label)
4
{
5
- uint32_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(channelmix_upmix_info); i++) {
7
- if (spa_streq(channelmix_upmix_infoi.label, label))
8
- return channelmix_upmix_infoi.upmix;
9
+ SPA_FOR_EACH_ELEMENT_VAR(channelmix_upmix_info, i) {
10
+ if (spa_streq(i->label, label))
11
+ return i->upmix;
12
}
13
return CHANNELMIX_UPMIX_NONE;
14
}
15
16
#if defined (HAVE_SSE)
17
DEFINE_FUNCTION(copy, sse);
18
DEFINE_FUNCTION(f32_n_m, sse);
19
+DEFINE_FUNCTION(f32_2_3p1, sse);
20
+DEFINE_FUNCTION(f32_2_5p1, sse);
21
+DEFINE_FUNCTION(f32_2_7p1, sse);
22
DEFINE_FUNCTION(f32_3p1_2, sse);
23
DEFINE_FUNCTION(f32_5p1_2, sse);
24
DEFINE_FUNCTION(f32_5p1_3p1, sse);
25
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/fmt-ops.c
Changed
59
1
2
static const struct conv_info *find_conv_info(uint32_t src_fmt, uint32_t dst_fmt,
3
uint32_t n_channels, uint32_t cpu_flags, uint32_t conv_flags)
4
{
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(conv_table); i++) {
7
- if (conv_tablei.src_fmt == src_fmt &&
8
- conv_tablei.dst_fmt == dst_fmt &&
9
- MATCH_CHAN(conv_tablei.n_channels, n_channels) &&
10
- MATCH_CPU_FLAGS(conv_tablei.cpu_flags, cpu_flags) &&
11
- MATCH_DITHER(conv_tablei.conv_flags, conv_flags))
12
- return &conv_tablei;
13
+ SPA_FOR_EACH_ELEMENT_VAR(conv_table, c) {
14
+ if (c->src_fmt == src_fmt &&
15
+ c->dst_fmt == dst_fmt &&
16
+ MATCH_CHAN(c->n_channels, n_channels) &&
17
+ MATCH_CPU_FLAGS(c->cpu_flags, cpu_flags) &&
18
+ MATCH_DITHER(c->conv_flags, conv_flags))
19
+ return c;
20
}
21
return NULL;
22
}
23
24
static const struct noise_info *find_noise_info(uint32_t method,
25
uint32_t cpu_flags)
26
{
27
- size_t i;
28
- for (i = 0; i < SPA_N_ELEMENTS(noise_table); i++) {
29
- if (noise_tablei.method == method &&
30
- MATCH_CPU_FLAGS(noise_tablei.cpu_flags, cpu_flags))
31
- return &noise_tablei;
32
+ SPA_FOR_EACH_ELEMENT_VAR(noise_table, t) {
33
+ if (t->method == method &&
34
+ MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags))
35
+ return t;
36
}
37
return NULL;
38
}
39
40
41
static const struct dither_info *find_dither_info(uint32_t method, uint32_t rate)
42
{
43
- size_t i;
44
-
45
- for (i = 0; i < SPA_N_ELEMENTS(dither_info); i++) {
46
- const struct dither_info *di = &dither_infoi;
47
+ SPA_FOR_EACH_ELEMENT_VAR(dither_info, di) {
48
if (di->method != method)
49
continue;
50
/* don't use shaped for too low rates, it moves the noise to
51
* audible ranges */
52
if (di->ns != NULL && rate < di->rate * 3 / 4)
53
return find_dither_info(DITHER_METHOD_TRIANGULAR_HF, rate);
54
- return &dither_infoi;
55
+ return di;
56
}
57
return NULL;
58
}
59
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops.h -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/fmt-ops.h
Changed
15
1
2
3
static inline uint32_t dither_method_from_label(const char *label)
4
{
5
- uint32_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(dither_method_info); i++) {
7
- if (spa_streq(dither_method_infoi.label, label))
8
- return dither_method_infoi.method;
9
+ SPA_FOR_EACH_ELEMENT_VAR(dither_method_info, i) {
10
+ if (spa_streq(i->label, label))
11
+ return i->method;
12
}
13
return DITHER_METHOD_NONE;
14
}
15
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/peaks-ops.c
Changed
16
1
2
3
static const struct peaks_info *find_peaks_info(uint32_t cpu_flags)
4
{
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(peaks_table); i++) {
7
- if (!MATCH_CPU_FLAGS(peaks_tablei.cpu_flags, cpu_flags))
8
- continue;
9
- return &peaks_tablei;
10
+ SPA_FOR_EACH_ELEMENT_VAR(peaks_table, t) {
11
+ if (MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags))
12
+ return t;
13
}
14
return NULL;
15
}
16
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/resample-native.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/resample-native.c
Changed
34
1
2
(alpha / 2.0) * cos(2.0 * x);
3
return r;
4
}
5
+
6
static inline double window_cosh(double x, double n_taps)
7
{
8
double r;
9
10
return r;
11
}
12
13
-#define window window_cosh
14
+#define window (1 ? window_cosh : window_blackman)
15
16
static int build_filter(float *taps, uint32_t stride, uint32_t n_taps, uint32_t n_phases, double cutoff)
17
{
18
19
#define MATCH_CPU_FLAGS(a,b) ((a) == 0 || ((a) & (b)) == a)
20
static const struct resample_info *find_resample_info(uint32_t format, uint32_t cpu_flags)
21
{
22
- size_t i;
23
- for (i = 0; i < SPA_N_ELEMENTS(resample_table); i++) {
24
- if (resample_tablei.format == format &&
25
- MATCH_CPU_FLAGS(resample_tablei.cpu_flags, cpu_flags))
26
- return &resample_tablei;
27
+ SPA_FOR_EACH_ELEMENT_VAR(resample_table, t) {
28
+ if (t->format == format &&
29
+ MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags))
30
+ return t;
31
}
32
return NULL;
33
}
34
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-audioconvert.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/test-audioconvert.c
Changed
201
1
2
3
res = memcmp(b->datasj.data, out_data->datak, out_data->size);
4
if (res != 0) {
5
- fprintf(stderr, "error plane %d\n", j);
6
+ fprintf(stderr, "error port %d plane %d\n", i, j);
7
spa_debug_mem(0, b->datasj.data, out_data->size);
8
- spa_debug_mem(0, out_data->dataj, out_data->size);
9
+ spa_debug_mem(0, out_data->datak, out_data->size);
10
}
11
spa_assert_se(res == 0);
12
13
14
static const float data_f32p_3 = { 0.3f, 0.3f, 0.3f, 0.3f };
15
static const float data_f32p_4 = { 0.4f, 0.4f, 0.4f, 0.4f };
16
static const float data_f32p_5 = { 0.5f, 0.5f, 0.5f, 0.5f };
17
+static const float data_f32p_5_6p1 = { 0.953553438f, 0.953553438f, 0.953553438f, 0.953553438f };
18
static const float data_f32p_6 = { 0.6f, 0.6f, 0.6f, 0.6f };
19
+static const float data_f32p_6_6p1 = { 1.053553343f, 1.053553343f, 1.053553343f, 1.053553343f };
20
static const float data_f32p_7 = { 0.7f, 0.7f, 0.7f, 0.7f };
21
static const float data_f32p_8 = { 0.8f, 0.8f, 0.8f, 0.8f };
22
23
24
0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f,
25
0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f,
26
0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f };
27
+static const float data_f32_6p1 = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f,
28
+ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f,
29
+ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f,
30
+ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f };
31
+static const float data_f32_6p1_from_5p1 = { 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f,
32
+ 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f,
33
+ 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f,
34
+ 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f };
35
36
static const float data_f32_7p1_remapped = { 0.1f, 0.2f, 0.5f, 0.6f, 0.7f, 0.8f, 0.3f, 0.4f,
37
0.1f, 0.2f, 0.5f, 0.6f, 0.7f, 0.8f, 0.3f, 0.4f,
38
39
.size = sizeof(float) * 4
40
};
41
42
+struct data dsp_5p1_from_6p1 = {
43
+ .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp,
44
+ .info = SPA_AUDIO_INFO_RAW_INIT(
45
+ .format = SPA_AUDIO_FORMAT_F32,
46
+ .rate = 48000,
47
+ .channels = 6,
48
+ .position = {
49
+ SPA_AUDIO_CHANNEL_FL,
50
+ SPA_AUDIO_CHANNEL_FR,
51
+ SPA_AUDIO_CHANNEL_FC,
52
+ SPA_AUDIO_CHANNEL_LFE,
53
+ SPA_AUDIO_CHANNEL_RL,
54
+ SPA_AUDIO_CHANNEL_RR,
55
+ }),
56
+ .ports = 6,
57
+ .planes = 1,
58
+ .data = { data_f32p_1, data_f32p_2, data_f32p_3, data_f32p_4, data_f32p_5_6p1, data_f32p_6_6p1, },
59
+ .size = sizeof(float) * 4
60
+};
61
+
62
+
63
struct data dsp_5p1_remapped = {
64
.mode = SPA_PARAM_PORT_CONFIG_MODE_dsp,
65
.info = SPA_AUDIO_INFO_RAW_INIT(
66
67
.size = sizeof(float) * 4
68
};
69
70
+struct data dsp_5p1_remapped_from_6p1 = {
71
+ .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp,
72
+ .info = SPA_AUDIO_INFO_RAW_INIT(
73
+ .format = SPA_AUDIO_FORMAT_F32,
74
+ .rate = 48000,
75
+ .channels = 6,
76
+ .position = {
77
+ SPA_AUDIO_CHANNEL_FL,
78
+ SPA_AUDIO_CHANNEL_FR,
79
+ SPA_AUDIO_CHANNEL_RL,
80
+ SPA_AUDIO_CHANNEL_RR,
81
+ SPA_AUDIO_CHANNEL_FC,
82
+ SPA_AUDIO_CHANNEL_LFE,
83
+ }),
84
+ .ports = 6,
85
+ .planes = 1,
86
+ .data = { data_f32p_1, data_f32p_2, data_f32p_5_6p1, data_f32p_6_6p1, data_f32p_3, data_f32p_4, },
87
+ .size = sizeof(float) * 4
88
+};
89
+
90
+struct data dsp_6p1 = {
91
+ .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp,
92
+ .info = SPA_AUDIO_INFO_RAW_INIT(
93
+ .format = SPA_AUDIO_FORMAT_F32,
94
+ .rate = 48000,
95
+ .channels = 7,
96
+ .position = {
97
+ SPA_AUDIO_CHANNEL_FL,
98
+ SPA_AUDIO_CHANNEL_FR,
99
+ SPA_AUDIO_CHANNEL_FC,
100
+ SPA_AUDIO_CHANNEL_LFE,
101
+ SPA_AUDIO_CHANNEL_RC,
102
+ SPA_AUDIO_CHANNEL_RL,
103
+ SPA_AUDIO_CHANNEL_RR,
104
+ }),
105
+ .ports = 7,
106
+ .planes = 1,
107
+ .data = { data_f32p_1, data_f32p_2, data_f32p_3, data_f32p_4, data_f32p_5, data_f32p_6, data_f32p_7 },
108
+ .size = sizeof(float) * 4
109
+};
110
+
111
+struct data dsp_6p1_side = {
112
+ .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp,
113
+ .info = SPA_AUDIO_INFO_RAW_INIT(
114
+ .format = SPA_AUDIO_FORMAT_F32,
115
+ .rate = 48000,
116
+ .channels = 7,
117
+ .position = {
118
+ SPA_AUDIO_CHANNEL_FL,
119
+ SPA_AUDIO_CHANNEL_FR,
120
+ SPA_AUDIO_CHANNEL_FC,
121
+ SPA_AUDIO_CHANNEL_LFE,
122
+ SPA_AUDIO_CHANNEL_RC,
123
+ SPA_AUDIO_CHANNEL_SL,
124
+ SPA_AUDIO_CHANNEL_SR,
125
+ }),
126
+ .ports = 7,
127
+ .planes = 1,
128
+ .data = { data_f32p_1, data_f32p_2, data_f32p_3, data_f32p_4, data_f32p_5, data_f32p_6, data_f32p_7 },
129
+ .size = sizeof(float) * 4
130
+};
131
+
132
struct data dsp_7p1_remapped = {
133
.mode = SPA_PARAM_PORT_CONFIG_MODE_dsp,
134
.info = SPA_AUDIO_INFO_RAW_INIT(
135
136
.size = sizeof(float) * 4
137
};
138
139
+struct data conv_f32_48000_6p1 = {
140
+ .mode = SPA_PARAM_PORT_CONFIG_MODE_convert,
141
+ .info = SPA_AUDIO_INFO_RAW_INIT(
142
+ .format = SPA_AUDIO_FORMAT_F32,
143
+ .rate = 48000,
144
+ .channels = 7,
145
+ .position = {
146
+ SPA_AUDIO_CHANNEL_FL,
147
+ SPA_AUDIO_CHANNEL_FR,
148
+ SPA_AUDIO_CHANNEL_FC,
149
+ SPA_AUDIO_CHANNEL_LFE,
150
+ SPA_AUDIO_CHANNEL_RC,
151
+ SPA_AUDIO_CHANNEL_RL,
152
+ SPA_AUDIO_CHANNEL_RR,
153
+ }),
154
+ .ports = 1,
155
+ .planes = 1,
156
+ .data = { data_f32_6p1 },
157
+ .size = sizeof(data_f32_6p1)
158
+};
159
+
160
+struct data conv_f32_48000_6p1_from_5p1 = {
161
+ .mode = SPA_PARAM_PORT_CONFIG_MODE_convert,
162
+ .info = SPA_AUDIO_INFO_RAW_INIT(
163
+ .format = SPA_AUDIO_FORMAT_F32,
164
+ .rate = 48000,
165
+ .channels = 7,
166
+ .position = {
167
+ SPA_AUDIO_CHANNEL_FL,
168
+ SPA_AUDIO_CHANNEL_FR,
169
+ SPA_AUDIO_CHANNEL_FC,
170
+ SPA_AUDIO_CHANNEL_LFE,
171
+ SPA_AUDIO_CHANNEL_RC,
172
+ SPA_AUDIO_CHANNEL_RL,
173
+ SPA_AUDIO_CHANNEL_RR,
174
+ }),
175
+ .ports = 1,
176
+ .planes = 1,
177
+ .data = { data_f32_6p1_from_5p1 },
178
+ .size = sizeof(data_f32_6p1_from_5p1)
179
+};
180
+
181
+struct data conv_f32_48000_6p1_side = {
182
+ .mode = SPA_PARAM_PORT_CONFIG_MODE_convert,
183
+ .info = SPA_AUDIO_INFO_RAW_INIT(
184
+ .format = SPA_AUDIO_FORMAT_F32,
185
+ .rate = 48000,
186
+ .channels = 7,
187
+ .position = {
188
+ SPA_AUDIO_CHANNEL_FL,
189
+ SPA_AUDIO_CHANNEL_FR,
190
+ SPA_AUDIO_CHANNEL_FC,
191
+ SPA_AUDIO_CHANNEL_LFE,
192
+ SPA_AUDIO_CHANNEL_RC,
193
+ SPA_AUDIO_CHANNEL_SL,
194
+ SPA_AUDIO_CHANNEL_SR,
195
+ }),
196
+ .ports = 1,
197
+ .planes = 1,
198
+ .data = { data_f32_6p1 },
199
+ .size = sizeof(data_f32_6p1)
200
+};
201
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-channelmix.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/test-channelmix.c
Changed
56
1
2
0.0, 0.0, 0.0, 0.0, 0.0, 1.0));
3
}
4
5
+static void test_6p1_N(void)
6
+{
7
+ test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RC)|_M(SL)|_M(SR), 1, _M(MONO), 0,
8
+ MATRIX(0.707107, 0.707107, 1.0, 0.0, 0.5, 0.5, 0.5));
9
+ test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RC),
10
+ 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR), 0,
11
+ MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
12
+ 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
13
+ 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
14
+ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
15
+ 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.707107,
16
+ 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.707107));
17
+ test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RC),
18
+ 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RL)|_M(RR), 0,
19
+ MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
20
+ 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
21
+ 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
22
+ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
23
+ 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.707107,
24
+ 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.707107));
25
+ test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RC)|_M(RL)|_M(RR),
26
+ 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RL)|_M(RR), 0,
27
+ MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
28
+ 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
29
+ 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
30
+ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
31
+ 0.0, 0.0, 0.0, 0.0, 0.707107, 1.0, 0.0,
32
+ 0.0, 0.0, 0.0, 0.0, 0.707107, 0.0, 1.0));
33
+ test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RC),
34
+ 8, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RL)|_M(RR), 0,
35
+ MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
36
+ 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
37
+ 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
38
+ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
39
+ 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
40
+ 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
41
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.707107,
42
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.707107));
43
+}
44
+
45
static void test_7p1_N(void)
46
{
47
test_mix(8, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RL)|_M(RR), 1, _M(MONO), 0,
48
49
test_3p1_N();
50
test_4_N();
51
test_5p1_N();
52
+ test_6p1_N();
53
test_7p1_N();
54
55
test_n_m_impl();
56
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/test-source.c
Changed
28
1
2
case SPA_AUDIO_FORMAT_S24:
3
case SPA_AUDIO_FORMAT_S24_OE:
4
return 3;
5
- default:
6
+ case SPA_AUDIO_FORMAT_S32P:
7
+ case SPA_AUDIO_FORMAT_S32:
8
+ case SPA_AUDIO_FORMAT_S32_OE:
9
return 4;
10
+ default:
11
+ return 0;
12
}
13
}
14
15
16
return res;
17
18
port->stride = calc_width(&info);
19
+ if (port->stride == 0)
20
+ return -EINVAL;
21
+ if (info.info.raw.rate == 0 ||
22
+ info.info.raw.channels == 0)
23
+ return -EINVAL;
24
+
25
if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) {
26
port->blocks = info.info.raw.channels;
27
}
28
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/volume-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/volume-ops.c
Changed
16
1
2
3
static const struct volume_info *find_volume_info(uint32_t cpu_flags)
4
{
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(volume_table); i++) {
7
- if (!MATCH_CPU_FLAGS(volume_tablei.cpu_flags, cpu_flags))
8
- continue;
9
- return &volume_tablei;
10
+ SPA_FOR_EACH_ELEMENT_VAR(volume_table, t) {
11
+ if (MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags))
12
+ return t;
13
}
14
return NULL;
15
}
16
pipewire-0.3.59.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiomixer/audiomixer.c
Changed
12
1
2
if (memcmp(&info, &this->format, sizeof(struct spa_audio_info)))
3
return -EINVAL;
4
} else {
5
+ if (info.info.raw.format == 0 ||
6
+ info.info.raw.channels == 0)
7
+ return -EINVAL;
8
+
9
this->ops.fmt = info.info.raw.format;
10
this->ops.n_channels = info.info.raw.channels;
11
this->ops.cpu_flags = this->cpu_flags;
12
pipewire-0.3.59.tar.gz/spa/plugins/audiomixer/mix-ops-avx.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiomixer/mix-ops-avx.c
Changed
64
1
2
3
#include <immintrin.h>
4
5
-static inline void mix_4(float * dst,
6
- const float * SPA_RESTRICT src0,
7
- const float * SPA_RESTRICT src1,
8
- const float * SPA_RESTRICT src2,
9
- uint32_t n_samples)
10
-{
11
- uint32_t n, unrolled;
12
-
13
- if (SPA_IS_ALIGNED(src0, 32) &&
14
- SPA_IS_ALIGNED(src1, 32) &&
15
- SPA_IS_ALIGNED(src2, 32) &&
16
- SPA_IS_ALIGNED(dst, 32))
17
- unrolled = n_samples & ~15;
18
- else
19
- unrolled = 0;
20
-
21
- for (n = 0; n < unrolled; n += 16) {
22
- __m256 in14, in24;
23
-
24
- in10 = _mm256_load_ps(&dstn + 0);
25
- in20 = _mm256_load_ps(&dstn + 8);
26
- in11 = _mm256_load_ps(&src0n + 0);
27
- in21 = _mm256_load_ps(&src0n + 8);
28
- in12 = _mm256_load_ps(&src1n + 0);
29
- in22 = _mm256_load_ps(&src1n + 8);
30
- in13 = _mm256_load_ps(&src2n + 0);
31
- in23 = _mm256_load_ps(&src2n + 8);
32
-
33
- in10 = _mm256_add_ps(in10, in11);
34
- in20 = _mm256_add_ps(in20, in21);
35
- in12 = _mm256_add_ps(in12, in13);
36
- in22 = _mm256_add_ps(in22, in23);
37
- in10 = _mm256_add_ps(in10, in12);
38
- in20 = _mm256_add_ps(in20, in22);
39
-
40
- _mm256_store_ps(&dstn + 0, in10);
41
- _mm256_store_ps(&dstn + 8, in20);
42
- }
43
- for (; n < n_samples; n++) {
44
- __m128 in4;
45
- in0 = _mm_load_ss(&dstn),
46
- in1 = _mm_load_ss(&src0n),
47
- in2 = _mm_load_ss(&src1n),
48
- in3 = _mm_load_ss(&src2n),
49
- in0 = _mm_add_ss(in0, in1);
50
- in2 = _mm_add_ss(in2, in3);
51
- in0 = _mm_add_ss(in0, in2);
52
- _mm_store_ss(&dstn, in0);
53
- }
54
-}
55
-
56
-
57
-static inline void mix_2(float * dst, const float * SPA_RESTRICT src, uint32_t n_samples)
58
-{
59
-}
60
-
61
void
62
mix_f32_avx(struct mix_ops *ops, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
63
uint32_t n_src, uint32_t n_samples)
64
pipewire-0.3.59.tar.gz/spa/plugins/audiomixer/mix-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiomixer/mix-ops.c
Changed
20
1
2
static const struct mix_info *find_mix_info(uint32_t fmt,
3
uint32_t n_channels, uint32_t cpu_flags)
4
{
5
- size_t i;
6
-
7
- for (i = 0; i < SPA_N_ELEMENTS(mix_table); i++) {
8
- if (mix_tablei.fmt == fmt &&
9
- MATCH_CHAN(mix_tablei.n_channels, n_channels) &&
10
- MATCH_CPU_FLAGS(mix_tablei.cpu_flags, cpu_flags))
11
- return &mix_tablei;
12
+ SPA_FOR_EACH_ELEMENT_VAR(mix_table, t) {
13
+ if (t->fmt == fmt &&
14
+ MATCH_CHAN(t->n_channels, n_channels) &&
15
+ MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags))
16
+ return t;
17
}
18
return NULL;
19
}
20
pipewire-0.3.59.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c
Changed
12
1
2
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
3
return -EINVAL;
4
5
+ if (info.info.raw.rate == 0 ||
6
+ info.info.raw.channels == 0)
7
+ return -EINVAL;
8
+
9
switch (info.info.raw.format) {
10
case SPA_AUDIO_FORMAT_S16:
11
idx = 0;
12
pipewire-0.3.59.tar.gz/spa/plugins/avb/avb-pcm.c -> pipewire-0.3.60.tar.gz/spa/plugins/avb/avb-pcm.c
Changed
44
1
2
}
3
}
4
5
-static int frame_size(uint32_t format)
6
+static int calc_frame_size(uint32_t format)
7
{
8
switch(format) {
9
case SPA_AUDIO_FORMAT_F32_BE:
10
11
SPA_AVBTP_PACKET_AAF_SET_FORMAT(pdu, spa_format_to_aaf(state->format));
12
SPA_AVBTP_PACKET_AAF_SET_NSR(pdu, spa_rate_to_aaf(state->rate));
13
SPA_AVBTP_PACKET_AAF_SET_CHAN_PER_FRAME(pdu, state->channels);
14
- SPA_AVBTP_PACKET_AAF_SET_BIT_DEPTH(pdu, frame_size(state->format)*8);
15
+ SPA_AVBTP_PACKET_AAF_SET_BIT_DEPTH(pdu, calc_frame_size(state->format)*8);
16
SPA_AVBTP_PACKET_AAF_SET_DATA_LEN(pdu, payload_size);
17
SPA_AVBTP_PACKET_AAF_SET_SP(pdu, SPA_AVBTP_AAF_PCM_SP_NORMAL);
18
}
19
20
21
int spa_avb_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t flags)
22
{
23
- int res;
24
+ int res, frame_size;
25
struct props *p = &state->props;
26
27
+ frame_size = calc_frame_size(fmt->info.raw.format);
28
+ if (frame_size == 0)
29
+ return -EINVAL;
30
+
31
+ if (fmt->info.raw.rate == 0 ||
32
+ fmt->info.raw.channels == 0)
33
+ return -EINVAL;
34
+
35
state->format = fmt->info.raw.format;
36
state->rate = fmt->info.raw.rate;
37
state->channels = fmt->info.raw.channels;
38
state->blocks = 1;
39
- state->stride = state->channels * frame_size(state->format);
40
+ state->stride = state->channels * frame_size;
41
42
if ((res = setup_socket(state)) < 0)
43
return res;
44
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c
Changed
47
1
2
spa_pod_builder_push_choice(b, &f1, SPA_CHOICE_None, 0);
3
choice = (struct spa_pod_choice*)spa_pod_builder_frame(b, &f1);
4
i = 0;
5
- for (size_t j = 0; j < SPA_N_ELEMENTS(aac_frequencies); j++) {
6
- if (AAC_GET_FREQUENCY(conf) & aac_frequenciesj.config) {
7
+ SPA_FOR_EACH_ELEMENT_VAR(aac_frequencies, f) {
8
+ if (AAC_GET_FREQUENCY(conf) & f->config) {
9
if (i++ == 0)
10
- spa_pod_builder_int(b, aac_frequenciesj.value);
11
- spa_pod_builder_int(b, aac_frequenciesj.value);
12
+ spa_pod_builder_int(b, f->value);
13
+ spa_pod_builder_int(b, f->value);
14
}
15
}
16
if (i == 0)
17
18
if (!(conf.object_type & (AAC_OBJECT_TYPE_MPEG2_AAC_LC |
19
AAC_OBJECT_TYPE_MPEG4_AAC_LC)))
20
return -EINVAL;
21
-
22
- for (j = 0; j < SPA_N_ELEMENTS(aac_frequencies); ++j) {
23
- if (AAC_GET_FREQUENCY(conf) & aac_frequenciesj.config) {
24
- info->info.raw.rate = aac_frequenciesj.value;
25
+ j = 0;
26
+ SPA_FOR_EACH_ELEMENT_VAR(aac_frequencies, f) {
27
+ if (AAC_GET_FREQUENCY(conf) & f->config) {
28
+ info->info.raw.rate = f->value;
29
+ j++;
30
break;
31
}
32
}
33
- if (j == SPA_N_ELEMENTS(aac_frequencies))
34
+ if (j == 0)
35
return -EINVAL;
36
37
if (conf.channels & AAC_CHANNELS_2) {
38
39
if (res != AACENC_OK)
40
return -EINVAL;
41
42
- return 0;
43
+ return this->cur_bitrate;
44
}
45
46
static int codec_reduce_bitpool(void *data)
47
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c
Changed
23
1
2
static int codec_reduce_bitpool(void *data)
3
{
4
struct impl *this = data;
5
- this->e.next_bitrate = this->bitrate * 3 / 4;
6
- return 0;
7
+ this->e.next_bitrate = SPA_CLAMP(this->bitrate * 3 / 4,
8
+ BITRATE_MIN * this->channels, BITRATE_MAX * this->channels);
9
+ return this->e.next_bitrate;
10
}
11
12
static int codec_increase_bitpool(void *data)
13
{
14
struct impl *this = data;
15
- this->e.next_bitrate = this->bitrate * 5 / 4;
16
- return 0;
17
+ this->e.next_bitrate = SPA_CLAMP(this->bitrate * 5 / 4,
18
+ BITRATE_MIN * this->channels, BITRATE_MAX * this->channels);
19
+ return this->e.next_bitrate;
20
}
21
22
const struct media_codec a2dp_codec_lc3plus_hr = {
23
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c
Changed
52
1
2
.codec_id = A2DP_CODEC_VENDOR, \
3
.vendor = { .vendor_id = OPUS_05_VENDOR_ID, \
4
.codec_id = OPUS_05_CODEC_ID }, \
5
- .fill_caps = codec_fill_caps, \
6
.select_config = codec_select_config, \
7
.enum_config = codec_enum_config, \
8
.validate_config = codec_validate_config, \
9
10
.id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05,
11
.name = "opus_05",
12
.description = "Opus",
13
+ .fill_caps = codec_fill_caps,
14
};
15
16
const struct media_codec a2dp_codec_opus_05_51 = {
17
18
.id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51,
19
.name = "opus_05_51",
20
.description = "Opus 5.1 Surround",
21
+ .endpoint_name = "opus_05",
22
+ .fill_caps = NULL,
23
};
24
25
const struct media_codec a2dp_codec_opus_05_71 = {
26
27
.id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71,
28
.name = "opus_05_71",
29
.description = "Opus 7.1 Surround",
30
+ .endpoint_name = "opus_05",
31
+ .fill_caps = NULL,
32
};
33
34
/* Bidi return channel codec: doesn't have endpoints */
35
36
.name = "opus_05_duplex",
37
.description = "Opus Duplex",
38
.duplex_codec = &a2dp_codec_opus_05_return,
39
+ .fill_caps = codec_fill_caps,
40
};
41
42
const struct media_codec a2dp_codec_opus_05_pro = {
43
44
.init_props = codec_init_props,
45
.clear_props = codec_clear_props,
46
.duplex_codec = &a2dp_codec_opus_05_return,
47
+ .endpoint_name = "opus_05_duplex",
48
+ .fill_caps = NULL,
49
};
50
51
MEDIA_CODEC_EXPORT_DEF(
52
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
201
1
2
#include <libusb.h>
3
#endif
4
5
+#include "modemmanager.h"
6
+#include "upower.h"
7
+
8
static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.native");
9
#undef SPA_LOG_TOPIC_DEFAULT
10
#define SPA_LOG_TOPIC_DEFAULT &log_topic
11
12
#define HFP_CODEC_SWITCH_INITIAL_TIMEOUT_MSEC 5000
13
#define HFP_CODEC_SWITCH_TIMEOUT_MSEC 20000
14
15
+#define INTERNATIONAL_NUMBER 145
16
+#define NATIONAL_NUMBER 129
17
+
18
+#define MAX_HF_INDICATORS 16
19
+
20
enum {
21
HFP_AG_INITIAL_CODEC_SETUP_NONE = 0,
22
HFP_AG_INITIAL_CODEC_SETUP_SEND,
23
HFP_AG_INITIAL_CODEC_SETUP_WAIT
24
};
25
26
+#define CIND_INDICATORS "(\"service\",(0-1)),(\"call\",(0-1)),(\"callsetup\",(0-3)),(\"callheld\",(0-2)),(\"signal\",(0-5)),(\"roam\",(0-1)),\"battchg\",(0-5))"
27
+enum {
28
+ CIND_SERVICE = 1,
29
+ CIND_CALL,
30
+ CIND_CALLSETUP,
31
+ CIND_CALLHELD,
32
+ CIND_SIGNAL,
33
+ CIND_ROAM,
34
+ CIND_BATTERY_LEVEL,
35
+ CIND_MAX
36
+};
37
+
38
+struct modem {
39
+ bool network_has_service;
40
+ unsigned int signal_strength;
41
+ bool network_is_roaming;
42
+ char *operator_name;
43
+ char *own_number;
44
+ bool active_call;
45
+ unsigned int call_setup;
46
+};
47
+
48
struct impl {
49
struct spa_bt_backend this;
50
51
52
53
struct spa_list rfcomm_list;
54
unsigned int defer_setup_enabled:1;
55
+
56
+ struct modem modem;
57
+ unsigned int battery_level;
58
+
59
+ void *modemmanager;
60
+ struct spa_source *ring_timer;
61
+ void *upower;
62
};
63
64
struct transport_data {
65
66
unsigned int hfp_ag_initial_codec_setup:2;
67
unsigned int cind_call_active:1;
68
unsigned int cind_call_notify:1;
69
+ unsigned int extended_error_reporting:1;
70
+ unsigned int clip_notify:1;
71
enum hfp_hf_state hf_state;
72
enum hsp_hs_state hs_state;
73
unsigned int codec;
74
+ uint32_t cind_enabled_indicators;
75
+ char *hf_indicatorsMAX_HF_INDICATORS;
76
#endif
77
};
78
79
80
static void rfcomm_free(struct rfcomm *rfcomm)
81
{
82
codec_switch_stop_timer(rfcomm);
83
+ for (int i = 0; i < MAX_HF_INDICATORS; i++) {
84
+ if (rfcomm->hf_indicatorsi) {
85
+ free(rfcomm->hf_indicatorsi);
86
+ }
87
+ }
88
spa_list_remove(&rfcomm->link);
89
if (rfcomm->path)
90
free(rfcomm->path);
91
92
return len;
93
}
94
95
+static void rfcomm_send_error(const struct rfcomm *rfcomm, enum cmee_error error)
96
+{
97
+ if (rfcomm->extended_error_reporting)
98
+ rfcomm_send_reply(rfcomm, "+CME ERROR: %d", error);
99
+ else
100
+ rfcomm_send_reply(rfcomm, "ERROR");
101
+}
102
+
103
static bool rfcomm_volume_enabled(struct rfcomm *rfcomm)
104
{
105
return rfcomm->device != NULL
106
107
unsigned int selected_codec;
108
unsigned int indicator;
109
unsigned int indicator_value;
110
+ unsigned int value;
111
int xapl_vendor;
112
int xapl_product;
113
int xapl_features;
114
115
}
116
117
/* send reply to HF with the features supported by Audio Gateway (=computer) */
118
+ ag_features |= mm_supported_features();
119
ag_features |= SPA_BT_HFP_AG_FEATURE_HF_INDICATORS;
120
rfcomm_send_reply(rfcomm, "+BRSF: %u", ag_features);
121
rfcomm_send_reply(rfcomm, "OK");
122
123
124
rfcomm_send_reply(rfcomm, "OK");
125
} else if (spa_strstartswith(buf, "AT+CIND=?")) {
126
- rfcomm_send_reply(rfcomm, "+CIND:(\"service\",(0-1)),(\"call\",(0-1)),(\"callsetup\",(0-3)),(\"callheld\",(0-2))");
127
+ rfcomm_send_reply(rfcomm, "+CIND:%s", CIND_INDICATORS);
128
rfcomm_send_reply(rfcomm, "OK");
129
} else if (spa_strstartswith(buf, "AT+CIND?")) {
130
- rfcomm_send_reply(rfcomm, "+CIND: 0,%d,0,0", rfcomm->cind_call_active);
131
+ rfcomm_send_reply(rfcomm, "+CIND: %d,%d,%d,0,%d,%d,%d", backend->modem.network_has_service,
132
+ backend->modem.active_call, backend->modem.call_setup, backend->modem.signal_strength,
133
+ backend->modem.network_is_roaming, backend->battery_level);
134
rfcomm_send_reply(rfcomm, "OK");
135
} else if (spa_strstartswith(buf, "AT+CMER")) {
136
int mode, keyp, disp, ind;
137
138
}
139
} else if (!rfcomm->slc_configured) {
140
spa_log_warn(backend->log, "RFCOMM receive command before SLC completed: %s", buf);
141
- rfcomm_send_reply(rfcomm, "ERROR");
142
+ rfcomm_send_error(rfcomm, CMEE_AG_FAILURE);
143
return true;
144
+
145
+ /* *****
146
+ * Following commands requires a Service Level Connection
147
+ * ***** */
148
+
149
} else if (sscanf(buf, "AT+BCS=%u", &selected_codec) == 1) {
150
/* parse BCS(=Bluetooth Codec Selection) reply */
151
bool was_switching_codec = rfcomm->hfp_ag_switching_codec && (rfcomm->device != NULL);
152
153
154
if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC) {
155
spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec);
156
- rfcomm_send_reply(rfcomm, "ERROR");
157
+ rfcomm_send_error(rfcomm, CMEE_AG_FAILURE);
158
if (was_switching_codec)
159
spa_bt_device_emit_codec_switched(rfcomm->device, -EIO);
160
return true;
161
162
if (rfcomm->transport == NULL) {
163
spa_log_warn(backend->log, "can't create transport: %m");
164
// TODO: We should manage the missing transport
165
- rfcomm_send_reply(rfcomm, "ERROR");
166
+ rfcomm_send_error(rfcomm, CMEE_AG_FAILURE);
167
if (was_switching_codec)
168
spa_bt_device_emit_codec_switched(rfcomm->device, -ENOMEM);
169
return true;
170
171
if (was_switching_codec)
172
spa_bt_device_emit_codec_switched(rfcomm->device, 0);
173
} else if (spa_strstartswith(buf, "AT+BIA=")) {
174
- /* We only support 'call' indicator, which HFP 4.35.1 defines as
175
- always active (assuming CMER enabled it), so we don't need to
176
- parse anything here. */
177
+ /* retrieve indicators activation
178
+ * form: AT+BIA=indrep1,indrep2,indrepx */
179
+ char *str = buf + 7;
180
+ unsigned int ind = 1;
181
+
182
+ while (*str && ind < CIND_MAX && *str != '\r' && *str != '\n') {
183
+ if (*str == ',') {
184
+ ind++;
185
+ goto next_indicator;
186
+ }
187
+
188
+ /* Ignore updates to mandantory indicators which are always ON */
189
+ if (ind == CIND_CALL || ind == CIND_CALLSETUP || ind == CIND_CALLHELD)
190
+ goto next_indicator;
191
+
192
+ switch (*str) {
193
+ case '0':
194
+ rfcomm->cind_enabled_indicators &= ~(1 << ind);
195
+ break;
196
+ case '1':
197
+ rfcomm->cind_enabled_indicators |= (1 << ind);
198
+ break;
199
+ default:
200
+ spa_log_warn(backend->log, "Unsupported entry in %s: %c", buf, *str);
201
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-caps.h -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bap-codec-caps.h
Changed
35
1
2
uint8_t n_blks;
3
} __attribute__ ((packed)) bap_lc3_t;
4
5
+#define BT_ISO_QOS_CIG_UNSET 0xff
6
+#define BT_ISO_QOS_CIS_UNSET 0xff
7
+
8
+#define BT_ISO_QOS_TARGET_LATENCY_LOW 0x01
9
+#define BT_ISO_QOS_TARGET_LATENCY_BALANCED 0x02
10
+#define BT_ISO_QOS_TARGET_LATENCY_RELIABILITY 0x03
11
+
12
+struct bap_endpoint_qos {
13
+ uint8_t framing;
14
+ uint8_t phy;
15
+ uint8_t retransmission;
16
+ uint16_t latency;
17
+ uint32_t delay_min;
18
+ uint32_t delay_max;
19
+ uint32_t preferred_delay_min;
20
+ uint32_t preferred_delay_max;
21
+};
22
+
23
+struct bap_codec_qos {
24
+ uint32_t interval;
25
+ uint8_t framing;
26
+ uint8_t phy;
27
+ uint16_t sdu;
28
+ uint8_t retransmission;
29
+ uint16_t latency;
30
+ uint32_t delay;
31
+ uint8_t target_latency;
32
+};
33
+
34
#endif
35
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c
Changed
67
1
2
return 0;
3
}
4
5
-static void codec_get_qos(const struct media_codec *codec,
6
- const void *config, size_t config_size,
7
- struct codec_qos *qos)
8
+static int codec_get_qos(const struct media_codec *codec,
9
+ const void *config, size_t config_size,
10
+ const struct bap_endpoint_qos *endpoint_qos,
11
+ struct bap_codec_qos *qos)
12
{
13
bap_lc3_t conf;
14
15
- memset(qos, 0, sizeof(*qos));
16
+ spa_zero(*qos);
17
18
if (!parse_conf(&conf, config, config_size))
19
- return;
20
+ return -EINVAL;
21
22
qos->framing = false;
23
- qos->phy = "2M";
24
+ if (endpoint_qos->phy & 0x2)
25
+ qos->phy = 0x2;
26
+ else if (endpoint_qos->phy & 0x1)
27
+ qos->phy = 0x1;
28
+ else
29
+ qos->phy = 0x2;
30
qos->retransmission = 2; /* default */
31
qos->sdu = conf.framelen * conf.n_blks;
32
qos->latency = 20; /* default */
33
qos->delay = 40000U;
34
qos->interval = (conf.frame_duration == LC3_CONFIG_DURATION_7_5 ? 7500 : 10000);
35
+ qos->target_latency = BT_ISO_QOS_TARGET_LATENCY_BALANCED;
36
37
switch (conf.rate) {
38
case LC3_CONFIG_FREQ_8KHZ:
39
40
qos->latency = (conf.frame_duration == LC3_CONFIG_DURATION_7_5 ? 15 : 20);
41
break;
42
}
43
+
44
+ /* Clamp to ASE values */
45
+ if (endpoint_qos->latency >= 0x0005 && endpoint_qos->latency <= 0x0FA0)
46
+ /* Values outside the range are RFU */
47
+ qos->latency = SPA_MAX(qos->latency, endpoint_qos->latency);
48
+
49
+ if (endpoint_qos->delay_min)
50
+ qos->delay = SPA_MAX(qos->delay, endpoint_qos->delay_min);
51
+ if (endpoint_qos->delay_max)
52
+ qos->delay = SPA_MIN(qos->delay, endpoint_qos->delay_max);
53
+
54
+ return 0;
55
}
56
57
static void *codec_init(const struct media_codec *codec, uint32_t flags,
58
59
}
60
this->codesize = this->samples * this->channels * sizeof(int32_t);
61
62
- if (flags & MEDIA_CODEC_FLAG_SINK) {
63
+ if (!(flags & MEDIA_CODEC_FLAG_SINK)) {
64
for (ich = 0; ich < this->channels; ich++) {
65
this->encich = lc3_setup_encoder(this->frame_dus, this->samplerate, 0, calloc(1, lc3_encoder_size(this->frame_dus, this->samplerate)));
66
if (this->encich == NULL) {
67
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
201
1
2
3
unsigned int filters_added:1;
4
unsigned int objects_listed:1;
5
+ DBusPendingCall *get_managed_objects_call;
6
7
struct spa_bt_backend *backend;
8
struct spa_bt_backend *backendsBACKEND_NUM;
9
10
return 0;
11
}
12
13
-static const struct media_codec *media_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink)
14
+static const struct media_codec *media_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink, const struct media_codec *preferred)
15
{
16
const char *ep_name;
17
const struct media_codec * const * const media_codecs = monitor->media_codecs;
18
+ const struct media_codec *found = NULL;
19
int i;
20
21
if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) {
22
23
const struct media_codec *codec = media_codecsi;
24
const char *codec_ep_name =
25
codec->endpoint_name ? codec->endpoint_name : codec->name;
26
- if (spa_streq(ep_name, codec_ep_name))
27
- return codec;
28
+
29
+ if (!spa_streq(ep_name, codec_ep_name))
30
+ continue;
31
+ if ((*sink && !codec->decode) || (!*sink && !codec->encode))
32
+ continue;
33
+
34
+ /* Same endpoint may be shared with multiple codec objects,
35
+ * which may e.g. correspond to different encoder settings.
36
+ * Look up which one we selected.
37
+ */
38
+ if ((preferred && codec == preferred) || found == NULL)
39
+ found = codec;
40
}
41
- return NULL;
42
+ return found;
43
}
44
45
static int media_endpoint_to_profile(const char *endpoint)
46
47
return spa_dict_lookup(&monitor->enabled_codecs, codec->name) != NULL;
48
}
49
50
+static bool codec_has_direction(const struct media_codec *codec, enum spa_bt_media_direction direction)
51
+{
52
+ switch (direction) {
53
+ case SPA_BT_MEDIA_SOURCE:
54
+ return codec->encode;
55
+ case SPA_BT_MEDIA_SINK:
56
+ return codec->decode;
57
+ default:
58
+ spa_assert_not_reached();
59
+ }
60
+}
61
+
62
+static bool endpoint_should_be_registered(struct spa_bt_monitor *monitor,
63
+ const struct media_codec *codec,
64
+ enum spa_bt_media_direction direction)
65
+{
66
+ /* Codecs with fill_caps == NULL share endpoint with another codec,
67
+ * and don't have their own endpoint
68
+ */
69
+ return is_media_codec_enabled(monitor, codec) &&
70
+ codec_has_direction(codec, direction) &&
71
+ codec->fill_caps;
72
+}
73
+
74
static DBusHandlerResult endpoint_select_configuration(DBusConnection *conn, DBusMessage *m, void *userdata)
75
{
76
struct spa_bt_monitor *monitor = userdata;
77
78
spa_log_info(monitor->log, "%p: %s select conf %d", monitor, path, size);
79
spa_log_hexdump(monitor->log, SPA_LOG_LEVEL_DEBUG, 2, cap, (size_t)size);
80
81
- codec = media_endpoint_to_codec(monitor, path, &sink);
82
+ /* For codecs sharing the same endpoint, BlueZ-initiated connections
83
+ * always pick the default one. The session manager will
84
+ * switch the codec to a saved value after connection, so this generally
85
+ * does not matter.
86
+ */
87
+ codec = media_endpoint_to_codec(monitor, path, &sink, NULL);
88
+ spa_log_debug(monitor->log, "%p: %s codec:%s", monitor, path, codec ? codec->name : "<null>");
89
+
90
if (codec != NULL)
91
/* FIXME: We can't determine which device the SelectConfiguration()
92
* call is associated with, therefore device settings are not passed.
93
94
DBUS_TYPE_BYTE, &pconf, size, DBUS_TYPE_INVALID))
95
return DBUS_HANDLER_RESULT_NEED_MEMORY;
96
97
- exit_send:
98
+exit_send:
99
if (!dbus_connection_send(conn, r, NULL))
100
return DBUS_HANDLER_RESULT_NEED_MEMORY;
101
102
103
{
104
struct spa_bt_monitor *monitor = userdata;
105
const char *path;
106
- const char *object_path;
107
DBusMessageIter args, props, iter;
108
DBusMessage *r = NULL;
109
- int size, res;
110
+ int res;
111
const struct media_codec *codec;
112
bool sink;
113
+ const char *err_msg = "Unknown error";
114
+
115
+ const char *endpoint_path = NULL;
116
+ uint8_t capsA2DP_MAX_CAPS_SIZE;
117
+ uint8_t configA2DP_MAX_CAPS_SIZE;
118
+ int caps_size = 0;
119
+ DBusMessageIter dict;
120
+ struct bap_endpoint_qos endpoint_qos;
121
+
122
+ spa_zero(endpoint_qos);
123
124
if (!dbus_message_iter_init(m, &args) || !spa_streq(dbus_message_get_signature(m), "a{sv}")) {
125
spa_log_error(monitor->log, "Invalid signature for method SelectProperties()");
126
127
128
path = dbus_message_get_path(m);
129
130
- codec = media_endpoint_to_codec(monitor, path, &sink);
131
+ /* TODO: for codecs with shared endpoint, this currently always picks the default
132
+ * one. However, currently we don't have BAP codecs with shared endpoint, so
133
+ * this does not matter, but in case they are needed later we should pick the
134
+ * right one here.
135
+ */
136
+ codec = media_endpoint_to_codec(monitor, path, &sink, NULL);
137
+ spa_log_debug(monitor->log, "%p: %s codec:%s", monitor, path, codec ? codec->name : "<null>");
138
if (!codec) {
139
- res = -ENOTSUP;
140
- spa_log_error(monitor->log, "Unsupported codec: %d (%s)",
141
- res, spa_strerror(res));
142
- if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments",
143
- "Unsupported codec")) == NULL)
144
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
145
- goto exit_send;
146
+ spa_log_error(monitor->log, "Unsupported codec");
147
+ err_msg = "Unsupported codec";
148
+ goto error;
149
}
150
151
- /* Read transport properties */
152
+ /* Parse transport properties */
153
while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
154
const char *key;
155
DBusMessageIter value, entry;
156
- int var;
157
+ int type;
158
159
dbus_message_iter_recurse(&props, &entry);
160
dbus_message_iter_get_basic(&entry, &key);
161
162
dbus_message_iter_next(&entry);
163
dbus_message_iter_recurse(&entry, &value);
164
165
- var = dbus_message_iter_get_arg_type(&value);
166
+ type = dbus_message_iter_get_arg_type(&value);
167
168
if (spa_streq(key, "Capabilities")) {
169
- DBusMessageIter array, dict;
170
- uint8_t configA2DP_MAX_CAPS_SIZE, *cap;
171
- uint8_t *pconf = (uint8_t *) config;
172
-
173
- if (r) {
174
- spa_log_warn(monitor->log, "Multiple Capabilities entries, skipped");
175
- goto next_entry;
176
- }
177
+ DBusMessageIter array;
178
+ uint8_t *buf;
179
180
- if (var != DBUS_TYPE_ARRAY) {
181
- spa_log_error(monitor->log, "Property %s of wrong type %c", key, (char)var);
182
- if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments",
183
- "Invalid property")) == NULL)
184
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
185
- goto exit_send;
186
+ if (type != DBUS_TYPE_ARRAY) {
187
+ spa_log_error(monitor->log, "Property %s of wrong type %c", key, (char)type);
188
+ goto error_invalid;
189
}
190
191
dbus_message_iter_recurse(&value, &array);
192
- var = dbus_message_iter_get_arg_type(&array);
193
- if (var != DBUS_TYPE_BYTE) {
194
- spa_log_error(monitor->log, "%s is an array of wrong type %c", key, (char)var);
195
- if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments",
196
- "Invalid property")) == NULL)
197
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
198
- goto exit_send;
199
- }
200
-
201
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
48
1
2
DEVICE_PROFILE_A2DP = 2,
3
DEVICE_PROFILE_HSP_HFP = 3,
4
DEVICE_PROFILE_BAP = 4,
5
+ DEVICE_PROFILE_LAST = DEVICE_PROFILE_BAP,
6
};
7
8
struct props {
9
10
*codec = 0;
11
*next = index + 1;
12
13
- if (index <= 3) {
14
+ if (index <= DEVICE_PROFILE_LAST) {
15
return index;
16
} else if (index != SPA_ID_INVALID) {
17
const struct spa_type_info *info;
18
uint32_t profile;
19
20
- *codec = index - 3;
21
+ *codec = index - DEVICE_PROFILE_LAST;
22
*next = SPA_ID_INVALID;
23
24
for (info = spa_type_bluetooth_audio_codec; info->type; ++info)
25
if (info->type > *codec)
26
- *next = SPA_MIN(info->type + 3, *next);
27
+ *next = SPA_MIN(info->type + DEVICE_PROFILE_LAST, *next);
28
29
if (get_hfp_codec(*codec))
30
profile = DEVICE_PROFILE_HSP_HFP;
31
32
if (codec == 0 || (this->bt_dev->connected_profiles & SPA_BT_PROFILE_MEDIA_SOURCE))
33
return profile;
34
35
- return codec + 3;
36
+ return codec + DEVICE_PROFILE_LAST;
37
}
38
39
if (profile == DEVICE_PROFILE_HSP_HFP) {
40
if (codec == 0 || (this->bt_dev->connected_profiles & SPA_BT_PROFILE_HFP_AG))
41
return profile;
42
43
- return codec + 3;
44
+ return codec + DEVICE_PROFILE_LAST;
45
}
46
47
return SPA_ID_INVALID;
48
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/codec-loader.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/codec-loader.c
Changed
34
1
2
3
for (i = 0; bluez5_codec_a2dp->codecsi; ++i) {
4
const struct media_codec *c = bluez5_codec_a2dp->codecsi;
5
+ const char *ep = c->endpoint_name ? c->endpoint_name : c->name;
6
size_t j;
7
8
+ if (!ep)
9
+ goto next_codec;
10
+
11
if (impl->n_codecs >= MAX_CODECS) {
12
spa_log_error(impl->log, "too many A2DP codecs");
13
break;
14
15
/* Don't load duplicate endpoints */
16
for (j = 0; j < impl->n_codecs; ++j) {
17
const struct media_codec *c2 = impl->codecsj;
18
- const char *ep1 = c->endpoint_name ? c->endpoint_name : c->name;
19
const char *ep2 = c2->endpoint_name ? c2->endpoint_name : c2->name;
20
- if (spa_streq(ep1, ep2))
21
+ if (spa_streq(ep, ep2) && c->fill_caps && c2->fill_caps) {
22
+ spa_log_debug(impl->log, "media codec %s from %s duplicate endpoint %s",
23
+ c->name, factory_name, ep);
24
goto next_codec;
25
+ }
26
}
27
28
- spa_log_debug(impl->log, "loaded media codec %s from %s", c->name, factory_name);
29
+ spa_log_debug(impl->log, "loaded media codec %s from %s, endpoint:%s",
30
+ c->name, factory_name, ep);
31
32
if (c->set_log)
33
c->set_log(impl->log);
34
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/defs.h
Changed
22
1
2
void (*destroy) (void *data);
3
};
4
5
+struct media_codec;
6
+
7
struct spa_bt_device {
8
struct spa_list link;
9
struct spa_bt_monitor *monitor;
10
11
const struct spa_dict *settings;
12
13
DBusPendingCall *battery_pending_call;
14
-};
15
16
-struct media_codec;
17
+ const struct media_codec *preferred_codec;
18
+};
19
20
struct spa_bt_device *spa_bt_device_find(struct spa_bt_monitor *monitor, const char *path);
21
struct spa_bt_device *spa_bt_device_find_by_address(struct spa_bt_monitor *monitor, const char *remote_address, const char *local_address);
22
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-codecs.h -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/media-codecs.h
Changed
59
1
2
#include <spa/support/log.h>
3
4
#include "a2dp-codec-caps.h"
5
+#include "bap-codec-caps.h"
6
7
/*
8
* The codec plugin SPA interface is private. The version should be incremented
9
10
11
#define SPA_TYPE_INTERFACE_Bluez5CodecMedia SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:Media:Private"
12
13
-#define SPA_VERSION_BLUEZ5_CODEC_MEDIA 5
14
+#define SPA_VERSION_BLUEZ5_CODEC_MEDIA 7
15
16
struct spa_bluez5_codec_a2dp {
17
struct spa_interface iface;
18
19
uint32_t channels;
20
};
21
22
-struct codec_qos {
23
- uint32_t interval;
24
- bool framing;
25
- char *phy;
26
- uint16_t sdu;
27
- uint8_t retransmission;
28
- uint16_t latency;
29
- uint32_t delay;
30
-};
31
-
32
struct media_codec {
33
enum spa_bluetooth_audio_codec id;
34
uint8_t codec_id;
35
36
37
struct spa_log *log;
38
39
+ /** If fill_caps is NULL, no endpoint is registered (for sharing with another codec). */
40
int (*fill_caps) (const struct media_codec *codec, uint32_t flags,
41
uint8_t capsA2DP_MAX_CAPS_SIZE);
42
+
43
int (*select_config) (const struct media_codec *codec, uint32_t flags,
44
const void *caps, size_t caps_size,
45
const struct media_codec_audio_info *info,
46
47
int (*validate_config) (const struct media_codec *codec, uint32_t flags,
48
const void *caps, size_t caps_size,
49
struct spa_audio_info *info);
50
- void (*get_qos)(const struct media_codec *codec,
51
+ int (*get_qos)(const struct media_codec *codec,
52
const void *config, size_t config_size,
53
- struct codec_qos *qos);
54
+ const struct bap_endpoint_qos *endpoint_qos,
55
+ struct bap_codec_qos *qos);
56
57
/** qsort comparison sorting caps in order of preference for the codec.
58
* Used in codec switching to select best remote endpoints.
59
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-sink.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/media-sink.c
Changed
201
1
2
#define DEFAULT_CLOCK_NAME "clock.system.monotonic"
3
4
struct props {
5
- uint32_t min_latency;
6
- uint32_t max_latency;
7
int64_t latency_offset;
8
char clock_name64;
9
};
10
11
-#define FILL_FRAMES 2
12
+#define FILL_FRAMES 4
13
+#define MIN_BUFFERS 2
14
#define MAX_BUFFERS 32
15
-#define MIN_LATENCY 128
16
-#define MAX_LATENCY 8192
17
-#define BUFFER_SIZE (MAX_LATENCY*8)
18
+#define BUFFER_SIZE (8192*8)
19
20
struct buffer {
21
uint32_t id;
22
23
struct spa_hook_list hooks;
24
struct spa_callbacks callbacks;
25
26
+ uint32_t quantum_limit;
27
+
28
uint64_t info_all;
29
struct spa_node_info info;
30
#define IDX_PropInfo 0
31
32
unsigned int started:1;
33
unsigned int following:1;
34
unsigned int is_output:1;
35
+ unsigned int flush_pending:1;
36
37
unsigned int is_duplex:1;
38
39
40
uint64_t current_time;
41
uint64_t next_time;
42
uint64_t last_error;
43
+ uint64_t process_time;
44
+
45
+ uint64_t prev_flush_time;
46
+ uint64_t next_flush_time;
47
48
const struct media_codec *codec;
49
bool codec_props_changed;
50
51
52
int need_flush;
53
bool fragment;
54
- uint64_t fragment_timeout;
55
uint32_t block_size;
56
uint8_t bufferBUFFER_SIZE;
57
uint32_t buffer_used;
58
uint32_t header_size;
59
- uint32_t frame_count;
60
+ uint32_t block_count;
61
uint16_t seqnum;
62
uint32_t timestamp;
63
uint64_t sample_count;
64
uint8_t tmp_bufferBUFFER_SIZE;
65
uint32_t tmp_buffer_used;
66
uint32_t fd_buffer_size;
67
-
68
- /* Times */
69
- uint64_t start_time;
70
- uint64_t total_samples;
71
};
72
73
-#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0)
74
+#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0)
75
76
static void reset_props(struct impl *this, struct props *props)
77
{
78
- props->min_latency = MIN_LATENCY;
79
- props->max_latency = MAX_LATENCY;
80
props->latency_offset = 0;
81
strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name));
82
}
83
84
switch (id) {
85
case SPA_PARAM_PropInfo:
86
{
87
- struct props *p = &this->props;
88
-
89
switch (result.index) {
90
case 0:
91
param = spa_pod_builder_add_object(&b,
92
SPA_TYPE_OBJECT_PropInfo, id,
93
- SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_minLatency),
94
- SPA_PROP_INFO_description, SPA_POD_String("The minimum latency"),
95
- SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->min_latency, 1, INT32_MAX));
96
- break;
97
- case 1:
98
- param = spa_pod_builder_add_object(&b,
99
- SPA_TYPE_OBJECT_PropInfo, id,
100
- SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_maxLatency),
101
- SPA_PROP_INFO_description, SPA_POD_String("The maximum latency"),
102
- SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->max_latency, 1, INT32_MAX));
103
- break;
104
- case 2:
105
- param = spa_pod_builder_add_object(&b,
106
- SPA_TYPE_OBJECT_PropInfo, id,
107
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec),
108
SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"),
109
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0LL, INT64_MIN, INT64_MAX));
110
break;
111
default:
112
enum_codec = true;
113
- index_offset = 3;
114
+ index_offset = 1;
115
}
116
break;
117
}
118
119
case 0:
120
param = spa_pod_builder_add_object(&b,
121
SPA_TYPE_OBJECT_Props, id,
122
- SPA_PROP_minLatency, SPA_POD_Int(p->min_latency),
123
- SPA_PROP_maxLatency, SPA_POD_Int(p->max_latency),
124
SPA_PROP_latencyOffsetNsec, SPA_POD_Long(p->latency_offset));
125
break;
126
default:
127
128
} else {
129
spa_pod_parse_object(param,
130
SPA_TYPE_OBJECT_Props, NULL,
131
- SPA_PROP_minLatency, SPA_POD_OPT_Int(&new_props.min_latency),
132
- SPA_PROP_maxLatency, SPA_POD_OPT_Int(&new_props.max_latency),
133
SPA_PROP_latencyOffsetNsec, SPA_POD_OPT_Long(&new_props.latency_offset));
134
}
135
136
137
this->codec_props_changed = false;
138
}
139
this->need_flush = 0;
140
- this->frame_count = 0;
141
+ this->block_count = 0;
142
this->fragment = false;
143
this->buffer_used = this->codec->start_encode(this->codec_data,
144
this->buffer, sizeof(this->buffer),
145
146
static int send_buffer(struct impl *this)
147
{
148
int written, unsent;
149
+
150
unsent = get_transport_unused_size(this);
151
if (unsent >= 0) {
152
unsent = this->fd_buffer_size - unsent;
153
this->codec->abr_process(this->codec_data, unsent);
154
}
155
156
- spa_log_trace(this->log, "%p: send %d %u %u %u %u",
157
- this, this->frame_count, this->block_size, this->seqnum,
158
- this->timestamp, this->buffer_used);
159
-
160
written = send(this->flush_source.fd, this->buffer,
161
this->buffer_used, MSG_DONTWAIT | MSG_NOSIGNAL);
162
163
- spa_log_trace(this->log, "%p: send %d", this, written);
164
+ if (SPA_UNLIKELY(spa_log_level_topic_enabled(this->log, SPA_LOG_TOPIC_DEFAULT, SPA_LOG_LEVEL_TRACE))) {
165
+ struct timespec ts;
166
+ uint64_t now;
167
+ uint64_t dt;
168
+
169
+ spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &ts);
170
+ now = SPA_TIMESPEC_TO_NSEC(&ts);
171
+ dt = now - this->prev_flush_time;
172
+ this->prev_flush_time = now;
173
+
174
+ spa_log_trace(this->log,
175
+ "%p: send blocks:%d block:%u seq:%u ts:%u size:%u "
176
+ "wrote:%d dt:%"PRIu64,
177
+ this, this->block_count, this->block_size, this->seqnum,
178
+ this->timestamp, this->buffer_used, written, dt);
179
+ }
180
181
if (written < 0) {
182
spa_log_debug(this->log, "%p: %m", this);
183
184
185
spa_log_trace(this->log, "%p: encode %d used %d, %d %d %d",
186
this, size, this->buffer_used, port->frame_size, this->block_size,
187
- this->frame_count);
188
+ this->block_count);
189
190
if (this->need_flush)
191
return 0;
192
193
return processed;
194
195
this->sample_count += processed / port->frame_size;
196
- this->frame_count += processed / this->block_size;
197
+ this->block_count += processed / this->block_size;
198
this->buffer_used += out_encoded;
199
200
spa_log_trace(this->log, "%p: processed %d %zd used %d",
201
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/media-source.c
Changed
147
1
2
struct impl *this = user_data;
3
struct port *port = &this->port;
4
5
+ set_timers(this);
6
spa_bt_decode_buffer_recover(&port->buffer);
7
return 0;
8
}
9
10
return 0;
11
}
12
13
+static int produce_buffer(struct impl *this);
14
+
15
static void media_on_timeout(struct spa_source *source)
16
{
17
struct impl *this = source->data;
18
struct port *port = &this->port;
19
uint64_t exp, duration;
20
uint32_t rate;
21
- struct spa_io_buffers *io = port->io;
22
uint64_t prev_time, now_time;
23
24
if (this->transport == NULL)
25
26
this->clock->next_nsec = this->next_time;
27
}
28
29
- spa_log_trace(this->log, "%p: %d", this, io->status);
30
- io->status = SPA_STATUS_HAVE_DATA;
31
+ if (port->io) {
32
+ int status = produce_buffer(this);
33
+ spa_log_trace(this->log, "%p: io:%d status:%d", this, port->io->status, status);
34
+ }
35
+
36
spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA);
37
38
set_timeout(this, this->next_time);
39
40
41
this->transport_acquired = true;
42
43
- if (this->codec->bap)
44
- flags = 0;
45
- else
46
- flags = this->is_duplex ? 0 : MEDIA_CODEC_FLAG_SINK;
47
+ flags = this->is_duplex ? 0 : MEDIA_CODEC_FLAG_SINK;
48
49
this->codec_data = this->codec->init(this->codec,
50
flags,
51
52
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
53
return -EINVAL;
54
55
+ if (info.info.raw.rate == 0 ||
56
+ info.info.raw.channels == 0 ||
57
+ info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS)
58
+ return -EINVAL;
59
+
60
port->frame_size = info.info.raw.channels;
61
62
switch (info.info.raw.format) {
63
64
}
65
}
66
67
-static int impl_node_process(void *object)
68
+static int produce_buffer(struct impl *this)
69
{
70
- struct impl *this = object;
71
- struct port *port;
72
- struct spa_io_buffers *io;
73
struct buffer *buffer;
74
+ struct port *port = &this->port;
75
+ struct spa_io_buffers *io = port->io;
76
77
- spa_return_val_if_fail(this != NULL, -EINVAL);
78
-
79
- port = &this->port;
80
- if ((io = port->io) == NULL)
81
+ if (io == NULL)
82
return -EIO;
83
84
- spa_log_trace(this->log, "%p status:%d", this, io->status);
85
-
86
/* Return if we already have a buffer */
87
if (io->status == SPA_STATUS_HAVE_DATA)
88
return SPA_STATUS_HAVE_DATA;
89
90
io->buffer_id = SPA_ID_INVALID;
91
}
92
93
- /* Handle buffering delay */
94
+ /* Handle buffering */
95
process_buffering(this);
96
97
/* Return if there are no buffers ready to be processed */
98
99
return SPA_STATUS_HAVE_DATA;
100
}
101
102
+static int impl_node_process(void *object)
103
+{
104
+ struct impl *this = object;
105
+ struct port *port;
106
+ struct spa_io_buffers *io;
107
+
108
+ spa_return_val_if_fail(this != NULL, -EINVAL);
109
+
110
+ port = &this->port;
111
+ if ((io = port->io) == NULL)
112
+ return -EIO;
113
+
114
+ spa_log_trace(this->log, "%p status:%d", this, io->status);
115
+
116
+ /* Return if we already have a buffer */
117
+ if (io->status == SPA_STATUS_HAVE_DATA)
118
+ return SPA_STATUS_HAVE_DATA;
119
+
120
+ /* Recycle */
121
+ if (io->buffer_id < port->n_buffers) {
122
+ recycle_buffer(this, port, io->buffer_id);
123
+ io->buffer_id = SPA_ID_INVALID;
124
+ }
125
+
126
+ /* Follower produces buffers here, driver in timeout */
127
+ if (this->following)
128
+ return produce_buffer(this);
129
+ else
130
+ return SPA_STATUS_OK;
131
+}
132
+
133
static const struct spa_node_methods impl_node = {
134
SPA_VERSION_NODE_METHODS,
135
.add_listener = impl_node_add_listener,
136
137
{
138
struct impl *this = (struct impl *) handle;
139
struct port *port = &this->port;
140
- if (this->codec_data)
141
- this->codec->deinit(this->codec_data);
142
+
143
+ do_stop(this);
144
if (this->codec_props && this->codec->clear_props)
145
this->codec->clear_props(this->codec_props);
146
if (this->transport)
147
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/meson.build
Changed
22
1
2
get_option('bluez5-backend-hfp-native').allowed())
3
cdata.set('HAVE_BLUEZ_5_BACKEND_HSP_NATIVE', get_option('bluez5-backend-hsp-native').allowed())
4
cdata.set('HAVE_BLUEZ_5_BACKEND_HFP_NATIVE', get_option('bluez5-backend-hfp-native').allowed())
5
+cdata.set('HAVE_BLUEZ_5_BACKEND_NATIVE_MM', get_option('bluez5-backend-native-mm').allowed())
6
cdata.set('HAVE_BLUEZ_5_BACKEND_OFONO', get_option('bluez5-backend-ofono').allowed())
7
cdata.set('HAVE_BLUEZ_5_BACKEND_HSPHFPD', get_option('bluez5-backend-hsphfpd').allowed())
8
cdata.set('HAVE_BLUEZ_5_HCI', dependency('bluez', version: '< 6', required: false).found())
9
10
if libusb_dep.found()
11
bluez5_deps += libusb_dep
12
endif
13
- bluez5_sources += 'backend-native.c'
14
+ if mm_dep.found()
15
+ bluez5_deps += mm_dep
16
+ bluez5_sources += 'modemmanager.c'
17
+ endif
18
+ bluez5_sources += 'backend-native.c', 'upower.c'
19
endif
20
21
if get_option('bluez5-backend-ofono').allowed()
22
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/modemmanager.c
Added
201
1
2
+/* Spa Bluez5 ModemManager proxy
3
+ *
4
+ * Copyright © 2022 Collabora
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 <errno.h>
27
+#include <spa/utils/string.h>
28
+
29
+#include <ModemManager.h>
30
+
31
+#include "modemmanager.h"
32
+
33
+#define DBUS_INTERFACE_OBJECTMANAGER "org.freedesktop.DBus.ObjectManager"
34
+
35
+struct modem {
36
+ char *path;
37
+ bool network_has_service;
38
+ unsigned int signal_strength;
39
+};
40
+
41
+struct impl {
42
+ struct spa_bt_monitor *monitor;
43
+
44
+ struct spa_log *log;
45
+ DBusConnection *conn;
46
+
47
+ char *allowed_modem_device;
48
+ bool filters_added;
49
+ DBusPendingCall *pending;
50
+ DBusPendingCall *voice_pending;
51
+
52
+ const struct mm_ops *ops;
53
+ void *user_data;
54
+
55
+ struct modem modem;
56
+ struct spa_list call_list;
57
+};
58
+
59
+struct dbus_cmd_data {
60
+ struct impl *this;
61
+ struct call *call;
62
+ void *user_data;
63
+};
64
+
65
+static bool mm_dbus_connection_send_with_reply(struct impl *this, DBusMessage *m, DBusPendingCall **pending_return,
66
+ DBusPendingCallNotifyFunction function, void *user_data)
67
+{
68
+ dbus_bool_t dbus_ret;
69
+
70
+ spa_assert(*pending_return == NULL);
71
+
72
+ dbus_ret = dbus_connection_send_with_reply(this->conn, m, pending_return, -1);
73
+ if (!dbus_ret || *pending_return == NULL) {
74
+ spa_log_debug(this->log, "dbus call failure");
75
+ return false;
76
+ }
77
+
78
+ dbus_ret = dbus_pending_call_set_notify(*pending_return, function, user_data, NULL);
79
+ if (!dbus_ret) {
80
+ spa_log_debug(this->log, "dbus set notify failure");
81
+ dbus_pending_call_cancel(*pending_return);
82
+ dbus_pending_call_unref(*pending_return);
83
+ *pending_return = NULL;
84
+ return false;
85
+ }
86
+
87
+ return true;
88
+}
89
+
90
+static int mm_state_to_clcc(struct impl *this, MMCallState state)
91
+{
92
+ switch (state) {
93
+ case MM_CALL_STATE_DIALING:
94
+ return CLCC_DIALING;
95
+ case MM_CALL_STATE_RINGING_OUT:
96
+ return CLCC_ALERTING;
97
+ case MM_CALL_STATE_RINGING_IN:
98
+ return CLCC_INCOMING;
99
+ case MM_CALL_STATE_ACTIVE:
100
+ return CLCC_ACTIVE;
101
+ case MM_CALL_STATE_HELD:
102
+ return CLCC_HELD;
103
+ case MM_CALL_STATE_WAITING:
104
+ return CLCC_WAITING;
105
+ case MM_CALL_STATE_TERMINATED:
106
+ case MM_CALL_STATE_UNKNOWN:
107
+ default:
108
+ return -1;
109
+ }
110
+}
111
+
112
+static void mm_call_state_changed(struct impl *this)
113
+{
114
+ struct call *call;
115
+ bool call_indicator = false;
116
+ enum call_setup call_setup_indicator = CIND_CALLSETUP_NONE;
117
+
118
+ spa_list_for_each(call, &this->call_list, link) {
119
+ call_indicator |= (call->state == CLCC_ACTIVE);
120
+
121
+ if (call->state == CLCC_INCOMING && call_setup_indicator < CIND_CALLSETUP_INCOMING)
122
+ call_setup_indicator = CIND_CALLSETUP_INCOMING;
123
+ else if (call->state == CLCC_DIALING && call_setup_indicator < CIND_CALLSETUP_DIALING)
124
+ call_setup_indicator = CIND_CALLSETUP_DIALING;
125
+ else if (call->state == CLCC_ALERTING && call_setup_indicator < CIND_CALLSETUP_ALERTING)
126
+ call_setup_indicator = CIND_CALLSETUP_ALERTING;
127
+ }
128
+
129
+ if (this->ops->set_call_active)
130
+ this->ops->set_call_active(call_indicator, this->user_data);
131
+
132
+ if (this->ops->set_call_setup)
133
+ this->ops->set_call_setup(call_setup_indicator, this->user_data);
134
+}
135
+
136
+static void mm_get_call_properties_reply(DBusPendingCall *pending, void *user_data)
137
+{
138
+ struct call *call = user_data;
139
+ struct impl *this = call->this;
140
+ DBusMessage *r;
141
+ DBusMessageIter arg_i, element_i;
142
+ MMCallDirection direction;
143
+ MMCallState state;
144
+
145
+ spa_assert(call->pending == pending);
146
+ dbus_pending_call_unref(pending);
147
+ call->pending = NULL;
148
+
149
+ r = dbus_pending_call_steal_reply(pending);
150
+ if (r == NULL)
151
+ return;
152
+
153
+ if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
154
+ spa_log_warn(this->log, "ModemManager D-Bus Call not available");
155
+ goto finish;
156
+ }
157
+ if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
158
+ spa_log_error(this->log, "GetAll() failed: %s", dbus_message_get_error_name(r));
159
+ goto finish;
160
+ }
161
+
162
+ if (!dbus_message_iter_init(r, &arg_i) || !spa_streq(dbus_message_get_signature(r), "a{sv}")) {
163
+ spa_log_error(this->log, "Invalid arguments in GetAll() reply");
164
+ goto finish;
165
+ }
166
+
167
+ spa_log_debug(this->log, "Call path: %s", call->path);
168
+
169
+ dbus_message_iter_recurse(&arg_i, &element_i);
170
+ while (dbus_message_iter_get_arg_type(&element_i) != DBUS_TYPE_INVALID) {
171
+ DBusMessageIter i, value_i;
172
+ const char *key;
173
+
174
+ dbus_message_iter_recurse(&element_i, &i);
175
+
176
+ dbus_message_iter_get_basic(&i, &key);
177
+ dbus_message_iter_next(&i);
178
+ dbus_message_iter_recurse(&i, &value_i);
179
+
180
+ if (spa_streq(key, MM_CALL_PROPERTY_DIRECTION)) {
181
+ dbus_message_iter_get_basic(&value_i, &direction);
182
+ spa_log_debug(this->log, "Call direction: %u", direction);
183
+ call->direction = (direction == MM_CALL_DIRECTION_INCOMING) ? CALL_INCOMING : CALL_OUTGOING;
184
+ } else if (spa_streq(key, MM_CALL_PROPERTY_NUMBER)) {
185
+ char *number;
186
+
187
+ dbus_message_iter_get_basic(&value_i, &number);
188
+ spa_log_debug(this->log, "Call number: %s", number);
189
+ if (call->number)
190
+ free(call->number);
191
+ call->number = strdup(number);
192
+ } else if (spa_streq(key, MM_CALL_PROPERTY_STATE)) {
193
+ int clcc_state;
194
+
195
+ dbus_message_iter_get_basic(&value_i, &state);
196
+ spa_log_debug(this->log, "Call state: %u", state);
197
+ clcc_state = mm_state_to_clcc(this, state);
198
+ if (clcc_state < 0) {
199
+ spa_log_debug(this->log, "Unsupported modem state: %s, state=%d", call->path, call->state);
200
+ } else {
201
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/modemmanager.h
Added
163
1
2
+/* Spa Bluez5 ModemManager proxy
3
+ *
4
+ * Copyright © 2022 Collabora
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#ifndef SPA_BLUEZ5_MODEMMANAGER_H_
27
+#define SPA_BLUEZ5_MODEMMANAGER_H_
28
+
29
+#include <spa/utils/list.h>
30
+
31
+#include "defs.h"
32
+
33
+enum cmee_error {
34
+ CMEE_AG_FAILURE = 0,
35
+ CMEE_NO_CONNECTION_TO_PHONE = 1,
36
+ CMEE_OPERATION_NOT_ALLOWED = 3,
37
+ CMEE_OPERATION_NOT_SUPPORTED = 4,
38
+ CMEE_INVALID_CHARACTERS_TEXT_STRING = 25,
39
+ CMEE_INVALID_CHARACTERS_DIAL_STRING = 27,
40
+ CMEE_NO_NETWORK_SERVICE = 30
41
+};
42
+
43
+enum call_setup {
44
+ CIND_CALLSETUP_NONE = 0,
45
+ CIND_CALLSETUP_INCOMING,
46
+ CIND_CALLSETUP_DIALING,
47
+ CIND_CALLSETUP_ALERTING
48
+};
49
+
50
+enum call_direction {
51
+ CALL_OUTGOING,
52
+ CALL_INCOMING
53
+};
54
+
55
+enum call_state {
56
+ CLCC_ACTIVE,
57
+ CLCC_HELD,
58
+ CLCC_DIALING,
59
+ CLCC_ALERTING,
60
+ CLCC_INCOMING,
61
+ CLCC_WAITING,
62
+ CLCC_RESPONSE_AND_HOLD
63
+};
64
+
65
+struct call {
66
+ struct spa_list link;
67
+ unsigned int index;
68
+ struct impl *this;
69
+ DBusPendingCall *pending;
70
+
71
+ char *path;
72
+ char *number;
73
+ bool call_indicator;
74
+ enum call_direction direction;
75
+ enum call_state state;
76
+ bool multiparty;
77
+};
78
+
79
+struct mm_ops {
80
+ void (*send_cmd_result)(bool success, enum cmee_error error, void *user_data);
81
+ void (*set_modem_service)(bool available, void *user_data);
82
+ void (*set_modem_signal_strength)(unsigned int strength, void *user_data);
83
+ void (*set_modem_operator_name)(const char *name, void *user_data);
84
+ void (*set_modem_own_number)(const char *number, void *user_data);
85
+ void (*set_modem_roaming)(bool is_roaming, void *user_data);
86
+ void (*set_call_active)(bool active, void *user_data);
87
+ void (*set_call_setup)(enum call_setup value, void *user_data);
88
+};
89
+
90
+#ifdef HAVE_BLUEZ_5_BACKEND_NATIVE_MM
91
+void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_dict *info,
92
+ const struct mm_ops *ops, void *user_data);
93
+void mm_unregister(void *data);
94
+bool mm_is_available(void *modemmanager);
95
+unsigned int mm_supported_features();
96
+bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error);
97
+bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error);
98
+bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error);
99
+bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error);
100
+const char *mm_get_incoming_call_number(void *modemmanager);
101
+struct spa_list *mm_get_calls(void *modemmanager);
102
+#else
103
+void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_dict *info,
104
+ const struct mm_ops *ops, void *user_data)
105
+{
106
+ return NULL;
107
+}
108
+
109
+void mm_unregister(void *data)
110
+{
111
+}
112
+
113
+bool mm_is_available(void *modemmanager)
114
+{
115
+ return false;
116
+}
117
+
118
+unsigned int mm_supported_features(void)
119
+{
120
+ return 0;
121
+}
122
+
123
+bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error)
124
+{
125
+ if (error)
126
+ *error = CMEE_OPERATION_NOT_SUPPORTED;
127
+ return false;
128
+}
129
+
130
+bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error)
131
+{
132
+ if (error)
133
+ *error = CMEE_OPERATION_NOT_SUPPORTED;
134
+ return false;
135
+}
136
+
137
+bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error)
138
+{
139
+ if (error)
140
+ *error = CMEE_OPERATION_NOT_SUPPORTED;
141
+ return false;
142
+}
143
+
144
+bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error)
145
+{
146
+ if (error)
147
+ *error = CMEE_OPERATION_NOT_SUPPORTED;
148
+ return false;
149
+}
150
+
151
+const char *mm_get_incoming_call_number(void *modemmanager)
152
+{
153
+ return NULL;
154
+}
155
+
156
+struct spa_list *mm_get_calls(void *modemmanager)
157
+{
158
+ return NULL;
159
+}
160
+#endif
161
+
162
+#endif
163
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/quirks.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/quirks.c
Changed
15
1
2
{ "faststream", SPA_BT_FEATURE_FASTSTREAM },
3
{ "a2dp-duplex", SPA_BT_FEATURE_A2DP_DUPLEX },
4
};
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(feature_keys); ++i) {
7
- if (spa_streq(str, feature_keysi.key))
8
- return feature_keysi.value;
9
+ SPA_FOR_EACH_ELEMENT_VAR(feature_keys, f) {
10
+ if (spa_streq(str, f->key))
11
+ return f->value;
12
}
13
return 0;
14
}
15
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
201
1
2
#define DEFAULT_CLOCK_NAME "clock.system.monotonic"
3
4
struct props {
5
- uint32_t min_latency;
6
- uint32_t max_latency;
7
char clock_name64;
8
};
9
10
#define MAX_BUFFERS 32
11
-#define MIN_LATENCY 512
12
-#define MAX_LATENCY 1024
13
14
struct buffer {
15
uint32_t id;
16
17
struct spa_param_info paramsN_NODE_PARAMS;
18
struct props props;
19
20
+ uint32_t quantum_limit;
21
+
22
/* Transport */
23
struct spa_bt_transport *transport;
24
struct spa_hook transport_listener;
25
26
/* Flags */
27
unsigned int started:1;
28
unsigned int following:1;
29
+ unsigned int flush_pending:1;
30
31
/* Sources */
32
struct spa_source source;
33
+ struct spa_source flush_timer_source;
34
35
/* Timer */
36
int timerfd;
37
- struct timespec now;
38
+ int flush_timerfd;
39
struct spa_io_clock *clock;
40
struct spa_io_position *position;
41
42
+ uint64_t current_time;
43
+ uint64_t next_time;
44
+ uint64_t process_time;
45
+ uint64_t prev_flush_time;
46
+ uint64_t next_flush_time;
47
+
48
/* mSBC */
49
sbc_t msbc;
50
uint8_t *buffer;
51
uint8_t *buffer_head;
52
uint8_t *buffer_next;
53
int buffer_size;
54
-
55
- /* Times */
56
- uint64_t start_time;
57
- uint64_t total_samples;
58
+ int msbc_seq;
59
};
60
61
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0)
62
63
-static const uint32_t default_min_latency = MIN_LATENCY;
64
-static const uint32_t default_max_latency = MAX_LATENCY;
65
static const char sntable4 = { 0x08, 0x38, 0xC8, 0xF8 };
66
67
static void reset_props(struct props *props)
68
{
69
- props->min_latency = default_min_latency;
70
- props->max_latency = default_max_latency;
71
strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name));
72
}
73
74
75
switch (id) {
76
case SPA_PARAM_PropInfo:
77
{
78
- struct props *p = &this->props;
79
-
80
switch (result.index) {
81
- case 0:
82
- param = spa_pod_builder_add_object(&b,
83
- SPA_TYPE_OBJECT_PropInfo, id,
84
- SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_minLatency),
85
- SPA_PROP_INFO_description, SPA_POD_String("The minimum latency"),
86
- SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->min_latency, 1, INT32_MAX));
87
- break;
88
- case 1:
89
- param = spa_pod_builder_add_object(&b,
90
- SPA_TYPE_OBJECT_PropInfo, id,
91
- SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_maxLatency),
92
- SPA_PROP_INFO_description, SPA_POD_String("The maximum latency"),
93
- SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->max_latency, 1, INT32_MAX));
94
- break;
95
default:
96
return 0;
97
}
98
99
}
100
case SPA_PARAM_Props:
101
{
102
- struct props *p = &this->props;
103
-
104
switch (result.index) {
105
case 0:
106
param = spa_pod_builder_add_object(&b,
107
- SPA_TYPE_OBJECT_Props, id,
108
- SPA_PROP_minLatency, SPA_POD_Int(p->min_latency),
109
- SPA_PROP_maxLatency, SPA_POD_Int(p->max_latency));
110
+ SPA_TYPE_OBJECT_Props, id);
111
break;
112
default:
113
return 0;
114
115
ts.it_interval.tv_sec = 0;
116
ts.it_interval.tv_nsec = 0;
117
return spa_system_timerfd_settime(this->data_system,
118
- this->timerfd, 0, &ts, NULL);
119
+ this->timerfd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
120
}
121
122
static int set_timers(struct impl *this)
123
{
124
- return set_timeout(this, this->following ? 0 : 1);
125
-}
126
-
127
-static uint64_t get_next_timeout(struct impl *this, uint64_t now_time, uint64_t processed_samples)
128
-{
129
- struct port *port = &this->port;
130
- uint64_t playback_time = 0, elapsed_time = 0, next_time = 0;
131
-
132
- this->total_samples += processed_samples;
133
+ struct timespec now;
134
135
- playback_time = (this->total_samples * SPA_NSEC_PER_SEC) / port->current_format.info.raw.rate;
136
- if (now_time > this->start_time)
137
- elapsed_time = now_time - this->start_time;
138
- if (elapsed_time < playback_time)
139
- next_time = playback_time - elapsed_time;
140
+ spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &now);
141
+ this->next_time = SPA_TIMESPEC_TO_NSEC(&now);
142
143
- return next_time;
144
+ return set_timeout(this, this->following ? 0 : this->next_time);
145
}
146
147
static int do_reassign_follower(struct spa_loop *loop,
148
149
reset_props(&new_props);
150
} else {
151
spa_pod_parse_object(param,
152
- SPA_TYPE_OBJECT_Props, NULL,
153
- SPA_PROP_minLatency, SPA_POD_OPT_Int(&new_props.min_latency),
154
- SPA_PROP_maxLatency, SPA_POD_OPT_Int(&new_props.max_latency));
155
+ SPA_TYPE_OBJECT_Props, NULL);
156
}
157
158
changed = (memcmp(&new_props, &this->props, sizeof(struct props)) != 0);
159
160
return 0;
161
}
162
163
+static void enable_flush_timer(struct impl *this, bool enabled)
164
+{
165
+ struct itimerspec ts;
166
+
167
+ if (!enabled)
168
+ this->next_flush_time = 0;
169
+
170
+ ts.it_value.tv_sec = this->next_flush_time / SPA_NSEC_PER_SEC;
171
+ ts.it_value.tv_nsec = this->next_flush_time % SPA_NSEC_PER_SEC;
172
+ ts.it_interval.tv_sec = 0;
173
+ ts.it_interval.tv_nsec = 0;
174
+ spa_system_timerfd_settime(this->data_system,
175
+ this->flush_timerfd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
176
+
177
+ this->flush_pending = enabled;
178
+}
179
+
180
+static uint32_t get_queued_frames(struct impl *this)
181
+{
182
+ struct port *port = &this->port;
183
+ uint32_t bytes = 0;
184
+ struct buffer *b;
185
+
186
+ spa_list_for_each(b, &port->ready, link) {
187
+ struct spa_data *d = b->buf->datas;
188
+
189
+ bytes += d0.chunk->size;
190
+ }
191
+
192
+ if (bytes > port->ready_offset)
193
+ bytes -= port->ready_offset;
194
+ else
195
+ bytes = 0;
196
+
197
+ return bytes / port->frame_size;
198
+}
199
+
200
static void flush_data(struct impl *this)
201
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/sco-source.c
Changed
127
1
2
struct impl *this = user_data;
3
struct port *port = &this->port;
4
5
+ set_timers(this);
6
spa_bt_decode_buffer_recover(&port->buffer);
7
return 0;
8
}
9
10
return 0;
11
}
12
13
+static int produce_buffer(struct impl *this);
14
+
15
static void sco_on_timeout(struct spa_source *source)
16
{
17
struct impl *this = source->data;
18
struct port *port = &this->port;
19
uint64_t exp, duration;
20
uint32_t rate;
21
- struct spa_io_buffers *io = port->io;
22
uint64_t prev_time, now_time;
23
24
if (this->transport == NULL)
25
26
this->clock->next_nsec = this->next_time;
27
}
28
29
- spa_log_trace(this->log, "%p: %d", this, io->status);
30
- io->status = SPA_STATUS_HAVE_DATA;
31
+ if (port->io) {
32
+ int status = produce_buffer(this);
33
+ spa_log_trace(this->log, "%p: io:%d status:%d", this, port->io->status, status);
34
+ }
35
+
36
spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA);
37
38
set_timeout(this, this->next_time);
39
40
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
41
return -EINVAL;
42
43
+ if (info.info.raw.format != SPA_AUDIO_FORMAT_S16_LE ||
44
+ info.info.raw.rate == 0 ||
45
+ info.info.raw.channels != 1)
46
+ return -EINVAL;
47
+
48
port->frame_size = info.info.raw.channels * 2;
49
port->current_format = info;
50
port->have_format = true;
51
52
}
53
}
54
55
-static int impl_node_process(void *object)
56
+static int produce_buffer(struct impl *this)
57
{
58
- struct impl *this = object;
59
- struct port *port;
60
- struct spa_io_buffers *io;
61
struct buffer *buffer;
62
+ struct port *port = &this->port;
63
+ struct spa_io_buffers *io = port->io;
64
65
- spa_return_val_if_fail(this != NULL, -EINVAL);
66
-
67
- port = &this->port;
68
- if ((io = port->io) == NULL)
69
+ if (io == NULL)
70
return -EIO;
71
72
/* Return if we already have a buffer */
73
74
io->buffer_id = SPA_ID_INVALID;
75
}
76
77
- /* Produce data */
78
+ /* Handle buffering */
79
process_buffering(this);
80
81
/* Return if there are no buffers ready to be processed */
82
83
return SPA_STATUS_HAVE_DATA;
84
}
85
86
+static int impl_node_process(void *object)
87
+{
88
+ struct impl *this = object;
89
+ struct port *port;
90
+ struct spa_io_buffers *io;
91
+
92
+ spa_return_val_if_fail(this != NULL, -EINVAL);
93
+
94
+ port = &this->port;
95
+ if ((io = port->io) == NULL)
96
+ return -EIO;
97
+
98
+ /* Return if we already have a buffer */
99
+ if (io->status == SPA_STATUS_HAVE_DATA)
100
+ return SPA_STATUS_HAVE_DATA;
101
+
102
+ /* Recycle */
103
+ if (io->buffer_id < port->n_buffers) {
104
+ recycle_buffer(this, port, io->buffer_id);
105
+ io->buffer_id = SPA_ID_INVALID;
106
+ }
107
+
108
+ /* Follower produces buffers here, driver in timeout */
109
+ if (this->following)
110
+ return produce_buffer(this);
111
+ else
112
+ return SPA_STATUS_OK;
113
+}
114
+
115
static const struct spa_node_methods impl_node = {
116
SPA_VERSION_NODE_METHODS,
117
.add_listener = impl_node_add_listener,
118
119
static int impl_clear(struct spa_handle *handle)
120
{
121
struct impl *this = (struct impl *) handle;
122
+
123
+ do_stop(this);
124
if (this->transport)
125
spa_hook_remove(&this->transport_listener);
126
spa_system_close(this->data_system, this->timerfd);
127
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/upower.c
Added
201
1
2
+/* Spa Bluez5 UPower proxy
3
+ *
4
+ * Copyright © 2022 Collabora
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 <errno.h>
27
+#include <spa/utils/string.h>
28
+
29
+#include "upower.h"
30
+
31
+#define UPOWER_SERVICE "org.freedesktop.UPower"
32
+#define UPOWER_DEVICE_INTERFACE UPOWER_SERVICE ".Device"
33
+#define UPOWER_DISPLAY_DEVICE_OBJECT "/org/freedesktop/UPower/devices/DisplayDevice"
34
+
35
+struct impl {
36
+ struct spa_bt_monitor *monitor;
37
+
38
+ struct spa_log *log;
39
+ DBusConnection *conn;
40
+
41
+ bool filters_added;
42
+
43
+ void *user_data;
44
+ void (*set_battery_level)(unsigned int level, void *user_data);
45
+};
46
+
47
+static DBusHandlerResult upower_parse_percentage(struct impl *this, DBusMessageIter *variant_i)
48
+{
49
+ double percentage;
50
+ unsigned int battery_level;
51
+
52
+ dbus_message_iter_get_basic(variant_i, &percentage);
53
+ spa_log_debug(this->log, "Battery level: %f %%", percentage);
54
+
55
+ battery_level = (unsigned int) round(percentage / 20.0);
56
+ this->set_battery_level(battery_level, this->user_data);
57
+
58
+ return DBUS_HANDLER_RESULT_HANDLED;
59
+}
60
+
61
+static void upower_get_percentage_properties_reply(DBusPendingCall *pending, void *user_data)
62
+{
63
+ struct impl *backend = user_data;
64
+ DBusMessage *r;
65
+ DBusMessageIter i, variant_i;
66
+
67
+ r = dbus_pending_call_steal_reply(pending);
68
+ if (r == NULL)
69
+ return;
70
+
71
+ if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
72
+ spa_log_error(backend->log, "Failed to get percentage from UPower: %s",
73
+ dbus_message_get_error_name(r));
74
+ goto finish;
75
+ }
76
+
77
+ if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "v")) {
78
+ spa_log_error(backend->log, "Invalid arguments in Get() reply");
79
+ goto finish;
80
+ }
81
+
82
+ dbus_message_iter_recurse(&i, &variant_i);
83
+ upower_parse_percentage(backend, &variant_i);
84
+
85
+finish:
86
+ dbus_message_unref(r);
87
+}
88
+
89
+static void upower_clean(struct impl *this)
90
+{
91
+ this->set_battery_level(0, this->user_data);
92
+}
93
+
94
+static DBusHandlerResult upower_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
95
+{
96
+ struct impl *this = user_data;
97
+ DBusError err;
98
+
99
+ dbus_error_init(&err);
100
+
101
+ if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
102
+ const char *name, *old_owner, *new_owner;
103
+
104
+ spa_log_debug(this->log, "Name owner changed %s", dbus_message_get_path(m));
105
+
106
+ if (!dbus_message_get_args(m, &err,
107
+ DBUS_TYPE_STRING, &name,
108
+ DBUS_TYPE_STRING, &old_owner,
109
+ DBUS_TYPE_STRING, &new_owner,
110
+ DBUS_TYPE_INVALID)) {
111
+ spa_log_error(this->log, "Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
112
+ goto finish;
113
+ }
114
+
115
+ if (spa_streq(name, UPOWER_SERVICE)) {
116
+ if (old_owner && *old_owner) {
117
+ spa_log_debug(this->log, "UPower daemon disappeared (%s)", old_owner);
118
+ upower_clean(this);
119
+ }
120
+
121
+ if (new_owner && *new_owner) {
122
+ DBusPendingCall *call;
123
+ static const char* upower_device_interface = UPOWER_DEVICE_INTERFACE;
124
+ static const char* percentage_property = "Percentage";
125
+
126
+ spa_log_debug(this->log, "UPower daemon appeared (%s)", new_owner);
127
+
128
+ m = dbus_message_new_method_call(UPOWER_SERVICE, UPOWER_DISPLAY_DEVICE_OBJECT, DBUS_INTERFACE_PROPERTIES, "Get");
129
+ if (m == NULL)
130
+ goto finish;
131
+ dbus_message_append_args(m, DBUS_TYPE_STRING, &upower_device_interface,
132
+ DBUS_TYPE_STRING, &percentage_property, DBUS_TYPE_INVALID);
133
+ dbus_connection_send_with_reply(this->conn, m, &call, -1);
134
+ dbus_pending_call_set_notify(call, upower_get_percentage_properties_reply, this, NULL);
135
+ dbus_message_unref(m);
136
+ }
137
+ }
138
+ } else if (dbus_message_is_signal(m, DBUS_INTERFACE_PROPERTIES, DBUS_SIGNAL_PROPERTIES_CHANGED)) {
139
+ const char *path;
140
+ DBusMessageIter iface_i, props_i;
141
+ const char *interface;
142
+
143
+ if (!dbus_message_iter_init(m, &iface_i) || !spa_streq(dbus_message_get_signature(m), "sa{sv}as")) {
144
+ spa_log_error(this->log, "Invalid signature found in PropertiesChanged");
145
+ goto finish;
146
+ }
147
+
148
+ dbus_message_iter_get_basic(&iface_i, &interface);
149
+ dbus_message_iter_next(&iface_i);
150
+ spa_assert(dbus_message_iter_get_arg_type(&iface_i) == DBUS_TYPE_ARRAY);
151
+
152
+ dbus_message_iter_recurse(&iface_i, &props_i);
153
+
154
+ path = dbus_message_get_path(m);
155
+
156
+ if (spa_streq(interface, UPOWER_DEVICE_INTERFACE)) {
157
+ spa_log_debug(this->log, "Properties changed on %s", path);
158
+
159
+ while (dbus_message_iter_get_arg_type(&props_i) != DBUS_TYPE_INVALID) {
160
+ DBusMessageIter i, value_i;
161
+ const char *key;
162
+
163
+ dbus_message_iter_recurse(&props_i, &i);
164
+
165
+ dbus_message_iter_get_basic(&i, &key);
166
+ dbus_message_iter_next(&i);
167
+ dbus_message_iter_recurse(&i, &value_i);
168
+
169
+ if(spa_streq(key, "Percentage"))
170
+ upower_parse_percentage(this, &value_i);
171
+
172
+ dbus_message_iter_next(&props_i);
173
+ }
174
+ }
175
+ }
176
+
177
+finish:
178
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
179
+}
180
+
181
+static int add_filters(struct impl *this)
182
+{
183
+ DBusError err;
184
+
185
+ if (this->filters_added)
186
+ return 0;
187
+
188
+ dbus_error_init(&err);
189
+
190
+ if (!dbus_connection_add_filter(this->conn, upower_filter_cb, this, NULL)) {
191
+ spa_log_error(this->log, "failed to add filter function");
192
+ goto fail;
193
+ }
194
+
195
+ dbus_bus_add_match(this->conn,
196
+ "type='signal',sender='org.freedesktop.DBus',"
197
+ "interface='org.freedesktop.DBus',member='NameOwnerChanged'," "arg0='" UPOWER_SERVICE "'", &err);
198
+ dbus_bus_add_match(this->conn,
199
+ "type='signal',sender='" UPOWER_SERVICE "',"
200
+ "interface='" DBUS_INTERFACE_PROPERTIES "',member='" DBUS_SIGNAL_PROPERTIES_CHANGED "',"
201
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/upower.h
Added
39
1
2
+/* Spa Bluez5 UPower proxy
3
+ *
4
+ * Copyright © 2022 Collabora
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#ifndef SPA_BLUEZ5_UPOWER_H_
27
+#define SPA_BLUEZ5_UPOWER_H_
28
+
29
+#include "defs.h"
30
+
31
+void *upower_register(struct spa_log *log,
32
+ void *dbus_connection,
33
+ void (*set_battery_level)(unsigned int level, void *user_data),
34
+ void *user_data);
35
+void upower_unregister(void *data);
36
+
37
+#endif
38
\ No newline at end of file
39
pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.60.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
201
1
2
struct spa_port_info info = SPA_PORT_INFO_INIT();
3
struct spa_io_buffers *io = nullptr;
4
struct spa_io_sequence *control = nullptr;
5
- struct spa_param_info params8;
6
+#define PORT_PropInfo 0
7
+#define PORT_EnumFormat 1
8
+#define PORT_Meta 2
9
+#define PORT_IO 3
10
+#define PORT_Format 4
11
+#define PORT_Buffers 5
12
+#define N_PORT_PARAMS 6
13
+ struct spa_param_info paramsN_PORT_PARAMS;
14
15
uint32_t fmt_index = 0;
16
PixelFormat enum_fmt;
17
18
{
19
spa_list_init(&queue);
20
21
- params0 = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ);
22
- params1 = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
23
- params2 = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
24
- params3 = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
25
- params4 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
26
- params5 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
27
+ paramsPORT_PropInfo = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ);
28
+ paramsPORT_EnumFormat = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
29
+ paramsPORT_Meta = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
30
+ paramsPORT_IO = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
31
+ paramsPORT_Format = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
32
+ paramsPORT_Buffers = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
33
34
info.flags = SPA_PORT_FLAG_LIVE | SPA_PORT_FLAG_PHYSICAL | SPA_PORT_FLAG_TERMINAL;
35
info.params = params;
36
- info.n_params = 6;
37
+ info.n_params = N_PORT_PARAMS;
38
}
39
};
40
41
42
SPA_NODE_CHANGE_MASK_PROPS |
43
SPA_NODE_CHANGE_MASK_PARAMS;
44
struct spa_node_info info = SPA_NODE_INFO_INIT();
45
- struct spa_param_info params8;
46
+#define NODE_PropInfo 0
47
+#define NODE_Props 1
48
+#define NODE_EnumFormat 2
49
+#define NODE_Format 3
50
+#define N_NODE_PARAMS 4
51
+ struct spa_param_info paramsN_NODE_PARAMS;
52
53
std::string device_id;
54
std::string device_name;
55
56
57
struct spa_source source = {};
58
59
+ ControlList ctrls;
60
bool active = false;
61
bool acquired = false;
62
63
64
65
#include "libcamera-utils.cpp"
66
67
+static int port_get_format(struct impl *impl, struct port *port,
68
+ uint32_t index,
69
+ const struct spa_pod *filter,
70
+ struct spa_pod **param,
71
+ struct spa_pod_builder *builder)
72
+{
73
+ struct spa_pod_frame f;
74
+
75
+ if (!port->current_format)
76
+ return -EIO;
77
+ if (index > 0)
78
+ return 0;
79
+
80
+ spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format);
81
+ spa_pod_builder_add(builder,
82
+ SPA_FORMAT_mediaType, SPA_POD_Id(port->current_format->media_type),
83
+ SPA_FORMAT_mediaSubtype, SPA_POD_Id(port->current_format->media_subtype),
84
+ 0);
85
+
86
+ switch (port->current_format->media_subtype) {
87
+ case SPA_MEDIA_SUBTYPE_raw:
88
+ spa_pod_builder_add(builder,
89
+ SPA_FORMAT_VIDEO_format, SPA_POD_Id(port->current_format->info.raw.format),
90
+ SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format->info.raw.size),
91
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format->info.raw.framerate),
92
+ 0);
93
+ break;
94
+ case SPA_MEDIA_SUBTYPE_mjpg:
95
+ case SPA_MEDIA_SUBTYPE_jpeg:
96
+ spa_pod_builder_add(builder,
97
+ SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format->info.mjpg.size),
98
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format->info.mjpg.framerate),
99
+ 0);
100
+ break;
101
+ case SPA_MEDIA_SUBTYPE_h264:
102
+ spa_pod_builder_add(builder,
103
+ SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format->info.h264.size),
104
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format->info.h264.framerate),
105
+ 0);
106
+ break;
107
+ default:
108
+ return -EIO;
109
+ }
110
+
111
+ *param = (struct spa_pod*)spa_pod_builder_pop(builder, &f);
112
+
113
+ return 1;
114
+}
115
+
116
static int impl_node_enum_params(void *object, int seq,
117
uint32_t id, uint32_t start, uint32_t num,
118
const struct spa_pod *filter)
119
120
uint8_t buffer1024;
121
struct spa_result_node_params result;
122
uint32_t count = 0;
123
+ int res;
124
125
spa_return_val_if_fail(impl != NULL, -EINVAL);
126
spa_return_val_if_fail(num != 0, -EINVAL);
127
128
SPA_PROP_INFO_type, SPA_POD_String(impl->device_name.c_str()));
129
break;
130
default:
131
- return 0;
132
+ return spa_libcamera_enum_controls(impl,
133
+ GET_OUT_PORT(impl, 0),
134
+ seq, result.index - 2, num, filter);
135
}
136
break;
137
}
138
139
}
140
break;
141
}
142
+ case SPA_PARAM_EnumFormat:
143
+ return spa_libcamera_enum_format(impl, GET_OUT_PORT(impl, 0),
144
+ seq, start, num, filter);
145
+ case SPA_PARAM_Format:
146
+ if ((res = port_get_format(impl, GET_OUT_PORT(impl, 0), result.index, filter, ¶m, &b)) <= 0)
147
+ return res;
148
+ break;
149
default:
150
return -ENOENT;
151
}
152
153
switch (id) {
154
case SPA_PARAM_Props:
155
{
156
+ struct spa_pod_object *obj = (struct spa_pod_object *) param;
157
+ struct spa_pod_prop *prop;
158
+
159
if (param == NULL) {
160
impl->device_id.clear();
161
impl->device_name.clear();
162
return 0;
163
}
164
-
165
- char device128;
166
- int res = spa_pod_parse_object(param,
167
- SPA_TYPE_OBJECT_Props, NULL,
168
- SPA_PROP_device, SPA_POD_OPT_Stringn(device, sizeof(device)));
169
-
170
- if (res < 0)
171
- return res;
172
-
173
- impl->device_id = device;
174
-
175
+ SPA_POD_OBJECT_FOREACH(obj, prop) {
176
+ char device128;
177
+
178
+ switch (prop->key) {
179
+ case SPA_PROP_device:
180
+ strncpy(device, (char *)SPA_POD_CONTENTS(struct spa_pod_string, &prop->value),
181
+ sizeof(device)-1);
182
+ impl->device_id = device;
183
+ break;
184
+ default:
185
+ spa_libcamera_set_control(impl, prop);
186
+ break;
187
+ }
188
+ }
189
break;
190
}
191
default:
192
193
{ SPA_KEY_DEVICE_API, "libcamera" },
194
{ SPA_KEY_MEDIA_CLASS, "Video/Source" },
195
{ SPA_KEY_MEDIA_ROLE, "Camera" },
196
- { SPA_KEY_NODE_PAUSE_ON_IDLE, "false" },
197
{ SPA_KEY_NODE_DRIVER, "true" },
198
};
199
200
201
pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp -> pipewire-0.3.60.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp
Changed
201
1
2
#include <errno.h>
3
#include <sys/mman.h>
4
#include <poll.h>
5
+#include <limits.h>
6
7
#include <linux/media.h>
8
9
10
impl->pendingRequests.push_back(request);
11
return 0;
12
} else {
13
+ request->controls().merge(impl->ctrls);
14
+ impl->ctrls.clear();
15
if ((res = impl->camera->queueRequest(request)) < 0) {
16
spa_log_warn(impl->log, "can't queue buffer %u: %s",
17
buffer_id, spa_strerror(res));
18
19
return NULL;
20
}
21
22
+static int score_size(Size &a, Size &b)
23
+{
24
+ int x, y;
25
+ x = (int)a.width - (int)b.width;
26
+ y = (int)a.height - (int)b.height;
27
+ return x * x + y * y;
28
+}
29
+
30
static int
31
spa_libcamera_enum_format(struct impl *impl, struct port *port, int seq,
32
uint32_t start, uint32_t num, const struct spa_pod *filter)
33
34
struct spa_pod_frame f2;
35
struct spa_result_node_params result;
36
struct spa_pod *fmt;
37
- uint32_t count = 0;
38
+ uint32_t i, count = 0, num_sizes;
39
PixelFormat format;
40
Size frameSize;
41
SizeRange sizeRange = SizeRange();
42
43
goto next_fmt;
44
}
45
46
- if (port->size_index < formats.sizes(format).size()) {
47
- frameSize = formats.sizes(format)port->size_index;
48
+ num_sizes = formats.sizes(format).size();
49
+ if (num_sizes > 0 && port->size_index <= num_sizes) {
50
+ if (port->size_index == 0) {
51
+ Size wanted = Size(640, 480), test;
52
+ int score, best = INT_MAX;
53
+ for (i = 0; i < num_sizes; i++) {
54
+ test = formats.sizes(format)i;
55
+ score = score_size(wanted, test);
56
+ if (score < best) {
57
+ best = score;
58
+ frameSize = test;
59
+ }
60
+ }
61
+ }
62
+ else {
63
+ frameSize = formats.sizes(format)port->size_index - 1;
64
+ }
65
} else if (port->size_index < 1) {
66
sizeRange = formats.range(format);
67
if (sizeRange.hStep == 0 || sizeRange.vStep == 0) {
68
69
uint32_t start, uint32_t num,
70
const struct spa_pod *filter)
71
{
72
+ const ControlInfoMap &info = impl->camera->controls();
73
+ uint8_t buffer1024;
74
+ struct spa_pod_builder b = { 0 };
75
+ struct spa_pod_frame f2;
76
+ struct spa_result_node_params result;
77
+ struct spa_pod *ctrl;
78
+ uint32_t count = 0, skip;
79
+ int res;
80
+ const ControlId *ctrl_id;
81
+ ControlInfo ctrl_info;
82
+
83
+ result.id = SPA_PARAM_PropInfo;
84
+ result.next = start;
85
+
86
+ auto it = info.begin();
87
+ for (skip = result.next; skip; skip--)
88
+ it++;
89
+
90
+ if (false) {
91
+next:
92
+ it++;
93
+ }
94
+ result.index = result.next++;
95
+ if (it == info.end())
96
+ goto enum_end;
97
+
98
+ ctrl_id = it->first;
99
+ ctrl_info = it->second;
100
+
101
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
102
+ spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo);
103
+ spa_pod_builder_add(&b,
104
+ SPA_PROP_INFO_id, SPA_POD_Id(ctrl_id->id()),
105
+ SPA_PROP_INFO_description, SPA_POD_String(ctrl_id->name().c_str()),
106
+ 0);
107
+
108
+ switch (ctrl_id->type()) {
109
+ case ControlTypeBool:
110
+ spa_pod_builder_add(&b,
111
+ SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool(
112
+ (bool)ctrl_info.def().get<bool>()),
113
+ 0);
114
+ break;
115
+ case ControlTypeFloat:
116
+ spa_pod_builder_add(&b,
117
+ SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
118
+ (float)ctrl_info.def().get<float>(),
119
+ (float)ctrl_info.min().get<float>(),
120
+ (float)ctrl_info.max().get<float>()),
121
+ 0);
122
+ break;
123
+ case ControlTypeInteger32:
124
+ spa_pod_builder_add(&b,
125
+ SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(
126
+ (int32_t)ctrl_info.def().get<int32_t>(),
127
+ (int32_t)ctrl_info.min().get<int32_t>(),
128
+ (int32_t)ctrl_info.max().get<int32_t>()),
129
+ 0);
130
+ break;
131
+ default:
132
+ goto next;
133
+ }
134
+
135
+ ctrl = (struct spa_pod*) spa_pod_builder_pop(&b, &f0);
136
+
137
+ if (spa_pod_filter(&b, &result.param, ctrl, filter) < 0)
138
+ goto next;
139
+
140
+ spa_node_emit_result(&impl->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
141
+
142
+ if (++count != num)
143
+ goto next;
144
+
145
+enum_end:
146
+ res = 0;
147
+ return res;
148
+}
149
+
150
+struct val {
151
+ uint32_t type;
152
+ float f_val;
153
+ int32_t i_val;
154
+ bool b_val;
155
+ uint32_t id;
156
+};
157
+
158
+static int do_update_ctrls(struct spa_loop *loop,
159
+ bool async,
160
+ uint32_t seq,
161
+ const void *data,
162
+ size_t size,
163
+ void *user_data)
164
+{
165
+ struct impl *impl = (struct impl *)user_data;
166
+ const struct val *d = (const struct val *)data;
167
+ switch (d->type) {
168
+ case ControlTypeBool:
169
+ impl->ctrls.set(d->id, d->b_val);
170
+ break;
171
+ case ControlTypeFloat:
172
+ impl->ctrls.set(d->id, d->f_val);
173
+ break;
174
+ case ControlTypeInteger32:
175
+ //impl->ctrls.set(d->id, (int32_t)d->i_val);
176
+ break;
177
+ default:
178
+ break;
179
+ }
180
return 0;
181
}
182
183
+static int
184
+spa_libcamera_set_control(struct impl *impl, const struct spa_pod_prop *prop)
185
+{
186
+ const ControlInfoMap &info = impl->camera->controls();
187
+ const ControlId *ctrl_id;
188
+ int res;
189
+ struct val d;
190
+
191
+ auto v = info.idmap().find(prop->key);
192
+ if (v == info.idmap().end())
193
+ return -ENOENT;
194
+
195
+ ctrl_id = v->second;
196
+
197
+ d.type = ctrl_id->type();
198
+ d.id = ctrl_id->id();
199
+
200
+ switch (d.type) {
201
pipewire-0.3.59.tar.gz/spa/plugins/support/cpu-x86.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/cpu-x86.c
Changed
9
1
2
} else if (family == 0x06)
3
model += extended_model;
4
}
5
+ (void)model;
6
7
flags = 0;
8
if (ecx & bit_SSE3)
9
pipewire-0.3.59.tar.gz/spa/plugins/support/cpu.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/cpu.c
Changed
27
1
2
/* https://wiki.freebsd.org/bhyve */
3
{ "BHYVE", SPA_CPU_VM_BHYVE },
4
};
5
- uint32_t i, j;
6
7
- for (i = 0; i < SPA_N_ELEMENTS(dmi_vendors); i++) {
8
+ SPA_FOR_EACH_ELEMENT_VAR(dmi_vendors, dv) {
9
char buffer256, *s;
10
11
- if ((s = read_file(dmi_vendorsi, buffer, sizeof(buffer))) == NULL)
12
+ if ((s = read_file(*dv, buffer, sizeof(buffer))) == NULL)
13
continue;
14
15
- for (j = 0; j < SPA_N_ELEMENTS(dmi_vendor_table); j++) {
16
- if (spa_strstartswith(s, dmi_vendor_tablej.vendor)) {
17
+ SPA_FOR_EACH_ELEMENT_VAR(dmi_vendor_table, t) {
18
+ if (spa_strstartswith(s, t->vendor)) {
19
spa_log_debug(impl->log, "Virtualization %s found in DMI (%s)",
20
- s, dmi_vendorsi);
21
- impl->vm_type = dmi_vendor_tablej.id;
22
+ s, *dv);
23
+ impl->vm_type = t->id;
24
goto done;
25
}
26
}
27
pipewire-0.3.59.tar.gz/spa/plugins/support/loop.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/loop.c
Changed
89
1
2
3
if (block) {
4
if ((res = spa_system_eventfd_write(impl->system, impl->ack_fd, 1)) < 0)
5
- spa_log_warn(impl->log, "%p: failed to write event fd: %s",
6
- impl, spa_strerror(res));
7
+ spa_log_warn(impl->log, "%p: failed to write event fd:%d: %s",
8
+ impl, impl->ack_fd, spa_strerror(res));
9
}
10
}
11
impl->flushing = false;
12
13
spa_loop_control_hook_before(&impl->hooks_list);
14
15
if ((res = spa_system_eventfd_read(impl->system, impl->ack_fd, &count)) < 0)
16
- spa_log_warn(impl->log, "%p: failed to read event fd: %s",
17
- impl, spa_strerror(res));
18
+ spa_log_warn(impl->log, "%p: failed to read event fd:%d: %s",
19
+ impl, impl->ack_fd, spa_strerror(res));
20
21
spa_loop_control_hook_after(&impl->hooks_list);
22
23
24
25
if (enabled && !s->enabled) {
26
if ((res = spa_system_eventfd_write(s->impl->system, source->fd, 1)) < 0)
27
- spa_log_warn(s->impl->log, "%p: failed to write idle fd %d: %s",
28
+ spa_log_warn(s->impl->log, "%p: failed to write idle fd:%d: %s",
29
source, source->fd, spa_strerror(res));
30
} else if (!enabled && s->enabled) {
31
uint64_t count;
32
if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0)
33
- spa_log_warn(s->impl->log, "%p: failed to read idle fd %d: %s",
34
+ spa_log_warn(s->impl->log, "%p: failed to read idle fd:%d: %s",
35
source, source->fd, spa_strerror(res));
36
}
37
s->enabled = enabled;
38
39
int res;
40
41
if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0)
42
- spa_log_warn(s->impl->log, "%p: failed to read event fd %d: %s",
43
+ spa_log_warn(s->impl->log, "%p: failed to read event fd:%d: %s",
44
source, source->fd, spa_strerror(res));
45
46
s->func.event(source->data, count);
47
48
spa_assert(source->func == source_event_func);
49
50
if (SPA_UNLIKELY((res = spa_system_eventfd_write(s->impl->system, source->fd, 1)) < 0))
51
- spa_log_warn(s->impl->log, "%p: failed to write event fd %d: %s",
52
+ spa_log_warn(s->impl->log, "%p: failed to write event fd:%d: %s",
53
source, source->fd, spa_strerror(res));
54
return res;
55
}
56
57
58
if (SPA_UNLIKELY((res = spa_system_timerfd_read(s->impl->system,
59
source->fd, &expirations)) < 0))
60
- spa_log_warn(s->impl->log, "%p: failed to read timer fd %d: %s",
61
+ spa_log_warn(s->impl->log, "%p: failed to read timer fd:%d: %s",
62
source, source->fd, spa_strerror(res));
63
64
s->func.timer(source->data, expirations);
65
66
int res, signal_number = 0;
67
68
if ((res = spa_system_signalfd_read(s->impl->system, source->fd, &signal_number)) < 0)
69
- spa_log_warn(s->impl->log, "%p: failed to read signal fd %d: %s",
70
+ spa_log_warn(s->impl->log, "%p: failed to read signal fd:%d: %s",
71
source, source->fd, spa_strerror(res));
72
73
s->func.signal(source->data, signal_number);
74
75
76
impl = (struct impl *) handle;
77
78
- if (impl->enter_count != 0)
79
- spa_log_warn(impl->log, "%p: loop is entered %d times",
80
- impl, impl->enter_count);
81
-
82
- spa_assert(!impl->polling);
83
+ if (impl->enter_count != 0 || impl->polling)
84
+ spa_log_warn(impl->log, "%p: loop is entered %d times polling:%d",
85
+ impl, impl->enter_count, impl->polling);
86
87
spa_list_consume(source, &impl->source_list, link)
88
loop_destroy_source(impl, &source->source);
89
pipewire-0.3.59.tar.gz/spa/plugins/support/null-audio-sink.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/null-audio-sink.c
Changed
13
1
2
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
3
return -EINVAL;
4
5
+ if (info.info.raw.rate == 0 ||
6
+ info.info.raw.channels == 0 ||
7
+ info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS)
8
+ return -EINVAL;
9
+
10
if (info.info.raw.format == SPA_AUDIO_FORMAT_F32) {
11
port->bpf = 4 * info.info.raw.channels;
12
port->blocks = 1;
13
pipewire-0.3.59.tar.gz/spa/plugins/v4l2/v4l2-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/v4l2/v4l2-source.c
Changed
201
1
2
#define NODE_PropInfo 0
3
#define NODE_Props 1
4
#define NODE_EnumFormat 2
5
-#define N_NODE_PARAMS 3
6
+#define NODE_Format 3
7
+#define N_NODE_PARAMS 4
8
struct spa_param_info paramsN_NODE_PARAMS;
9
struct props props;
10
11
12
13
#include "v4l2-utils.c"
14
15
+static int port_get_format(struct port *port,
16
+ uint32_t index,
17
+ const struct spa_pod *filter,
18
+ struct spa_pod **param,
19
+ struct spa_pod_builder *builder)
20
+{
21
+ struct spa_pod_frame f;
22
+
23
+ if (!port->have_format)
24
+ return -EIO;
25
+ if (index > 0)
26
+ return 0;
27
+
28
+ spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format);
29
+ spa_pod_builder_add(builder,
30
+ SPA_FORMAT_mediaType, SPA_POD_Id(port->current_format.media_type),
31
+ SPA_FORMAT_mediaSubtype, SPA_POD_Id(port->current_format.media_subtype),
32
+ 0);
33
+
34
+ switch (port->current_format.media_subtype) {
35
+ case SPA_MEDIA_SUBTYPE_raw:
36
+ spa_pod_builder_add(builder,
37
+ SPA_FORMAT_VIDEO_format, SPA_POD_Id(port->current_format.info.raw.format),
38
+ SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.raw.size),
39
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.raw.framerate),
40
+ 0);
41
+ break;
42
+ case SPA_MEDIA_SUBTYPE_mjpg:
43
+ case SPA_MEDIA_SUBTYPE_jpeg:
44
+ spa_pod_builder_add(builder,
45
+ SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.mjpg.size),
46
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.mjpg.framerate),
47
+ 0);
48
+ break;
49
+ case SPA_MEDIA_SUBTYPE_h264:
50
+ spa_pod_builder_add(builder,
51
+ SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.h264.size),
52
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.h264.framerate),
53
+ 0);
54
+ break;
55
+ default:
56
+ return -EIO;
57
+ }
58
+
59
+ *param = spa_pod_builder_pop(builder, &f);
60
+
61
+ return 1;
62
+}
63
+
64
+
65
static int impl_node_enum_params(void *object, int seq,
66
uint32_t id, uint32_t start, uint32_t num,
67
const struct spa_pod *filter)
68
69
uint8_t buffer1024;
70
struct spa_result_node_params result;
71
uint32_t count = 0;
72
+ int res;
73
74
spa_return_val_if_fail(this != NULL, -EINVAL);
75
spa_return_val_if_fail(num != 0, -EINVAL);
76
77
SPA_PROP_INFO_type, SPA_POD_Int(p->device_fd));
78
break;
79
default:
80
- return 0;
81
+ return spa_v4l2_enum_controls(this, seq, result.index - 3, num, filter);
82
}
83
- return spa_v4l2_enum_controls(this, seq, start, num, filter);
84
+ break;
85
}
86
case SPA_PARAM_Props:
87
{
88
89
}
90
case SPA_PARAM_EnumFormat:
91
return spa_v4l2_enum_format(this, seq, start, num, filter);
92
+ case SPA_PARAM_Format:
93
+ if((res = port_get_format(GET_OUT_PORT(this, 0),
94
+ result.index, filter, ¶m, &b)) <= 0)
95
+ return res;
96
+ break;
97
default:
98
return -ENOENT;
99
}
100
101
case SPA_PARAM_Props:
102
{
103
struct props *p = &this->props;
104
+ struct spa_pod_object *obj = (struct spa_pod_object *) param;
105
+ struct spa_pod_prop *prop;
106
+ int res = 0;
107
108
if (param == NULL) {
109
reset_props(p);
110
return 0;
111
}
112
- spa_pod_parse_object(param,
113
- SPA_TYPE_OBJECT_Props, NULL,
114
- SPA_PROP_device, SPA_POD_OPT_Stringn(p->device, sizeof(p->device)));
115
+ SPA_POD_OBJECT_FOREACH(obj, prop) {
116
+ switch (prop->key) {
117
+ case SPA_PROP_device:
118
+ strncpy(p->device,
119
+ (char *)SPA_POD_CONTENTS(struct spa_pod_string, &prop->value),
120
+ sizeof(p->device)-1);
121
+ break;
122
+ default:
123
+ res = spa_v4l2_set_control(this, prop->key, prop);
124
+ break;
125
+ }
126
+ if (res < 0)
127
+ return res;
128
+ }
129
+
130
break;
131
}
132
default:
133
134
return -ENOTSUP;
135
}
136
137
-static int port_get_format(void *object,
138
- enum spa_direction direction, uint32_t port_id,
139
- uint32_t index,
140
- const struct spa_pod *filter,
141
- struct spa_pod **param,
142
- struct spa_pod_builder *builder)
143
-{
144
- struct impl *this = object;
145
- struct port *port = GET_PORT(this, direction, port_id);
146
- struct spa_pod_frame f;
147
-
148
- if (!port->have_format)
149
- return -EIO;
150
- if (index > 0)
151
- return 0;
152
-
153
- spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format);
154
- spa_pod_builder_add(builder,
155
- SPA_FORMAT_mediaType, SPA_POD_Id(port->current_format.media_type),
156
- SPA_FORMAT_mediaSubtype, SPA_POD_Id(port->current_format.media_subtype),
157
- 0);
158
-
159
- switch (port->current_format.media_subtype) {
160
- case SPA_MEDIA_SUBTYPE_raw:
161
- spa_pod_builder_add(builder,
162
- SPA_FORMAT_VIDEO_format, SPA_POD_Id(port->current_format.info.raw.format),
163
- SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.raw.size),
164
- SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.raw.framerate),
165
- 0);
166
- break;
167
- case SPA_MEDIA_SUBTYPE_mjpg:
168
- case SPA_MEDIA_SUBTYPE_jpeg:
169
- spa_pod_builder_add(builder,
170
- SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.mjpg.size),
171
- SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.mjpg.framerate),
172
- 0);
173
- break;
174
- case SPA_MEDIA_SUBTYPE_h264:
175
- spa_pod_builder_add(builder,
176
- SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.h264.size),
177
- SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.h264.framerate),
178
- 0);
179
- break;
180
- default:
181
- return -EIO;
182
- }
183
-
184
- *param = spa_pod_builder_pop(builder, &f);
185
-
186
- return 1;
187
-}
188
-
189
static int impl_node_port_enum_params(void *object, int seq,
190
enum spa_direction direction,
191
uint32_t port_id,
192
193
return spa_v4l2_enum_format(this, seq, start, num, filter);
194
195
case SPA_PARAM_Format:
196
- if((res = port_get_format(this, direction, port_id,
197
- result.index, filter, ¶m, &b)) <= 0)
198
+ if((res = port_get_format(port, result.index, filter, ¶m, &b)) <= 0)
199
return res;
200
break;
201
pipewire-0.3.59.tar.gz/spa/plugins/v4l2/v4l2-udev.c -> pipewire-0.3.60.tar.gz/spa/plugins/v4l2/v4l2-udev.c
Changed
10
1
2
if (str && *str) {
3
itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS_PATH, str);
4
}
5
- if ((str = udev_device_get_syspath(dev)) && *str) {
6
+ if ((str = udev_device_get_devpath(dev)) && *str) {
7
itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_SYSFS_PATH, str);
8
}
9
if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) {
10
pipewire-0.3.59.tar.gz/spa/plugins/v4l2/v4l2-utils.c -> pipewire-0.3.60.tar.gz/spa/plugins/v4l2/v4l2-utils.c
Changed
201
1
2
#include <sys/mman.h>
3
#include <poll.h>
4
5
-static void v4l2_on_fd_events(struct spa_source *source);
6
+#include <spa/utils/result.h>
7
8
static int xioctl(int fd, int request, void *arg)
9
{
10
11
return err;
12
}
13
14
-
15
int spa_v4l2_open(struct spa_v4l2_device *dev, const char *path)
16
{
17
struct stat st;
18
19
20
static const struct format_info *fourcc_to_format_info(uint32_t fourcc)
21
{
22
- size_t i;
23
-
24
- for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) {
25
- if (format_infoi.fourcc == fourcc)
26
- return &format_infoi;
27
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, i) {
28
+ if (i->fourcc == fourcc)
29
+ return i;
30
}
31
return NULL;
32
}
33
34
#if 0
35
static const struct format_info *video_format_to_format_info(uint32_t format)
36
{
37
- int i;
38
-
39
- for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) {
40
- if (format_infoi.format == format)
41
- return &format_infoi;
42
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, i) {
43
+ if (i->format == format)
44
+ return i;
45
}
46
return NULL;
47
}
48
49
size_t i;
50
51
for (i = startidx; i < SPA_N_ELEMENTS(format_info); i++) {
52
- if ((format_infoi.media_type == type) &&
53
- (format_infoi.media_subtype == subtype) &&
54
- (format == 0 || format_infoi.format == format))
55
- return &format_infoi;
56
+ const struct format_info *fi = &format_infoi;
57
+ if ((fi->media_type == type) &&
58
+ (fi->media_subtype == subtype) &&
59
+ (format == 0 || fi->format == format))
60
+ return fi;
61
}
62
return NULL;
63
}
64
65
bool match;
66
67
spa_zero(fmt);
68
- spa_zero(streamparm);
69
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
70
+
71
+ spa_zero(streamparm);
72
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
73
74
switch (format->media_subtype) {
75
76
return -EINVAL;
77
}
78
79
-
80
fmt.fmt.pix.pixelformat = info->fourcc;
81
fmt.fmt.pix.field = V4L2_FIELD_ANY;
82
fmt.fmt.pix.width = size->width;
83
84
return res;
85
}
86
87
+static struct {
88
+ uint32_t v4l2_id;
89
+ uint32_t spa_id;
90
+} control_map = {
91
+ { V4L2_CID_BRIGHTNESS, SPA_PROP_brightness },
92
+ { V4L2_CID_CONTRAST, SPA_PROP_contrast },
93
+ { V4L2_CID_SATURATION, SPA_PROP_saturation },
94
+ { V4L2_CID_HUE, SPA_PROP_hue },
95
+ { V4L2_CID_GAMMA, SPA_PROP_gamma },
96
+ { V4L2_CID_EXPOSURE, SPA_PROP_exposure },
97
+ { V4L2_CID_GAIN, SPA_PROP_gain },
98
+ { V4L2_CID_SHARPNESS, SPA_PROP_sharpness },
99
+};
100
+
101
static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id)
102
{
103
- switch (control_id) {
104
- case V4L2_CID_BRIGHTNESS:
105
- return SPA_PROP_brightness;
106
- case V4L2_CID_CONTRAST:
107
- return SPA_PROP_contrast;
108
- case V4L2_CID_SATURATION:
109
- return SPA_PROP_saturation;
110
- case V4L2_CID_HUE:
111
- return SPA_PROP_hue;
112
- case V4L2_CID_GAMMA:
113
- return SPA_PROP_gamma;
114
- case V4L2_CID_EXPOSURE:
115
- return SPA_PROP_exposure;
116
- case V4L2_CID_GAIN:
117
- return SPA_PROP_gain;
118
- case V4L2_CID_SHARPNESS:
119
- return SPA_PROP_sharpness;
120
- default:
121
- return SPA_PROP_START_CUSTOM + control_id;
122
+ SPA_FOR_EACH_ELEMENT_VAR(control_map, c) {
123
+ if (c->v4l2_id == control_id)
124
+ return c->spa_id;
125
+ }
126
+ return SPA_PROP_START_CUSTOM + control_id;
127
+}
128
+
129
+static uint32_t prop_id_to_control(struct impl *impl, uint32_t prop_id)
130
+{
131
+ SPA_FOR_EACH_ELEMENT_VAR(control_map, c) {
132
+ if (c->spa_id == prop_id)
133
+ return c->v4l2_id;
134
}
135
+ if (prop_id >= SPA_PROP_START_CUSTOM)
136
+ return prop_id - SPA_PROP_START_CUSTOM;
137
+ return SPA_ID_INVALID;
138
}
139
140
static int
141
142
return res;
143
}
144
145
+static int
146
+spa_v4l2_set_control(struct impl *this, uint32_t id,
147
+ const struct spa_pod_prop *prop)
148
+{
149
+ struct port *port = &this->out_ports0;
150
+ struct spa_v4l2_device *dev = &port->dev;
151
+ struct v4l2_control control;
152
+ int res;
153
+
154
+ spa_zero(control);
155
+ control.id = prop_id_to_control(this, prop->key);
156
+ if (control.id == SPA_ID_INVALID)
157
+ return -ENOENT;
158
+
159
+ if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
160
+ return res;
161
+
162
+ switch (SPA_POD_TYPE(&prop->value)) {
163
+ case SPA_TYPE_Bool:
164
+ {
165
+ bool val;
166
+ if ((res = spa_pod_get_bool(&prop->value, &val)) < 0)
167
+ goto done;
168
+ control.value = val;
169
+ break;
170
+ }
171
+ case SPA_TYPE_Int:
172
+ {
173
+ int32_t val;
174
+ if ((res = spa_pod_get_int(&prop->value, &val)) < 0)
175
+ goto done;
176
+ control.value = val;
177
+ break;
178
+ }
179
+ default:
180
+ res = -EINVAL;
181
+ goto done;
182
+ }
183
+ if (xioctl(dev->fd, VIDIOC_S_CTRL, &control) < 0) {
184
+ res = -errno;
185
+ goto done;
186
+ }
187
+
188
+ res = 0;
189
+
190
+done:
191
+ spa_v4l2_close(dev);
192
+ return res;
193
+}
194
+
195
static int mmap_read(struct impl *this)
196
{
197
struct port *port = &this->out_ports0;
198
199
return;
200
201
pipewire-0.3.59.tar.gz/spa/plugins/videoconvert/videoadapter.c -> pipewire-0.3.60.tar.gz/spa/plugins/videoconvert/videoadapter.c
Changed
55
1
2
return 0;
3
}
4
5
-static int format_video_raw_parse_opt(const struct spa_pod *format, struct spa_video_info_raw *info)
6
-{
7
- uint32_t media_type, media_subtype;
8
- int res;
9
- if ((res = spa_format_parse(format, &media_type, &media_subtype)) < 0)
10
- return res;
11
- if (media_type != SPA_MEDIA_TYPE_video ||
12
- media_subtype != SPA_MEDIA_SUBTYPE_raw)
13
- return -ENOTSUP;
14
-
15
- spa_zero(*info);
16
- res = spa_pod_parse_object(format,
17
- SPA_TYPE_OBJECT_Format, NULL,
18
- SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format),
19
- SPA_FORMAT_VIDEO_size, SPA_POD_OPT_Int(&info->size));
20
- return res;
21
-}
22
-
23
static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
24
const struct spa_pod *param)
25
{
26
27
if ((res = spa_format_parse(param, &info.media_type, &info.media_subtype)) < 0)
28
return res;
29
if (info.media_type != SPA_MEDIA_TYPE_video ||
30
- info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
31
- return -EINVAL;
32
+ info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
33
+ return -EINVAL;
34
+
35
if (spa_format_video_raw_parse(param, &info.info.raw) < 0)
36
return -EINVAL;
37
38
39
40
if (format) {
41
struct spa_video_info info;
42
- if (format_video_raw_parse_opt(format, &info.info.raw) >= 0)
43
+
44
+ spa_zero(info);
45
+ if ((res = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0)
46
+ return res;
47
+ if (info.media_type != SPA_MEDIA_TYPE_video ||
48
+ info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
49
+ return -ENOTSUP;
50
+
51
+ if (spa_format_video_raw_parse(format, &info.info.raw) >= 0)
52
this->default_format = info;
53
}
54
55
pipewire-0.3.59.tar.gz/spa/plugins/videotestsrc/videotestsrc.c -> pipewire-0.3.60.tar.gz/spa/plugins/videotestsrc/videotestsrc.c
Changed
14
1
2
else
3
return -EINVAL;
4
5
+ if (info.info.raw.size.width == 0 ||
6
+ info.info.raw.size.height == 0 ||
7
+ info.info.raw.framerate.num == 0 ||
8
+ info.info.raw.framerate.denom == 0)
9
+ return -EINVAL;
10
+
11
port->current_format = info;
12
port->have_format = true;
13
}
14
pipewire-0.3.59.tar.gz/spa/plugins/volume/volume.c -> pipewire-0.3.60.tar.gz/spa/plugins/volume/volume.c
Changed
26
1
2
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
3
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
4
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
5
- SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(3,
6
+ SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(2,
7
SPA_AUDIO_FORMAT_S16,
8
- SPA_AUDIO_FORMAT_S16,
9
- SPA_AUDIO_FORMAT_S32),
10
+ SPA_AUDIO_FORMAT_S16),
11
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(
12
DEFAULT_RATE, 1, INT32_MAX),
13
SPA_FORMAT_AUDIO_channels, SPA_POD_CHOICE_RANGE_Int(
14
15
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
16
return -EINVAL;
17
18
+ if (info.info.raw.format != SPA_AUDIO_FORMAT_S16 ||
19
+ info.info.raw.channels == 0 ||
20
+ info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS)
21
+ return -EINVAL;
22
+
23
this->bpf = 2 * info.info.raw.channels;
24
this->current_format = info;
25
port->have_format = true;
26
pipewire-0.3.59.tar.gz/spa/tests/benchmark-dict.c -> pipewire-0.3.60.tar.gz/spa/tests/benchmark-dict.c
Changed
10
1
2
static struct spa_dict_item itemsMAX_ITEMS;
3
static char valuesMAX_ITEMS32;
4
5
-static void gen_values()
6
+static void gen_values(void)
7
{
8
uint32_t i, j, idx;
9
static const char chars = "abcdefghijklmnopqrstuvwxyz.:*ABCDEFGHIJKLMNOPQRSTUVWXYZ";
10
pipewire-0.3.59.tar.gz/spa/tests/benchmark-pod.c -> pipewire-0.3.60.tar.gz/spa/tests/benchmark-pod.c
Changed
37
1
2
3
#define MAX_COUNT 10000000
4
5
-static void test_builder()
6
+static void test_builder(void)
7
{
8
uint8_t buffer1024;
9
struct spa_pod_builder b = { NULL, };
10
11
t2 - t1, count, count * (uint64_t)SPA_NSEC_PER_SEC / (t2 - t1));
12
}
13
14
-static void test_builder2()
15
+static void test_builder2(void)
16
{
17
uint8_t buffer1024;
18
struct spa_pod_builder b = { NULL, };
19
20
t2 - t1, count, count * (uint64_t)SPA_NSEC_PER_SEC / (t2 - t1));
21
}
22
23
-static void test_parse()
24
+static void test_parse(void)
25
{
26
uint8_t buffer1024;
27
struct spa_pod_builder b = { NULL, };
28
29
t2 - t1, count, count * (uint64_t)SPA_NSEC_PER_SEC / (t2 - t1));
30
}
31
32
-static void test_parser()
33
+static void test_parser(void)
34
{
35
uint8_t buffer1024;
36
struct spa_pod_builder b = { NULL, };
37
pipewire-0.3.59.tar.gz/src/daemon/jack.conf.in -> pipewire-0.3.60.tar.gz/src/daemon/jack.conf.in
Changed
26
1
2
#jack.locked-process = true
3
#jack.default-as-system = false
4
#jack.fix-midi-events = true
5
+ #jack.global-buffer-size = false
6
}
7
8
# client specific properties
9
10
}
11
}
12
}
13
+ {
14
+ matches =
15
+ {
16
+ application.process.binary = "jack_bufsize"
17
+ }
18
+
19
+ actions = {
20
+ update-props = {
21
+ jack.global-buffer-size = true
22
+ }
23
+ }
24
+ }
25
26
pipewire-0.3.59.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.60.tar.gz/src/daemon/pipewire.conf.in
Changed
25
1
2
{ name = libpipewire-module-session-manager }
3
4
# Use libcanberra to play X11 Bell
5
- #{ name = libpipewire-module-x11-bell
6
- # args = {
7
- # #sink.name = "@DEFAULT_SINK@"
8
- # #sample.name = "bell-window-system"
9
- # #x11.display = null
10
- # #x11.xauthority = null
11
- # }
12
- #}
13
+ { name = libpipewire-module-x11-bell
14
+ args = {
15
+ #sink.name = "@DEFAULT_SINK@"
16
+ #sample.name = "bell-window-system"
17
+ #x11.display = null
18
+ #x11.xauthority = null
19
+ }
20
+ flags = ifexists nofail
21
+ }
22
23
24
context.objects =
25
pipewire-0.3.59.tar.gz/src/examples/export-sink.c -> pipewire-0.3.60.tar.gz/src/examples/export-sink.c
Changed
42
1
2
Uint32 sdl_format;
3
void *dest;
4
5
- d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS;
6
if (format == NULL) {
7
+ spa_zero(d->format);
8
SDL_DestroyTexture(d->texture);
9
- d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
10
- d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
11
+ d->texture = NULL;
12
} else {
13
spa_debug_format(0, NULL, format);
14
15
16
sdl_format = id_to_sdl_format(d->format.format);
17
if (sdl_format == SDL_PIXELFORMAT_UNKNOWN)
18
return -EINVAL;
19
+ if (d->format.size.width == 0 ||
20
+ d->format.size.height == 0)
21
+ return -EINVAL;
22
23
d->texture = SDL_CreateTexture(d->renderer,
24
sdl_format,
25
26
SDL_LockTexture(d->texture, NULL, &dest, &d->stride);
27
SDL_UnlockTexture(d->texture);
28
29
+ }
30
+ d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS;
31
+ if (format) {
32
d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
33
d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
34
+ } else {
35
+ d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
36
+ d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
37
}
38
+
39
spa_node_emit_port_info(&d->hooks, direction, port_id, &d->info);
40
d->info.change_mask = 0;
41
42
pipewire-0.3.59.tar.gz/src/examples/export-source.c -> pipewire-0.3.60.tar.gz/src/examples/export-source.c
Changed
49
1
2
{
3
struct data *d = object;
4
5
- d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS;
6
if (format == NULL) {
7
- d->format.format = 0;
8
- d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
9
- d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
10
- spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_OUTPUT, 0, &d->info);
11
- return 0;
12
- }
13
+ spa_zero(d->format);
14
+ } else {
15
+ spa_debug_format(0, NULL, format);
16
17
- spa_debug_format(0, NULL, format);
18
-
19
- if (spa_format_audio_raw_parse(format, &d->format) < 0)
20
- return -EINVAL;
21
+ if (spa_format_audio_raw_parse(format, &d->format) < 0)
22
+ return -EINVAL;
23
24
- if (d->format.format != SPA_AUDIO_FORMAT_S16 &&
25
- d->format.format != SPA_AUDIO_FORMAT_F32)
26
- return -EINVAL;
27
+ if (d->format.format != SPA_AUDIO_FORMAT_S16 &&
28
+ d->format.format != SPA_AUDIO_FORMAT_F32)
29
+ return -EINVAL;
30
+ if (d->format.rate == 0 ||
31
+ d->format.channels == 0 ||
32
+ d->format.channels > SPA_AUDIO_MAX_CHANNELS)
33
+ return -EINVAL;
34
+ }
35
36
- d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
37
- d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
38
+ d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS;
39
+ if (format) {
40
+ d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
41
+ d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
42
+ } else {
43
+ d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
44
+ d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
45
+ }
46
spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_OUTPUT, 0, &d->info);
47
48
return 0;
49
pipewire-0.3.59.tar.gz/src/examples/local-v4l2.c -> pipewire-0.3.60.tar.gz/src/examples/local-v4l2.c
Changed
61
1
2
Uint32 sdl_format;
3
void *dest;
4
5
- if (format == NULL)
6
- return 0;
7
-
8
- spa_debug_format(0, NULL, format);
9
-
10
- spa_format_video_raw_parse(format, &d->format);
11
-
12
- sdl_format = id_to_sdl_format(d->format.format);
13
- if (sdl_format == SDL_PIXELFORMAT_UNKNOWN)
14
- return -EINVAL;
15
-
16
- d->texture = SDL_CreateTexture(d->renderer,
17
- sdl_format,
18
- SDL_TEXTUREACCESS_STREAMING,
19
- d->format.size.width,
20
- d->format.size.height);
21
- SDL_LockTexture(d->texture, NULL, &dest, &d->stride);
22
- SDL_UnlockTexture(d->texture);
23
+ if (format == NULL) {
24
+ spa_zero(d->format);
25
+ SDL_DestroyTexture(d->texture);
26
+ d->texture = NULL;
27
+ } else {
28
+ spa_debug_format(0, NULL, format);
29
+
30
+ spa_format_video_raw_parse(format, &d->format);
31
+
32
+ sdl_format = id_to_sdl_format(d->format.format);
33
+ if (sdl_format == SDL_PIXELFORMAT_UNKNOWN)
34
+ return -EINVAL;
35
+ if (d->format.size.width == 0 ||
36
+ d->format.size.height == 0)
37
+ return -EINVAL;
38
+
39
+ d->texture = SDL_CreateTexture(d->renderer,
40
+ sdl_format,
41
+ SDL_TEXTUREACCESS_STREAMING,
42
+ d->format.size.width,
43
+ d->format.size.height);
44
+ SDL_LockTexture(d->texture, NULL, &dest, &d->stride);
45
+ SDL_UnlockTexture(d->texture);
46
+ }
47
48
d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS;
49
- d->params1 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
50
- d->params2 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
51
+ if (format) {
52
+ d->params1 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
53
+ d->params2 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
54
+ } else {
55
+ d->params1 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
56
+ d->params2 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
57
+ }
58
spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_INPUT, 0, &d->info);
59
60
return 0;
61
pipewire-0.3.59.tar.gz/src/examples/sdl.h -> pipewire-0.3.60.tar.gz/src/examples/sdl.h
Changed
44
1
2
3
static inline uint32_t sdl_format_to_id(Uint32 format)
4
{
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(sdl_video_formats); i++) {
7
- if (sdl_video_formatsi.format == format)
8
- return sdl_video_formatsi.id;
9
+ SPA_FOR_EACH_ELEMENT_VAR(sdl_video_formats, f) {
10
+ if (f->format == format)
11
+ return f->id;
12
}
13
return SPA_VIDEO_FORMAT_UNKNOWN;
14
}
15
16
static inline Uint32 id_to_sdl_format(uint32_t id)
17
{
18
- size_t i;
19
- for (i = 0; i < SPA_N_ELEMENTS(sdl_video_formats); i++) {
20
- if (sdl_video_formatsi.id == id)
21
- return sdl_video_formatsi.format;
22
+ SPA_FOR_EACH_ELEMENT_VAR(sdl_video_formats, f) {
23
+ if (f->id == id)
24
+ return f->format;
25
}
26
return SDL_PIXELFORMAT_UNKNOWN;
27
}
28
29
-
30
static inline struct spa_pod *sdl_build_formats(SDL_RendererInfo *info, struct spa_pod_builder *b)
31
{
32
uint32_t i, c;
33
34
spa_pod_builder_id(b, id);
35
}
36
/* then all the other ones SDL can convert from/to */
37
- for (i = 0; i < SPA_N_ELEMENTS(sdl_video_formats); i++) {
38
- uint32_t id = sdl_video_formatsi.id;
39
+ SPA_FOR_EACH_ELEMENT_VAR(sdl_video_formats, f) {
40
+ uint32_t id = f->id;
41
if (id != SPA_VIDEO_FORMAT_UNKNOWN)
42
spa_pod_builder_id(b, id);
43
}
44
pipewire-0.3.59.tar.gz/src/examples/video-play-fixate.c -> pipewire-0.3.60.tar.gz/src/examples/video-play-fixate.c
Changed
12
1
2
pw_stream_set_error(stream, -EINVAL, "unknown pixel format");
3
return;
4
}
5
+ if (data->size.width == 0 || data->size.height == 0) {
6
+ pw_stream_set_error(stream, -EINVAL, "invalid size");
7
+ return;
8
+ }
9
10
data->texture = SDL_CreateTexture(data->renderer,
11
sdl_format,
12
pipewire-0.3.59.tar.gz/src/examples/video-play-pull.c -> pipewire-0.3.60.tar.gz/src/examples/video-play-pull.c
Changed
12
1
2
pw_stream_set_error(stream, -EINVAL, "unknown pixel format");
3
return;
4
}
5
+ if (data->size.width == 0 || data->size.height == 0) {
6
+ pw_stream_set_error(stream, -EINVAL, "invalid size");
7
+ return;
8
+ }
9
10
data->texture = SDL_CreateTexture(data->renderer,
11
sdl_format,
12
pipewire-0.3.59.tar.gz/src/examples/video-play-reneg.c -> pipewire-0.3.60.tar.gz/src/examples/video-play-reneg.c
Changed
12
1
2
pw_stream_set_error(stream, -EINVAL, "unknown pixel format");
3
return;
4
}
5
+ if (data->size.width == 0 || data->size.height == 0) {
6
+ pw_stream_set_error(stream, -EINVAL, "invalid size");
7
+ return;
8
+ }
9
10
data->texture = SDL_CreateTexture(data->renderer,
11
sdl_format,
12
pipewire-0.3.59.tar.gz/src/examples/video-play.c -> pipewire-0.3.60.tar.gz/src/examples/video-play.c
Changed
12
1
2
pw_stream_set_error(stream, -EINVAL, "unknown pixel format");
3
return;
4
}
5
+ if (data->size.width == 0 || data->size.height == 0) {
6
+ pw_stream_set_error(stream, -EINVAL, "invalid size");
7
+ return;
8
+ }
9
10
data->texture = SDL_CreateTexture(data->renderer,
11
sdl_format,
12
pipewire-0.3.59.tar.gz/src/gst/gstpipewiredeviceprovider.c -> pipewire-0.3.60.tar.gz/src/gst/gstpipewiredeviceprovider.c
Changed
10
1
2
gst_device_provider_hide_provider (provider, "pulsedeviceprovider");
3
else if (g_str_has_prefix(str, "v4l2:"))
4
gst_device_provider_hide_provider (provider, "v4l2deviceprovider");
5
+ else if (g_str_has_prefix(str, "libcamera:"))
6
+ gst_device_provider_hide_provider (provider, "libcameraprovider");
7
}
8
}
9
10
pipewire-0.3.59.tar.gz/src/modules/meson.build -> pipewire-0.3.60.tar.gz/src/modules/meson.build
Changed
44
1
2
'module-rt.c',
3
'module-raop-discover.c',
4
'module-raop-sink.c',
5
+ 'module-rtp-source.c',
6
+ 'module-rtp-sink.c',
7
'module-session-manager.c',
8
'module-zeroconf-discover.c',
9
'module-roc-source.c',
10
11
'module-protocol-pulse/modules/module-roc-sink.c',
12
'module-protocol-pulse/modules/module-roc-sink-input.c',
13
'module-protocol-pulse/modules/module-roc-source.c',
14
+ 'module-protocol-pulse/modules/module-rtp-recv.c',
15
+ 'module-protocol-pulse/modules/module-rtp-send.c',
16
'module-protocol-pulse/modules/module-simple-protocol-tcp.c',
17
'module-protocol-pulse/modules/module-switch-on-connect.c',
18
'module-protocol-pulse/modules/module-tunnel-sink.c',
19
20
roc_lib = cc.find_library('roc', has_headers: 'roc/config.h' , required: get_option('roc'))
21
summary({'ROC': roc_lib.found()}, bool_yn: true, section: 'Streaming between daemons')
22
23
+pipewire_module_rtp_source = shared_library('pipewire-module-rtp-source',
24
+ 'module-rtp-source.c' ,
25
+ include_directories : configinc,
26
+ install : true,
27
+ install_dir : modules_install_dir,
28
+ install_rpath: modules_install_dir,
29
+ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep,
30
+)
31
+
32
+pipewire_module_rtp_sink = shared_library('pipewire-module-rtp-sink',
33
+ 'module-rtp-sink.c' ,
34
+ include_directories : configinc,
35
+ install : true,
36
+ install_dir : modules_install_dir,
37
+ install_rpath: modules_install_dir,
38
+ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep,
39
+)
40
+
41
build_module_roc = roc_lib.found()
42
if build_module_roc
43
pipewire_module_roc_sink = shared_library('pipewire-module-roc-sink',
44
pipewire-0.3.59.tar.gz/src/modules/module-avb/acmp.c -> pipewire-0.3.60.tar.gz/src/modules/module-avb/acmp.c
Changed
17
1
2
3
static inline const struct msg_info *find_msg_info(uint16_t type, const char *name)
4
{
5
- uint32_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(msg_info); i++) {
7
- if ((name == NULL && type == msg_infoi.type) ||
8
- (name != NULL && spa_streq(name, msg_infoi.name)))
9
- return &msg_infoi;
10
+ SPA_FOR_EACH_ELEMENT_VAR(msg_info, i) {
11
+ if ((name == NULL && type == i->type) ||
12
+ (name != NULL && spa_streq(name, i->name)))
13
+ return i;
14
}
15
return NULL;
16
}
17
pipewire-0.3.59.tar.gz/src/modules/module-avb/aecp-aem.c -> pipewire-0.3.60.tar.gz/src/modules/module-avb/aecp-aem.c
Changed
17
1
2
3
static inline const struct cmd_info *find_cmd_info(uint16_t type, const char *name)
4
{
5
- uint32_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(cmd_info); i++) {
7
- if ((name == NULL && type == cmd_infoi.type) ||
8
- (name != NULL && spa_streq(name, cmd_infoi.name)))
9
- return &cmd_infoi;
10
+ SPA_FOR_EACH_ELEMENT_VAR(cmd_info, i) {
11
+ if ((name == NULL && type == i->type) ||
12
+ (name != NULL && spa_streq(name, i->name)))
13
+ return i;
14
}
15
return NULL;
16
}
17
pipewire-0.3.59.tar.gz/src/modules/module-avb/aecp.c -> pipewire-0.3.60.tar.gz/src/modules/module-avb/aecp.c
Changed
17
1
2
3
static inline const struct msg_info *find_msg_info(uint16_t type, const char *name)
4
{
5
- uint32_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(msg_info); i++) {
7
- if ((name == NULL && type == msg_infoi.type) ||
8
- (name != NULL && spa_streq(name, msg_infoi.name)))
9
- return &msg_infoi;
10
+ SPA_FOR_EACH_ELEMENT_VAR(msg_info, i) {
11
+ if ((name == NULL && type == i->type) ||
12
+ (name != NULL && spa_streq(name, i->name)))
13
+ return i;
14
}
15
return NULL;
16
}
17
pipewire-0.3.59.tar.gz/src/modules/module-client-node/v0/client-node.c -> pipewire-0.3.60.tar.gz/src/modules/module-client-node/v0/client-node.c
Changed
19
1
2
{ "pipewire.target.node", PW_KEY_NODE_TARGET, }
3
};
4
5
- uint32_t i;
6
const char *str;
7
8
- for(i = 0; i < SPA_N_ELEMENTS(props); i++) {
9
- if ((str = pw_properties_get(properties, propsi.from)) != NULL) {
10
- pw_properties_set(properties, propsi.to, str);
11
- pw_properties_set(properties, propsi.from, NULL);
12
+ SPA_FOR_EACH_ELEMENT_VAR(props, p) {
13
+ if ((str = pw_properties_get(properties, p->from)) != NULL) {
14
+ pw_properties_set(properties, p->to, str);
15
+ pw_properties_set(properties, p->from, NULL);
16
}
17
}
18
}
19
pipewire-0.3.59.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.60.tar.gz/src/modules/module-echo-cancel.c
Changed
201
1
2
#include <spa/param/audio/raw.h>
3
#include <spa/param/profiler.h>
4
#include <spa/pod/builder.h>
5
+#include <spa/pod/dynamic.h>
6
#include <spa/support/plugin.h>
7
#include <spa/utils/json.h>
8
#include <spa/utils/names.h>
9
10
11
uint32_t max_buffer_size;
12
uint32_t buffer_delay;
13
+ uint32_t current_delay;
14
15
struct spa_handle *spa_handle;
16
struct spa_plugin_loader *loader;
17
+
18
+ bool monitor_mode;
19
};
20
21
static void process(struct impl *impl)
22
{
23
struct pw_buffer *cout;
24
- struct pw_buffer *pout;
25
+ struct pw_buffer *pout = NULL;
26
float rec_bufimpl->info.channelsimpl->aec_blocksize / sizeof(float);
27
float play_bufimpl->info.channelsimpl->aec_blocksize / sizeof(float);
28
float play_delayed_bufimpl->info.channelsimpl->aec_blocksize / sizeof(float);
29
30
uint32_t rindex, pindex, oindex, pdindex, avail;
31
int32_t stride = 0;
32
33
- if ((pout = pw_stream_dequeue_buffer(impl->playback)) == NULL) {
34
+ if (impl->playback != NULL && (pout = pw_stream_dequeue_buffer(impl->playback)) == NULL) {
35
pw_log_debug("out of playback buffers: %m");
36
goto done;
37
}
38
39
impl->play_ringsize, pdindex % impl->play_ringsize,
40
(void *)play_delayedi, size);
41
42
- /* output to sink, just copy */
43
- dd = &pout->buffer->datasi;
44
- memcpy(dd->data, playi, size);
45
+ if (pout != NULL) {
46
+ /* output to sink, just copy */
47
+ dd = &pout->buffer->datasi;
48
+ memcpy(dd->data, playi, size);
49
50
- dd->chunk->offset = 0;
51
- dd->chunk->size = size;
52
- dd->chunk->stride = stride;
53
+ dd->chunk->offset = 0;
54
+ dd->chunk->size = size;
55
+ dd->chunk->stride = stride;
56
+ }
57
}
58
59
spa_ringbuffer_read_update(&impl->rec_ring, rindex + size);
60
spa_ringbuffer_read_update(&impl->play_ring, pindex + size);
61
spa_ringbuffer_read_update(&impl->play_delayed_ring, pdindex + size);
62
63
- pw_stream_queue_buffer(impl->playback, pout);
64
+ if (impl->playback != NULL)
65
+ pw_stream_queue_buffer(impl->playback, pout);
66
67
- /* Now run the canceller */
68
- spa_audio_aec_run(impl->aec, rec, play_delayed, out, size / sizeof(float));
69
+ if (SPA_UNLIKELY (impl->current_delay < impl->buffer_delay)) {
70
+ uint32_t delay_left = impl->buffer_delay - impl->current_delay;
71
+ uint32_t silence_size;
72
+
73
+ /* don't run the canceller until play_buffer has been filled,
74
+ * copy silence to output in the meantime */
75
+ silence_size = SPA_MIN(size, delay_left * sizeof(float));
76
+ for (i = 0; i < impl->info.channels; i++)
77
+ memset(outi, 0, silence_size);
78
+ impl->current_delay += silence_size / sizeof(float);
79
+ pw_log_debug("current_delay %d", impl->current_delay);
80
+
81
+ if (silence_size != size) {
82
+ const float *pdimpl->info.channels;
83
+ float *oimpl->info.channels;
84
+
85
+ for (i = 0; i < impl->info.channels; i++) {
86
+ pdi = play_delayedi + delay_left;
87
+ oi = outi + delay_left;
88
+ }
89
+ spa_audio_aec_run(impl->aec, rec, pd, o, size / sizeof(float) - delay_left);
90
+ }
91
+ } else {
92
+ /* run the canceller */
93
+ spa_audio_aec_run(impl->aec, rec, play_delayed, out, size / sizeof(float));
94
+ }
95
96
/* Next, copy over the output to the output ringbuffer */
97
avail = spa_ringbuffer_get_write_index(&impl->out_ring, &oindex);
98
99
else
100
pw_stream_update_params(impl->capture, params, 1);
101
}
102
+static struct spa_pod* get_props_param(struct impl* impl, struct spa_pod_builder* b)
103
+{
104
+ if (spa_audio_aec_get_params(impl->aec, NULL) > 0) {
105
+ struct spa_pod_frame f2;
106
+ spa_pod_builder_push_object(
107
+ b, &f0, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
108
+ spa_pod_builder_prop(b, SPA_PROP_params, 0);
109
+ spa_pod_builder_push_struct(b, &f1);
110
+
111
+ spa_audio_aec_get_params(impl->aec, b);
112
+
113
+ spa_pod_builder_pop(b, &f1);
114
+ return spa_pod_builder_pop(b, &f0);
115
+ }
116
+ return NULL;
117
+}
118
119
-static void input_param_changed(void *data, uint32_t id, const struct spa_pod *param)
120
+static void input_param_changed(void *data, uint32_t id, const struct spa_pod* param)
121
{
122
- struct impl *impl = data;
123
+ struct spa_pod_object* obj = (struct spa_pod_object*)param;
124
+ const struct spa_pod_prop* prop;
125
+ struct impl* impl = data;
126
switch (id) {
127
case SPA_PARAM_Latency:
128
input_param_latency_changed(impl, param);
129
break;
130
+ case SPA_PARAM_Props:
131
+ if (param != NULL) {
132
+ uint8_t buffer1024;
133
+ struct spa_pod_dynamic_builder b;
134
+ const struct spa_pod* params1;
135
+ SPA_POD_OBJECT_FOREACH(obj, prop)
136
+ {
137
+ if (prop->key == SPA_PROP_params) {
138
+ spa_audio_aec_set_params(impl->aec, &prop->value);
139
+ }
140
+ }
141
+
142
+ spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
143
+ params0 = get_props_param(impl, &b.b);
144
+ if (params0) {
145
+ pw_stream_update_params(impl->capture, params, 1);
146
+ pw_stream_update_params(impl->playback, params, 1);
147
+ }
148
+ spa_pod_dynamic_builder_clean(&b);
149
+ } else {
150
+ pw_log_warn("param is null");
151
+ }
152
+ break;
153
}
154
}
155
156
157
switch (state) {
158
case PW_STREAM_STATE_PAUSED:
159
pw_stream_flush(impl->sink, false);
160
- pw_stream_flush(impl->playback, false);
161
+ if (impl->playback != NULL)
162
+ pw_stream_flush(impl->playback, false);
163
+ if (old == PW_STREAM_STATE_STREAMING) {
164
+ impl->current_delay = 0;
165
+ }
166
break;
167
case PW_STREAM_STATE_UNCONNECTED:
168
pw_log_info("%p: output unconnected", impl);
169
170
171
if (latency.direction == SPA_DIRECTION_INPUT)
172
pw_stream_update_params(impl->sink, params, 1);
173
- else
174
+ else if (impl->playback != NULL)
175
pw_stream_update_params(impl->playback, params, 1);
176
}
177
178
static void output_param_changed(void *data, uint32_t id, const struct spa_pod *param)
179
{
180
+ struct spa_pod_object *obj = (struct spa_pod_object *) param;
181
+ const struct spa_pod_prop *prop;
182
struct impl *impl = data;
183
switch (id) {
184
case SPA_PARAM_Latency:
185
output_param_latency_changed(impl, param);
186
break;
187
+ case SPA_PARAM_Props:
188
+ if (param != NULL) {
189
+ uint8_t buffer1024;
190
+ struct spa_pod_dynamic_builder b;
191
+ const struct spa_pod* params1;
192
+
193
+ SPA_POD_OBJECT_FOREACH(obj, prop)
194
+ {
195
+ if (prop->key == SPA_PROP_params) {
196
+ spa_audio_aec_set_params(impl->aec, &prop->value);
197
+ }
198
+ }
199
+ spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
200
+ params0 = get_props_param(impl, &b.b);
201
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain.c
Changed
194
1
2
spa_pod_builder_prop(b, SPA_PROP_INFO_type, 0);
3
if (p->hint & FC_HINT_BOOLEAN) {
4
if (min == max) {
5
- spa_pod_builder_bool(b, def <= 0.0 ? false : true);
6
+ spa_pod_builder_bool(b, def <= 0.0f ? false : true);
7
} else {
8
spa_pod_builder_push_choice(b, &f1, SPA_CHOICE_Enum, 0);
9
- spa_pod_builder_bool(b, def <= 0.0 ? false : true);
10
+ spa_pod_builder_bool(b, def <= 0.0f ? false : true);
11
spa_pod_builder_bool(b, false);
12
spa_pod_builder_bool(b, true);
13
spa_pod_builder_pop(b, &f1);
14
15
16
spa_pod_builder_string(b, name);
17
if (p->hint & FC_HINT_BOOLEAN) {
18
- spa_pod_builder_bool(b, port->control_data <= 0.0 ? false : true);
19
+ spa_pod_builder_bool(b, port->control_data <= 0.0f ? false : true);
20
} else if (p->hint & FC_HINT_INTEGER) {
21
spa_pod_builder_int(b, port->control_data);
22
} else {
23
24
{
25
struct impl *impl = data;
26
struct graph *graph = &impl->graph;
27
+ int res;
28
29
switch (id) {
30
case SPA_PARAM_Format:
31
32
} else {
33
struct spa_audio_info_raw info;
34
spa_zero(info);
35
- spa_format_audio_raw_parse(param, &info);
36
+ if ((res = spa_format_audio_raw_parse(param, &info)) < 0)
37
+ goto error;
38
+ if (info.rate == 0) {
39
+ res = -EINVAL;
40
+ goto error;
41
+ }
42
impl->rate = info.rate;
43
- graph_instantiate(graph);
44
+ if ((res = graph_instantiate(graph)) < 0)
45
+ goto error;
46
}
47
break;
48
case SPA_PARAM_Props:
49
50
param_latency_changed(impl, param);
51
break;
52
}
53
+ return;
54
+
55
+error:
56
+ pw_stream_set_error(impl->capture, res, "can't start graph: %s",
57
+ spa_strerror(res));
58
}
59
60
static const struct pw_stream_events in_stream_events = {
61
62
else if (spa_streq(type, "ladspa")) {
63
pl = load_ladspa_plugin(support, n_support, path, NULL);
64
}
65
-#ifdef HAVE_LILV
66
else if (spa_streq(type, "lv2")) {
67
+#ifdef HAVE_LILV
68
pl = load_lv2_plugin(support, n_support, path, NULL);
69
- }
70
+#else
71
+ pw_log_error("filter-chain is compiled without lv2 support");
72
+ pl = NULL;
73
+ errno = ENOTSUP;
74
#endif
75
- else {
76
+ } else {
77
+ pw_log_error("invalid plugin type '%s'", type);
78
pl = NULL;
79
errno = EINVAL;
80
}
81
-
82
if (pl == NULL)
83
goto exit;
84
85
86
bool have_config = false;
87
uint32_t i;
88
int res;
89
- float *data;
90
91
while (spa_json_get_string(json, key, sizeof(key)) > 0) {
92
if (spa_streq("type", key)) {
93
94
break;
95
}
96
97
- if (spa_streq(type, "builtin")) {
98
+ if (spa_streq(type, "builtin"))
99
snprintf(plugin, sizeof(plugin), "%s", "builtin");
100
- } else if (!spa_streq(type, "ladspa") && !spa_streq(type, "lv2"))
101
- return -ENOTSUP;
102
103
pw_log_info("loading type:%s plugin:%s label:%s", type, plugin, label);
104
105
106
node->control_port = calloc(desc->n_control, sizeof(struct port));
107
node->notify_port = calloc(desc->n_notify, sizeof(struct port));
108
109
+ pw_log_info("loaded n_input:%d n_output:%d n_control:%d n_notify:%d",
110
+ desc->n_input, desc->n_output,
111
+ desc->n_control, desc->n_notify);
112
+
113
for (i = 0; i < desc->n_input; i++) {
114
struct port *port = &node->input_porti;
115
port->node = node;
116
117
port->idx = i;
118
port->external = SPA_ID_INVALID;
119
port->p = desc->outputi;
120
- if ((data = port->audio_datai) == NULL) {
121
- data = calloc(1, MAX_SAMPLES * sizeof(float));
122
- if (data == NULL) {
123
- pw_log_error("cannot create port data: %m");
124
- return -errno;
125
- }
126
- }
127
- port->audio_datai = data;
128
spa_list_init(&port->link_list);
129
}
130
for (i = 0; i < desc->n_control; i++) {
131
132
}
133
}
134
135
+static int port_ensure_data(struct port *port, uint32_t i)
136
+{
137
+ float *data;
138
+ if ((data = port->audio_datai) == NULL) {
139
+ data = calloc(1, MAX_SAMPLES * sizeof(float));
140
+ if (data == NULL) {
141
+ pw_log_error("cannot create port data: %m");
142
+ return -errno;
143
+ }
144
+ }
145
+ port->audio_datai = data;
146
+ return 0;
147
+}
148
+
149
+static void port_free_data(struct port *port, uint32_t i)
150
+{
151
+ free(port->audio_datai);
152
+ port->audio_datai = NULL;
153
+}
154
+
155
static void node_free(struct node *node)
156
{
157
uint32_t i, j;
158
159
spa_list_remove(&node->link);
160
for (i = 0; i < node->n_hndl; i++) {
161
for (j = 0; j < node->desc->n_output; j++)
162
- free(node->output_portj.audio_datai);
163
+ port_free_data(&node->output_portj, i);
164
}
165
node_cleanup(node);
166
descriptor_unref(node->desc);
167
168
169
spa_list_for_each(link, &port->link_list, input_link) {
170
struct port *peer = link->output;
171
+ if ((res = port_ensure_data(peer, i)) < 0)
172
+ goto error;
173
pw_log_info("connect input port %s%d:%s %p",
174
node->name, i, d->portsport->p.name,
175
peer->audio_datai);
176
177
}
178
for (j = 0; j < desc->n_output; j++) {
179
port = &node->output_portj;
180
+ if ((res = port_ensure_data(port, i)) < 0)
181
+ goto error;
182
pw_log_info("connect output port %s%d:%s %p",
183
node->name, i, d->portsport->p.name,
184
port->audio_datai);
185
186
gh->hndl = &node->hndli;
187
gh->desc = d;
188
189
+ }
190
+ for (i = 0; i < desc->n_output; i++) {
191
spa_list_for_each(link, &node->output_porti.link_list, output_link)
192
link->input->node->n_deps--;
193
}
194
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/biquad.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/biquad.c
Changed
132
1
2
#include <math.h>
3
#include "biquad.h"
4
5
-#ifndef max
6
-#define max(a, b) \
7
- ({ \
8
- __typeof__(a) _a = (a); \
9
- __typeof__(b) _b = (b); \
10
- _a > _b ? _a : _b; \
11
- })
12
-#endif
13
-
14
-#ifndef min
15
-#define min(a, b) \
16
- ({ \
17
- __typeof__(a) _a = (a); \
18
- __typeof__(b) _b = (b); \
19
- _a < _b ? _a : _b; \
20
- })
21
-#endif
22
-
23
#ifndef M_PI
24
#define M_PI 3.14159265358979323846
25
#endif
26
27
static void biquad_lowpass(struct biquad *bq, double cutoff, double resonance)
28
{
29
/* Limit cutoff to 0 to 1. */
30
- cutoff = max(0.0, min(cutoff, 1.0));
31
+ cutoff = fmax(0.0, fmin(cutoff, 1.0));
32
33
if (cutoff == 1 || cutoff == 0) {
34
/* When cutoff is 1, the z-transform is 1.
35
36
}
37
38
/* Compute biquad coefficients for lowpass filter */
39
- resonance = max(0.0, resonance); /* can't go negative */
40
+ resonance = fmax(0.0, resonance); /* can't go negative */
41
double g = pow(10.0, 0.05 * resonance);
42
double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2);
43
44
45
static void biquad_highpass(struct biquad *bq, double cutoff, double resonance)
46
{
47
/* Limit cutoff to 0 to 1. */
48
- cutoff = max(0.0, min(cutoff, 1.0));
49
+ cutoff = fmax(0.0, fmin(cutoff, 1.0));
50
51
if (cutoff == 1 || cutoff == 0) {
52
/* When cutoff is one, the z-transform is 0. */
53
54
}
55
56
/* Compute biquad coefficients for highpass filter */
57
- resonance = max(0.0, resonance); /* can't go negative */
58
+ resonance = fmax(0.0, resonance); /* can't go negative */
59
double g = pow(10.0, 0.05 * resonance);
60
double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2);
61
62
63
static void biquad_bandpass(struct biquad *bq, double frequency, double Q)
64
{
65
/* No negative frequencies allowed. */
66
- frequency = max(0.0, frequency);
67
+ frequency = fmax(0.0, frequency);
68
69
/* Don't let Q go negative, which causes an unstable filter. */
70
- Q = max(0.0, Q);
71
+ Q = fmax(0.0, Q);
72
73
if (frequency <= 0 || frequency >= 1) {
74
/* When the cutoff is zero, the z-transform approaches 0, if Q
75
76
static void biquad_lowshelf(struct biquad *bq, double frequency, double db_gain)
77
{
78
/* Clip frequencies to between 0 and 1, inclusive. */
79
- frequency = max(0.0, min(frequency, 1.0));
80
+ frequency = fmax(0.0, fmin(frequency, 1.0));
81
82
double A = pow(10.0, db_gain / 40);
83
84
85
double db_gain)
86
{
87
/* Clip frequencies to between 0 and 1, inclusive. */
88
- frequency = max(0.0, min(frequency, 1.0));
89
+ frequency = fmax(0.0, fmin(frequency, 1.0));
90
91
double A = pow(10.0, db_gain / 40);
92
93
94
double db_gain)
95
{
96
/* Clip frequencies to between 0 and 1, inclusive. */
97
- frequency = max(0.0, min(frequency, 1.0));
98
+ frequency = fmax(0.0, fmin(frequency, 1.0));
99
100
/* Don't let Q go negative, which causes an unstable filter. */
101
- Q = max(0.0, Q);
102
+ Q = fmax(0.0, Q);
103
104
double A = pow(10.0, db_gain / 40);
105
106
107
static void biquad_notch(struct biquad *bq, double frequency, double Q)
108
{
109
/* Clip frequencies to between 0 and 1, inclusive. */
110
- frequency = max(0.0, min(frequency, 1.0));
111
+ frequency = fmax(0.0, fmin(frequency, 1.0));
112
113
/* Don't let Q go negative, which causes an unstable filter. */
114
- Q = max(0.0, Q);
115
+ Q = fmax(0.0, Q);
116
117
if (frequency <= 0 || frequency >= 1) {
118
/* When frequency is 0 or 1, the z-transform is 1. */
119
120
static void biquad_allpass(struct biquad *bq, double frequency, double Q)
121
{
122
/* Clip frequencies to between 0 and 1, inclusive. */
123
- frequency = max(0.0, min(frequency, 1.0));
124
+ frequency = fmax(0.0, fmin(frequency, 1.0));
125
126
/* Don't let Q go negative, which causes an unstable filter. */
127
- Q = max(0.0, Q);
128
+ Q = fmax(0.0, Q);
129
130
if (frequency <= 0 || frequency >= 1) {
131
/* When frequency is 0 or 1, the z-transform is 1. */
132
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
122
1
2
float gain = 1.0f;
3
unsigned long rate;
4
5
+ errno = EINVAL;
6
if (config == NULL)
7
return NULL;
8
9
10
11
while (spa_json_get_string(&it1, key, sizeof(key)) > 0) {
12
if (spa_streq(key, "blocksize")) {
13
- if (spa_json_get_int(&it1, &blocksize) <= 0)
14
+ if (spa_json_get_int(&it1, &blocksize) <= 0) {
15
+ pw_log_error("convolver:blocksize requires a number");
16
return NULL;
17
+ }
18
}
19
else if (spa_streq(key, "tailsize")) {
20
- if (spa_json_get_int(&it1, &tailsize) <= 0)
21
+ if (spa_json_get_int(&it1, &tailsize) <= 0) {
22
+ pw_log_error("convolver:tailsize requires a number");
23
return NULL;
24
+ }
25
}
26
else if (spa_streq(key, "gain")) {
27
- if (spa_json_get_float(&it1, &gain) <= 0)
28
+ if (spa_json_get_float(&it1, &gain) <= 0) {
29
+ pw_log_error("convolver:gain requires a number");
30
return NULL;
31
+ }
32
}
33
else if (spa_streq(key, "delay")) {
34
- if (spa_json_get_int(&it1, &delay) <= 0)
35
+ if (spa_json_get_int(&it1, &delay) <= 0) {
36
+ pw_log_error("convolver:delay requires a number");
37
return NULL;
38
+ }
39
}
40
else if (spa_streq(key, "filename")) {
41
- if (spa_json_get_string(&it1, filename, sizeof(filename)) <= 0)
42
+ if (spa_json_get_string(&it1, filename, sizeof(filename)) <= 0) {
43
+ pw_log_error("convolver:filename requires a string");
44
return NULL;
45
+ }
46
}
47
else if (spa_streq(key, "offset")) {
48
- if (spa_json_get_int(&it1, &offset) <= 0)
49
+ if (spa_json_get_int(&it1, &offset) <= 0) {
50
+ pw_log_error("convolver:offset requires a number");
51
return NULL;
52
+ }
53
}
54
else if (spa_streq(key, "length")) {
55
- if (spa_json_get_int(&it1, &length) <= 0)
56
+ if (spa_json_get_int(&it1, &length) <= 0) {
57
+ pw_log_error("convolver:length requires a number");
58
return NULL;
59
+ }
60
}
61
else if (spa_streq(key, "channel")) {
62
- if (spa_json_get_int(&it1, &channel) <= 0)
63
+ if (spa_json_get_int(&it1, &channel) <= 0) {
64
+ pw_log_error("convolver:channel requires a number");
65
return NULL;
66
+ }
67
}
68
else if (spa_json_next(&it1, &val) < 0)
69
break;
70
}
71
- if (!filename0)
72
+ if (!filename0) {
73
+ pw_log_error("convolver:filename was not given");
74
return NULL;
75
+ }
76
77
if (delay < 0)
78
delay = 0;
79
80
"Consider forcing a filter rate.", rate, SampleRate);
81
}
82
}
83
- if (samples == NULL)
84
+ if (samples == NULL) {
85
+ errno = ENOENT;
86
return NULL;
87
+ }
88
89
if (blocksize <= 0)
90
blocksize = SPA_CLAMP(n_samples, 64, 256);
91
if (tailsize <= 0)
92
- tailsize = SPA_CLAMP(4096, blocksize, 4096);
93
+ tailsize = SPA_CLAMP(4096, blocksize, 32768);
94
95
- pw_log_info("using %d:%d blocksize ir:%s", blocksize, tailsize, filename);
96
+ pw_log_info("using n_samples:%u %d:%d blocksize ir:%s", n_samples,
97
+ blocksize, tailsize, filename);
98
99
impl = calloc(1, sizeof(*impl));
100
if (impl == NULL)
101
102
103
while (spa_json_get_string(&it1, key, sizeof(key)) > 0) {
104
if (spa_streq(key, "max-delay")) {
105
- if (spa_json_get_float(&it1, &max_delay) <= 0)
106
+ if (spa_json_get_float(&it1, &max_delay) <= 0) {
107
+ pw_log_error("delay:max-delay requires a number");
108
return NULL;
109
+ }
110
}
111
else if (spa_json_next(&it1, &val) < 0)
112
break;
113
114
115
impl->rate = SampleRate;
116
impl->buffer_samples = max_delay * impl->rate;
117
- pw_log_info("%lu %d", impl->rate, impl->buffer_samples);
118
+ pw_log_info("max-delay:%f seconds rate:%lu samples:%d", max_delay, impl->rate, impl->buffer_samples);
119
120
impl->buffer = calloc(impl->buffer_samples, sizeof(float));
121
if (impl->buffer == NULL) {
122
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/convolver.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/convolver.c
Changed
10
1
2
{
3
int i, processed = 0;
4
5
- if (conv->segCount == 0) {
6
+ if (conv == NULL || conv->segCount == 0) {
7
fft_clear(output, len);
8
return len;
9
}
10
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c
Changed
70
1
2
* DEALINGS IN THE SOFTWARE.
3
*/
4
5
+#include "config.h"
6
+
7
#include <dlfcn.h>
8
#include <math.h>
9
10
11
break;
12
case LADSPA_HINT_DEFAULT_LOW:
13
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
14
- def = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25);
15
+ def = (LADSPA_Data) expf(logf(lower) * 0.75f + logf(upper) * 0.25f);
16
else
17
- def = (LADSPA_Data) (lower * 0.75 + upper * 0.25);
18
+ def = (LADSPA_Data) (lower * 0.75f + upper * 0.25f);
19
break;
20
case LADSPA_HINT_DEFAULT_MIDDLE:
21
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
22
- def = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5);
23
+ def = (LADSPA_Data) expf(logf(lower) * 0.5f + logf(upper) * 0.5f);
24
else
25
- def = (LADSPA_Data) (lower * 0.5 + upper * 0.5);
26
+ def = (LADSPA_Data) (lower * 0.5f + upper * 0.5f);
27
break;
28
case LADSPA_HINT_DEFAULT_HIGH:
29
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
30
- def = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75);
31
+ def = (LADSPA_Data) expf(logf(lower) * 0.25f + logf(upper) * 0.75f);
32
else
33
- def = (LADSPA_Data) (lower * 0.25 + upper * 0.75);
34
+ def = (LADSPA_Data) (lower * 0.25f + upper * 0.75f);
35
break;
36
case LADSPA_HINT_DEFAULT_0:
37
- def = 0;
38
+ def = 0.0f;
39
break;
40
case LADSPA_HINT_DEFAULT_1:
41
- def = 1;
42
+ def = 1.0f;
43
break;
44
case LADSPA_HINT_DEFAULT_100:
45
- def = 100;
46
+ def = 100.0f;
47
break;
48
case LADSPA_HINT_DEFAULT_440:
49
- def = 440;
50
+ def = 440.0f;
51
break;
52
default:
53
if (upper == lower)
54
def = upper;
55
else
56
- def = SPA_CLAMP(0.5 * upper, lower, upper);
57
+ def = SPA_CLAMPF(0.5f * upper, lower, upper);
58
break;
59
}
60
if (LADSPA_IS_HINT_INTEGER(hint))
61
62
63
search_dirs = getenv("LADSPA_PATH");
64
if (!search_dirs)
65
- search_dirs = "/usr/lib64/ladspa";
66
+ search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR;
67
68
/*
69
* set the errno for the case when `ladspa_handle_load_by_path()`
70
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/pffft.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/pffft.c
Changed
73
1
2
Laboratory, the University Corporation for Atmospheric Research,
3
nor the names of its sponsors or contributors may be used to
4
endorse or promote products derived from this Software without
5
- specific prior written permission.
6
+ specific prior written permission.
7
8
- Redistributions of source code must retain the above copyright
9
notices, this list of conditions, and the disclaimer below.
10
11
*/
12
13
/*
14
- ChangeLog:
15
+ ChangeLog:
16
- 2011/10/02, version 1: This is the very first release of this file.
17
*/
18
19
20
#define assertv4(v,f0,f1,f2,f3) assert(v.f0 == (f0) && v.f1 == (f1) && v.f2 == (f2) && v.f3 == (f3))
21
22
/* detect bugs with the vector support macros */
23
-static void validate_pffft_simd()
24
+static void validate_pffft_simd(void)
25
{
26
float f16 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
27
v4sf_union a0, a1, a2, a3, t, u;
28
29
assertv4(a3, 3, 7, 11, 15);
30
}
31
#else
32
-static void validate_pffft_simd()
33
+static void validate_pffft_simd(void)
34
{
35
} // allow test_pffft.c to call this function even when simd is not available..
36
#endif //!PFFFT_SIMD_DISABLE
37
38
{
39
PFFFT_Setup *s = (PFFFT_Setup *) malloc(sizeof(PFFFT_Setup));
40
int k, m;
41
- /* unfortunately, the fft size must be a multiple of 16 for complex FFTs
42
+ /* unfortunately, the fft size must be a multiple of 16 for complex FFTs
43
and 32 for real FFTs -- a lot of stuff would need to be rewritten to
44
handle other cases (or maybe just switch to a scalar fft, I don't know..) */
45
if (transform == PFFFT_REAL) {
46
47
0 0 0 0 1 1 1 1 * i0
48
0 1 0 -1 1 0 -1 0 i1
49
0 0 0 0 1 -1 1 -1 i2
50
- 0 -1 0 1 1 0 -1 0 i3
51
+ 0 -1 0 1 1 0 -1 0 i3
52
*/
53
54
r0 = VADD(sr0, sr1);
55
56
0 0 0 0 1 1 1 1 * i0
57
0 -1 0 1 -1 0 1 0 i1
58
0 -1 0 1 1 0 -1 0 i2
59
- 0 0 0 0 -1 1 -1 1 i3
60
+ 0 0 0 0 -1 1 -1 1 i3
61
*/
62
63
//cerr << "matrix initial, before e , REAL:\n 1: " << r0 << "\n 1: " << r1 << "\n 1: " << r2 << "\n 1: " << r3 << "\n";
64
65
0 0 0 0 1 -1 1 -1 * i0
66
0 -1 1 0 1 0 0 1 i1
67
0 0 0 0 1 1 -1 -1 i2
68
- 0 1 -1 0 1 0 0 1 i3
69
+ 0 1 -1 0 1 0 0 1 i3
70
*/
71
72
v4sf sr0 = VADD(r0, r3), dr0 = VSUB(r0, r3);
73
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/pffft.h -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/pffft.h
Changed
17
1
2
/*
3
the float buffers must have the correct alignment (16-byte boundary
4
on intel and powerpc). This function may be used to obtain such
5
- correctly aligned buffers.
6
+ correctly aligned buffers.
7
*/
8
void *pffft_aligned_malloc(size_t nb_bytes);
9
void pffft_aligned_free(void *);
10
11
/* return 4 or 1 depending on whether support for SSE/Altivec instructions was enabled when building pffft.c */
12
- int pffft_simd_size();
13
+ int pffft_simd_size(void);
14
15
void pffft_select_cpu(int flags);
16
17
pipewire-0.3.59.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.60.tar.gz/src/modules/module-loopback.c
Changed
201
1
2
#include <spa/utils/result.h>
3
#include <spa/utils/string.h>
4
#include <spa/utils/json.h>
5
+#include <spa/utils/ringbuffer.h>
6
#include <spa/param/profiler.h>
7
#include <spa/debug/pod.h>
8
9
10
* ## Module Options
11
*
12
* - `node.description`: a human readable name for the loopback streams
13
+ * - `target.delay.sec`: delay in seconds as float (Since 0.3.60)
14
* - `capture.props = {}`: properties to be passed to the input stream
15
* - `playback.props = {}`: properties to be passed to the output stream
16
*
17
18
* { name = libpipewire-module-loopback
19
* args = {
20
* node.description = "CM106 Stereo Pair 2"
21
+ * #target.delay.sec = 1.5
22
* capture.props = {
23
* node.name = "CM106_stereo_pair_2"
24
* media.class = "Audio/Sink"
25
26
" audio.rate=<sample rate> "
27
" audio.channels=<number of channels> "
28
" audio.position=<channel map> "
29
+ " target.delay.sec=<delay as seconds in float> "
30
" capture.props=<properties> "
31
" playback.props=<properties> " },
32
{ PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
33
34
struct pw_stream *capture;
35
struct spa_hook capture_listener;
36
struct spa_audio_info_raw capture_info;
37
+ struct spa_latency_info capture_latency;
38
39
struct pw_properties *playback_props;
40
struct pw_stream *playback;
41
struct spa_hook playback_listener;
42
struct spa_audio_info_raw playback_info;
43
+ struct spa_latency_info playback_latency;
44
45
unsigned int do_disconnect:1;
46
+ unsigned int recalc_delay:1;
47
+
48
+ float target_delay;
49
+ struct spa_ringbuffer buffer;
50
+ uint8_t *buffer_data;
51
+ uint32_t buffer_size;
52
};
53
54
static void capture_destroy(void *d)
55
56
impl->capture = NULL;
57
}
58
59
+static void recalculate_delay(struct impl *impl)
60
+{
61
+ uint32_t target = impl->capture_info.rate * impl->target_delay, cdelay, pdelay;
62
+ uint32_t delay, w;
63
+ struct pw_time pwt;
64
+
65
+ pw_stream_get_time_n(impl->playback, &pwt, sizeof(pwt));
66
+ pdelay = pwt.delay;
67
+ pw_stream_get_time_n(impl->capture, &pwt, sizeof(pwt));
68
+ cdelay = pwt.delay;
69
+
70
+ delay = target - SPA_MIN(target, pdelay + cdelay);
71
+ delay = SPA_MIN(delay, impl->buffer_size / 4);
72
+
73
+ spa_ringbuffer_get_write_index(&impl->buffer, &w);
74
+ spa_ringbuffer_read_update(&impl->buffer, w - (delay * 4));
75
+
76
+ pw_log_info("target:%d c:%d + p:%d + delay:%d = (%d)",
77
+ target, cdelay, pdelay, delay,
78
+ cdelay + pdelay + delay);
79
+}
80
+
81
static void capture_process(void *d)
82
{
83
struct impl *impl = d;
84
85
struct pw_buffer *in, *out;
86
uint32_t i;
87
88
+ if (impl->recalc_delay) {
89
+ recalculate_delay(impl);
90
+ impl->recalc_delay = false;
91
+ }
92
+
93
if ((in = pw_stream_dequeue_buffer(impl->capture)) == NULL)
94
pw_log_debug("out of capture buffers: %m");
95
96
97
int32_t stride = 0;
98
struct spa_data *d;
99
const void *srcin->buffer->n_datas;
100
+ uint32_t r, w, buffer_size;
101
102
for (i = 0; i < in->buffer->n_datas; i++) {
103
uint32_t offs, size;
104
105
outsize = SPA_MIN(outsize, size);
106
stride = SPA_MAX(stride, d->chunk->stride);
107
}
108
+ if (impl->buffer_size > 0) {
109
+ buffer_size = impl->buffer_size;
110
+ spa_ringbuffer_get_write_index(&impl->buffer, &w);
111
+ for (i = 0; i < in->buffer->n_datas; i++) {
112
+ void *buffer_data = &impl->buffer_datai * buffer_size;
113
+ spa_ringbuffer_write_data(&impl->buffer,
114
+ buffer_data, buffer_size,
115
+ w % buffer_size, srci, outsize);
116
+ srci = buffer_data;
117
+ }
118
+ w += outsize;
119
+ spa_ringbuffer_write_update(&impl->buffer, w);
120
+ spa_ringbuffer_get_read_index(&impl->buffer, &r);
121
+ } else {
122
+ r = 0;
123
+ buffer_size = outsize;
124
+ }
125
for (i = 0; i < out->buffer->n_datas; i++) {
126
d = &out->buffer->datasi;
127
128
outsize = SPA_MIN(outsize, d->maxsize);
129
130
if (i < in->buffer->n_datas)
131
- memcpy(d->data, srci, outsize);
132
+ spa_ringbuffer_read_data(&impl->buffer,
133
+ srci, buffer_size,
134
+ r % buffer_size,
135
+ d->data, outsize);
136
else
137
memset(d->data, 0, outsize);
138
139
140
d->chunk->size = outsize;
141
d->chunk->stride = stride;
142
}
143
+ if (impl->buffer_size > 0) {
144
+ r += outsize;
145
+ spa_ringbuffer_read_update(&impl->buffer, r);
146
+ }
147
}
148
149
if (in != NULL)
150
151
}
152
153
static void param_latency_changed(struct impl *impl, const struct spa_pod *param,
154
- struct pw_stream *other)
155
+ struct spa_latency_info *info, struct pw_stream *other)
156
{
157
struct spa_latency_info latency;
158
uint8_t buffer1024;
159
160
if (spa_latency_parse(param, &latency) < 0)
161
return;
162
163
+ *info = latency;
164
+
165
spa_pod_builder_init(&b, buffer, sizeof(buffer));
166
params0 = spa_latency_build(&b, SPA_PARAM_Latency, &latency);
167
pw_stream_update_params(other, params, 1);
168
+
169
+ impl->recalc_delay = true;
170
}
171
172
static void stream_state_changed(void *data, enum pw_stream_state old,
173
174
case PW_STREAM_STATE_PAUSED:
175
pw_stream_flush(impl->playback, false);
176
pw_stream_flush(impl->capture, false);
177
+ impl->recalc_delay = true;
178
break;
179
case PW_STREAM_STATE_UNCONNECTED:
180
pw_log_info("module %p: unconnected", impl);
181
182
}
183
}
184
185
+static void recalculate_buffer(struct impl *impl)
186
+{
187
+ if (impl->target_delay > 0.0f) {
188
+ uint32_t delay = impl->capture_info.rate * impl->target_delay;
189
+ void *data;
190
+
191
+ impl->buffer_size = (delay + (1u<<15)) * 4;
192
+ data = realloc(impl->buffer_data, impl->buffer_size * impl->capture_info.channels);
193
+ if (data == NULL) {
194
+ pw_log_warn("can't allocate delay buffer, delay disabled: %m");
195
+ impl->buffer_size = 0;
196
+ free(impl->buffer_data);
197
+ }
198
+ impl->buffer_data = data;
199
+ spa_ringbuffer_init(&impl->buffer);
200
+ } else {
201
pipewire-0.3.59.tar.gz/src/modules/module-pipe-tunnel.c -> pipewire-0.3.60.tar.gz/src/modules/module-pipe-tunnel.c
Changed
27
1
2
/** \page page_module_pipe_tunnel PipeWire Module: Unix Pipe Tunnel
3
*
4
* The pipe-tunnel module provides a source or sink that tunnels all audio to
5
- * a unix pipe.
6
+ * or from a unix pipe respectively.
7
*
8
* ## Module Options
9
*
10
11
.process = capture_stream_process
12
};
13
14
-static int create_stream(struct impl *impl)
15
+static int create_stream(struct impl *impl)
16
{
17
int res;
18
uint32_t n_params;
19
20
copy_props(impl, props, PW_KEY_NODE_LATENCY);
21
copy_props(impl, props, PW_KEY_NODE_VIRTUAL);
22
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
23
+ copy_props(impl, props, PW_KEY_TARGET_OBJECT);
24
25
parse_audio_info(impl->stream_props, &impl->info);
26
27
pipewire-0.3.59.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-native.c
Changed
11
1
2
hex = true;
3
if (hex)
4
spa_debug_mem(0, msg->data, msg->size);
5
+
6
+ pw_logt_debug(mod_topic_connection, "%s ****", prefix);
7
+
8
}
9
10
static void pre_demarshal(struct pw_protocol_native_connection *conn,
11
pipewire-0.3.59.tar.gz/src/modules/module-protocol-native/connection.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-native/connection.c
Changed
15
1
2
buf->n_fds = buf->msg.n_fds;
3
4
if (mod_topic_connection->level >= SPA_LOG_LEVEL_DEBUG) {
5
- pw_log_debug(">>>>>>>>> out: id:%d op:%d size:%d seq:%d",
6
+ pw_logt_debug(mod_topic_connection,
7
+ ">>>>>>>>> out: id:%d op:%d size:%d seq:%d",
8
buf->msg.id, buf->msg.opcode, size, buf->msg.seq);
9
spa_debug_pod(0, NULL, SPA_PTROFF(p, impl->hdr_size, struct spa_pod));
10
+ pw_logt_debug(mod_topic_connection,
11
+ ">>>>>>>>> out: done");
12
}
13
14
buf->seq = (buf->seq + 1) & SPA_ASYNC_SEQ_MASK;
15
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/client.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/client.c
Changed
27
1
2
int res = -errno;
3
if (res == -EINTR)
4
continue;
5
- if (res != -EAGAIN && res != -EWOULDBLOCK)
6
- pw_log_warn("client %p: send channel:%u %zu, error %d: %m",
7
- client, m->channel, size, res);
8
return res;
9
}
10
-
11
client->out_index += sent;
12
break;
13
}
14
}
15
-
16
return 0;
17
}
18
19
20
if (res != -EAGAIN && res != -EWOULDBLOCK)
21
return res;
22
}
23
-
24
return 0;
25
}
26
27
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/extension.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/extension.c
Changed
15
1
2
3
const struct extension *extension_find(uint32_t index, const char *name)
4
{
5
- const struct extension *ext;
6
-
7
- SPA_FOR_EACH_ELEMENT(extensions, ext) {
8
+ SPA_FOR_EACH_ELEMENT_VAR(extensions, ext) {
9
if (index == ext->index || spa_streq(name, ext->name))
10
return ext;
11
}
12
-
13
return NULL;
14
}
15
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/format.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/format.c
Changed
120
1
2
3
uint32_t format_paname2id(const char *name, size_t size)
4
{
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(audio_formats); i++) {
7
- if (audio_formatsi.name != NULL &&
8
- strncmp(name, audio_formatsi.name, size) == 0)
9
- return audio_formatsi.id;
10
+ SPA_FOR_EACH_ELEMENT_VAR(audio_formats, f) {
11
+ if (f->name != NULL &&
12
+ strncmp(name, f->name, size) == 0)
13
+ return f->id;
14
}
15
return SPA_AUDIO_FORMAT_UNKNOWN;
16
}
17
18
enum sample_format format_id2pa(uint32_t id)
19
{
20
- size_t i;
21
- for (i = 0; i < SPA_N_ELEMENTS(audio_formats); i++) {
22
- if (id == audio_formatsi.id)
23
- return audio_formatsi.pa;
24
+ SPA_FOR_EACH_ELEMENT_VAR(audio_formats, f) {
25
+ if (id == f->id)
26
+ return f->pa;
27
}
28
return SAMPLE_INVALID;
29
}
30
31
const char *format_id2paname(uint32_t id)
32
{
33
- size_t i;
34
- for (i = 0; i < SPA_N_ELEMENTS(audio_formats); i++) {
35
- if (id == audio_formatsi.id &&
36
- audio_formatsi.name != NULL)
37
- return audio_formatsi.name;
38
+ SPA_FOR_EACH_ELEMENT_VAR(audio_formats, f) {
39
+ if (id == f->id && f->name != NULL)
40
+ return f->name;
41
}
42
return "invalid";
43
}
44
45
46
const char *channel_id2paname(uint32_t id, uint32_t *aux)
47
{
48
- size_t i;
49
- for (i = 0; i < SPA_N_ELEMENTS(audio_channels); i++) {
50
- if (id == audio_channelsi.channel &&
51
- audio_channelsi.name != NULL)
52
- return audio_channelsi.name;
53
+ SPA_FOR_EACH_ELEMENT_VAR(audio_channels, i) {
54
+ if (id == i->channel && i->name != NULL)
55
+ return i->name;
56
}
57
return audio_channelsCHANNEL_POSITION_AUX0 + ((*aux)++ & 31).name;
58
}
59
60
uint32_t channel_paname2id(const char *name, size_t size)
61
{
62
- size_t i;
63
- for (i = 0; i < SPA_N_ELEMENTS(audio_channels); i++) {
64
- if (strncmp(name, audio_channelsi.name, size) == 0)
65
- return audio_channelsi.channel;
66
+ SPA_FOR_EACH_ELEMENT_VAR(audio_channels, i) {
67
+ if (strncmp(name, i->name, size) == 0)
68
+ return i->channel;
69
}
70
return SPA_AUDIO_CHANNEL_UNKNOWN;
71
}
72
73
return ENCODING_ANY;
74
}
75
76
-static inline int
77
-audio_raw_parse_opt(const struct spa_pod *format, struct spa_audio_info_raw *info)
78
-{
79
- struct spa_pod *position = NULL;
80
- int res;
81
- info->flags = 0;
82
- res = spa_pod_parse_object(format,
83
- SPA_TYPE_OBJECT_Format, NULL,
84
- SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format),
85
- SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate),
86
- SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels),
87
- SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
88
- if (position == NULL ||
89
- !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS))
90
- SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED);
91
-
92
- return res;
93
-}
94
-
95
int format_parse_param(const struct spa_pod *param, bool collect,
96
struct sample_spec *ss, struct channel_map *map,
97
const struct sample_spec *def_ss, const struct channel_map *def_map)
98
99
100
switch (info.media_subtype) {
101
case SPA_MEDIA_SUBTYPE_raw:
102
+ if (spa_format_audio_raw_parse(param, &info.info.raw) < 0)
103
+ return -ENOTSUP;
104
if (def_ss != NULL) {
105
if (ss != NULL)
106
*ss = *def_ss;
107
- if (audio_raw_parse_opt(param, &info.info.raw) < 0)
108
- return -ENOTSUP;
109
} else {
110
- if (spa_format_audio_raw_parse(param, &info.info.raw) < 0)
111
- return -ENOTSUP;
112
+ if (info.info.raw.format == 0 ||
113
+ info.info.raw.rate == 0 ||
114
+ info.info.raw.channels == 0 ||
115
+ info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS)
116
+ return -ENOTSUP;
117
}
118
break;
119
case SPA_MEDIA_SUBTYPE_iec958:
120
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/manager.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/manager.c
Changed
201
1
2
#include "log.h"
3
#include "module-protocol-pulse/server.h"
4
5
-#define MAX_PARAMS 32
6
-
7
#define manager_emit_sync(m) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, sync, 0)
8
#define manager_emit_added(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, added, 0, o)
9
#define manager_emit_updated(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, updated, 0, o)
10
11
struct spa_hook proxy_listener;
12
struct spa_hook object_listener;
13
14
- int param_seqMAX_PARAMS;
15
-
16
struct spa_list data_list;
17
};
18
19
20
}
21
22
static struct pw_manager_param *add_param(struct spa_list *params,
23
- int seq, int *param_seq, uint32_t id, const struct spa_pod *param)
24
+ int seq, uint32_t id, const struct spa_pod *param)
25
{
26
struct pw_manager_param *p;
27
28
29
id = SPA_POD_OBJECT_ID(param);
30
}
31
32
- if (id >= MAX_PARAMS) {
33
- pw_log_error("too big param id %d", id);
34
- errno = EINVAL;
35
- return NULL;
36
- }
37
-
38
- if (seq != param_seqid) {
39
- pw_log_debug("ignoring param %d, seq:%d != current_seq:%d",
40
- id, seq, param_seqid);
41
- errno = EBUSY;
42
- return NULL;
43
- }
44
-
45
p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0));
46
if (p == NULL)
47
return NULL;
48
49
p->id = id;
50
+ p->seq = seq;
51
if (param != NULL) {
52
p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod);
53
memcpy(p->param, param, SPA_POD_SIZE(param));
54
55
return false;
56
}
57
58
-
59
static struct object *find_object_by_id(struct manager *m, uint32_t id)
60
{
61
struct object *o;
62
63
64
static void object_update_params(struct object *o)
65
{
66
- struct pw_manager_param *p;
67
+ struct pw_manager_param *p, *t;
68
+ uint32_t i;
69
+
70
+ for (i = 0; i < o->this.n_params; i++) {
71
+ spa_list_for_each_safe(p, t, &o->pending_list, link) {
72
+ if (p->id == o->this.paramsi.id &&
73
+ p->seq != o->this.paramsi.seq &&
74
+ p->param != NULL) {
75
+ spa_list_remove(&p->link);
76
+ free(p);
77
+ }
78
+ }
79
+ }
80
81
spa_list_consume(p, &o->pending_list, link) {
82
spa_list_remove(&p->link);
83
84
pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
85
86
info = o->this.info = pw_client_info_merge(o->this.info, info, o->this.changed == 0);
87
+ if (info == NULL)
88
+ return;
89
90
if (info->change_mask & PW_CLIENT_CHANGE_MASK_PROPS)
91
changed++;
92
93
pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
94
95
info = o->this.info = pw_module_info_merge(o->this.info, info, o->this.changed == 0);
96
+ if (info == NULL)
97
+ return;
98
99
if (info->change_mask & PW_MODULE_CHANGE_MASK_PROPS)
100
changed++;
101
102
pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
103
104
info = o->this.info = pw_device_info_merge(o->this.info, info, o->this.changed == 0);
105
+ if (info == NULL)
106
+ return;
107
+
108
+ o->this.n_params = info->n_params;
109
+ o->this.params = info->params;
110
111
if (info->change_mask & PW_DEVICE_CHANGE_MASK_PROPS)
112
changed++;
113
114
continue;
115
info->paramsi.user = 0;
116
117
- if (id >= MAX_PARAMS) {
118
- pw_log_error("too big param id %d", id);
119
- continue;
120
- }
121
-
122
switch (id) {
123
case SPA_PARAM_EnumProfile:
124
case SPA_PARAM_Profile:
125
126
case SPA_PARAM_Route:
127
break;
128
}
129
- add_param(&o->pending_list, o->param_seqid, o->param_seq, id, NULL);
130
+ add_param(&o->pending_list, info->paramsi.seq, id, NULL);
131
if (!(info->paramsi.flags & SPA_PARAM_INFO_READ))
132
continue;
133
134
res = pw_device_enum_params((struct pw_device*)o->this.proxy,
135
- ++o->param_seqid, id, 0, -1, NULL);
136
+ ++info->paramsi.seq, id, 0, -1, NULL);
137
if (SPA_RESULT_IS_ASYNC(res))
138
- o->param_seqid = res;
139
+ info->paramsi.seq = res;
140
}
141
}
142
if (changed) {
143
144
struct manager *m = o->manager;
145
struct pw_manager_param *p;
146
147
- p = add_param(&o->pending_list, seq, o->param_seq, id, param);
148
+ p = add_param(&o->pending_list, seq, id, param);
149
if (p == NULL)
150
return;
151
152
153
pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
154
155
info = o->this.info = pw_node_info_merge(o->this.info, info, o->this.changed == 0);
156
+ if (info == NULL)
157
+ return;
158
+
159
+ o->this.n_params = info->n_params;
160
+ o->this.params = info->params;
161
162
if (info->change_mask & PW_NODE_CHANGE_MASK_STATE)
163
changed++;
164
165
continue;
166
info->paramsi.user = 0;
167
168
- if (id >= MAX_PARAMS) {
169
- pw_log_error("too big param id %d", id);
170
- continue;
171
- }
172
-
173
changed++;
174
- add_param(&o->pending_list, o->param_seqid, o->param_seq, id, NULL);
175
+ add_param(&o->pending_list, info->paramsi.seq, id, NULL);
176
if (!(info->paramsi.flags & SPA_PARAM_INFO_READ))
177
continue;
178
179
res = pw_node_enum_params((struct pw_node*)o->this.proxy,
180
- ++o->param_seqid, id, 0, -1, NULL);
181
+ ++info->paramsi.seq, id, 0, -1, NULL);
182
if (SPA_RESULT_IS_ASYNC(res))
183
- o->param_seqid = res;
184
+ info->paramsi.seq = res;
185
}
186
}
187
if (changed) {
188
189
const struct spa_pod *param)
190
{
191
struct object *o = data;
192
- add_param(&o->pending_list, seq, o->param_seq, id, param);
193
+ add_param(&o->pending_list, seq, id, param);
194
}
195
196
static const struct pw_node_events node_events = {
197
198
199
static const struct object_info *find_info(const char *type, uint32_t version)
200
{
201
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/manager.h -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/manager.h
Changed
19
1
2
3
struct pw_manager_param {
4
uint32_t id;
5
+ int32_t seq;
6
struct spa_list link; /**< link in manager_object param_list */
7
struct spa_pod *param;
8
};
9
10
11
int changed;
12
void *info;
13
+ struct spa_param_info *params;
14
+ uint32_t n_params;
15
+
16
struct spa_list param_list;
17
unsigned int creating:1;
18
unsigned int removing:1;
19
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c
Changed
46
1
2
struct pw_properties *playback_props;
3
4
struct spa_audio_info_raw info;
5
+ uint32_t latency_msec;
6
};
7
8
static void module_destroy(void *data)
9
10
FILE *f;
11
char *args;
12
size_t size, i;
13
+ char val256;
14
15
pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index);
16
pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index);
17
18
fprintf(f, " ");
19
}
20
}
21
+ if (data->latency_msec != 0)
22
+ fprintf(f, " target.delay.sec = %s",
23
+ spa_json_format_float(val, sizeof(val),
24
+ data->latency_msec / 1000.0f));
25
fprintf(f, " capture.props = {");
26
pw_properties_serialize_dict(f, &data->capture_props->dict, 0);
27
fprintf(f, " } playback.props = {");
28
29
pw_properties_set(props, "remix", NULL);
30
}
31
32
- if ((str = pw_properties_get(props, "latency_msec")) != NULL) {
33
- /* Half the latency on each of the playback and capture streams */
34
- pw_properties_setf(capture_props, PW_KEY_NODE_LATENCY, "%s/2000", str);
35
- pw_properties_setf(playback_props, PW_KEY_NODE_LATENCY, "%s/2000", str);
36
- pw_properties_set(props, "latency_msec", NULL);
37
- } else {
38
- pw_properties_set(capture_props, PW_KEY_NODE_LATENCY, "100/1000");
39
- pw_properties_set(playback_props, PW_KEY_NODE_LATENCY, "100/1000");
40
- }
41
+ if ((str = pw_properties_get(props, "latency_msec")) != NULL)
42
+ d->latency_msec = atoi(str);
43
44
if ((str = pw_properties_get(props, "sink_input_properties")) != NULL) {
45
module_args_add_props(playback_props, str);
46
pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c
Added
167
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <spa/utils/hook.h>
27
+#include <pipewire/pipewire.h>
28
+#include <pipewire/private.h>
29
+
30
+#include "../defs.h"
31
+#include "../module.h"
32
+
33
+#define NAME "rtp-recv"
34
+
35
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
36
+#define PW_LOG_TOPIC_DEFAULT mod_topic
37
+
38
+struct module_rtp_recv_data {
39
+ struct module *module;
40
+
41
+ struct spa_hook mod_listener;
42
+ struct pw_impl_module *mod;
43
+
44
+ struct pw_properties *stream_props;
45
+ struct pw_properties *global_props;
46
+};
47
+
48
+static void module_destroy(void *data)
49
+{
50
+ struct module_rtp_recv_data *d = data;
51
+ spa_hook_remove(&d->mod_listener);
52
+ d->mod = NULL;
53
+ module_schedule_unload(d->module);
54
+}
55
+
56
+static const struct pw_impl_module_events module_events = {
57
+ PW_VERSION_IMPL_MODULE_EVENTS,
58
+ .destroy = module_destroy
59
+};
60
+
61
+static int module_rtp_recv_load(struct client *client, struct module *module)
62
+{
63
+ struct module_rtp_recv_data *data = module->user_data;
64
+ FILE *f;
65
+ char *args;
66
+ size_t size;
67
+
68
+ pw_properties_setf(data->stream_props, "pulse.module.id",
69
+ "%u", module->index);
70
+
71
+ if ((f = open_memstream(&args, &size)) == NULL)
72
+ return -errno;
73
+
74
+ fprintf(f, "{");
75
+ pw_properties_serialize_dict(f, &data->global_props->dict, 0);
76
+ fprintf(f, " stream.props = {");
77
+ pw_properties_serialize_dict(f, &data->stream_props->dict, 0);
78
+ fprintf(f, " } }");
79
+ fclose(f);
80
+
81
+ data->mod = pw_context_load_module(module->impl->context,
82
+ "libpipewire-module-rtp-source",
83
+ args, NULL);
84
+
85
+ free(args);
86
+
87
+ if (data->mod == NULL)
88
+ return -errno;
89
+
90
+ pw_impl_module_add_listener(data->mod,
91
+ &data->mod_listener,
92
+ &module_events, data);
93
+
94
+ return 0;
95
+}
96
+
97
+static int module_rtp_recv_unload(struct module *module)
98
+{
99
+ struct module_rtp_recv_data *d = module->user_data;
100
+
101
+ if (d->mod) {
102
+ spa_hook_remove(&d->mod_listener);
103
+ pw_impl_module_destroy(d->mod);
104
+ d->mod = NULL;
105
+ }
106
+
107
+ pw_properties_free(d->global_props);
108
+ pw_properties_free(d->stream_props);
109
+
110
+ return 0;
111
+}
112
+
113
+static const struct spa_dict_item module_rtp_recv_info = {
114
+ { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
115
+ { PW_KEY_MODULE_DESCRIPTION, "Receive data from a network via RTP/SAP/SDP" },
116
+ { PW_KEY_MODULE_USAGE, "sink=<name of the sink> "
117
+ "sap_address=<multicast address to listen on> "
118
+ "latency_msec=<latency in ms> " },
119
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
120
+};
121
+
122
+static int module_rtp_recv_prepare(struct module * const module)
123
+{
124
+ struct module_rtp_recv_data * const d = module->user_data;
125
+ struct pw_properties * const props = module->props;
126
+ struct pw_properties *stream_props = NULL, *global_props = NULL;
127
+ const char *str;
128
+ int res;
129
+
130
+ PW_LOG_TOPIC_INIT(mod_topic);
131
+
132
+ stream_props = pw_properties_new(NULL, NULL);
133
+ global_props = pw_properties_new(NULL, NULL);
134
+ if (!stream_props || !global_props) {
135
+ res = -errno;
136
+ goto out;
137
+ }
138
+ if ((str = pw_properties_get(props, "sink")) != NULL)
139
+ pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str);
140
+
141
+ if ((str = pw_properties_get(props, "sap_address")) != NULL)
142
+ pw_properties_set(global_props, "sap.ip", str);
143
+
144
+ if ((str = pw_properties_get(props, "latency_msec")) != NULL)
145
+ pw_properties_set(global_props, "sess.latency.msec", str);
146
+
147
+ d->module = module;
148
+ d->stream_props = stream_props;
149
+ d->global_props = global_props;
150
+
151
+ return 0;
152
+out:
153
+ pw_properties_free(stream_props);
154
+ pw_properties_free(global_props);
155
+
156
+ return res;
157
+}
158
+
159
+DEFINE_MODULE_INFO(module_rtp_recv) = {
160
+ .name = "module-rtp-recv",
161
+ .prepare = module_rtp_recv_prepare,
162
+ .load = module_rtp_recv_load,
163
+ .unload = module_rtp_recv_unload,
164
+ .properties = &SPA_DICT_INIT_ARRAY(module_rtp_recv_info),
165
+ .data_size = sizeof(struct module_rtp_recv_data),
166
+};
167
pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c
Added
201
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include <spa/utils/hook.h>
27
+#include <pipewire/pipewire.h>
28
+#include <pipewire/private.h>
29
+
30
+#include "../defs.h"
31
+#include "../module.h"
32
+
33
+#define NAME "rtp-send"
34
+
35
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
36
+#define PW_LOG_TOPIC_DEFAULT mod_topic
37
+
38
+struct module_rtp_send_data {
39
+ struct module *module;
40
+
41
+ struct spa_hook mod_listener;
42
+ struct pw_impl_module *mod;
43
+
44
+ struct pw_properties *stream_props;
45
+ struct pw_properties *global_props;
46
+ struct spa_audio_info_raw info;
47
+};
48
+
49
+static void module_destroy(void *data)
50
+{
51
+ struct module_rtp_send_data *d = data;
52
+ spa_hook_remove(&d->mod_listener);
53
+ d->mod = NULL;
54
+ module_schedule_unload(d->module);
55
+}
56
+
57
+static const struct pw_impl_module_events module_events = {
58
+ PW_VERSION_IMPL_MODULE_EVENTS,
59
+ .destroy = module_destroy
60
+};
61
+
62
+static int module_rtp_send_load(struct client *client, struct module *module)
63
+{
64
+ struct module_rtp_send_data *data = module->user_data;
65
+ FILE *f;
66
+ char *args;
67
+ size_t size;
68
+ uint32_t i;
69
+
70
+ pw_properties_setf(data->stream_props, "pulse.module.id",
71
+ "%u", module->index);
72
+
73
+ if ((f = open_memstream(&args, &size)) == NULL)
74
+ return -errno;
75
+
76
+ fprintf(f, "{");
77
+ pw_properties_serialize_dict(f, &data->global_props->dict, 0);
78
+ if (data->info.format != 0)
79
+ fprintf(f, " \"audio.format\": \"%s\"", format_id2name(data->info.format));
80
+ if (data->info.rate != 0)
81
+ fprintf(f, " \"audio.rate\": %u,", data->info.rate);
82
+ if (data->info.channels != 0) {
83
+ fprintf(f, " \"audio.channels\": %u,", data->info.channels);
84
+ if (!(data->info.flags & SPA_AUDIO_FLAG_UNPOSITIONED)) {
85
+ fprintf(f, " \"audio.position\": ");
86
+ for (i = 0; i < data->info.channels; i++)
87
+ fprintf(f, "%s\"%s\"", i == 0 ? "" : ",",
88
+ channel_id2name(data->info.positioni));
89
+ fprintf(f, " ,");
90
+ }
91
+ }
92
+ fprintf(f, " stream.props = {");
93
+ pw_properties_serialize_dict(f, &data->stream_props->dict, 0);
94
+ fprintf(f, " } }");
95
+ fclose(f);
96
+
97
+ data->mod = pw_context_load_module(module->impl->context,
98
+ "libpipewire-module-rtp-sink",
99
+ args, NULL);
100
+
101
+ free(args);
102
+
103
+ if (data->mod == NULL)
104
+ return -errno;
105
+
106
+ pw_impl_module_add_listener(data->mod,
107
+ &data->mod_listener,
108
+ &module_events, data);
109
+
110
+ return 0;
111
+}
112
+
113
+static int module_rtp_send_unload(struct module *module)
114
+{
115
+ struct module_rtp_send_data *d = module->user_data;
116
+
117
+ if (d->mod) {
118
+ spa_hook_remove(&d->mod_listener);
119
+ pw_impl_module_destroy(d->mod);
120
+ d->mod = NULL;
121
+ }
122
+
123
+ pw_properties_free(d->global_props);
124
+ pw_properties_free(d->stream_props);
125
+
126
+ return 0;
127
+}
128
+
129
+static const struct spa_dict_item module_rtp_send_info = {
130
+ { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
131
+ { PW_KEY_MODULE_DESCRIPTION, "Read data from source and send it to the network via RTP/SAP/SDP" },
132
+ { PW_KEY_MODULE_USAGE, "source=<name of the source> "
133
+ "format=<sample format> "
134
+ "channels=<number of channels> "
135
+ "rate=<sample rate> "
136
+ "destination_ip=<destination IP address> "
137
+ "source_ip=<source IP address> "
138
+ "port=<port number> "
139
+ "mtu=<maximum transfer unit> "
140
+ "loop=<loopback to local host?> "
141
+ "ttl=<ttl value> "
142
+ "inhibit_auto_suspend=<always|never|only_with_non_monitor_sources> "
143
+ "stream_name=<name of the stream> "
144
+ "enable_opus=<enable OPUS codec>" },
145
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
146
+};
147
+
148
+static int module_rtp_send_prepare(struct module * const module)
149
+{
150
+ struct module_rtp_send_data * const d = module->user_data;
151
+ struct pw_properties * const props = module->props;
152
+ struct pw_properties *stream_props = NULL, *global_props = NULL;
153
+ struct spa_audio_info_raw info = { 0 };
154
+ const char *str;
155
+ int res;
156
+
157
+ PW_LOG_TOPIC_INIT(mod_topic);
158
+
159
+ stream_props = pw_properties_new(NULL, NULL);
160
+ global_props = pw_properties_new(NULL, NULL);
161
+ if (!stream_props || !global_props) {
162
+ res = -errno;
163
+ goto out;
164
+ }
165
+
166
+ if ((str = pw_properties_get(props, "source")) != NULL) {
167
+ pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str);
168
+ if (spa_strendswith(str, ".monitor")) {
169
+ pw_properties_setf(stream_props, PW_KEY_NODE_TARGET,
170
+ "%.*s", (int)strlen(str)-8, str);
171
+ pw_properties_set(stream_props, PW_KEY_STREAM_CAPTURE_SINK,
172
+ "true");
173
+ } else {
174
+ pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str);
175
+ }
176
+ }
177
+ if (module_args_to_audioinfo(module->impl, props, &info) < 0) {
178
+ res = -EINVAL;
179
+ goto out;
180
+ }
181
+ info.format = 0;
182
+ if ((str = pw_properties_get(props, "format")) != NULL) {
183
+ if ((info.format = format_paname2id(str, strlen(str))) ==
184
+ SPA_AUDIO_FORMAT_UNKNOWN) {
185
+ pw_log_error("unknown format %s", str);
186
+ res = -EINVAL;
187
+ goto out;
188
+ }
189
+ }
190
+
191
+ if ((str = pw_properties_get(props, "destination_ip")) != NULL)
192
+ pw_properties_set(global_props, "destination.ip", str);
193
+ if ((str = pw_properties_get(props, "source_ip")) != NULL)
194
+ pw_properties_set(global_props, "source.ip", str);
195
+ if ((str = pw_properties_get(props, "port")) != NULL)
196
+ pw_properties_set(global_props, "destination.port", str);
197
+ if ((str = pw_properties_get(props, "mtu")) != NULL)
198
+ pw_properties_set(global_props, "net.mtu", str);
199
+ if ((str = pw_properties_get(props, "loop")) != NULL)
200
+ pw_properties_set(global_props, "net.loop",
201
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c
Changed
60
1
2
3
struct spa_hook mod_listener;
4
struct pw_impl_module *mod;
5
+
6
+ uint32_t latency_msec;
7
};
8
9
static void module_destroy(void *data)
10
11
static int module_zeroconf_discover_load(struct client *client, struct module *module)
12
{
13
struct module_zeroconf_discover_data *data = module->user_data;
14
+ FILE *f;
15
+ char *args;
16
+ size_t size;
17
+
18
+ if ((f = open_memstream(&args, &size)) == NULL)
19
+ return -errno;
20
+
21
+ fprintf(f, "{");
22
+ if (data->latency_msec > 0)
23
+ fprintf(f, " pulse.latency = %u ", data->latency_msec);
24
+ fprintf(f, "}");
25
+ fclose(f);
26
27
data->mod = pw_context_load_module(module->impl->context,
28
"libpipewire-module-zeroconf-discover",
29
- NULL, NULL);
30
+ args, NULL);
31
+
32
+ free(args);
33
+
34
if (data->mod == NULL)
35
return -errno;
36
37
38
static const struct spa_dict_item module_zeroconf_discover_info = {
39
{ PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.con>" },
40
{ PW_KEY_MODULE_DESCRIPTION, "mDNS/DNS-SD Service Discovery" },
41
- { PW_KEY_MODULE_USAGE, "" },
42
+ { PW_KEY_MODULE_USAGE,
43
+ "latency_msec=<fixed latency in ms> " },
44
{ PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
45
};
46
47
48
{
49
PW_LOG_TOPIC_INIT(mod_topic);
50
51
+ struct pw_properties * const props = module->props;
52
struct module_zeroconf_discover_data * const data = module->user_data;
53
data->module = module;
54
55
+ pw_properties_fetch_uint32(props, "latency_msec", &data->latency_msec);
56
+
57
return 0;
58
}
59
60
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c
Changed
11
1
2
txt = avahi_string_list_add_pair(txt, "channel_map", channel_map_snprint(cm, sizeof(cm), &s->cm));
3
txt = avahi_string_list_add_pair(txt, "subtype", subtype_texts->subtype);
4
5
- const struct mapping *m;
6
- SPA_FOR_EACH_ELEMENT(mappings, m) {
7
+ SPA_FOR_EACH_ELEMENT_VAR(mappings, m) {
8
const char *value = pw_properties_get(s->props, m->pw_key);
9
if (value != NULL)
10
txt = avahi_string_list_add_pair(txt, m->txt_key, value);
11
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
21
1
2
}
3
if ((stream->attr.prebuf == 0 || do_flush) && !stream->corked) {
4
if (avail > 0) {
5
+ avail = SPA_MIN((uint32_t)avail, size);
6
spa_ringbuffer_read_data(&stream->ring,
7
stream->buffer, MAXLENGTH,
8
index % MAXLENGTH,
9
- p, SPA_MIN((uint32_t)avail, size));
10
+ p, avail);
11
index += avail;
12
+ pd.read_inc = avail;
13
+ spa_ringbuffer_read_update(&stream->ring, index);
14
}
15
pd.playing_for = size;
16
- pd.read_inc = size;
17
- spa_ringbuffer_read_update(&stream->ring, index);
18
}
19
pw_log_debug("%p: %s underrun read:%u avail:%d max:%u",
20
stream, client->name, index, avail, minreq);
21
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/quirks.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/quirks.c
Changed
15
1
2
{ "force-s16-info", QUIRK_FORCE_S16_FORMAT },
3
{ "remove-capture-dont-move", QUIRK_REMOVE_CAPTURE_DONT_MOVE },
4
};
5
- size_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(quirk_keys); ++i) {
7
- if (spa_streq(str, quirk_keysi.key))
8
- return quirk_keysi.value;
9
+ SPA_FOR_EACH_ELEMENT_VAR(quirk_keys, i) {
10
+ if (spa_streq(str, i->key))
11
+ return i->value;
12
}
13
return 0;
14
}
15
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
20
1
2
pw_log_warn("server %p: unlink('%s') failed: %m",
3
server, addr_un->sun_path);
4
}
5
-
6
if (bind(fd, (const struct sockaddr *) addr_un, SUN_LEN(addr_un)) < 0) {
7
res = -errno;
8
pw_log_warn("server %p: bind() to '%s' failed: %m",
9
10
goto error_close;
11
}
12
13
+ if (chmod(addr_un->sun_path, 0777) < 0)
14
+ pw_log_warn("server %p: chmod('%s') failed: %m",
15
+ server, addr_un->sun_path);
16
+
17
if (listen(fd, server->listen_backlog) < 0) {
18
res = -errno;
19
pw_log_warn("server %p: listen() on '%s' failed: %m",
20
pipewire-0.3.59.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.60.tar.gz/src/modules/module-pulse-tunnel.c
Changed
152
1
2
pa_context *pa_context;
3
pa_stream *pa_stream;
4
5
+ struct ratelimit rate_limit;
6
+
7
uint32_t target_latency;
8
uint32_t current_latency;
9
uint32_t target_buffer;
10
11
{
12
struct impl *impl = userdata;
13
int32_t avail;
14
- uint32_t index, len, offset, l0, l1;
15
+ uint32_t index;
16
+ size_t size;
17
pa_usec_t latency;
18
- int negative;
19
+ int negative, res;
20
21
if (impl->resync) {
22
impl->resync = false;
23
24
impl->current_latency += avail / impl->frame_size;
25
26
while (avail < (int32_t)length) {
27
+ uint32_t maxsize = SPA_ROUND_DOWN(sizeof(impl->empty), impl->frame_size);
28
/* send silence for the data we don't have */
29
- len = SPA_MIN(length - avail, sizeof(impl->empty));
30
- pa_stream_write(impl->pa_stream,
31
- impl->empty, len,
32
- NULL, 0, PA_SEEK_RELATIVE);
33
- length -= len;
34
+ size = SPA_MIN(length - avail, maxsize);
35
+ if ((res = pa_stream_write(impl->pa_stream,
36
+ impl->empty, size,
37
+ NULL, 0, PA_SEEK_RELATIVE)) != 0)
38
+ pw_log_warn("error writing stream: %s", pa_strerror(res));
39
+ length -= size;
40
}
41
- if (length > 0 && avail >= (int32_t)length) {
42
- /* always send as much as is requested */
43
- len = length;
44
- offset = index & RINGBUFFER_MASK;
45
- l0 = SPA_MIN(len, RINGBUFFER_SIZE - offset);
46
- l1 = len - l0;
47
-
48
- pa_stream_write(impl->pa_stream,
49
- SPA_PTROFF(impl->buffer, offset, void), l0,
50
- NULL, 0, PA_SEEK_RELATIVE);
51
-
52
- if (SPA_UNLIKELY(l1 > 0)) {
53
- pa_stream_write(impl->pa_stream,
54
- impl->buffer, l1,
55
- NULL, 0, PA_SEEK_RELATIVE);
56
- }
57
- index += len;
58
+ while (length > 0 && avail >= (int32_t)length) {
59
+ void *data;
60
+
61
+ size = length;
62
+ pa_stream_begin_write(impl->pa_stream, &data, &size);
63
+
64
+ spa_ringbuffer_read_data(&impl->ring,
65
+ impl->buffer, RINGBUFFER_SIZE,
66
+ index & RINGBUFFER_MASK,
67
+ data, size);
68
+
69
+ if ((res = pa_stream_write(impl->pa_stream,
70
+ data, size, NULL, 0, PA_SEEK_RELATIVE)) != 0)
71
+ pw_log_warn("error writing stream: %zd %s", size,
72
+ pa_strerror(res));
73
+
74
+ index += size;
75
+ length -= size;
76
+ avail -= size;
77
spa_ringbuffer_read_update(&impl->ring, index);
78
}
79
}
80
static void stream_underflow_cb(pa_stream *s, void *userdata)
81
{
82
struct impl *impl = userdata;
83
- pw_log_warn("underflow");
84
+ struct timespec ts;
85
+
86
+ clock_gettime(CLOCK_MONOTONIC, &ts);
87
+ if (ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts), SPA_LOG_LEVEL_WARN))
88
+ pw_log_warn("underflow");
89
impl->resync = true;
90
}
91
static void stream_overflow_cb(pa_stream *s, void *userdata)
92
{
93
struct impl *impl = userdata;
94
- pw_log_warn("overflow");
95
+ struct timespec ts;
96
+ clock_gettime(CLOCK_MONOTONIC, &ts);
97
+ if (ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts), SPA_LOG_LEVEL_WARN))
98
+ pw_log_warn("overflow");
99
impl->resync = true;
100
}
101
102
103
static int create_pulse_stream(struct impl *impl)
104
{
105
pa_sample_spec ss;
106
+ pa_channel_map map;
107
const char *server_address, *remote_node_target;
108
pa_proplist *props = NULL;
109
pa_mainloop_api *api;
110
char stream_name1024;
111
pa_buffer_attr bufferattr;
112
int res = -EIO;
113
- uint32_t latency_bytes;
114
+ uint32_t latency_bytes, i, aux = 0;
115
116
if ((impl->pa_mainloop = pa_threaded_mainloop_new()) == NULL)
117
goto error;
118
119
ss.channels = impl->info.channels;
120
ss.rate = impl->info.rate;
121
122
+ map.channels = impl->info.channels;
123
+ for (i = 0; i < map.channels; i++)
124
+ map.mapi = (pa_channel_position_t)channel_id2pa(impl->info.positioni, &aux);
125
+
126
snprintf(stream_name, sizeof(stream_name), _("Tunnel for %s@%s"),
127
pw_get_user_name(), pw_get_host_name());
128
129
- if (!(impl->pa_stream = pa_stream_new(impl->pa_context, stream_name, &ss, NULL))) {
130
+ if (!(impl->pa_stream = pa_stream_new(impl->pa_context, stream_name, &ss, &map))) {
131
res = pa_context_errno(impl->pa_context);
132
goto error_unlock;
133
}
134
135
PA_STREAM_AUTO_TIMING_UPDATE);
136
} else {
137
bufferattr.tlength = latency_bytes / 2;
138
+ bufferattr.minreq = bufferattr.tlength / 4;
139
+ bufferattr.prebuf = bufferattr.tlength;
140
141
res = pa_stream_connect_playback(impl->pa_stream,
142
remote_node_target, &bufferattr,
143
144
spa_ringbuffer_init(&impl->ring);
145
impl->buffer = calloc(1, RINGBUFFER_SIZE);
146
spa_dll_init(&impl->dll);
147
+ impl->rate_limit.interval = 2 * SPA_NSEC_PER_SEC;
148
+ impl->rate_limit.burst = 1;
149
150
if ((str = pw_properties_get(props, "tunnel.mode")) != NULL) {
151
if (spa_streq(str, "source")) {
152
pipewire-0.3.59.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.60.tar.gz/src/modules/module-raop-sink.c
Changed
201
1
2
* raop.hostname = "my-raop-device"
3
* raop.port = 8190
4
* #raop.transport = "udp"
5
- * raop.encryption = "RSA"
6
+ * raop.encryption.type = "RSA"
7
* #raop.audio.codec = "PCM"
8
* #raop.password = "****"
9
* #audio.format = "S16"
10
* #audio.rate = 44100
11
- * #audio.channels = 22
12
+ * #audio.channels = 2
13
* #audio.position = FL FR
14
* stream.props = {
15
* # extra sink properties
16
17
#define DEFAULT_CHANNELS 2
18
#define DEFAULT_POSITION " FL FR "
19
20
-#define DEFAULT_LATENCY (DEFAULT_RATE*2)
21
+#define DEFAULT_LATENCY 22050
22
23
#define MODULE_USAGE " raop.hostname=<name of host> " \
24
" raop.port=<remote port> " \
25
26
memset(dst, 0, len);
27
break;
28
}
29
- if (impl->encryption != CRYPTO_NONE)
30
+ if (impl->encryption == CRYPTO_RSA)
31
aes_encrypt(impl, dst, len);
32
33
impl->rtptime += n_frames;
34
35
memset(dst, 0, len);
36
break;
37
}
38
- if (impl->encryption != CRYPTO_NONE)
39
+ if (impl->encryption == CRYPTO_RSA)
40
aes_encrypt(impl, dst, len);
41
42
pkt0 |= htonl((uint32_t) len + 12);
43
44
}
45
}
46
47
-static void rtsp_flush_reply(void *data, int status, const struct spa_dict *headers)
48
+static int rtsp_flush_reply(void *data, int status, const struct spa_dict *headers)
49
{
50
pw_log_info("reply %d", status);
51
+ return 0;
52
}
53
54
static int rtsp_do_flush(struct impl *impl)
55
56
return res;
57
}
58
59
-static void rtsp_record_reply(void *data, int status, const struct spa_dict *headers)
60
+static int rtsp_record_reply(void *data, int status, const struct spa_dict *headers)
61
{
62
struct impl *impl = data;
63
const char *str;
64
65
uint8_t buffer1024;
66
struct spa_pod_builder b;
67
struct spa_latency_info latency;
68
+ char progress128;
69
70
pw_log_info("reply %d", status);
71
72
73
impl->sync = 0;
74
impl->sync_period = impl->info.rate / (impl->block_size / impl->frame_size);
75
impl->recording = true;
76
+
77
+ snprintf(progress, sizeof(progress), "progress: %s/%s/%s\r\n", "0", "0", "0");
78
+ return pw_rtsp_client_send(impl->rtsp, "SET_PARAMETER", NULL,
79
+ "text/parameters", progress, NULL, NULL);
80
}
81
82
static int rtsp_do_record(struct impl *impl)
83
84
pw_loop_update_io(impl->loop, impl->server_source, 0);
85
}
86
87
-static void rtsp_setup_reply(void *data, int status, const struct spa_dict *headers)
88
+static int rtsp_setup_reply(void *data, int status, const struct spa_dict *headers)
89
{
90
struct impl *impl = data;
91
const char *str, *state = NULL, *s;
92
93
94
if ((str = spa_dict_lookup(headers, "Session")) == NULL) {
95
pw_log_error("missing Session header");
96
- return;
97
+ return 0;
98
}
99
pw_properties_set(impl->headers, "Session", str);
100
101
if ((str = spa_dict_lookup(headers, "Transport")) == NULL) {
102
pw_log_error("missing Transport header");
103
- return;
104
+ return 0;
105
}
106
107
impl->server_port = control_port = timing_port = 0;
108
109
}
110
if (impl->server_port == 0) {
111
pw_log_error("missing server port in Transport");
112
- return;
113
+ return 0;
114
}
115
116
- pw_getrandom(&impl->seq, sizeof(impl->seq), 0);
117
- pw_getrandom(&impl->rtptime, sizeof(impl->rtptime), 0);
118
+ if (pw_getrandom(&impl->seq, sizeof(impl->seq), 0) < 0 ||
119
+ pw_getrandom(&impl->rtptime, sizeof(impl->rtptime), 0) < 0) {
120
+ pw_log_error("error generating random seq and rtptime: %m");
121
+ return 0;
122
+ }
123
124
pw_log_info("server port:%u", impl->server_port);
125
126
switch (impl->protocol) {
127
case PROTO_TCP:
128
- if ((impl->server_fd = connect_socket(impl, SOCK_STREAM, -1, impl->server_port)) <= 0)
129
- return;
130
+ if ((impl->server_fd = connect_socket(impl, SOCK_STREAM, -1, impl->server_port)) < 0)
131
+ return impl->server_fd;
132
133
impl->server_source = pw_loop_add_io(impl->loop, impl->server_fd,
134
SPA_IO_OUT, false, on_server_source_io, impl);
135
136
case PROTO_UDP:
137
if (control_port == 0 || timing_port == 0) {
138
pw_log_error("missing UDP ports in Transport");
139
- return;
140
+ return 0;
141
}
142
pw_log_info("control:%u timing:%u", control_port, timing_port);
143
144
- if ((impl->server_fd = connect_socket(impl, SOCK_DGRAM, -1, impl->server_port)) <= 0)
145
- return;
146
- if ((impl->control_fd = connect_socket(impl, SOCK_DGRAM, impl->control_fd, control_port)) <= 0)
147
- return;
148
- if ((impl->timing_fd = connect_socket(impl, SOCK_DGRAM, impl->timing_fd, timing_port)) <= 0)
149
- return;
150
+ if ((impl->server_fd = connect_socket(impl, SOCK_DGRAM, -1, impl->server_port)) < 0)
151
+ return impl->server_fd;
152
+ if ((impl->control_fd = connect_socket(impl, SOCK_DGRAM, impl->control_fd, control_port)) < 0)
153
+ return impl->control_fd;
154
+ if ((impl->timing_fd = connect_socket(impl, SOCK_DGRAM, impl->timing_fd, timing_port)) < 0)
155
+ return impl->timing_fd;
156
157
ntp = ntp_now(CLOCK_MONOTONIC);
158
send_udp_timing_packet(impl, ntp, ntp, NULL, 0);
159
160
rtsp_do_record(impl);
161
break;
162
default:
163
- return;
164
+ return 0;
165
}
166
+ return 0;
167
}
168
169
static int rtsp_do_setup(struct impl *impl)
170
171
return -EIO;
172
}
173
174
-static void rtsp_announce_reply(void *data, int status, const struct spa_dict *headers)
175
+static int rtsp_announce_reply(void *data, int status, const struct spa_dict *headers)
176
{
177
struct impl *impl = data;
178
179
180
181
pw_properties_set(impl->headers, "Apple-Challenge", NULL);
182
183
- rtsp_do_setup(impl);
184
+ return rtsp_do_setup(impl);
185
}
186
187
static void base64_encode(const uint8_t *data, size_t len, char *enc, char pad)
188
189
int res, frames, i, ip_version;
190
char *sdp;
191
char local_ip256;
192
-
193
+ int min_latency;
194
+ min_latency = DEFAULT_LATENCY;
195
host = pw_properties_get(impl->props, "raop.hostname");
196
197
if (impl->protocol == PROTO_TCP)
198
199
ip_version, host, frames);
200
break;
201
pipewire-0.3.59.tar.gz/src/modules/module-raop/rtsp-client.c -> pipewire-0.3.60.tar.gz/src/modules/module-raop/rtsp-client.c
Changed
66
1
2
size_t len;
3
size_t offset;
4
uint32_t cseq;
5
- void (*reply) (void *user_data, int status, const struct spa_dict *headers);
6
+ int (*reply) (void *user_data, int status, const struct spa_dict *headers);
7
void *user_data;
8
};
9
10
11
return client->user_data;
12
}
13
14
+const char *pw_rtsp_client_get_url(struct pw_rtsp_client *client)
15
+{
16
+ return client->url;
17
+}
18
+
19
void pw_rtsp_client_add_listener(struct pw_rtsp_client *client,
20
struct spa_hook *listener,
21
const struct pw_rtsp_client_events *events, void *data)
22
23
static void dispatch_handler(struct pw_rtsp_client *client)
24
{
25
uint32_t cseq;
26
+ int res;
27
+ struct message *msg;
28
+
29
if (pw_properties_fetch_uint32(client->headers, "CSeq", &cseq) < 0)
30
return;
31
32
pw_log_info("received reply to request with cseq:%" PRIu32, cseq);
33
34
- struct message *msg = find_pending(client, cseq);
35
+ msg = find_pending(client, cseq);
36
if (msg) {
37
- msg->reply(msg->user_data, client->status, &client->headers->dict);
38
+ res = msg->reply(msg->user_data, client->status, &client->headers->dict);
39
spa_list_remove(&msg->link);
40
free(msg);
41
+
42
+ if (res < 0)
43
+ pw_log_warn("client %p: handle reply cseq:%u error: %s",
44
+ client, cseq, spa_strerror(res));
45
}
46
else {
47
pw_rtsp_client_emit_message(client, client->status, &client->headers->dict);
48
49
int pw_rtsp_client_url_send(struct pw_rtsp_client *client, const char *url,
50
const char *cmd, const struct spa_dict *headers,
51
const char *content_type, const void *content, size_t content_length,
52
- void (*reply) (void *user_data, int status, const struct spa_dict *headers),
53
+ int (*reply) (void *user_data, int status, const struct spa_dict *headers),
54
void *user_data)
55
{
56
FILE *f;
57
58
int pw_rtsp_client_send(struct pw_rtsp_client *client,
59
const char *cmd, const struct spa_dict *headers,
60
const char *content_type, const char *content,
61
- void (*reply) (void *user_data, int status, const struct spa_dict *headers),
62
+ int (*reply) (void *user_data, int status, const struct spa_dict *headers),
63
void *user_data)
64
{
65
const size_t content_length = content ? strlen(content) : 0;
66
pipewire-0.3.59.tar.gz/src/modules/module-raop/rtsp-client.h -> pipewire-0.3.60.tar.gz/src/modules/module-raop/rtsp-client.h
Changed
25
1
2
void pw_rtsp_client_destroy(struct pw_rtsp_client *client);
3
4
void *pw_rtsp_client_get_user_data(struct pw_rtsp_client *client);
5
+const char *pw_rtsp_client_get_url(struct pw_rtsp_client *client);
6
7
void pw_rtsp_client_add_listener(struct pw_rtsp_client *client,
8
struct spa_hook *listener,
9
10
int pw_rtsp_client_url_send(struct pw_rtsp_client *client, const char *url,
11
const char *cmd, const struct spa_dict *headers,
12
const char *content_type, const void *content, size_t content_length,
13
- void (*reply) (void *user_data, int status, const struct spa_dict *headers),
14
+ int (*reply) (void *user_data, int status, const struct spa_dict *headers),
15
void *user_data);
16
17
int pw_rtsp_client_send(struct pw_rtsp_client *client,
18
const char *cmd, const struct spa_dict *headers,
19
const char *content_type, const char *content,
20
- void (*reply) (void *user_data, int status, const struct spa_dict *headers),
21
+ int (*reply) (void *user_data, int status, const struct spa_dict *headers),
22
void *user_data);
23
24
25
pipewire-0.3.60.tar.gz/src/modules/module-rtp
Added
2
1
+(directory)
2
pipewire-0.3.60.tar.gz/src/modules/module-rtp-sink.c
Added
201
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include "config.h"
27
+
28
+#include <limits.h>
29
+#include <unistd.h>
30
+#include <sys/stat.h>
31
+#include <sys/socket.h>
32
+#include <sys/ioctl.h>
33
+#include <arpa/inet.h>
34
+#include <netinet/ip.h>
35
+#include <net/if.h>
36
+#include <ctype.h>
37
+
38
+#include <spa/param/audio/format-utils.h>
39
+#include <spa/utils/hook.h>
40
+#include <spa/utils/ringbuffer.h>
41
+#include <spa/utils/json.h>
42
+#include <spa/debug/pod.h>
43
+
44
+#include <pipewire/pipewire.h>
45
+#include <pipewire/private.h>
46
+
47
+#include <module-rtp/sap.h>
48
+#include <module-rtp/rtp.h>
49
+
50
+
51
+/** \page page_module_rtp_sink PipeWire Module: RTP sink
52
+ *
53
+ * The `rtp-sink` module creates a PipeWire sink that sends audio
54
+ * RTP packets.
55
+ *
56
+ * ## Module Options
57
+ *
58
+ * Options specific to the behavior of this module
59
+ *
60
+ * - `sap.ip = <str>`: IP address of the SAP messages, default "224.0.0.56"
61
+ * - `sap.port = <int>`: port of the SAP messages, default 9875
62
+ * - `source.ip =<str>`: source IP address, default "0.0.0.0"
63
+ * - `destination.ip =<str>`: destination IP address, default "224.0.0.56"
64
+ * - `destination.port =<int>`: destination port, default random beteen 46000 and 47024
65
+ * - `local.ifname = <str>`: interface name to use
66
+ * - `net.mtu = <int>`: MTU to use, default 1280
67
+ * - `net.ttl = <int>`: TTL to use, default 1
68
+ * - `net.loop = <bool>`: loopback multicast, default false
69
+ * - `sess.name = <str>`: a session name
70
+ * - `stream.props = {}`: properties to be passed to the stream
71
+ *
72
+ * ## General options
73
+ *
74
+ * Options with well-known behavior:
75
+ *
76
+ * - \ref PW_KEY_REMOTE_NAME
77
+ * - \ref PW_KEY_AUDIO_FORMAT
78
+ * - \ref PW_KEY_AUDIO_RATE
79
+ * - \ref PW_KEY_AUDIO_CHANNELS
80
+ * - \ref SPA_KEY_AUDIO_POSITION
81
+ * - \ref PW_KEY_NODE_NAME
82
+ * - \ref PW_KEY_NODE_DESCRIPTION
83
+ * - \ref PW_KEY_MEDIA_NAME
84
+ * - \ref PW_KEY_NODE_GROUP
85
+ * - \ref PW_KEY_NODE_LATENCY
86
+ * - \ref PW_KEY_NODE_VIRTUAL
87
+ * - \ref PW_KEY_MEDIA_CLASS
88
+ *
89
+ * ## Example configuration
90
+ *\code{.unparsed}
91
+ * context.modules =
92
+ * { name = libpipewire-module-rtp-sink
93
+ * args = {
94
+ * #sap.ip = "224.0.0.56"
95
+ * #sap.port = 9875
96
+ * #source.ip = "0.0.0.0"
97
+ * #destination.ip = "224.0.0.56"
98
+ * #destination.port = 46000
99
+ * #local.ifname = "eth0"
100
+ * #net.mtu = 1280
101
+ * #net.ttl = 1
102
+ * #net.loop = false
103
+ * #sess.name = "PipeWire RTP stream"
104
+ * #audio.format = "S16BE"
105
+ * #audio.rate = 48000
106
+ * #audio.channels = 2
107
+ * #audio.position = FL FR
108
+ * stream.props = {
109
+ * node.name = "rtp-sink"
110
+ * }
111
+ * }
112
+ *}
113
+ *
114
+ *\endcode
115
+ *
116
+ * \since 0.3.60
117
+ */
118
+
119
+#define NAME "rtp-sink"
120
+
121
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
122
+#define PW_LOG_TOPIC_DEFAULT mod_topic
123
+
124
+#define SAP_INTERVAL_SEC 5
125
+#define SAP_MIME_TYPE "application/sdp"
126
+
127
+#define BUFFER_SIZE (1u<<20)
128
+#define BUFFER_MASK (BUFFER_SIZE-1)
129
+
130
+#define DEFAULT_SAP_IP "224.0.0.56"
131
+#define DEFAULT_SAP_PORT 9875
132
+
133
+#define DEFAULT_FORMAT "S16BE"
134
+#define DEFAULT_RATE 48000
135
+#define DEFAULT_CHANNELS 2
136
+#define DEFAULT_POSITION " FL FR "
137
+
138
+#define DEFAULT_PORT 46000
139
+#define DEFAULT_SOURCE_IP "0.0.0.0"
140
+#define DEFAULT_DESTINATION_IP "224.0.0.56"
141
+#define DEFAULT_TTL 1
142
+#define DEFAULT_MTU 1280
143
+#define DEFAULT_LOOP false
144
+
145
+#define DEFAULT_MIN_PTIME 2
146
+#define DEFAULT_MAX_PTIME 20
147
+
148
+#define USAGE "sap.ip=<SAP IP address to send announce, default:"DEFAULT_SAP_IP"> " \
149
+ "sap.port=<SAP port to send on, default:"SPA_STRINGIFY(DEFAULT_SAP_PORT)"> " \
150
+ "source.ip=<source IP address, default:"DEFAULT_SOURCE_IP"> " \
151
+ "destination.ip=<destination IP address, default:"DEFAULT_DESTINATION_IP"> " \
152
+ "local.ifname=<local interface name to use> " \
153
+ "net.mtu=<desired MTU, default:"SPA_STRINGIFY(DEFAULT_MTU)"> " \
154
+ "net.ttl=<desired TTL, default:"SPA_STRINGIFY(DEFAULT_TTL)"> " \
155
+ "net.loop=<desired loopback, default:"SPA_STRINGIFY(DEFAULT_LOOP)"> " \
156
+ "sess.name=<a name for the session> " \
157
+ "audio.format=<format, default:"DEFAULT_FORMAT"> " \
158
+ "audio.rate=<sample rate, default:"SPA_STRINGIFY(DEFAULT_RATE)"> " \
159
+ "audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS)"> "\
160
+ "audio.position=<channel map, default:"DEFAULT_POSITION"> " \
161
+ "stream.props= { key=value ... }"
162
+
163
+static const struct spa_dict_item module_info = {
164
+ { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
165
+ { PW_KEY_MODULE_DESCRIPTION, "RTP Sink" },
166
+ { PW_KEY_MODULE_USAGE, USAGE },
167
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
168
+};
169
+
170
+static const struct format_info {
171
+ uint32_t format;
172
+ uint32_t size;
173
+ const char *mime;
174
+} format_info = {
175
+ { SPA_AUDIO_FORMAT_U8, 1, "L8" },
176
+ { SPA_AUDIO_FORMAT_ALAW, 1, "PCMA" },
177
+ { SPA_AUDIO_FORMAT_ULAW, 1, "PCMU" },
178
+ { SPA_AUDIO_FORMAT_S16_BE, 2, "L16" },
179
+ { SPA_AUDIO_FORMAT_S24_BE, 3, "L24" },
180
+};
181
+
182
+static const struct format_info *find_format_info(uint32_t format)
183
+{
184
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, f)
185
+ if (f->format == format)
186
+ return f;
187
+ return NULL;
188
+}
189
+
190
+struct impl {
191
+ struct pw_impl_module *module;
192
+ struct spa_hook module_listener;
193
+ struct pw_properties *props;
194
+ struct pw_context *module_context;
195
+
196
+ struct pw_loop *loop;
197
+
198
+ struct pw_core *core;
199
+ struct spa_hook core_listener;
200
+ struct spa_hook core_proxy_listener;
201
pipewire-0.3.60.tar.gz/src/modules/module-rtp-source.c
Added
201
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#include "config.h"
27
+
28
+#include <limits.h>
29
+#include <unistd.h>
30
+#include <sys/stat.h>
31
+#include <sys/socket.h>
32
+#include <sys/ioctl.h>
33
+#include <arpa/inet.h>
34
+#include <netinet/in.h>
35
+#include <net/if.h>
36
+#include <ctype.h>
37
+
38
+#include <spa/param/audio/format-utils.h>
39
+#include <spa/utils/hook.h>
40
+#include <spa/utils/ringbuffer.h>
41
+#include <spa/utils/dll.h>
42
+#include <spa/debug/mem.h>
43
+
44
+#include <pipewire/pipewire.h>
45
+#include <pipewire/private.h>
46
+
47
+#include <module-rtp/sap.h>
48
+#include <module-rtp/rtp.h>
49
+
50
+
51
+/** \page page_module_rtp_source PipeWire Module: RTP source
52
+ *
53
+ * The `rtp-source` module creates a PipeWire source that receives audio
54
+ * RTP packets.
55
+ *
56
+ * ## Module Options
57
+ *
58
+ * Options specific to the behavior of this module
59
+ *
60
+ * - `sap.ip = <str>`: IP address of the SAP messages, default "224.0.0.56"
61
+ * - `sap.port = <str>`: port of the SAP messages, default 9875
62
+ * - `local.ifname = <str>`: interface name to use
63
+ * - `sess.latency.msec = <str>`: target network latency in milliseconds, default 100
64
+ * - `stream.props = {}`: properties to be passed to the stream
65
+ *
66
+ * ## General options
67
+ *
68
+ * Options with well-known behavior:
69
+ *
70
+ * - \ref PW_KEY_NODE_NAME
71
+ * - \ref PW_KEY_NODE_DESCRIPTION
72
+ * - \ref PW_KEY_MEDIA_NAME
73
+ * - \ref PW_KEY_MEDIA_CLASS
74
+ *
75
+ * ## Example configuration
76
+ *\code{.unparsed}
77
+ * context.modules =
78
+ * { name = libpipewire-module-rtp-source
79
+ * args = {
80
+ * #sap.ip = 224.0.0.56
81
+ * #sap.port = 9875
82
+ * #local.ifname = eth0
83
+ * sess.latency.msec = 100
84
+ * stream.props = {
85
+ * node.name = "rtp-source"
86
+ * #media.class = "Audio/Source"
87
+ * }
88
+ * }
89
+ * }
90
+ *
91
+ *\endcode
92
+ *
93
+ * \since 0.3.60
94
+ */
95
+
96
+#define NAME "rtp-source"
97
+
98
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
99
+#define PW_LOG_TOPIC_DEFAULT mod_topic
100
+
101
+#define SAP_MIME_TYPE "application/sdp"
102
+
103
+#define ERROR_MSEC 2
104
+#define MAX_SESSIONS 16
105
+#define CLEANUP_INTERVAL_SEC 20
106
+
107
+#define DEFAULT_SAP_IP "224.0.0.56"
108
+#define DEFAULT_SAP_PORT 9875
109
+#define DEFAULT_SESS_LATENCY 100
110
+
111
+#define BUFFER_SIZE (1u<<22)
112
+#define BUFFER_MASK (BUFFER_SIZE-1)
113
+
114
+#define USAGE "sap.ip=<SAP IP address to listen on, default "DEFAULT_SAP_IP"> " \
115
+ "sap.port=<SAP port to listen on, default "SPA_STRINGIFY(DEFAULT_SAP_PORT)"> " \
116
+ "local.ifname=<local interface name to use> " \
117
+ "sess.latency.msec=<target network latency, default "SPA_STRINGIFY(DEFAULT_SESS_LATENCY)"> " \
118
+ "stream.props= { key=value ... }"
119
+
120
+static const struct spa_dict_item module_info = {
121
+ { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
122
+ { PW_KEY_MODULE_DESCRIPTION, "RTP Source" },
123
+ { PW_KEY_MODULE_USAGE, USAGE },
124
+ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
125
+};
126
+
127
+struct impl {
128
+ struct pw_impl_module *module;
129
+ struct spa_hook module_listener;
130
+ struct pw_properties *props;
131
+ struct pw_context *module_context;
132
+
133
+ struct pw_loop *loop;
134
+ struct pw_loop *data_loop;
135
+
136
+ struct pw_core *core;
137
+ struct spa_hook core_listener;
138
+ struct spa_hook core_proxy_listener;
139
+
140
+ struct spa_source *timer;
141
+ struct spa_source *sap_source;
142
+
143
+ struct pw_properties *stream_props;
144
+
145
+ unsigned int do_disconnect:1;
146
+
147
+ char *ifname;
148
+ char *sap_ip;
149
+ int sap_port;
150
+ int sess_latency_msec;
151
+
152
+ struct spa_list sessions;
153
+ uint32_t n_sessions;
154
+};
155
+
156
+static const struct format_info {
157
+ uint32_t format;
158
+ uint32_t size;
159
+ const char *mime;
160
+} format_info = {
161
+ { SPA_AUDIO_FORMAT_U8, 1, "L8" },
162
+ { SPA_AUDIO_FORMAT_ALAW, 1, "PCMA" },
163
+ { SPA_AUDIO_FORMAT_ULAW, 1, "PCMU" },
164
+ { SPA_AUDIO_FORMAT_S16_BE, 2, "L16" },
165
+ { SPA_AUDIO_FORMAT_S24_BE, 3, "L24" },
166
+};
167
+
168
+static const struct format_info *find_format_info(const char *mime)
169
+{
170
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, f)
171
+ if (spa_streq(f->mime, mime))
172
+ return f;
173
+ return NULL;
174
+}
175
+
176
+struct sdp_info {
177
+ uint16_t hash;
178
+
179
+ char origin128;
180
+ char session256;
181
+
182
+ struct sockaddr_storage sa;
183
+ socklen_t salen;
184
+
185
+ uint16_t port;
186
+ uint8_t payload;
187
+
188
+ const struct format_info *format_info;
189
+ struct spa_audio_info_raw info;
190
+ uint32_t stride;
191
+};
192
+
193
+struct session {
194
+ struct impl *impl;
195
+ struct spa_list link;
196
+
197
+ uint64_t timestamp;
198
+
199
+ struct sdp_info info;
200
+
201
pipewire-0.3.60.tar.gz/src/modules/module-rtp/rtp.h
Added
80
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#ifndef PIPEWIRE_RTP_H
27
+#define PIPEWIRE_RTP_H
28
+
29
+#ifdef __cplusplus
30
+extern "C" {
31
+#endif
32
+
33
+struct rtp_header {
34
+#if __BYTE_ORDER == __LITTLE_ENDIAN
35
+ unsigned cc:4;
36
+ unsigned x:1;
37
+ unsigned p:1;
38
+ unsigned v:2;
39
+
40
+ unsigned pt:7;
41
+ unsigned m:1;
42
+#elif __BYTE_ORDER == __BIG_ENDIAN
43
+ unsigned v:2;
44
+ unsigned p:1;
45
+ unsigned x:1;
46
+ unsigned cc:4;
47
+
48
+ unsigned m:1;
49
+ unsigned pt:7;
50
+#else
51
+#error "Unknown byte order"
52
+#endif
53
+ uint16_t sequence_number;
54
+ uint32_t timestamp;
55
+ uint32_t ssrc;
56
+ uint32_t csrc0;
57
+} __attribute__ ((packed));
58
+
59
+struct rtp_payload {
60
+#if __BYTE_ORDER == __LITTLE_ENDIAN
61
+ unsigned frame_count:4;
62
+ unsigned rfa0:1;
63
+ unsigned is_last_fragment:1;
64
+ unsigned is_first_fragment:1;
65
+ unsigned is_fragmented:1;
66
+#elif __BYTE_ORDER == __BIG_ENDIAN
67
+ unsigned is_fragmented:1;
68
+ unsigned is_first_fragment:1;
69
+ unsigned is_last_fragment:1;
70
+ unsigned rfa0:1;
71
+ unsigned frame_count:4;
72
+#endif
73
+} __attribute__ ((packed));
74
+
75
+#ifdef __cplusplus
76
+}
77
+#endif
78
+
79
+#endif /* PIPEWIRE_RTP_H */
80
pipewire-0.3.60.tar.gz/src/modules/module-rtp/sap.h
Added
60
1
2
+/* PipeWire
3
+ *
4
+ * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com>
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ * DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+#ifndef PIPEWIRE_SAP_H
27
+#define PIPEWIRE_SAP_H
28
+
29
+#ifdef __cplusplus
30
+extern "C" {
31
+#endif
32
+
33
+struct sap_header {
34
+#if __BYTE_ORDER == __LITTLE_ENDIAN
35
+ unsigned c:1;
36
+ unsigned e:1;
37
+ unsigned t:1;
38
+ unsigned r:1;
39
+ unsigned a:1;
40
+ unsigned v:3;
41
+#elif __BYTE_ORDER == __BIG_ENDIAN
42
+ unsigned v:3;
43
+ unsigned a:1;
44
+ unsigned r:1;
45
+ unsigned t:1;
46
+ unsigned e:1;
47
+ unsigned c:1;
48
+#else
49
+#error "Unknown byte order"
50
+#endif
51
+ uint8_t auth_len;
52
+ uint16_t msg_id_hash;
53
+} __attribute__ ((packed));
54
+
55
+#ifdef __cplusplus
56
+}
57
+#endif
58
+
59
+#endif /* PIPEWIRE_SAP_H */
60
pipewire-0.3.59.tar.gz/src/modules/module-x11-bell.c -> pipewire-0.3.60.tar.gz/src/modules/module-x11-bell.c
Changed
10
1
2
if (sample == NULL)
3
sample = "bell-window-system";
4
5
- pw_log_debug("play sample %s", sample);
6
+ pw_log_info("play sample %s", sample);
7
8
if ((res = ca_context_create(&ca)) < 0) {
9
pw_log_error("canberra context create error: %s", ca_strerror(res));
10
pipewire-0.3.59.tar.gz/src/modules/module-zeroconf-discover.c -> pipewire-0.3.60.tar.gz/src/modules/module-zeroconf-discover.c
Changed
32
1
2
* audio to/from remote PulseAudio servers. It also works with
3
* module-protocol-pulse.
4
*
5
- * This module has no options.
6
+ * ## Module Options
7
+ *
8
+ * - `pulse.latency`: the latency to end-to-end latency in milliseconds to
9
+ * maintain (Default 200ms).
10
*
11
* ## Example configuration
12
*
13
14
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
15
#define PW_LOG_TOPIC_DEFAULT mod_topic
16
17
-#define MODULE_USAGE " "
18
+#define MODULE_USAGE "pulse.latency=<latency in msec> "
19
20
static const struct spa_dict_item module_props = {
21
{ PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
22
23
_("%s on %s"), desc, fqdn);
24
}
25
26
+ if ((str = pw_properties_get(impl->properties, "pulse.latency")) != NULL)
27
+ pw_properties_set(props, "pulse.latency", str);
28
+
29
if ((f = open_memstream(&args, &size)) == NULL) {
30
pw_log_error("Can't open memstream: %m");
31
goto done;
32
pipewire-0.3.59.tar.gz/src/pipewire/buffers.c -> pipewire-0.3.60.tar.gz/src/pipewire/buffers.c
Changed
14
1
2
struct port input = { innode, SPA_DIRECTION_INPUT, in_port_id };
3
int res;
4
5
+ if (flags & PW_BUFFERS_FLAG_IN_PRIORITY) {
6
+ struct port tmp = output;
7
+ output = input;
8
+ input = tmp;
9
+ }
10
+
11
res = param_filter(result, &input, &output, SPA_PARAM_Buffers, &b);
12
if (res < 0) {
13
pw_context_debug_port_params(context, input.node, input.direction,
14
pipewire-0.3.59.tar.gz/src/pipewire/buffers.h -> pipewire-0.3.60.tar.gz/src/pipewire/buffers.h
Changed
9
1
2
#define PW_BUFFERS_FLAG_SHARED (1<<1) /**< buffers can be shared */
3
#define PW_BUFFERS_FLAG_DYNAMIC (1<<2) /**< buffers have dynamic data */
4
#define PW_BUFFERS_FLAG_SHARED_MEM (1<<3) /**< buffers need shared memory */
5
+#define PW_BUFFERS_FLAG_IN_PRIORITY (1<<4) /**< input parameters have priority */
6
7
struct pw_buffers {
8
struct pw_memblock *mem; /**< allocated buffer memory */
9
pipewire-0.3.59.tar.gz/src/pipewire/context.c -> pipewire-0.3.60.tar.gz/src/pipewire/context.c
Changed
36
1
2
return fa < fb ? -1 : (fa > fb ? 1 : 0);
3
}
4
5
-static bool rates_contains(uint32_t *rates, uint32_t n_rates, uint32_t rate)
6
+static uint32_t find_best_rate(uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t best)
7
{
8
uint32_t i;
9
- for (i = 0; i < n_rates; i++)
10
- if (ratesi == rate)
11
- return true;
12
- return false;
13
+ for (i = 0; i < n_rates; i++) {
14
+ if (SPA_ABS((int32_t)rate - (int32_t)ratesi) <
15
+ SPA_ABS((int32_t)rate - (int32_t)best))
16
+ best = ratesi;
17
+ }
18
+ return best;
19
}
20
21
/* here we evaluate the complete state of the graph.
22
23
* Start with the default rate. If the desired rate is
24
* allowed, switch to it */
25
target_rate = def_rate;
26
- if (rate.denom != 0 && rate.num == 1) {
27
- if (rates_contains(rates, n_rates, rate.denom))
28
- target_rate = rate.denom;
29
- }
30
+ if (rate.denom != 0 && rate.num == 1)
31
+ target_rate = find_best_rate(rates, n_rates,
32
+ rate.denom, target_rate);
33
}
34
35
if (target_rate != current_rate) {
36
pipewire-0.3.59.tar.gz/src/pipewire/filter.c -> pipewire-0.3.60.tar.gz/src/pipewire/filter.c
Changed
22
1
2
spa_list_for_each(p, param_list, link) {
3
struct spa_pod *param;
4
5
- result.index = result.next++;
6
- if (result.index < start)
7
- continue;
8
-
9
param = p->param;
10
if (param == NULL || p->id != id)
11
continue;
12
13
found = true;
14
15
+ result.index = result.next++;
16
+ if (result.index < start)
17
+ continue;
18
+
19
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
20
if (spa_pod_filter(&b.b, &result.param, param, filter) == 0) {
21
spa_node_emit_result(&d->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
22
pipewire-0.3.59.tar.gz/src/pipewire/impl-device.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-device.c
Changed
42
1
2
3
if (d->end != -1) {
4
if (d->pi && d->data.cache) {
5
- pw_param_update(&impl->param_list, &impl->pending_list);
6
+ pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL);
7
d->pi->user = 1;
8
d->pi = NULL;
9
}
10
11
if (d->cache) {
12
pw_log_debug("%p: add param %d", impl, r->id);
13
if (d->count++ == 0)
14
- pw_param_add(&impl->pending_list, r->id, NULL);
15
- pw_param_add(&impl->pending_list, r->id, r->param);
16
+ pw_param_add(&impl->pending_list, seq, r->id, NULL);
17
+ pw_param_add(&impl->pending_list, seq, r->id, r->param);
18
}
19
break;
20
}
21
22
result.next = 0;
23
24
spa_list_for_each(p, &impl->param_list, link) {
25
- result.index = result.next++;
26
if (p->id != param_id)
27
continue;
28
29
+ result.index = result.next++;
30
if (result.index < index)
31
continue;
32
33
34
spa_hook_remove(&listener);
35
36
if (!SPA_RESULT_IS_ASYNC(res) && user_data.cache) {
37
- pw_param_update(&impl->param_list, &impl->pending_list);
38
+ pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL);
39
pi->user = 1;
40
}
41
}
42
pipewire-0.3.59.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-link.c
Changed
21
1
2
if (output->node->remote || input->node->remote)
3
alloc_flags |= PW_BUFFERS_FLAG_SHARED_MEM;
4
5
+ if (output->node->driver)
6
+ alloc_flags |= PW_BUFFERS_FLAG_IN_PRIORITY;
7
+
8
/* if output port can alloc buffers, alloc skeleton buffers */
9
if (SPA_FLAG_IS_SET(out_flags, SPA_PORT_FLAG_CAN_ALLOC_BUFFERS)) {
10
SPA_FLAG_SET(alloc_flags, PW_BUFFERS_FLAG_NO_MEM);
11
12
pw_log_debug("%p: activate activated:%d state:%s", this, impl->activated,
13
pw_link_state_as_string(this->info.state));
14
15
- if (impl->activated || !this->prepared || !impl->inode->added || !impl->onode->active)
16
+ if (impl->activated || !this->prepared || !impl->inode->active ||
17
+ !impl->inode->added || !impl->onode->active)
18
return 0;
19
20
if (!impl->io_set) {
21
pipewire-0.3.59.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-node.c
Changed
128
1
2
this->rt.driver_target.node = NULL;
3
}
4
5
-static int
6
-do_node_remove(struct spa_loop *loop,
7
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
8
-{
9
- struct pw_impl_node *this = user_data;
10
- if (this->source.loop != NULL) {
11
- spa_loop_remove_source(loop, &this->source);
12
- remove_node(this);
13
- }
14
- this->added = false;
15
- return 0;
16
-}
17
-
18
static void node_deactivate(struct pw_impl_node *this)
19
{
20
struct pw_impl_port *port;
21
22
spa_list_for_each(link, &port->links, output_link)
23
pw_impl_link_deactivate(link);
24
}
25
- pw_loop_invoke(this->data_loop, do_node_remove, 1, NULL, 0, true, this);
26
}
27
28
static int idle_node(struct pw_impl_node *this)
29
30
return 0;
31
}
32
33
+static int
34
+do_node_remove(struct spa_loop *loop,
35
+ bool async, uint32_t seq, const void *data, size_t size, void *user_data)
36
+{
37
+ struct pw_impl_node *this = user_data;
38
+ if (this->source.loop != NULL) {
39
+ spa_loop_remove_source(loop, &this->source);
40
+ remove_node(this);
41
+ }
42
+ this->added = false;
43
+ return 0;
44
+}
45
+
46
static void node_update_state(struct pw_impl_node *node, enum pw_node_state state, int res, char *error)
47
{
48
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
49
50
pw_log_debug("%p: start node driving:%d driver:%d added:%d", node,
51
node->driving, node->driver, node->added);
52
53
+ if (res >= 0) {
54
+ pw_loop_invoke(node->data_loop, do_node_add, 1, NULL, 0, true, node);
55
+ }
56
if (node->driving && node->driver) {
57
res = spa_node_send_command(node->node,
58
&SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Start));
59
if (res < 0) {
60
state = PW_NODE_STATE_ERROR;
61
error = spa_aprintf("Start error: %s", spa_strerror(res));
62
+ pw_loop_invoke(node->data_loop, do_node_remove, 1, NULL, 0, true, node);
63
}
64
}
65
if (res >= 0) {
66
- pw_loop_invoke(node->data_loop, do_node_add, 1, NULL, 0, true, node);
67
/* now activate the inputs */
68
node_activate_inputs(node);
69
}
70
break;
71
+ case PW_NODE_STATE_IDLE:
72
+ case PW_NODE_STATE_SUSPENDED:
73
+ case PW_NODE_STATE_ERROR:
74
+ if (state != PW_NODE_STATE_IDLE || impl->pause_on_idle)
75
+ pw_loop_invoke(node->data_loop, do_node_remove, 1, NULL, 0, true, node);
76
+ break;
77
default:
78
break;
79
}
80
81
struct pw_node_target *t;
82
struct pw_impl_port *p;
83
84
- pw_log_trace_fp("%p: ready driver:%d exported:%d %p status:%d", node,
85
- node->driver, node->exported, driver, status);
86
+ pw_log_trace_fp("%p: ready driver:%d exported:%d %p status:%d added:%d", node,
87
+ node->driver, node->exported, driver, status, node->added);
88
+
89
+ if (!node->added) {
90
+ pw_log_warn("%p: ready non-active node", node);
91
+ return -EIO;
92
+ }
93
94
if (SPA_UNLIKELY(node == driver)) {
95
struct pw_node_activation *a = node->rt.activation;
96
97
d->callback(d->data, seq, r->id, r->index, r->next, r->param);
98
if (d->cache) {
99
if (d->count++ == 0)
100
- pw_param_add(&impl->pending_list, r->id, NULL);
101
- pw_param_add(&impl->pending_list, r->id, r->param);
102
+ pw_param_add(&impl->pending_list, seq, r->id, NULL);
103
+ pw_param_add(&impl->pending_list, seq, r->id, r->param);
104
}
105
}
106
break;
107
108
result.next = 0;
109
110
spa_list_for_each(p, &impl->param_list, link) {
111
- result.index = result.next++;
112
if (p->id != param_id)
113
continue;
114
115
+ result.index = result.next++;
116
if (result.index < index)
117
continue;
118
119
120
spa_hook_remove(&listener);
121
122
if (user_data.cache) {
123
- pw_param_update(&impl->param_list, &impl->pending_list);
124
+ pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL);
125
pi->user = 1;
126
}
127
}
128
pipewire-0.3.59.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-port.c
Changed
33
1
2
d->callback(d->data, seq, r->id, r->index, r->next, r->param);
3
if (d->cache) {
4
if (d->count++ == 0)
5
- pw_param_add(&impl->pending_list, r->id, NULL);
6
- pw_param_add(&impl->pending_list, r->id, r->param);
7
+ pw_param_add(&impl->pending_list, seq, r->id, NULL);
8
+ pw_param_add(&impl->pending_list, seq, r->id, r->param);
9
}
10
}
11
break;
12
13
result.next = 0;
14
15
spa_list_for_each(p, &impl->param_list, link) {
16
- result.index = result.next++;
17
if (p->id != param_id)
18
continue;
19
20
+ result.index = result.next++;
21
if (result.index < index)
22
continue;
23
24
25
spa_hook_remove(&listener);
26
27
if (user_data.cache) {
28
- pw_param_update(&impl->param_list, &impl->pending_list);
29
+ pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL);
30
pi->user = 1;
31
}
32
}
33
pipewire-0.3.59.tar.gz/src/pipewire/introspect.c -> pipewire-0.3.60.tar.gz/src/pipewire/introspect.c
Changed
103
1
2
info->props = pw_spa_dict_copy(update->props);
3
}
4
if (update->change_mask & PW_NODE_CHANGE_MASK_PARAMS) {
5
- uint32_t i, user, n_params = update->n_params;
6
+ uint32_t i, n_params = update->n_params;
7
void *np;
8
9
np = pw_reallocarray(info->params, n_params, sizeof(struct spa_param_info));
10
11
info->params = np;
12
13
for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) {
14
- user = reset ? 0 : info->paramsi.user;
15
- if (info->paramsi.flags != update->paramsi.flags)
16
- user++;
17
- info->paramsi = update->paramsi;
18
- info->paramsi.user = user;
19
+ info->paramsi.id = update->paramsi.id;
20
+ if (reset)
21
+ info->paramsi.user = 0;
22
+ if (info->paramsi.flags != update->paramsi.flags) {
23
+ info->paramsi.flags = update->paramsi.flags;
24
+ info->paramsi.user++;
25
+ }
26
}
27
info->n_params = n_params;
28
for (; i < info->n_params; i++) {
29
- info->paramsi = update->paramsi;
30
+ info->paramsi.id = update->paramsi.id;
31
+ info->paramsi.flags = update->paramsi.flags;
32
info->paramsi.user = 1;
33
}
34
}
35
36
info->props = pw_spa_dict_copy(update->props);
37
}
38
if (update->change_mask & PW_PORT_CHANGE_MASK_PARAMS) {
39
- uint32_t i, user, n_params = update->n_params;
40
+ uint32_t i, n_params = update->n_params;
41
void *np;
42
43
np = pw_reallocarray(info->params, n_params, sizeof(struct spa_param_info));
44
45
info->params = np;
46
47
for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) {
48
- user = reset ? 0 : info->paramsi.user;
49
- if (info->paramsi.flags != update->paramsi.flags)
50
- user++;
51
- info->paramsi = update->paramsi;
52
- info->paramsi.user = user;
53
+ info->paramsi.id = update->paramsi.id;
54
+ if (reset)
55
+ info->paramsi.user = 0;
56
+ if (info->paramsi.flags != update->paramsi.flags) {
57
+ info->paramsi.flags = update->paramsi.flags;
58
+ info->paramsi.user++;
59
+ }
60
}
61
info->n_params = n_params;
62
for (; i < info->n_params; i++) {
63
- info->paramsi = update->paramsi;
64
+ info->paramsi.id = update->paramsi.id;
65
+ info->paramsi.flags = update->paramsi.flags;
66
info->paramsi.user = 1;
67
}
68
}
69
70
info->props = pw_spa_dict_copy(update->props);
71
}
72
if (update->change_mask & PW_DEVICE_CHANGE_MASK_PARAMS) {
73
- uint32_t i, user, n_params = update->n_params;
74
+ uint32_t i, n_params = update->n_params;
75
void *np;
76
77
np = pw_reallocarray(info->params, n_params, sizeof(struct spa_param_info));
78
79
info->params = np;
80
81
for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) {
82
- user = reset ? 0 : info->paramsi.user;
83
- if (info->paramsi.flags != update->paramsi.flags)
84
- user++;
85
- info->paramsi = update->paramsi;
86
- info->paramsi.user = user;
87
+ info->paramsi.id = update->paramsi.id;
88
+ if (reset)
89
+ info->paramsi.user = 0;
90
+ if (info->paramsi.flags != update->paramsi.flags) {
91
+ info->paramsi.flags = update->paramsi.flags;
92
+ info->paramsi.user++;
93
+ }
94
}
95
info->n_params = n_params;
96
for (; i < info->n_params; i++) {
97
- info->paramsi = update->paramsi;
98
+ info->paramsi.id = update->paramsi.id;
99
+ info->paramsi.flags = update->paramsi.flags;
100
info->paramsi.user = 1;
101
}
102
}
103
pipewire-0.3.59.tar.gz/src/pipewire/private.h -> pipewire-0.3.60.tar.gz/src/pipewire/private.h
Changed
51
1
2
3
struct pw_param {
4
uint32_t id;
5
+ int32_t seq;
6
struct spa_list link;
7
struct spa_pod *param;
8
};
9
10
return count;
11
}
12
13
-static inline struct pw_param *pw_param_add(struct spa_list *params,
14
+static inline struct pw_param *pw_param_add(struct spa_list *params, int32_t seq,
15
uint32_t id, const struct spa_pod *param)
16
{
17
struct pw_param *p;
18
19
return NULL;
20
21
p->id = id;
22
+ p->seq = seq;
23
if (param != NULL) {
24
p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod);
25
memcpy(p->param, param, SPA_POD_SIZE(param));
26
27
return p;
28
}
29
30
-static inline void pw_param_update(struct spa_list *param_list, struct spa_list *pending_list)
31
+static inline void pw_param_update(struct spa_list *param_list, struct spa_list *pending_list,
32
+ uint32_t n_params, struct spa_param_info *params)
33
{
34
- struct pw_param *p;
35
+ struct pw_param *p, *t;
36
+ uint32_t i;
37
38
+ for (i = 0; i < n_params; i++) {
39
+ spa_list_for_each_safe(p, t, pending_list, link) {
40
+ if (p->id == paramsi.id &&
41
+ p->seq != paramsi.seq &&
42
+ p->param != NULL) {
43
+ spa_list_remove(&p->link);
44
+ free(p);
45
+ }
46
+ }
47
+ }
48
spa_list_consume(p, pending_list, link) {
49
spa_list_remove(&p->link);
50
if (p->param == NULL) {
51
pipewire-0.3.59.tar.gz/src/pipewire/stream.c -> pipewire-0.3.60.tar.gz/src/pipewire/stream.c
Changed
31
1
2
spa_list_for_each(p, &d->param_list, link) {
3
struct spa_pod *param;
4
5
- result.index = result.next++;
6
- if (result.index < start)
7
- continue;
8
-
9
param = p->param;
10
if (param == NULL || p->id != id)
11
continue;
12
13
found = true;
14
15
+ result.index = result.next++;
16
+ if (result.index < start)
17
+ continue;
18
+
19
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
20
if (spa_pod_filter(&b.b, &result.param, param, filter) == 0) {
21
spa_node_emit_result(&d->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
22
23
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
24
pw_loop_invoke(impl->context->data_loop,
25
drain ? do_drain : do_flush, 1, NULL, 0, true, impl);
26
- if (!drain)
27
+ if (!drain && impl->node != NULL)
28
spa_node_send_command(impl->node->node,
29
&SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Flush));
30
return 0;
31
pipewire-0.3.59.tar.gz/src/pipewire/thread.c -> pipewire-0.3.60.tar.gz/src/pipewire/thread.c
Changed
30
1
2
*max = sched_get_priority_max(SCHED_OTHER);
3
return 0;
4
}
5
+static int impl_acquire_rt(void *object, struct spa_thread *thread, int priority)
6
+{
7
+ pw_log_warn("acquire_rt thread:%p prio:%d not implemented", thread, priority);
8
+ return -ENOTSUP;
9
+}
10
+
11
+static int impl_drop_rt(void *object, struct spa_thread *thread)
12
+{
13
+ pw_log_warn("drop_rt thread:%p not implemented", thread);
14
+ return -ENOTSUP;
15
+}
16
17
static struct {
18
struct spa_thread_utils utils;
19
20
{ SPA_VERSION_THREAD_UTILS_METHODS,
21
.create = impl_create,
22
.join = impl_join,
23
- .get_rt_range = impl_get_rt_range
24
+ .get_rt_range = impl_get_rt_range,
25
+ .acquire_rt = impl_acquire_rt,
26
+ .drop_rt = impl_drop_rt,
27
}
28
};
29
30
pipewire-0.3.59.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.60.tar.gz/src/tools/pw-cat.c
Changed
65
1
2
3
static const struct format_info *format_info_by_name(const char *str)
4
{
5
- uint32_t i;
6
- for (i = 0; i < SPA_N_ELEMENTS(format_info); i++)
7
- if (spa_streq(str, format_infoi.name))
8
- return &format_infoi;
9
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, i)
10
+ if (spa_streq(str, i->name))
11
+ return i;
12
return NULL;
13
}
14
15
static const struct format_info *format_info_by_sf_format(int format)
16
{
17
- uint32_t i;
18
int sub_type = (format & SF_FORMAT_SUBMASK);
19
- for (i = 0; i < SPA_N_ELEMENTS(format_info); i++)
20
- if (format_infoi.sf_format == sub_type)
21
- return &format_infoi;
22
+ SPA_FOR_EACH_ELEMENT_VAR(format_info, i)
23
+ if (i->sf_format == sub_type)
24
+ return i;
25
return NULL;
26
}
27
28
29
int i, nch;
30
char **ch;
31
32
- for (i = 0; i < (int) SPA_N_ELEMENTS(maps); i++) {
33
- if (spa_streq(mapsi.name, channel_map)) {
34
- map->n_channels = mapsi.channels;
35
- spa_memcpy(map->channels, &mapsi.values,
36
+ SPA_FOR_EACH_ELEMENT_VAR(maps, m) {
37
+ if (spa_streq(m->name, channel_map)) {
38
+ map->n_channels = m->channels;
39
+ spa_memcpy(map->channels, &m->values,
40
map->n_channels * sizeof(unsigned int));
41
return 0;
42
}
43
44
case TYPE_DSD:
45
{
46
struct spa_audio_info_dsd info;
47
- size_t i;
48
49
spa_zero(info);
50
info.channels = data.dsf.info.channels;
51
info.rate = data.dsf.info.rate / 8;
52
53
- for (i = 0; i < SPA_N_ELEMENTS(dsd_layouts); i++) {
54
- if (dsd_layoutsi.type != data.dsf.info.channel_type)
55
+ SPA_FOR_EACH_ELEMENT_VAR(dsd_layouts, i) {
56
+ if (i->type != data.dsf.info.channel_type)
57
continue;
58
- info.channels = dsd_layoutsi.info.n_channels;
59
- memcpy(info.position, dsd_layoutsi.info.position,
60
+ info.channels = i->info.n_channels;
61
+ memcpy(info.position, i->info.position,
62
info.channels * sizeof(uint32_t));
63
}
64
params0 = spa_format_audio_dsd_build(&b, SPA_PARAM_EnumFormat, &info);
65
pipewire-0.3.59.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.60.tar.gz/src/tools/pw-cli.c
Changed
74
1
2
3
static bool do_help(struct data *data, const char *cmd, char *args, char **error)
4
{
5
- size_t i;
6
-
7
printf("Available commands:\n");
8
- for (i = 0; i < SPA_N_ELEMENTS(command_list); i++) {
9
+ SPA_FOR_EACH_ELEMENT_VAR(command_list, c) {
10
char cmd256;
11
- snprintf(cmd, sizeof(cmd), "%s | %s",
12
- command_listi.name, command_listi.alias);
13
- printf("\t%-20.20s\t%s\n", cmd, command_listi.description);
14
+ snprintf(cmd, sizeof(cmd), "%s | %s", c->name, c->alias);
15
+ printf("\t%-20.20s\t%s\n", cmd, c->description);
16
}
17
return true;
18
}
19
20
21
static const struct class *find_class(const char *type, uint32_t version)
22
{
23
- size_t i;
24
- for (i = 0; i < SPA_N_ELEMENTS(classes); i++) {
25
- if (spa_streq(classesi->type, type) &&
26
- classesi->version <= version)
27
- return classesi;
28
+ SPA_FOR_EACH_ELEMENT_VAR(classes, c) {
29
+ if (spa_streq((*c)->type, type) &&
30
+ (*c)->version <= version)
31
+ return *c;
32
}
33
return NULL;
34
}
35
36
{
37
char *a2;
38
int n;
39
- size_t i;
40
char *p, *cmd, *args;
41
42
if ((p = strchr(buf, '#')))
43
44
cmd = a0;
45
args = n > 1 ? a1 : "";
46
47
- for (i = 0; i < SPA_N_ELEMENTS(command_list); i++) {
48
- if (spa_streq(command_listi.name, cmd) ||
49
- spa_streq(command_listi.alias, cmd)) {
50
- return command_listi.func(data, cmd, args, error);
51
+ SPA_FOR_EACH_ELEMENT_VAR(command_list, c) {
52
+ if (spa_streq(c->name, cmd) ||
53
+ spa_streq(c->alias, cmd)) {
54
+ return c->func(data, cmd, args, error);
55
}
56
}
57
*error = spa_aprintf("Command \"%s\" does not exist. Type 'help' for usage.", cmd);
58
59
return matches;
60
}
61
62
-static void readline_init()
63
+static void readline_init(void)
64
{
65
rl_attempted_completion_function = readline_command_completion;
66
rl_callback_handler_install(">> ", input_process_line);
67
}
68
69
-static void readline_cleanup()
70
+static void readline_cleanup(void)
71
{
72
rl_callback_handler_remove();
73
}
74
pipewire-0.3.59.tar.gz/src/tools/pw-dot.c -> pipewire-0.3.60.tar.gz/src/tools/pw-dot.c
Changed
10
1
2
struct spa_hook object_listener;
3
};
4
5
-static char *dot_str_new()
6
+static char *dot_str_new(void)
7
{
8
return strdup("");
9
}
10
pipewire-0.3.59.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.60.tar.gz/src/tools/pw-dump.c
Changed
201
1
2
3
struct param {
4
uint32_t id;
5
+ int32_t seq;
6
struct spa_list link;
7
struct spa_pod *param;
8
};
9
10
11
const struct class *class;
12
void *info;
13
+ struct spa_param_info *params;
14
+ uint32_t n_params;
15
16
int changed;
17
struct spa_list param_list;
18
19
return count;
20
}
21
22
-static struct param *add_param(struct spa_list *params, uint32_t id, const struct spa_pod *param)
23
+static struct param *add_param(struct spa_list *params, int seq,
24
+ uint32_t id, const struct spa_pod *param)
25
{
26
struct param *p;
27
28
29
return NULL;
30
31
p->id = id;
32
+ p->seq = seq;
33
if (param != NULL) {
34
p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod);
35
memcpy(p->param, param, SPA_POD_SIZE(param));
36
37
return NULL;
38
}
39
40
-static void object_update_params(struct object *o)
41
+static void object_update_params(struct spa_list *param_list, struct spa_list *pending_list,
42
+ uint32_t n_params, struct spa_param_info *params)
43
{
44
- struct param *p;
45
+ struct param *p, *t;
46
+ uint32_t i;
47
+
48
+ for (i = 0; i < n_params; i++) {
49
+ spa_list_for_each_safe(p, t, pending_list, link) {
50
+ if (p->id == paramsi.id &&
51
+ p->seq != paramsi.seq &&
52
+ p->param != NULL) {
53
+ spa_list_remove(&p->link);
54
+ free(p);
55
+ }
56
+ }
57
+ }
58
59
- spa_list_consume(p, &o->pending_list, link) {
60
+ spa_list_consume(p, pending_list, link) {
61
spa_list_remove(&p->link);
62
if (p->param == NULL) {
63
- clear_params(&o->param_list, p->id);
64
+ clear_params(param_list, p->id);
65
free(p);
66
} else {
67
- spa_list_append(&o->param_list, &p->link);
68
+ spa_list_append(param_list, &p->link);
69
}
70
}
71
}
72
73
struct object *o = data;
74
int changed = 0;
75
76
- pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
77
+ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
78
79
- info = o->info = pw_client_info_update(o->info, info);
80
+ info = o->info = pw_client_info_update(o->info, info);
81
+ if (info == NULL)
82
+ return;
83
84
if (info->change_mask & PW_CLIENT_CHANGE_MASK_PROPS)
85
changed++;
86
87
88
static void module_event_info(void *data, const struct pw_module_info *info)
89
{
90
- struct object *o = data;
91
+ struct object *o = data;
92
int changed = 0;
93
94
- pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
95
+ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
96
97
- info = o->info = pw_module_info_update(o->info, info);
98
+ info = o->info = pw_module_info_update(o->info, info);
99
+ if (info == NULL)
100
+ return;
101
102
if (info->change_mask & PW_MODULE_CHANGE_MASK_PROPS)
103
changed++;
104
105
106
static void factory_event_info(void *data, const struct pw_factory_info *info)
107
{
108
- struct object *o = data;
109
+ struct object *o = data;
110
int changed = 0;
111
112
- pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
113
+ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
114
115
- info = o->info = pw_factory_info_update(o->info, info);
116
+ info = o->info = pw_factory_info_update(o->info, info);
117
+ if (info == NULL)
118
+ return;
119
120
if (info->change_mask & PW_FACTORY_CHANGE_MASK_PROPS)
121
changed++;
122
123
{
124
struct object *o = data;
125
uint32_t i, changed = 0;
126
+ int res;
127
128
pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
129
130
info = o->info = pw_device_info_update(o->info, info);
131
+ if (info == NULL)
132
+ return;
133
+
134
+ o->params = info->params;
135
+ o->n_params = info->n_params;
136
137
if (info->change_mask & PW_DEVICE_CHANGE_MASK_PROPS)
138
changed++;
139
140
info->paramsi.user = 0;
141
142
changed++;
143
- clear_params(&o->pending_list, id);
144
+ add_param(&o->pending_list, 0, id, NULL);
145
if (!(info->paramsi.flags & SPA_PARAM_INFO_READ))
146
continue;
147
148
- pw_device_enum_params((struct pw_device*)o->proxy,
149
- 0, id, 0, -1, NULL);
150
+ res = pw_device_enum_params((struct pw_device*)o->proxy,
151
+ ++info->paramsi.seq, id, 0, -1, NULL);
152
+ if (SPA_RESULT_IS_ASYNC(res))
153
+ info->paramsi.seq = res;
154
}
155
}
156
if (changed) {
157
158
const struct spa_pod *param)
159
{
160
struct object *o = data;
161
- add_param(&o->pending_list, id, param);
162
+ add_param(&o->pending_list, seq, id, param);
163
}
164
165
static const struct pw_device_events device_events = {
166
167
{
168
struct object *o = data;
169
uint32_t i, changed = 0;
170
+ int res;
171
172
pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask);
173
174
info = o->info = pw_node_info_update(o->info, info);
175
+ if (info == NULL)
176
+ return;
177
+
178
+ o->params = info->params;
179
+ o->n_params = info->n_params;
180
181
if (info->change_mask & PW_NODE_CHANGE_MASK_STATE)
182
changed++;
183
184
info->paramsi.user = 0;
185
186
changed++;
187
- add_param(&o->pending_list, id, NULL);
188
+ add_param(&o->pending_list, 0, id, NULL);
189
if (!(info->paramsi.flags & SPA_PARAM_INFO_READ))
190
continue;
191
192
- pw_node_enum_params((struct pw_node*)o->proxy,
193
- 0, id, 0, -1, NULL);
194
+ res = pw_node_enum_params((struct pw_node*)o->proxy,
195
+ ++info->paramsi.seq, id, 0, -1, NULL);
196
+ if (SPA_RESULT_IS_ASYNC(res))
197
+ info->paramsi.seq = res;
198
}
199
}
200
if (changed) {
201
pipewire-0.3.59.tar.gz/src/tools/pw-link.c -> pipewire-0.3.60.tar.gz/src/tools/pw-link.c
Changed
30
1
2
struct object *port_out = find_node_port(data, out_node, PW_DIRECTION_OUTPUT, port_id);
3
struct object *port_in = find_node_port(data, in_node, PW_DIRECTION_INPUT, port_id);
4
5
- if (!port_out || !port_in)
6
- break;
7
+ if (!port_out && !port_in) {
8
+ fprintf(stderr, "Input & output port do not exist\n");
9
+ goto no_port;
10
+ } else if (!port_in) {
11
+ fprintf(stderr, "Input port does not exist\n");
12
+ goto no_port;
13
+ } else if (!port_out) {
14
+ fprintf(stderr, "Output port does not exist\n");
15
+ goto no_port;
16
+ }
17
18
pw_properties_setf(data->props, PW_KEY_LINK_OUTPUT_PORT, "%u", port_out->id);
19
pw_properties_setf(data->props, PW_KEY_LINK_INPUT_PORT, "%u", port_in->id);
20
21
pw_properties_setf(data->props, PW_KEY_LINK_INPUT_PORT, "%u", in_port);
22
23
return create_link(data);
24
+
25
+no_port:
26
+ return -ENOENT;
27
}
28
29
static int do_unlink_ports(struct data *data)
30
pipewire-0.3.59.tar.gz/src/tools/pw-loopback.c -> pipewire-0.3.60.tar.gz/src/tools/pw-loopback.c
Changed
63
1
2
3
uint32_t channels;
4
uint32_t latency;
5
+ float delay;
6
7
struct pw_properties *capture_props;
8
struct pw_properties *playback_props;
9
10
" -c, --channels Number of channels (default %d)\n"
11
" -m, --channel-map Channel map (default '%s')\n"
12
" -l, --latency Desired latency in ms\n"
13
+ " -d, --delay Desired delay in float s\n"
14
" -C --capture Capture source to connect to\n"
15
" --capture-props Capture stream properties\n"
16
" -P --playback Playback sink to connect to\n"
17
18
struct data data = { 0 };
19
struct pw_loop *l;
20
const char *opt_remote = NULL;
21
- char cname256;
22
+ char cname256, value256;
23
char *args;
24
size_t size;
25
FILE *f;
26
27
{ "name", required_argument, NULL, 'n' },
28
{ "channels", required_argument, NULL, 'c' },
29
{ "latency", required_argument, NULL, 'l' },
30
+ { "delay", required_argument, NULL, 'd' },
31
{ "capture", required_argument, NULL, 'C' },
32
{ "playback", required_argument, NULL, 'P' },
33
{ "capture-props", required_argument, NULL, 'i' },
34
35
goto exit;
36
}
37
38
- while ((c = getopt_long(argc, argv, "hVr:n:g:c:m:l:C:P:i:o:", long_options, NULL)) != -1) {
39
+ while ((c = getopt_long(argc, argv, "hVr:n:g:c:m:l:d:C:P:i:o:", long_options, NULL)) != -1) {
40
switch (c) {
41
case 'h':
42
show_help(&data, argv0, false);
43
44
case 'l':
45
data.latency = atoi(optarg) * DEFAULT_RATE / SPA_MSEC_PER_SEC;
46
break;
47
+ case 'd':
48
+ data.delay = atof(optarg);
49
+ break;
50
case 'C':
51
pw_properties_set(data.capture_props, PW_KEY_NODE_TARGET, optarg);
52
break;
53
54
fprintf(f, " remote.name = \"%s\"", opt_remote);
55
if (data.latency != 0)
56
fprintf(f, " node.latency = %u/%u", data.latency, DEFAULT_RATE);
57
+ if (data.delay != 0.0f)
58
+ fprintf(f, " target.delay.sec = %s",
59
+ spa_json_format_float(value, sizeof(value), data.delay));
60
if (data.channels != 0)
61
fprintf(f, " audio.channels = %u", data.channels);
62
if (data.opt_channel_map != NULL)
63
pipewire-0.3.59.tar.gz/src/tools/pw-top.c -> pipewire-0.3.60.tar.gz/src/tools/pw-top.c
Changed
201
1
2
3
struct node {
4
struct spa_list link;
5
+ struct data *data;
6
uint32_t id;
7
char nameMAX_NAME+1;
8
+ enum pw_node_state state;
9
struct measurement measurement;
10
struct driver info;
11
struct node *driver;
12
13
char formatMAX_FORMAT+1;
14
struct pw_proxy *proxy;
15
struct spa_hook proxy_listener;
16
+ unsigned int inactive:1;
17
struct spa_hook object_listener;
18
};
19
20
21
int n_nodes;
22
struct spa_list node_list;
23
uint32_t generation;
24
+ unsigned pending_refresh:1;
25
26
WINDOW *win;
27
};
28
29
.destroy = on_node_destroy,
30
};
31
32
+static void do_refresh(struct data *d);
33
+
34
+static void node_info(void *data, const struct pw_node_info *info)
35
+{
36
+ struct node *n = data;
37
+
38
+ if (n->state != info->state) {
39
+ n->state = info->state;
40
+ do_refresh(n->data);
41
+ }
42
+}
43
+
44
static void node_param(void *data, int seq,
45
uint32_t id, uint32_t index, uint32_t next,
46
const struct spa_pod *param)
47
{
48
struct node *n = data;
49
50
+ if (param == NULL) {
51
+ spa_zero(n->format);
52
+ goto done;
53
+ }
54
+
55
switch (id) {
56
case SPA_PARAM_Format:
57
{
58
59
switch(media_subtype) {
60
case SPA_MEDIA_SUBTYPE_raw:
61
{
62
- struct spa_audio_info_raw info;
63
+ struct spa_audio_info_raw info = { 0 };
64
if (spa_format_audio_raw_parse(param, &info) >= 0) {
65
snprintf(n->format, sizeof(n->format), "%6.6s %d %d",
66
- spa_debug_type_find_short_name(spa_type_audio_format, info.format),
67
+ spa_debug_type_find_short_name(
68
+ spa_type_audio_format, info.format),
69
info.channels, info.rate);
70
}
71
break;
72
}
73
case SPA_MEDIA_SUBTYPE_dsd:
74
{
75
- struct spa_audio_info_dsd info;
76
+ struct spa_audio_info_dsd info = { 0 };
77
if (spa_format_audio_dsd_parse(param, &info) >= 0) {
78
snprintf(n->format, sizeof(n->format), "DSD%d %d ",
79
8 * info.rate / 44100, info.channels);
80
81
}
82
break;
83
}
84
+ case SPA_MEDIA_SUBTYPE_iec958:
85
+ {
86
+ struct spa_audio_info_iec958 info = { 0 };
87
+ if (spa_format_audio_iec958_parse(param, &info) >= 0) {
88
+ snprintf(n->format, sizeof(n->format), "IEC958 %s %d",
89
+ spa_debug_type_find_short_name(
90
+ spa_type_audio_iec958_codec, info.codec),
91
+ info.rate);
92
+
93
+ }
94
+ break;
95
+ }
96
}
97
break;
98
case SPA_MEDIA_TYPE_video:
99
switch(media_subtype) {
100
case SPA_MEDIA_SUBTYPE_raw:
101
{
102
- struct spa_video_info_raw info;
103
+ struct spa_video_info_raw info = { 0 };
104
if (spa_format_video_raw_parse(param, &info) >= 0) {
105
snprintf(n->format, sizeof(n->format), "%6.6s %dx%d",
106
spa_debug_type_find_short_name(spa_type_video_format, info.format),
107
108
}
109
break;
110
}
111
+ case SPA_MEDIA_SUBTYPE_mjpg:
112
+ {
113
+ struct spa_video_info_mjpg info = { 0 };
114
+ if (spa_format_video_mjpg_parse(param, &info) >= 0) {
115
+ snprintf(n->format, sizeof(n->format), "MJPG %dx%d",
116
+ info.size.width, info.size.height);
117
+ }
118
+ break;
119
+ }
120
+ case SPA_MEDIA_SUBTYPE_h264:
121
+ {
122
+ struct spa_video_info_h264 info = { 0 };
123
+ if (spa_format_video_h264_parse(param, &info) >= 0) {
124
+ snprintf(n->format, sizeof(n->format), "H264 %dx%d",
125
+ info.size.width, info.size.height);
126
+ }
127
+ break;
128
+ }
129
}
130
break;
131
case SPA_MEDIA_TYPE_application:
132
133
default:
134
break;
135
}
136
+done:
137
+ do_refresh(n->data);
138
}
139
140
static const struct pw_node_events node_events = {
141
PW_VERSION_NODE,
142
+ .info = node_info,
143
.param = node_param,
144
};
145
146
147
strncpy(n->name, name, MAX_NAME);
148
else
149
snprintf(n->name, sizeof(n->name), "%u", id);
150
+ n->data = d;
151
n->id = id;
152
n->driver = n;
153
n->proxy = pw_registry_bind(d->registry, id, PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, 0);
154
155
}
156
spa_list_append(&d->node_list, &n->link);
157
d->n_nodes++;
158
+ d->pending_refresh = true;
159
160
return n;
161
}
162
163
pw_proxy_destroy(n->proxy);
164
spa_list_remove(&n->link);
165
d->n_nodes--;
166
+ d->pending_refresh = true;
167
free(n);
168
}
169
170
171
return -ENOENT;
172
173
n->measurement = m;
174
- n->driver = point->driver;
175
+ if (n->driver != point->driver) {
176
+ n->driver = point->driver;
177
+ d->pending_refresh = true;
178
+ }
179
n->generation = d->generation;
180
if (m.status != 3) {
181
n->errors++;
182
183
return 0;
184
}
185
186
-static const char *print_time(char *buf, size_t len, uint64_t val)
187
+static const char *print_time(char *buf, bool active, size_t len, uint64_t val)
188
{
189
- if (val == (uint64_t)-1)
190
+ if (val == (uint64_t)-1 || !active)
191
snprintf(buf, len, " --- ");
192
else if (val == (uint64_t)-2)
193
snprintf(buf, len, " +++ ");
194
195
return buf;
196
}
197
198
-static const char *print_perc(char *buf, size_t len, uint64_t val, float quantum)
199
+static const char *print_perc(char *buf, bool active, size_t len, uint64_t val, float quantum)
200
{
201
pipewire-0.3.59.tar.gz/test/pwtest.c -> pipewire-0.3.60.tar.gz/test/pwtest.c
Changed
20
1
2
void
3
pwtest_spa_plugin_destroy(struct pwtest_spa_plugin *plugin)
4
{
5
- void **dll;
6
- struct spa_handle **hnd;
7
-
8
- SPA_FOR_EACH_ELEMENT(plugin->handles, hnd) {
9
+ SPA_FOR_EACH_ELEMENT_VAR(plugin->handles, hnd) {
10
if (*hnd) {
11
spa_handle_clear(*hnd);
12
free(*hnd);
13
}
14
}
15
- SPA_FOR_EACH_ELEMENT(plugin->dlls, dll) {
16
+ SPA_FOR_EACH_ELEMENT_VAR(plugin->dlls, dll) {
17
if (*dll)
18
dlclose(*dll);
19
}
20
pipewire-0.3.59.tar.gz/test/test-functional.c -> pipewire-0.3.60.tar.gz/test/test-functional.c
Changed
25
1
2
3
PWTEST(openal_info_test)
4
{
5
- int status;
6
-
7
#ifdef OPENAL_INFO_PATH
8
- status = pwtest_spawn(OPENAL_INFO_PATH, (char *){ "openal-info", NULL });
9
+ int status = pwtest_spawn(OPENAL_INFO_PATH, (char *){ "openal-info", NULL });
10
pwtest_int_eq(WEXITSTATUS(status), 0);
11
return PWTEST_PASS;
12
#else
13
14
15
PWTEST(pactl_test)
16
{
17
- int status;
18
-
19
#ifdef PACTL_PATH
20
- status = pwtest_spawn(PACTL_PATH, (char *){ "pactl", "info", NULL });
21
+ int status = pwtest_spawn(PACTL_PATH, (char *){ "pactl", "info", NULL });
22
pwtest_int_eq(WEXITSTATUS(status), 0);
23
return PWTEST_PASS;
24
#else
25
pipewire-0.3.59.tar.gz/test/test-spa-utils.c -> pipewire-0.3.60.tar.gz/test/test-spa-utils.c
Changed
12
1
2
3
#define check_traversal(array_) \
4
{ \
5
- __typeof__(array_0) *it; \
6
int count = 0; \
7
- SPA_FOR_EACH_ELEMENT(array_, it) \
8
+ SPA_FOR_EACH_ELEMENT_VAR(array_, it) \
9
*it = count++; \
10
for (size_t i = 0; i < SPA_N_ELEMENTS(array_); i++) \
11
pwtest_int_eq(array_i, i); \
12
pipewire-0.3.59.tar.gz/test/test-utils.c -> pipewire-0.3.60.tar.gz/test/test-utils.c
Changed
12
1
2
},
3
};
4
5
- const struct test_case *tc;
6
-
7
- SPA_FOR_EACH_ELEMENT(test_cases, tc) {
8
+ SPA_FOR_EACH_ELEMENT_VAR(test_cases, tc) {
9
const char *str = tc->input, *s;
10
const char *state = NULL;
11
size_t j = 0, len;
12