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 39
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Fri Nov 24 19:29:49 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.85
6
+
7
+-------------------------------------------------------------------
8
Fri Nov 3 13:41:27 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.84
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.84
6
+Version: 0.3.85
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.84.tar.gz/NEWS -> pipewire-0.3.85.tar.gz/NEWS
Changed
73
1
2
+# PipeWire 0.3.85 (2023-11-16)
3
+
4
+This is the fifth (and last) 1.0 release candidate that is API and ABI
5
+compatible with previous 0.3.x releases.
6
+
7
+## Highlights
8
+ - Fix an issue where a link could end up paused while not negotiated.
9
+ - Fix an infinite recursion issue when finding runnable nodes.
10
+ - Support XDG base directories when loading ACP config.
11
+ - Fix MIDI event recording preview in Ardour.
12
+ - Many more small fixes, cleanups and improvements.
13
+
14
+
15
+## PipeWire
16
+ - Fix an issue where a link could end up paused while not negotiated.
17
+ (#3619)
18
+ - Fix an infinite recursion issue when finding runnable nodes by stopping
19
+ the scan on feedback links around the driver. (#3621)
20
+ - The system service now has better socket permissions.
21
+
22
+## Modules
23
+ - Add support for uclamp. This allows the scheduler to make better informed
24
+ decisions about where tasks should be placed, and what pstate to set
25
+ for the CPU it is running on.
26
+ - Emit warnings when applications are not doing the right locking instead
27
+ of crashing.
28
+ - Improve media.name for RAOP sinks. (#3801)
29
+ - Support pause/resume in pipe-tunnel. (#3197)
30
+ - Remove time rlimit when probing for realtime to avoid SIGXCPU.
31
+
32
+## SPA
33
+ - Fix a bug where the resampler would be activated even when there is an
34
+ ALSA pitch element. (#3628)
35
+ - Improve resume from suspend in ALSA. (#3646)
36
+ - Add option to expose ALSA controls as prop params.
37
+ - Support XDG base directories when loading ACP config. This makes it possible
38
+ to override the ACP config files.
39
+
40
+## Bluetooth
41
+ - Schedule nodes in the same ISO group together.
42
+ - More BAP fixes and cleanups.
43
+
44
+## JACK
45
+ - Fix MIDI events from peer ports. This makes the MIDI event recording preview
46
+ of Ardour work correctly.
47
+
48
+## GStreamer
49
+ - Fix some error handling in the source and sink.
50
+
51
+## ALSA plugin
52
+ - Improve poll descriptor handling. (#3648)
53
+
54
+## Docs
55
+ - Many improvements to the layout and organization.
56
+
57
+Older versions:
58
+
59
+
60
# PipeWire 0.3.84 (2023-11-02)
61
62
This is the fourth 1.0 release candidate that is API and ABI compatible
63
64
## ALSA
65
- The ALSA plugin now handles NULL values from mmap_areas. (#3600)
66
67
-Older versions:
68
-
69
-
70
# PipeWire 0.3.83 (2023-10-19)
71
72
This is the third 1.0 release candidate that is API and ABI compatible
73
pipewire-0.3.84.tar.gz/doc/Doxyfile.in -> pipewire-0.3.85.tar.gz/doc/Doxyfile.in
Changed
20
1
2
PROJECT_NAME = PipeWire
3
PROJECT_NUMBER = @PACKAGE_VERSION@
4
OUTPUT_DIRECTORY = "@output_directory@"
5
-FULL_PATH_NAMES = NO
6
+FULL_PATH_NAMES = YES
7
JAVADOC_AUTOBRIEF = YES
8
TAB_SIZE = 8
9
OPTIMIZE_OUTPUT_FOR_C = YES
10
11
SEARCHENGINE = YES
12
GENERATE_LATEX = NO
13
14
+TOC_INCLUDE_HEADINGS = 0
15
+LAYOUT_FILE = @layout@
16
+
17
MACRO_EXPANSION = YES
18
EXPAND_ONLY_PREDEF = YES
19
PREDEFINED = PA_C_DECL_BEGIN= \
20
pipewire-0.3.85.tar.gz/doc/DoxygenLayout.xml
Added
201
1
2
+<doxygenlayout version="1.0">
3
+ <navindex>
4
+ <tab type="mainpage" visible="yes" title=""/>
5
+ <tab type="pages" visible="yes" title="Pages" intro=""/>
6
+ <tab type="modules" visible="yes" title="API Reference" intro="" />
7
+ <tab type="namespaces" visible="no" title="">
8
+ <tab type="namespacelist" visible="yes" title="" intro=""/>
9
+ <tab type="namespacemembers" visible="yes" title="" intro=""/>
10
+ </tab>
11
+ <tab type="concepts" visible="no" title="">
12
+ </tab>
13
+ <tab type="interfaces" visible="no" title="">
14
+ <tab type="interfacelist" visible="yes" title="" intro=""/>
15
+ <tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
16
+ <tab type="interfacehierarchy" visible="yes" title="" intro=""/>
17
+ </tab>
18
+ <tab type="classes" visible="yes" title="">
19
+ <tab type="classlist" visible="yes" title="" intro=""/>
20
+ <tab type="classindex" visible="yes" title=""/>
21
+ <tab type="hierarchy" visible="yes" title="" intro=""/>
22
+ <tab type="classmembers" visible="no" title="" intro=""/>
23
+ </tab>
24
+ <tab type="structs" visible="no" title="">
25
+ <tab type="structlist" visible="yes" title="" intro=""/>
26
+ <tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
27
+ </tab>
28
+ <tab type="exceptions" visible="no" title="">
29
+ <tab type="exceptionlist" visible="yes" title="" intro=""/>
30
+ <tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
31
+ <tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
32
+ </tab>
33
+ <tab type="files" visible="yes" title="">
34
+ <tab type="filelist" visible="yes" title="" intro=""/>
35
+ <tab type="globals" visible="no" title="" intro=""/>
36
+ </tab>
37
+ <tab type="examples" visible="yes" title="" intro=""/>
38
+ </navindex>
39
+
40
+ <!-- Layout definition for a class page -->
41
+ <class>
42
+ <briefdescription visible="yes"/>
43
+ <includes visible="$SHOW_HEADERFILE"/>
44
+ <inheritancegraph visible="$CLASS_GRAPH"/>
45
+ <collaborationgraph visible="$COLLABORATION_GRAPH"/>
46
+ <memberdecl>
47
+ <nestedclasses visible="yes" title=""/>
48
+ <publictypes title=""/>
49
+ <services title=""/>
50
+ <interfaces title=""/>
51
+ <publicslots title=""/>
52
+ <signals title=""/>
53
+ <publicmethods title=""/>
54
+ <publicstaticmethods title=""/>
55
+ <publicattributes title=""/>
56
+ <publicstaticattributes title=""/>
57
+ <protectedtypes title=""/>
58
+ <protectedslots title=""/>
59
+ <protectedmethods title=""/>
60
+ <protectedstaticmethods title=""/>
61
+ <protectedattributes title=""/>
62
+ <protectedstaticattributes title=""/>
63
+ <packagetypes title=""/>
64
+ <packagemethods title=""/>
65
+ <packagestaticmethods title=""/>
66
+ <packageattributes title=""/>
67
+ <packagestaticattributes title=""/>
68
+ <properties title=""/>
69
+ <events title=""/>
70
+ <privatetypes title=""/>
71
+ <privateslots title=""/>
72
+ <privatemethods title=""/>
73
+ <privatestaticmethods title=""/>
74
+ <privateattributes title=""/>
75
+ <privatestaticattributes title=""/>
76
+ <friends title=""/>
77
+ <related title="" subtitle=""/>
78
+ <membergroups visible="yes"/>
79
+ </memberdecl>
80
+ <detaileddescription title=""/>
81
+ <memberdef>
82
+ <inlineclasses title=""/>
83
+ <typedefs title=""/>
84
+ <enums title=""/>
85
+ <services title=""/>
86
+ <interfaces title=""/>
87
+ <constructors title=""/>
88
+ <functions title=""/>
89
+ <related title=""/>
90
+ <variables title=""/>
91
+ <properties title=""/>
92
+ <events title=""/>
93
+ </memberdef>
94
+ <allmemberslink visible="yes"/>
95
+ <usedfiles visible="$SHOW_USED_FILES"/>
96
+ <authorsection visible="yes"/>
97
+ </class>
98
+
99
+ <!-- Layout definition for a namespace page -->
100
+ <namespace>
101
+ <briefdescription visible="yes"/>
102
+ <memberdecl>
103
+ <nestednamespaces visible="yes" title=""/>
104
+ <constantgroups visible="yes" title=""/>
105
+ <interfaces visible="yes" title=""/>
106
+ <classes visible="yes" title=""/>
107
+ <concepts visible="yes" title=""/>
108
+ <structs visible="yes" title=""/>
109
+ <exceptions visible="yes" title=""/>
110
+ <typedefs title=""/>
111
+ <sequences title=""/>
112
+ <dictionaries title=""/>
113
+ <enums title=""/>
114
+ <functions title=""/>
115
+ <variables title=""/>
116
+ <membergroups visible="yes"/>
117
+ </memberdecl>
118
+ <detaileddescription title=""/>
119
+ <memberdef>
120
+ <inlineclasses title=""/>
121
+ <typedefs title=""/>
122
+ <sequences title=""/>
123
+ <dictionaries title=""/>
124
+ <enums title=""/>
125
+ <functions title=""/>
126
+ <variables title=""/>
127
+ </memberdef>
128
+ <authorsection visible="yes"/>
129
+ </namespace>
130
+
131
+ <!-- Layout definition for a concept page -->
132
+ <concept>
133
+ <briefdescription visible="yes"/>
134
+ <includes visible="$SHOW_HEADERFILE"/>
135
+ <definition visible="yes" title=""/>
136
+ <detaileddescription title=""/>
137
+ <authorsection visible="yes"/>
138
+ </concept>
139
+
140
+ <!-- Layout definition for a file page -->
141
+ <file>
142
+ <briefdescription visible="yes"/>
143
+ <includes visible="$SHOW_INCLUDE_FILES"/>
144
+ <includegraph visible="$INCLUDE_GRAPH"/>
145
+ <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
146
+ <sourcelink visible="yes"/>
147
+ <memberdecl>
148
+ <interfaces visible="yes" title=""/>
149
+ <classes visible="yes" title=""/>
150
+ <structs visible="yes" title=""/>
151
+ <exceptions visible="yes" title=""/>
152
+ <namespaces visible="yes" title=""/>
153
+ <concepts visible="yes" title=""/>
154
+ <constantgroups visible="yes" title=""/>
155
+ <defines title=""/>
156
+ <typedefs title=""/>
157
+ <sequences title=""/>
158
+ <dictionaries title=""/>
159
+ <enums title=""/>
160
+ <functions title=""/>
161
+ <variables title=""/>
162
+ <membergroups visible="yes"/>
163
+ </memberdecl>
164
+ <detaileddescription title=""/>
165
+ <memberdef>
166
+ <inlineclasses title=""/>
167
+ <defines title=""/>
168
+ <typedefs title=""/>
169
+ <sequences title=""/>
170
+ <dictionaries title=""/>
171
+ <enums title=""/>
172
+ <functions title=""/>
173
+ <variables title=""/>
174
+ </memberdef>
175
+ <authorsection/>
176
+ </file>
177
+
178
+ <!-- Layout definition for a group page -->
179
+ <group>
180
+ <briefdescription visible="yes"/>
181
+ <groupgraph visible="$GROUP_GRAPHS"/>
182
+ <memberdecl>
183
+ <nestedgroups visible="yes" title=""/>
184
+ <dirs visible="yes" title=""/>
185
+ <files visible="yes" title=""/>
186
+ <namespaces visible="yes" title=""/>
187
+ <concepts visible="yes" title=""/>
188
+ <classes visible="yes" title=""/>
189
+ <typedefs title=""/>
190
+ <sequences title=""/>
191
+ <dictionaries title=""/>
192
+ <enums title=""/>
193
+ <enumvalues title=""/>
194
+ <defines title=""/>
195
+ <functions title=""/>
196
+ <variables title=""/>
197
+ <signals title=""/>
198
+ <publicslots title=""/>
199
+ <protectedslots title=""/>
200
+ <privateslots title=""/>
201
pipewire-0.3.84.tar.gz/doc/api-tree.dox -> pipewire-0.3.85.tar.gz/doc/api-tree.dox
Changed
18
1
2
\addtogroup spa_hooks
3
\addtogroup spa_interfaces
4
\addtogroup spa_json
5
+\addtogroup spa_json_pod
6
\addtogroup spa_keys
7
\addtogroup spa_names
8
\addtogroup spa_result
9
10
\{
11
\}
12
13
-\defgroup pwtest Test Suite
14
-\{
15
-\}
16
-
17
*/
18
pipewire-0.3.84.tar.gz/doc/custom.css -> pipewire-0.3.85.tar.gz/doc/custom.css
Changed
22
1
2
--fragment-link: #729fcf;
3
}
4
}
5
+
6
+#nav-tree .arrow {
7
+ opacity: 1;
8
+ padding-right: 0.25em;
9
+}
10
+
11
+.textblock h1 {
12
+ font-size: 150%;
13
+}
14
+.textblock h2 {
15
+ font-size: 100%;
16
+}
17
+.textblock h3, .textblock h4, .textblock h5, .textblock h6 {
18
+ font-size: 100%;
19
+ font-style: italic;
20
+ font-size: medium;
21
+}
22
pipewire-0.3.84.tar.gz/doc/index.dox -> pipewire-0.3.85.tar.gz/doc/index.dox
Changed
15
1
2
- Intoduction to PipeWire(https://bootlin.com/blog/an-introduction-to-pipewire/)
3
- A custom PipeWire node(https://bootlin.com/blog/a-custom-pipewire-node/)
4
5
+
6
+\page page_overview
7
+\page page_pipewire
8
+\page page_tools
9
+\page page_pipewire_modules
10
+\page page_api
11
+\page page_spa
12
+\page page_tutorial
13
+
14
*/
15
pipewire-0.3.84.tar.gz/doc/manpage.dox.in -> pipewire-0.3.85.tar.gz/doc/manpage.dox.in
Changed
9
1
2
/** \page @pagename@ @title@
3
4
+\brief Manual page for @title@
5
+
6
\verbinclude @filename@
7
8
*/
9
pipewire-0.3.84.tar.gz/doc/meson.build -> pipewire-0.3.85.tar.gz/doc/meson.build
Changed
37
1
2
foreach h : module_sources
3
inputs += meson.project_source_root() / 'src' / 'modules' / h
4
endforeach
5
-inputs += meson.project_source_root() / 'test' / 'pwtest.h'
6
input_dirs = meson.project_source_root() / 'spa' / 'include' / 'spa'
7
8
path_prefixes =
9
10
configuration: pw_tools_dox_conf)
11
input_dirs += 'doc/pipewire-tools.dox'
12
13
+doxygen_layout = meson.project_source_root() / 'doc' / 'DoxygenLayout.xml'
14
+doxygen_filter_c = meson.project_source_root() / 'doc' / 'input-filter.sh'
15
+doxygen_filter_h = meson.project_source_root() / 'doc' / 'input-filter-h.sh'
16
+
17
doxyfile_conf.set('inputs', ' '.join(inputs + input_dirs))
18
doxyfile_conf.set('cssfiles', ' '.join(cssfiles))
19
+doxyfile_conf.set('layout', doxygen_layout)
20
doxyfile_conf.set('path_prefixes', ' '.join(path_prefixes))
21
-doxyfile_conf.set('c_input_filter', meson.project_source_root() / 'doc' / 'input-filter.sh')
22
-doxyfile_conf.set('h_input_filter', meson.project_source_root() / 'doc' / 'input-filter-h.sh')
23
+doxyfile_conf.set('c_input_filter', doxygen_filter_c)
24
+doxyfile_conf.set('h_input_filter', doxygen_filter_h)
25
26
doxyfile = configure_file(input: 'Doxyfile.in',
27
output: 'Doxyfile',
28
29
endif
30
31
html_target = custom_target('pipewire-docs',
32
- input: doxyfile, examples_dox, pw_tools_dox + inputs + cssfiles + man_doxygen,
33
+ input: doxyfile, doxygen_layout, examples_dox, pw_tools_dox, doxygen_filter_c, doxygen_filter_h + inputs + cssfiles + man_doxygen,
34
output: 'html' ,
35
command: doxygen, doxyfile ,
36
install: true,
37
pipewire-0.3.84.tar.gz/doc/pipewire.dox -> pipewire-0.3.85.tar.gz/doc/pipewire.dox
Changed
12
1
2
# Components
3
4
- \subpage page_daemon
5
-- \subpage page_tools
6
- \subpage page_session_manager
7
8
-
9
# Backends
10
11
- \subpage page_pulseaudio
12
pipewire-0.3.84.tar.gz/doc/tutorial4.c -> pipewire-0.3.85.tar.gz/doc/tutorial4.c
Changed
10
1
2
3
stride = sizeof(int16_t) * DEFAULT_CHANNELS;
4
n_frames = buf->datas0.maxsize / stride;
5
+ if (b->requested)
6
+ n_frames = SPA_MIN(b->requested, n_frames);
7
8
for (i = 0; i < n_frames; i++) {
9
data->accumulator += M_PI_M2 * 440 / DEFAULT_RATE;
10
pipewire-0.3.84.tar.gz/meson.build -> pipewire-0.3.85.tar.gz/meson.build
Changed
18
1
2
project('pipewire', 'c' ,
3
- version : '0.3.84',
4
+ version : '0.3.85',
5
license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ,
6
meson_version : '>= 0.61.1',
7
default_options : 'warning_level=3',
8
9
cdata.set_quoted('PIPEWIRE_CONFIG_DIR', pipewire_configdir)
10
cdata.set_quoted('PLUGINDIR', spa_plugindir)
11
cdata.set_quoted('SPADATADIR', spa_datadir)
12
-cdata.set_quoted('PA_ALSA_PATHS_DIR', alsadatadir / 'paths')
13
-cdata.set_quoted('PA_ALSA_PROFILE_SETS_DIR', alsadatadir / 'profile-sets')
14
+cdata.set_quoted('PA_ALSA_DATA_DIR', alsadatadir)
15
16
if host_machine.endian() == 'big'
17
cdata.set('WORDS_BIGENDIAN', 1)
18
pipewire-0.3.84.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.85.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
104
1
2
3
static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io);
4
5
-static int check_active(snd_pcm_ioplug_t *io)
6
+static int update_active(snd_pcm_ioplug_t *io)
7
{
8
snd_pcm_pipewire_t *pw = io->private_data;
9
snd_pcm_sframes_t avail;
10
11
12
avail = snd_pcm_ioplug_avail(io, pw->hw_ptr, io->appl_ptr);
13
14
- if (io->state == SND_PCM_STATE_DRAINING) {
15
+ if (pw->error > 0) {
16
+ active = true;
17
+ }
18
+ else if (io->state == SND_PCM_STATE_DRAINING) {
19
active = pw->drained;
20
}
21
else if (avail >= 0 && avail < (snd_pcm_sframes_t)pw->min_avail) {
22
23
}
24
else if (avail >= (snd_pcm_sframes_t)pw->min_avail) {
25
active = true;
26
- } else {
27
+ }
28
+ else {
29
active = false;
30
}
31
if (pw->active != active) {
32
+ uint64_t val;
33
+
34
pw_log_trace("%p: avail:%lu min-avail:%lu state:%s hw:%lu appl:%lu active:%d->%d state:%s",
35
pw, avail, pw->min_avail, snd_pcm_state_name(io->state),
36
pw->hw_ptr, io->appl_ptr, pw->active, active,
37
snd_pcm_state_name(io->state));
38
+
39
+ pw->active = active;
40
+ if (active)
41
+ spa_system_eventfd_write(pw->system, io->poll_fd, 1);
42
+ else
43
+ spa_system_eventfd_read(pw->system, io->poll_fd, &val);
44
}
45
return active;
46
}
47
48
-
49
-static int update_active(snd_pcm_ioplug_t *io)
50
-{
51
- snd_pcm_pipewire_t *pw = io->private_data;
52
- pw->active = check_active(io);
53
- uint64_t val;
54
-
55
- if (pw->active || pw->error < 0)
56
- spa_system_eventfd_write(pw->system, io->poll_fd, 1);
57
- else
58
- spa_system_eventfd_read(pw->system, io->poll_fd, &val);
59
-
60
- return pw->active;
61
-}
62
-
63
static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw)
64
{
65
if (pw == NULL)
66
67
return 0;
68
}
69
70
-static int snd_pcm_pipewire_poll_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfds, unsigned int space)
71
-{
72
- snd_pcm_pipewire_t *pw = io->private_data;
73
- update_active(io);
74
- pfds->fd = pw->fd;
75
- pfds->events = POLLIN | POLLERR | POLLNVAL;
76
- return 1;
77
-}
78
-
79
static int snd_pcm_pipewire_poll_revents(snd_pcm_ioplug_t *io,
80
struct pollfd *pfds, unsigned int nfds,
81
unsigned short *revents)
82
83
return pw->error;
84
85
*revents = pfds0.revents & ~(POLLIN | POLLOUT);
86
- if (pfds0.revents & POLLIN && check_active(io)) {
87
+ if (pfds0.revents & POLLIN && update_active(io))
88
*revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN;
89
- update_active(io);
90
- }
91
+
92
+ pw_log_trace_fp("poll %d", *revents);
93
94
return 0;
95
}
96
97
.delay = snd_pcm_pipewire_delay,
98
.drain = snd_pcm_pipewire_drain,
99
.prepare = snd_pcm_pipewire_prepare,
100
- .poll_descriptors = snd_pcm_pipewire_poll_descriptors,
101
.poll_revents = snd_pcm_pipewire_poll_revents,
102
.hw_params = snd_pcm_pipewire_hw_params,
103
.sw_params = snd_pcm_pipewire_sw_params,
104
pipewire-0.3.84.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.85.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
201
1
2
static struct globals globals;
3
static bool mlock_warned = false;
4
5
+#define MIDI_SCRATCH_FRAMES 8192
6
+static float midi_scratchMIDI_SCRATCH_FRAMES;
7
+
8
+
9
#define OBJECT_CHUNK 8
10
#define RECYCLE_THRESHOLD 128
11
12
13
14
struct client *client;
15
16
-#define INTERFACE_Port 0
17
-#define INTERFACE_Node 1
18
-#define INTERFACE_Link 2
19
+#define INTERFACE_Invalid 0
20
+#define INTERFACE_Port 1
21
+#define INTERFACE_Node 2
22
+#define INTERFACE_Link 3
23
uint32_t type;
24
uint32_t id;
25
uint32_t serial;
26
27
pthread_mutex_lock(&globals.lock);
28
spa_list_for_each_safe(o, t, &c->context.objects, link) {
29
if (o->removed) {
30
- pw_log_info("%p: recycle object:%p type:%d id:%u/%u",
31
+ pw_log_debug("%p: recycle object:%p type:%d id:%u/%u",
32
c, o, o->type, o->id, o->serial);
33
spa_list_remove(&o->link);
34
memset(o, 0, sizeof(struct object));
35
36
37
}
38
39
+static inline struct object *port_to_object(const jack_port_t *port)
40
+{
41
+ return (struct object*)port;
42
+}
43
+static inline jack_port_t *object_to_port(struct object *o)
44
+{
45
+ return (jack_port_t*)o;
46
+}
47
+
48
struct io_info {
49
struct mix *mix;
50
void *data;
51
52
return 0;
53
}
54
55
+static void midi_init_buffer(void *data, uint32_t max_frames)
56
+{
57
+ struct midi_buffer *mb = data;
58
+ mb->magic = MIDI_BUFFER_MAGIC;
59
+ mb->buffer_size = max_frames * sizeof(float);
60
+ mb->nframes = max_frames;
61
+ mb->write_pos = 0;
62
+ mb->event_count = 0;
63
+ mb->lost_events = 0;
64
+}
65
+
66
static inline void *init_buffer(struct port *p)
67
{
68
struct client *c = p->client;
69
70
71
if (p->object->port.type_id == TYPE_ID_MIDI) {
72
struct midi_buffer *mb = data;
73
- mb->magic = MIDI_BUFFER_MAGIC;
74
- mb->buffer_size = c->max_frames * sizeof(float);
75
- mb->nframes = c->max_frames;
76
- mb->write_pos = 0;
77
- mb->event_count = 0;
78
- mb->lost_events = 0;
79
+ midi_init_buffer(data, c->max_frames);
80
pw_log_debug("port %p: init midi buffer size:%d", p, mb->buffer_size);
81
} else
82
memset(data, 0, c->max_frames * sizeof(float));
83
84
}
85
86
static const struct pw_node_events node_events = {
87
- PW_VERSION_NODE,
88
+ PW_VERSION_NODE_EVENTS,
89
.info = node_info,
90
};
91
92
93
}
94
95
static const struct pw_port_events port_events = {
96
- PW_VERSION_PORT,
97
+ PW_VERSION_PORT_EVENTS,
98
.param = port_param,
99
};
100
101
102
goto error_free;
103
}
104
105
- return (jack_port_t *) o;
106
+ return object_to_port(o);
107
108
error_free:
109
free_port(c, p, true);
110
111
int jack_port_unregister (jack_client_t *client, jack_port_t *port)
112
{
113
struct client *c = (struct client *) client;
114
- struct object *o = (struct object *) port;
115
+ struct object *o = port_to_object(port);
116
struct port *p;
117
int res;
118
119
120
SPA_EXPORT
121
void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t frames)
122
{
123
- struct object *o = (struct object *) port;
124
- struct port *p;
125
- void *ptr;
126
+ struct object *o = port_to_object(port);
127
+ struct port *p = NULL;
128
+ void *ptr = NULL;
129
130
return_val_if_fail(o != NULL, NULL);
131
132
if (o->type != INTERFACE_Port || o->client == NULL)
133
- return NULL;
134
+ goto done;
135
136
if ((p = o->port.port) == NULL) {
137
struct mix *mix;
138
struct buffer *b;
139
140
if ((mix = find_mix_peer(o->client, o->id)) == NULL)
141
- return NULL;
142
+ goto done;
143
144
pw_log_trace("peer mix: %p %d", mix, mix->peer_id);
145
146
if ((b = get_mix_buffer(mix, frames)) == NULL)
147
- return NULL;
148
+ goto done;
149
150
- return get_buffer_data(b, frames);
151
+ if (o->port.type_id == TYPE_ID_MIDI) {
152
+ struct spa_pod_sequence *seq1;
153
+ struct spa_data *d;
154
+ void *pod;
155
+
156
+ ptr = midi_scratch;
157
+ midi_init_buffer(ptr, MIDI_SCRATCH_FRAMES);
158
+
159
+ d = &b->datas0;
160
+ if ((pod = spa_pod_from_data(d->data, d->maxsize,
161
+ d->chunk->offset, d->chunk->size)) == NULL)
162
+ goto done;
163
+ if (!spa_pod_is_sequence(pod))
164
+ goto done;
165
+ seq0 = pod;
166
+ convert_to_midi(seq, 1, ptr, o->client->fix_midi_events);
167
+ } else {
168
+ ptr = get_buffer_data(b, frames);
169
+ }
170
+ } else if (p->valid) {
171
+ ptr = p->get_buffer(p, frames);
172
}
173
- if (!p->valid)
174
- return NULL;
175
-
176
- ptr = p->get_buffer(p, frames);
177
- pw_log_trace_fp("%p: port %p buffer %p empty:%u", p->client, p, ptr, p->empty_out);
178
+done:
179
+ pw_log_trace_fp("%p: port %p buffer %p", p->client, p, ptr);
180
return ptr;
181
}
182
183
SPA_EXPORT
184
jack_uuid_t jack_port_uuid (const jack_port_t *port)
185
{
186
- struct object *o = (struct object *) port;
187
+ struct object *o = port_to_object(port);
188
return_val_if_fail(o != NULL, 0);
189
return jack_port_uuid_generate(o->serial);
190
}
191
192
SPA_EXPORT
193
const char * jack_port_name (const jack_port_t *port)
194
{
195
- struct object *o = (struct object *) port;
196
+ struct object *o = port_to_object(port);
197
return_val_if_fail(o != NULL, NULL);
198
+ if (o->type != INTERFACE_Port)
199
+ return NULL;
200
return port_name(o);
201
pipewire-0.3.84.tar.gz/spa/include/spa/debug/log.h -> pipewire-0.3.85.tar.gz/spa/include/spa/debug/log.h
Changed
10
1
2
SPA_PRINTF_FUNC(2,3)
3
static inline void spa_debug_log_log(struct spa_debug_context *ctx, const char *fmt, ...)
4
{
5
- struct spa_debug_log_ctx *c = (struct spa_debug_log_ctx*)ctx;
6
+ struct spa_debug_log_ctx *c = SPA_CONTAINER_OF(ctx, struct spa_debug_log_ctx, ctx);
7
va_list args;
8
va_start(args, fmt);
9
spa_log_logtv(c->log, c->level, c->topic, c->file, c->line, c->func, fmt, args);
10
pipewire-0.3.84.tar.gz/spa/include/spa/param/props.h -> pipewire-0.3.85.tar.gz/spa/include/spa/param/props.h
Changed
36
1
2
SPA_PROP_patternType,
3
SPA_PROP_ditherType,
4
SPA_PROP_truncate,
5
- SPA_PROP_channelVolumes, /**< a volume array, one volume per channel
6
+ SPA_PROP_channelVolumes, /**< a volume array, one (linear) volume per channel
7
* (Array of Float). 0.0 is silence, 1.0 is
8
- * without attenuation. This is the effective volume
9
- * that is applied. It can result in a hardware volume
10
- * and software volume (see softVolumes) */
11
+ * without attenuation. This is the effective
12
+ * volume that is applied. It can result
13
+ * in a hardware volume and software volume
14
+ * (see softVolumes) */
15
SPA_PROP_volumeBase, /**< a volume base (Float) */
16
SPA_PROP_volumeStep, /**< a volume step (Float) */
17
SPA_PROP_channelMap, /**< a channelmap array
18
* (Array (Id enum spa_audio_channel)) */
19
SPA_PROP_monitorMute, /**< mute (Bool) */
20
- SPA_PROP_monitorVolumes, /**< a volume array, one volume per
21
+ SPA_PROP_monitorVolumes, /**< a volume array, one (linear) volume per
22
* channel (Array of Float) */
23
SPA_PROP_latencyOffsetNsec, /**< delay adjustment */
24
SPA_PROP_softMute, /**< mute (Bool) applied in software */
25
- SPA_PROP_softVolumes, /**< a volume array, one volume per channel
26
+ SPA_PROP_softVolumes, /**< a volume array, one (linear) volume per channel
27
* (Array of Float). 0.0 is silence, 1.0 is without
28
- * attenuation. This is the volume applied in software,
29
- * there might be a part applied in hardware. */
30
+ * attenuation. This is the volume applied in
31
+ * software, there might be a part applied in
32
+ * hardware. */
33
34
SPA_PROP_iec958Codecs, /**< enabled IEC958 (S/PDIF) codecs,
35
* (Array (Id enum spa_audio_iec958_codec) */
36
pipewire-0.3.84.tar.gz/spa/include/spa/utils/keys.h -> pipewire-0.3.85.tar.gz/spa/include/spa/utils/keys.h
Changed
9
1
2
#define SPA_KEY_API_ALSA_OPEN_UCM "api.alsa.open.ucm" /**< if UCM should be opened card */
3
#define SPA_KEY_API_ALSA_DISABLE_LONGNAME \
4
"api.alsa.disable-longname" /**< if card long name should not be passed to MIDI port */
5
+#define SPA_KEY_API_ALSA_BIND_CTLS "api.alsa.bind-ctls" /**< alsa controls to bind as params */
6
7
/** info from alsa card_info */
8
#define SPA_KEY_API_ALSA_CARD_ID "api.alsa.card.id" /**< id from card_info */
9
pipewire-0.3.84.tar.gz/spa/plugins/alsa/acp/alsa-mixer.c -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/acp/alsa-mixer.c
Changed
75
1
2
return 0;
3
}
4
5
-static const char *get_default_paths_dir(void) {
6
- const char *str;
7
-#ifdef HAVE_RUNNING_FROM_BUILD_TREE
8
- if (pa_run_from_build_tree())
9
- return PA_SRCDIR "mixer/paths";
10
- else
11
-#endif
12
- if (getenv("ACP_BUILDDIR") != NULL)
13
- return "mixer/paths";
14
- if ((str = getenv("ACP_PATHS_DIR")) != NULL)
15
- return str;
16
- return PA_ALSA_PATHS_DIR;
17
-}
18
-
19
pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction) {
20
pa_alsa_path *p;
21
char *fn;
22
23
items2.data = &p->description;
24
items3.data = &mute_during_activation;
25
26
- if (!paths_dir)
27
- paths_dir = get_default_paths_dir();
28
+ fn = get_data_path(paths_dir, "paths", fname);
29
30
- fn = pa_maybe_prefix_path(fname, paths_dir);
31
+ pa_log_info("Loading path config: %s", fn);
32
33
r = pa_config_parse(fn, NULL, items, p->proplist, false, p);
34
pa_xfree(fn);
35
36
pa_xfree(db_values);
37
}
38
39
-static const char *get_default_profile_dir(void) {
40
- const char *str;
41
-#ifdef HAVE_RUNNING_FROM_BUILD_TREE
42
- if (pa_run_from_build_tree())
43
- return PA_SRCDIR "mixer/profile-sets";
44
- else
45
-#endif
46
- if (getenv("ACP_BUILDDIR") != NULL)
47
- return "mixer/profile-sets";
48
- if ((str = getenv("ACP_PROFILES_DIR")) != NULL)
49
- return str;
50
- return PA_ALSA_PROFILE_SETS_DIR;
51
-}
52
-
53
pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus) {
54
pa_alsa_profile_set *ps;
55
pa_alsa_profile *p;
56
57
58
items0.data = &ps->auto_profiles;
59
60
- fn = pa_maybe_prefix_path(fname ? fname : "default.conf",
61
- get_default_profile_dir());
62
+ fn = get_data_path(NULL, "profile-sets", fname ? fname : "default.conf");
63
+
64
+ pa_log_info("Loading profile set: %s", fn);
65
+
66
if ((r = access(fn, R_OK)) != 0) {
67
if (fname != NULL) {
68
pa_log_warn("profile-set '%s' can't be accessed: %m", fn);
69
- fn = pa_maybe_prefix_path("default.conf",
70
- get_default_profile_dir());
71
+ fn = get_data_path(NULL, "profile-sets", "default.conf");
72
r = access(fn, R_OK);
73
}
74
if (r != 0) {
75
pipewire-0.3.84.tar.gz/spa/plugins/alsa/acp/compat.c -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/acp/compat.c
Changed
92
1
2
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
3
***/
4
5
+#include <spa/utils/string.h>
6
+#include <spa/utils/cleanup.h>
7
+
8
#include "compat.h"
9
#include "device-port.h"
10
#include "alsa-mixer.h"
11
+#include "config.h"
12
13
static const char *port_types = {
14
PA_DEVICE_PORT_TYPE_UNKNOWN = "unknown",
15
16
17
return true;
18
}
19
+
20
+static char *try_path(const char *fname, const char *path)
21
+{
22
+ char *result = pa_maybe_prefix_path(fname, path);
23
+
24
+ pa_log_trace("Check for file: %s", result);
25
+
26
+ if (access(result, R_OK) == 0)
27
+ return result;
28
+
29
+ pa_xfree(result);
30
+ return NULL;
31
+}
32
+
33
+static char *get_xdg_home(const char *key, const char *fallback)
34
+{
35
+ const char *e;
36
+
37
+ e = getenv(key);
38
+ if (e && *e) {
39
+ return strdup(e);
40
+ } else {
41
+ e = getenv("HOME");
42
+ if (!(e && *e))
43
+ e = getenv("USERPROFILE");
44
+ if (e && *e)
45
+ return spa_aprintf("%s/%s", e, fallback);
46
+ }
47
+ return NULL;
48
+}
49
+
50
+char *get_data_path(const char *data_dir, const char *data_type, const char *fname)
51
+{
52
+ static const char * const subpaths = {
53
+ "alsa-card-profile/mixer",
54
+ "alsa-card-profile",
55
+ };
56
+ const char *e;
57
+ spa_autofree char *base = NULL;
58
+ char *result;
59
+
60
+ if (data_dir)
61
+ if ((result = try_path(fname, data_dir)) != NULL)
62
+ return result;
63
+
64
+ e = getenv("ACP_PATHS_DIR");
65
+ if (e && *e && spa_streq(data_type, "paths"))
66
+ if ((result = try_path(fname, e)) != NULL)
67
+ return result;
68
+
69
+ e = getenv("ACP_PROFILES_DIR");
70
+ if (e && *e && spa_streq(data_type, "profile-sets"))
71
+ if ((result = try_path(fname, e)) != NULL)
72
+ return result;
73
+
74
+ base = get_xdg_home("XDG_CONFIG_HOME", ".config");
75
+ if (base) {
76
+ SPA_FOR_EACH_ELEMENT_VAR(subpaths, subpath) {
77
+ spa_autofree char *path = spa_aprintf("%s/%s/%s", base, *subpath, data_type);
78
+ if ((result = try_path(fname, path)) != NULL)
79
+ return result;
80
+ }
81
+ }
82
+
83
+ SPA_FOR_EACH_ELEMENT_VAR(subpaths, subpath) {
84
+ spa_autofree char *path = spa_aprintf("/etc/%s/%s", *subpath, data_type);
85
+ if ((result = try_path(fname, path)) != NULL)
86
+ return result;
87
+ }
88
+
89
+ spa_autofree char *path = spa_aprintf("%s/%s", PA_ALSA_DATA_DIR, data_type);
90
+ return pa_maybe_prefix_path(fname, path);
91
+}
92
pipewire-0.3.84.tar.gz/spa/plugins/alsa/acp/compat.h -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/acp/compat.h
Changed
26
1
2
PA_LOG_NOTICE = 2, /* Notice messages */
3
PA_LOG_INFO = 3, /* Info messages */
4
PA_LOG_DEBUG = 4, /* Debug messages */
5
+ PA_LOG_TRACE = 5,
6
PA_LOG_LEVEL_MAX
7
} pa_log_level_t;
8
9
10
#define pa_log_notice(fmt,...) pa_logl(PA_LOG_NOTICE, fmt, ##__VA_ARGS__)
11
#define pa_log_info(fmt,...) pa_logl(PA_LOG_INFO, fmt, ##__VA_ARGS__)
12
#define pa_log_debug(fmt,...) pa_logl(PA_LOG_DEBUG, fmt, ##__VA_ARGS__)
13
+#define pa_log_trace(fmt,...) pa_logl(PA_LOG_TRACE, fmt, ##__VA_ARGS__)
14
#define pa_log pa_log_error
15
16
#define pa_assert_se(expr) \
17
18
#endif
19
}
20
21
+char *get_data_path(const char *data_dir, const char *data_type, const char *fname);
22
+
23
#include <spa/support/i18n.h>
24
25
extern struct spa_i18n *acp_i18n;
26
pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-compress-offload-device.c -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/alsa-compress-offload-device.c
Changed
10
1
2
* hardware that can capture audio is difficult to do. The only hardware
3
* known is the Wolfson ADSP; the only driver in the kernel that exposes
4
* Compress-Offload capture devices is the one for that hardware. */
5
- assert(false);
6
+ spa_assert_not_reached();
7
}
8
9
info.change_mask = SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS;
10
pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
155
1
2
3
#include <spa/node/node.h>
4
#include <spa/node/utils.h>
5
-#include <spa/node/keys.h>
6
-#include <spa/monitor/device.h>
7
#include <spa/utils/keys.h>
8
#include <spa/utils/names.h>
9
#include <spa/utils/string.h>
10
11
props->use_chmap = DEFAULT_USE_CHMAP;
12
}
13
14
-static void emit_node_info(struct state *this, bool full)
15
-{
16
- uint64_t old = full ? this->info.change_mask : 0;
17
-
18
- if (full)
19
- this->info.change_mask = this->info_all;
20
- if (this->info.change_mask) {
21
- struct spa_dict_item items7;
22
- uint32_t i, n_items = 0;
23
- char latency64, period64, nperiods64, headroom64;
24
-
25
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "alsa");
26
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Sink");
27
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_DRIVER, "true");
28
- if (this->have_format) {
29
- snprintf(latency, sizeof(latency), "%lu/%d", this->buffer_frames / 2, this->rate);
30
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, latency);
31
- snprintf(period, sizeof(period), "%lu", this->period_frames);
32
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", period);
33
- snprintf(nperiods, sizeof(nperiods), "%lu",
34
- this->period_frames != 0 ? this->buffer_frames / this->period_frames : 0);
35
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", nperiods);
36
- snprintf(headroom, sizeof(headroom), "%u", this->headroom);
37
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", headroom);
38
- } else {
39
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, NULL);
40
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", NULL);
41
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", NULL);
42
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", NULL);
43
- }
44
- this->info.props = &SPA_DICT_INIT(items, n_items);
45
-
46
- if (this->info.change_mask & SPA_NODE_CHANGE_MASK_PARAMS) {
47
- for (i = 0; i < this->info.n_params; i++) {
48
- if (this->paramsi.user > 0) {
49
- this->paramsi.flags ^= SPA_PARAM_INFO_SERIAL;
50
- this->paramsi.user = 0;
51
- }
52
- }
53
- }
54
- spa_node_emit_info(&this->hooks, &this->info);
55
-
56
- this->info.change_mask = old;
57
- }
58
-}
59
-
60
-static void emit_port_info(struct state *this, bool full)
61
-{
62
- uint64_t old = full ? this->port_info.change_mask : 0;
63
-
64
- if (full)
65
- this->port_info.change_mask = this->port_info_all;
66
- if (this->port_info.change_mask) {
67
- uint32_t i;
68
-
69
- if (this->port_info.change_mask & SPA_PORT_CHANGE_MASK_PARAMS) {
70
- for (i = 0; i < this->port_info.n_params; i++) {
71
- if (this->port_paramsi.user > 0) {
72
- this->port_paramsi.flags ^= SPA_PARAM_INFO_SERIAL;
73
- this->port_paramsi.user = 0;
74
- }
75
- }
76
- }
77
- spa_node_emit_port_info(&this->hooks,
78
- SPA_DIRECTION_INPUT, 0, &this->port_info);
79
- this->port_info.change_mask = old;
80
- }
81
-}
82
-
83
static int impl_node_enum_params(void *object, int seq,
84
uint32_t id, uint32_t start, uint32_t num,
85
const struct spa_pod *filter)
86
87
info.ns = lat_ns;
88
handle_process_latency(this, &info);
89
}
90
- emit_node_info(this, false);
91
- emit_port_info(this, false);
92
+ spa_alsa_emit_node_info(this, false);
93
+ spa_alsa_emit_port_info(this, false);
94
break;
95
}
96
case SPA_PARAM_ProcessLatency:
97
98
99
handle_process_latency(this, &info);
100
101
- emit_node_info(this, false);
102
- emit_port_info(this, false);
103
+ spa_alsa_emit_node_info(this, false);
104
+ spa_alsa_emit_port_info(this, false);
105
break;
106
}
107
default:
108
109
110
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
111
112
- emit_node_info(this, true);
113
- emit_port_info(this, true);
114
+ spa_alsa_emit_node_info(this, true);
115
+ spa_alsa_emit_port_info(this, true);
116
117
spa_hook_list_join(&this->hooks, &save);
118
119
120
}
121
122
this->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
123
- emit_node_info(this, false);
124
+ spa_alsa_emit_node_info(this, false);
125
126
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_RATE;
127
this->port_info.rate = SPA_FRACTION(1, this->rate);
128
129
this->port_paramsPORT_Format = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
130
this->port_paramsPORT_Buffers = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
131
}
132
- emit_port_info(this, false);
133
+ spa_alsa_emit_port_info(this, false);
134
135
return err;
136
}
137
138
this->latencyinfo.direction = info;
139
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
140
this->port_paramsPORT_Latency.user++;
141
- emit_port_info(this, false);
142
+ spa_alsa_emit_port_info(this, false);
143
break;
144
}
145
case SPA_PARAM_Tag:
146
147
148
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
149
this->port_paramsPORT_Tag.user++;
150
- emit_port_info(this, false);
151
+ spa_alsa_emit_port_info(this, false);
152
}
153
break;
154
}
155
pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
157
1
2
3
#include <spa/node/node.h>
4
#include <spa/node/utils.h>
5
-#include <spa/node/keys.h>
6
#include <spa/utils/keys.h>
7
#include <spa/utils/names.h>
8
#include <spa/utils/list.h>
9
#include <spa/utils/string.h>
10
-#include <spa/monitor/device.h>
11
#include <spa/param/audio/format.h>
12
#include <spa/pod/filter.h>
13
#include <spa/pod/dynamic.h>
14
15
props->use_chmap = DEFAULT_USE_CHMAP;
16
}
17
18
-static void emit_node_info(struct state *this, bool full)
19
-{
20
- uint64_t old = full ? this->info.change_mask : 0;
21
- if (full)
22
- this->info.change_mask = this->info_all;
23
- if (this->info.change_mask) {
24
- struct spa_dict_item items7;
25
- uint32_t i, n_items = 0;
26
- char latency64, period64, nperiods64, headroom64;
27
-
28
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "alsa");
29
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Source");
30
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_DRIVER, "true");
31
- if (this->have_format) {
32
- snprintf(latency, sizeof(latency), "%lu/%d", this->buffer_frames / 2, this->rate);
33
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, latency);
34
- snprintf(period, sizeof(period), "%lu", this->period_frames);
35
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", period);
36
- snprintf(nperiods, sizeof(nperiods), "%lu",
37
- this->period_frames != 0 ? this->buffer_frames / this->period_frames : 0);
38
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", nperiods);
39
- snprintf(headroom, sizeof(headroom), "%u", this->headroom);
40
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", headroom);
41
- } else {
42
- itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, NULL);
43
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", NULL);
44
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", NULL);
45
- itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", NULL);
46
- }
47
- this->info.props = &SPA_DICT_INIT(items, n_items);
48
-
49
- if (this->info.change_mask & SPA_NODE_CHANGE_MASK_PARAMS) {
50
- for (i = 0; i < this->info.n_params; i++) {
51
- if (this->paramsi.user > 0) {
52
- this->paramsi.flags ^= SPA_PARAM_INFO_SERIAL;
53
- this->paramsi.user = 0;
54
- }
55
- }
56
- }
57
- spa_node_emit_info(&this->hooks, &this->info);
58
- this->info.change_mask = old;
59
- }
60
-}
61
-
62
-static void emit_port_info(struct state *this, bool full)
63
-{
64
- uint64_t old = full ? this->port_info.change_mask : 0;
65
- if (full)
66
- this->port_info.change_mask = this->port_info_all;
67
- if (this->port_info.change_mask) {
68
- uint32_t i;
69
-
70
- if (this->port_info.change_mask & SPA_PORT_CHANGE_MASK_PARAMS) {
71
- for (i = 0; i < this->port_info.n_params; i++) {
72
- if (this->port_paramsi.user > 0) {
73
- this->port_paramsi.flags ^= SPA_PARAM_INFO_SERIAL;
74
- this->port_paramsi.user = 0;
75
- }
76
- }
77
- }
78
- spa_node_emit_port_info(&this->hooks,
79
- SPA_DIRECTION_OUTPUT, 0, &this->port_info);
80
- this->port_info.change_mask = old;
81
- }
82
-}
83
-
84
-
85
static int impl_node_enum_params(void *object, int seq,
86
uint32_t id, uint32_t start, uint32_t num,
87
const struct spa_pod *filter)
88
89
handle_process_latency(this, &info);
90
}
91
92
- emit_node_info(this, false);
93
- emit_port_info(this, false);
94
+ spa_alsa_emit_node_info(this, false);
95
+ spa_alsa_emit_port_info(this, false);
96
break;
97
}
98
case SPA_PARAM_ProcessLatency:
99
100
101
handle_process_latency(this, &info);
102
103
- emit_node_info(this, false);
104
- emit_port_info(this, false);
105
+ spa_alsa_emit_node_info(this, false);
106
+ spa_alsa_emit_port_info(this, false);
107
break;
108
}
109
default:
110
111
112
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
113
114
- emit_node_info(this, true);
115
- emit_port_info(this, true);
116
+ spa_alsa_emit_node_info(this, true);
117
+ spa_alsa_emit_port_info(this, true);
118
119
spa_hook_list_join(&this->hooks, &save);
120
121
122
}
123
124
this->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
125
- emit_node_info(this, false);
126
+ spa_alsa_emit_node_info(this, false);
127
128
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_RATE;
129
this->port_info.rate = SPA_FRACTION(1, this->rate);
130
131
this->port_paramsPORT_Format = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
132
this->port_paramsPORT_Buffers = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
133
}
134
- emit_port_info(this, false);
135
+ spa_alsa_emit_port_info(this, false);
136
137
return err;
138
}
139
140
this->latencyinfo.direction = info;
141
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
142
this->port_paramsPORT_Latency.user++;
143
- emit_port_info(this, false);
144
+ spa_alsa_emit_port_info(this, false);
145
break;
146
}
147
case SPA_PARAM_Tag:
148
149
150
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
151
this->port_paramsPORT_Tag.user++;
152
- emit_port_info(this, false);
153
+ spa_alsa_emit_port_info(this, false);
154
}
155
break;
156
}
157
pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
201
1
2
#include <spa/utils/result.h>
3
#include <spa/support/system.h>
4
#include <spa/utils/keys.h>
5
+#include <spa/node/keys.h>
6
+#include <spa/monitor/device.h>
7
8
#include "alsa-pcm.h"
9
10
11
return 0;
12
}
13
14
+static struct spa_pod *enum_bind_ctl_propinfo(struct state *state, uint32_t idx, struct spa_pod_builder *b)
15
+{
16
+ char param_name1024;
17
+ char param_desc1024;
18
+ snd_ctl_elem_info_t *info = state->bound_ctlsidx.info;
19
+
20
+ if (!info) {
21
+ // This will end iteration early, so print a warning
22
+ spa_log_warn(state->log, "Don't have prop info for bind ctl, bailing");
23
+ return NULL;
24
+ }
25
+
26
+ snprintf(param_name, sizeof(param_name), "api.alsa.bind-ctl.%s",
27
+ snd_ctl_elem_info_get_name(info));
28
+ snprintf(param_desc, sizeof(param_desc), "Value of ALSA control '%s'",
29
+ snd_ctl_elem_info_get_name(info));
30
+
31
+ // We don't have meaningful default values
32
+ switch (snd_ctl_elem_info_get_type(info)) {
33
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
34
+ return spa_pod_builder_add_object(b,
35
+ SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
36
+ SPA_PROP_INFO_name, SPA_POD_String(param_name),
37
+ SPA_PROP_INFO_description, SPA_POD_String(param_desc),
38
+ SPA_PROP_INFO_type, SPA_POD_Bool(false),
39
+ SPA_PROP_INFO_params, SPA_POD_Bool(true));
40
+
41
+ case SND_CTL_ELEM_TYPE_INTEGER:
42
+ return spa_pod_builder_add_object(b,
43
+ SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
44
+ SPA_PROP_INFO_name, SPA_POD_String(param_name),
45
+ SPA_PROP_INFO_description, SPA_POD_String(param_desc),
46
+ SPA_PROP_INFO_type, SPA_POD_Int(0),
47
+ SPA_PROP_INFO_params, SPA_POD_Bool(true));
48
+ break;
49
+
50
+ case SND_CTL_ELEM_TYPE_INTEGER64:
51
+ return spa_pod_builder_add_object(b,
52
+ SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
53
+ SPA_PROP_INFO_name, SPA_POD_String(param_name),
54
+ SPA_PROP_INFO_description, SPA_POD_String(param_desc),
55
+ SPA_PROP_INFO_type, SPA_POD_Long(0),
56
+ SPA_PROP_INFO_params, SPA_POD_Bool(true));
57
+ break;
58
+
59
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
60
+ return spa_pod_builder_add_object(b,
61
+ SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
62
+ SPA_PROP_INFO_name, SPA_POD_String(param_name),
63
+ SPA_PROP_INFO_description, SPA_POD_String(param_desc),
64
+ SPA_PROP_INFO_type, SPA_POD_Int(0),
65
+ SPA_PROP_INFO_params, SPA_POD_Bool(true));
66
+ break;
67
+
68
+ default:
69
+ // FIXME: we can probably support bytes but the length seems unknown in the API
70
+ spa_log_warn(state->log, "%s ctl '%s' not supported",
71
+ snd_ctl_elem_type_name(snd_ctl_elem_info_get_type(info)),
72
+ snd_ctl_elem_info_get_name(info));
73
+ return NULL;
74
+ }
75
+}
76
+
77
struct spa_pod *spa_alsa_enum_propinfo(struct state *state,
78
uint32_t idx, struct spa_pod_builder *b)
79
{
80
81
SPA_PROP_INFO_type, SPA_POD_String(state->clock_name),
82
SPA_PROP_INFO_params, SPA_POD_Bool(true));
83
break;
84
+ // While adding params here, update the math in default too
85
default:
86
- return NULL;
87
+ idx -= 17;
88
+ if (idx <= state->num_bind_ctls)
89
+ param = enum_bind_ctl_propinfo(state, idx - 1, b);
90
+ else
91
+ return NULL;
92
}
93
return param;
94
}
95
96
+static void add_bind_ctl_param(struct state *state, const snd_ctl_elem_value_t *elem, const snd_ctl_elem_info_t *info,
97
+ struct spa_pod_builder *b)
98
+{
99
+ char param_name1024;
100
+
101
+ snprintf(param_name, sizeof(param_name), "api.alsa.bind-ctl.%s",
102
+ snd_ctl_elem_info_get_name(info));
103
+ spa_pod_builder_string(b, param_name);
104
+
105
+ switch (snd_ctl_elem_info_get_type(info)) {
106
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
107
+ spa_pod_builder_bool(b, snd_ctl_elem_value_get_boolean(elem, 0));
108
+ break;
109
+
110
+ case SND_CTL_ELEM_TYPE_INTEGER:
111
+ spa_pod_builder_int(b, snd_ctl_elem_value_get_integer(elem, 0));
112
+ break;
113
+
114
+ case SND_CTL_ELEM_TYPE_INTEGER64:
115
+ spa_pod_builder_long(b, snd_ctl_elem_value_get_integer64(elem, 0));
116
+ break;
117
+
118
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
119
+ spa_pod_builder_int(b, snd_ctl_elem_value_get_enumerated(elem, 0));
120
+ break;
121
+
122
+ default:
123
+ // FIXME: we can probably support bytes but the length seems unknown in the API
124
+ spa_log_warn(state->log, "%s ctl '%s' not supported",
125
+ snd_ctl_elem_type_name(snd_ctl_elem_info_get_type(info)),
126
+ snd_ctl_elem_info_get_name(info));
127
+ break;
128
+ }
129
+}
130
+
131
+static void add_bind_ctl_params(struct state *state, struct spa_pod_builder *b)
132
+{
133
+ int err;
134
+
135
+ for (unsigned int i = 0; i < state->num_bind_ctls; i++) {
136
+ err = snd_ctl_elem_read(state->ctl, state->bound_ctlsi.value);
137
+ if (err < 0) {
138
+ spa_log_warn(state->log, "Could not read elem value for '%s': %s",
139
+ state->bound_ctlsi.name, snd_strerror(err));
140
+ }
141
+
142
+ add_bind_ctl_param(state, state->bound_ctlsi.value, state->bound_ctlsi.info, b);
143
+ }
144
+}
145
+
146
int spa_alsa_add_prop_params(struct state *state, struct spa_pod_builder *b)
147
{
148
struct spa_pod_frame f1;
149
150
spa_pod_builder_string(b, "clock.name");
151
spa_pod_builder_string(b, state->clock_name);
152
153
+ add_bind_ctl_params(state, b);
154
+
155
spa_pod_builder_pop(b, &f0);
156
return 0;
157
}
158
159
{
160
}
161
162
+static void fill_device_name(struct state *state, const char *params, char device_name, size_t len)
163
+{
164
+ spa_scnprintf(device_name, len, "%s%s%s",
165
+ state->card->ucm_prefix ? state->card->ucm_prefix : "",
166
+ state->props.device, params ? params : "");
167
+}
168
+
169
+static void bind_ctl_event(struct spa_source *source)
170
+{
171
+ // We don't know if a bound element changed or not, so let's find out
172
+ struct state *state = source->data;
173
+ snd_ctl_elem_value_t *old_value;
174
+ bool changed = false;
175
+
176
+ snd_ctl_elem_value_alloca(&old_value);
177
+
178
+ for (unsigned int i = 0; i < state->num_bind_ctls; i++) {
179
+ int err;
180
+
181
+ snd_ctl_elem_value_copy(old_value, state->bound_ctlsi.value);
182
+
183
+ err = snd_ctl_elem_read(state->ctl, state->bound_ctlsi.value);
184
+ if (err < 0) {
185
+ spa_log_warn(state->log, "Could not read ctl '%s': %s",
186
+ state->bound_ctlsi.name, snd_strerror(err));
187
+ continue;
188
+ }
189
+
190
+ if (snd_ctl_elem_value_compare(old_value, state->bound_ctlsi.value) != 0) {
191
+ // We don't need to check all the ctls, if one changed,
192
+ // we'll emit a notification and they'll be read when
193
+ // the props are read
194
+ spa_log_debug(state->log, "bound ctl '%s' has changed", state->bound_ctlsi.name);
195
+ changed = true;
196
+ break;
197
+ }
198
+ }
199
+
200
+ if (changed) {
201
pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.85.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
45
1
2
unsigned int following:1;
3
};
4
5
+struct bound_ctl {
6
+ char name256;
7
+ snd_ctl_elem_info_t *info;
8
+ snd_ctl_elem_value_t *value;
9
+};
10
+
11
struct state {
12
struct spa_handle handle;
13
struct spa_node node;
14
15
16
struct spa_pod *tag2;
17
18
- /* Rate match via an ALSA ctl */
19
+ /* for rate match and bind ctls */
20
snd_ctl_t *ctl;
21
+
22
+ /* Rate match via an ALSA ctl */
23
snd_ctl_elem_value_t *pitch_elem;
24
double last_rate;
25
26
+ /* ALSA ctls exposed as params */
27
+ unsigned int num_bind_ctls;
28
+ struct bound_ctl bound_ctls16;
29
+ struct spa_source ctl_sourcesMAX_POLL;
30
+ int ctl_n_fds;
31
+
32
struct spa_list link;
33
34
struct spa_list followers;
35
36
37
void spa_alsa_recycle_buffer(struct state *state, uint32_t buffer_id);
38
39
+void spa_alsa_emit_node_info(struct state *state, bool full);
40
+void spa_alsa_emit_port_info(struct state *state, bool full);
41
+
42
static inline uint32_t spa_alsa_format_from_name(const char *name, size_t len)
43
{
44
int i;
45
pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c -> pipewire-0.3.85.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c
Changed
26
1
2
spa_pod_builder_int(b, 8000);
3
spa_pod_builder_int(b, 8000);
4
}
5
- if (i == 0)
6
- return -EINVAL;
7
if (i > 1)
8
choice->body.type = SPA_CHOICE_Enum;
9
spa_pod_builder_pop(b, &f1);
10
11
+ if (i == 0)
12
+ return -EINVAL;
13
+
14
res = channels_to_positions(conf.channels, position);
15
if (res == 0)
16
return -EINVAL;
17
18
if (endpoint_qos->latency >= 0x0005 && endpoint_qos->latency <= 0x0FA0)
19
/* Values outside the range are RFU */
20
qos->latency = endpoint_qos->latency;
21
+ if (endpoint_qos->retransmission)
22
+ qos->retransmission = endpoint_qos->retransmission;
23
if (endpoint_qos->delay_min)
24
qos->delay = SPA_MAX(qos->delay, endpoint_qos->delay_min);
25
if (endpoint_qos->delay_max)
26
pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.85.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
36
1
2
goto error_invalid;
3
}
4
5
+ spa_log_debug(monitor->log, "select qos: interval:%d framing:%d phy:%d sdu:%d "
6
+ "rtn:%d latency:%d delay:%d target_latency:%d",
7
+ qos.interval, qos.framing, qos.phy, qos.sdu, qos.retransmission,
8
+ qos.latency, (int)qos.delay, qos.target_latency);
9
+
10
dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
11
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &entry_key);
12
dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, "a{sv}", &variant);
13
14
SPA_BT_PROFILE_BAP_BROADCAST_SINK | SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)))
15
continue;
16
17
+ if (t->device->adapter != transport->device->adapter)
18
+ continue;
19
+
20
if ((transport->profile == SPA_BT_PROFILE_BAP_BROADCAST_SINK) ||
21
(transport->profile == SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)) {
22
if (t->bap_big != transport->bap_big)
23
24
/* For broadcast there initiator moves the transport state to SPA_BT_TRANSPORT_STATE_ACTIVE */
25
if ((transport->profile == SPA_BT_PROFILE_BAP_BROADCAST_SINK) ||
26
(transport->profile == SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)) {
27
- spa_bt_transport_set_state(transport, SPA_BT_TRANSPORT_STATE_ACTIVE);
28
+ spa_bt_transport_set_state(t_linked, SPA_BT_TRANSPORT_STATE_ACTIVE);
29
} else {
30
if (!transport->bap_initiator)
31
- spa_bt_transport_set_state(transport, SPA_BT_TRANSPORT_STATE_ACTIVE);
32
+ spa_bt_transport_set_state(t_linked, SPA_BT_TRANSPORT_STATE_ACTIVE);
33
}
34
}
35
36
pipewire-0.3.84.tar.gz/spa/plugins/bluez5/codec-loader.c -> pipewire-0.3.85.tar.gz/spa/plugins/bluez5/codec-loader.c
Changed
10
1
2
#undef MEDIA_CODEC_FACTORY_LIB
3
};
4
5
- impl = calloc(sizeof(struct impl), 1);
6
+ impl = calloc(1, sizeof(struct impl));
7
if (impl == NULL)
8
return NULL;
9
10
pipewire-0.3.84.tar.gz/spa/plugins/bluez5/iso-io.c -> pipewire-0.3.85.tar.gz/spa/plugins/bluez5/iso-io.c
Changed
77
1
2
struct spa_source source;
3
struct spa_list streams;
4
int timerfd;
5
- uint8_t cig;
6
+ uint8_t id;
7
uint64_t next;
8
uint64_t duration;
9
uint32_t paused;
10
11
if ((res = spa_system_timerfd_read(group->data_system, group->timerfd, &exp)) < 0) {
12
if (res != -EAGAIN)
13
spa_log_warn(group->log, "%p: ISO group:%u error reading timerfd: %s",
14
- group, group->cig, spa_strerror(res));
15
+ group, group->id, spa_strerror(res));
16
return;
17
}
18
19
20
21
if (group->paused) {
22
--group->paused;
23
- spa_log_debug(group->log, "%p: ISO group:%d paused:%u", group, group->cig, group->paused);
24
+ spa_log_debug(group->log, "%p: ISO group:%u paused:%u", group, group->id, group->paused);
25
}
26
27
/* Produce output */
28
29
}
30
if (stream->this.size == 0) {
31
spa_log_debug(group->log, "%p: ISO group:%u miss fd:%d",
32
- group, group->cig, stream->fd);
33
+ group, group->id, stream->fd);
34
if (stream_silence(stream) < 0) {
35
fail = true;
36
continue;
37
38
}
39
40
spa_log_trace(group->log, "%p: ISO group:%u sent fd:%d size:%u ts:%u idle:%d res:%d",
41
- group, group->cig, stream->fd, (unsigned)stream->this.size,
42
+ group, group->id, stream->fd, (unsigned)stream->this.size,
43
(unsigned)stream->this.timestamp, stream->idle, res);
44
45
stream->this.size = 0;
46
47
struct spa_log *log, struct spa_loop *data_loop, struct spa_system *data_system)
48
{
49
struct group *group;
50
+ uint8_t id;
51
52
if (t->bap_interval <= 5000) {
53
errno = EINVAL;
54
return NULL;
55
}
56
57
+ if (t->profile & (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE)) {
58
+ id = t->bap_cig;
59
+ } else if (t->profile & (SPA_BT_PROFILE_BAP_BROADCAST_SINK | SPA_BT_PROFILE_BAP_BROADCAST_SOURCE)) {
60
+ id = t->bap_big;
61
+ } else {
62
+ errno = EINVAL;
63
+ return NULL;
64
+ }
65
+
66
group = calloc(1, sizeof(struct group));
67
if (group == NULL)
68
return NULL;
69
70
spa_log_topic_init(log, &log_topic);
71
72
- group->cig = t->bap_cig;
73
+ group->id = id;
74
group->log = log;
75
group->data_loop = data_loop;
76
group->data_system = data_system;
77
pipewire-0.3.84.tar.gz/spa/plugins/bluez5/media-sink.c -> pipewire-0.3.85.tar.gz/spa/plugins/bluez5/media-sink.c
Changed
31
1
2
3
static void emit_node_info(struct impl *this, bool full)
4
{
5
+ char node_group_buf256;
6
+ char *node_group = NULL;
7
+
8
+ if (this->transport && (this->transport->profile & SPA_BT_PROFILE_BAP_SINK)) {
9
+ spa_scnprintf(node_group_buf, sizeof(node_group_buf), "bluez-iso-%s-cig-%d",
10
+ this->transport->device->adapter->address,
11
+ this->transport->bap_cig);
12
+ node_group = node_group_buf;
13
+ } else if (this->transport && (this->transport->profile & SPA_BT_PROFILE_BAP_BROADCAST_SINK)) {
14
+ spa_scnprintf(node_group_buf, sizeof(node_group_buf), "bluez-iso-%s-big-%d",
15
+ this->transport->device->adapter->address,
16
+ this->transport->bap_big);
17
+ node_group = node_group_buf;
18
+ }
19
+
20
struct spa_dict_item node_info_items = {
21
{ SPA_KEY_DEVICE_API, "bluez5" },
22
{ SPA_KEY_MEDIA_CLASS, this->is_internal ? "Audio/Sink/Internal" :
23
24
{ "media.name", ((this->transport && this->transport->device->name) ?
25
this->transport->device->name : this->codec->bap ? "BAP" : "A2DP" ) },
26
{ SPA_KEY_NODE_DRIVER, this->is_output ? "true" : "false" },
27
+ { "node.group", node_group },
28
};
29
uint64_t old = full ? this->info.change_mask : 0;
30
if (full)
31
pipewire-0.3.84.tar.gz/spa/plugins/libcamera/libcamera-device.cpp -> pipewire-0.3.85.tar.gz/spa/plugins/libcamera/libcamera-device.cpp
Changed
24
1
2
uint32_t n_items = 0;
3
struct spa_device_info info;
4
struct spa_param_info params2;
5
- char path256, model256, name256, devices_str128;
6
+ char path256, name256, devices_str128;
7
struct spa_strbuf buf;
8
9
info = SPA_DEVICE_INFO_INIT();
10
11
if (auto location = cameraLoc(impl->camera.get()))
12
ADD_ITEM(SPA_KEY_API_LIBCAMERA_LOCATION, location);
13
14
- snprintf(model, sizeof(model), "%s", cameraModel(impl->camera.get()).c_str());
15
- ADD_ITEM(SPA_KEY_DEVICE_PRODUCT_NAME, model);
16
- ADD_ITEM(SPA_KEY_DEVICE_DESCRIPTION, model);
17
+ const auto model = cameraModel(impl->camera.get());
18
+ ADD_ITEM(SPA_KEY_DEVICE_PRODUCT_NAME, model.c_str());
19
+ ADD_ITEM(SPA_KEY_DEVICE_DESCRIPTION, model.c_str());
20
+
21
snprintf(name, sizeof(name), "libcamera_device.%s", impl->device_id.c_str());
22
ADD_ITEM(SPA_KEY_DEVICE_NAME, name);
23
24
pipewire-0.3.84.tar.gz/src/daemon/pipewire-pulse.conf.in -> pipewire-0.3.85.tar.gz/src/daemon/pipewire-pulse.conf.in
Changed
10
1
2
rt.prio = 65
3
#rt.time.soft = -1
4
#rt.time.hard = -1
5
+ #uclamp.min = 0
6
+ #uclamp.max = 1024
7
}
8
flags = ifexists nofail
9
}
10
pipewire-0.3.84.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.85.tar.gz/src/daemon/pipewire.conf.in
Changed
19
1
2
3
# Uses realtime scheduling to boost the audio thread priorities. This uses
4
# RTKit if the user doesn't have permission to use regular realtime
5
- # scheduling.
6
+ # scheduling. You can also clamp utilisation values to improve scheduling
7
+ # on embedded and heterogeneous systems, e.g. Arm big.LITTLE devices.
8
{ name = libpipewire-module-rt
9
args = {
10
nice.level = -11
11
#rt.prio = 88
12
#rt.time.soft = -1
13
#rt.time.hard = -1
14
+ #uclamp.min = 0
15
+ #uclamp.max = 1024
16
}
17
flags = ifexists nofail
18
}
19
pipewire-0.3.84.tar.gz/src/daemon/systemd/system/meson.build -> pipewire-0.3.85.tar.gz/src/daemon/systemd/system/meson.build
Changed
10
1
2
systemd_system_services_dir = get_option('systemd-system-unit-dir')
3
endif
4
5
-install_data(sources : 'pipewire.socket',
6
+install_data(sources : 'pipewire.socket', 'pipewire-manager.socket',
7
install_dir : systemd_system_services_dir)
8
9
systemd_config = configuration_data()
10
pipewire-0.3.85.tar.gz/src/daemon/systemd/system/pipewire-manager.socket
Added
15
1
2
+Unit
3
+Description=PipeWire Multimedia System Manager Socket
4
+
5
+Socket
6
+Service=pipewire.service
7
+Priority=6
8
+ListenStream=%t/pipewire/pipewire-0-manager
9
+SocketUser=pipewire
10
+SocketGroup=pipewire
11
+SocketMode=0600
12
+
13
+Install
14
+WantedBy=sockets.target
15
pipewire-0.3.84.tar.gz/src/daemon/systemd/system/pipewire.service.in -> pipewire-0.3.85.tar.gz/src/daemon/systemd/system/pipewire.service.in
Changed
8
1
2
Environment=PIPEWIRE_RUNTIME_DIR=%t/pipewire
3
4
Install
5
-Also=pipewire.socket
6
+Also=pipewire.socket pipewire-manager.socket
7
WantedBy=default.target
8
pipewire-0.3.84.tar.gz/src/daemon/systemd/system/pipewire.socket -> pipewire-0.3.85.tar.gz/src/daemon/systemd/system/pipewire.socket
Changed
13
1
2
Unit
3
-Description=PipeWire Multimedia System Sockets
4
+Description=PipeWire Multimedia System Socket
5
6
Socket
7
Priority=6
8
ListenStream=%t/pipewire/pipewire-0
9
-ListenStream=%t/pipewire/pipewire-0-manager
10
SocketUser=pipewire
11
SocketGroup=pipewire
12
SocketMode=0660
13
pipewire-0.3.84.tar.gz/src/gst/gstpipewiresink.c -> pipewire-0.3.85.tar.gz/src/gst/gstpipewiresink.c
Changed
17
1
2
pw_stream_trigger_process (pwsink->stream);
3
break;
4
case PW_STREAM_STATE_ERROR:
5
- GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED,
6
- ("stream error: %s", error), (NULL));
7
+ /* make the error permanent, if it is not already;
8
+ pw_stream_set_error() will recursively call us again */
9
+ if (pw_stream_get_state (pwsink->stream, NULL) != PW_STREAM_STATE_ERROR)
10
+ pw_stream_set_error (pwsink->stream, -EPIPE, "%s", error);
11
+ else
12
+ GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED,
13
+ ("stream error: %s", error), (NULL));
14
break;
15
}
16
pw_thread_loop_signal (pwsink->core->loop, FALSE);
17
pipewire-0.3.84.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.85.tar.gz/src/gst/gstpipewiresrc.c
Changed
18
1
2
case PW_STREAM_STATE_STREAMING:
3
break;
4
case PW_STREAM_STATE_ERROR:
5
- pw_stream_set_error (pwsrc->stream, -EPIPE, "%s", error);
6
- GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED,
7
- ("stream error: %s", error), (NULL));
8
+ /* make the error permanent, if it is not already;
9
+ pw_stream_set_error() will recursively call us again */
10
+ if (pw_stream_get_state (pwsrc->stream, NULL) != PW_STREAM_STATE_ERROR)
11
+ pw_stream_set_error (pwsrc->stream, -EPIPE, "%s", error);
12
+ else
13
+ GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED,
14
+ ("stream error: %s", error), (NULL));
15
break;
16
}
17
pw_thread_loop_signal (pwsrc->core->loop, FALSE);
18
pipewire-0.3.84.tar.gz/src/modules/meson.build -> pipewire-0.3.85.tar.gz/src/modules/meson.build
Changed
13
1
2
summary({'ffado-driver': build_module_ffado_driver}, bool_yn: true, section: 'Optional Modules')
3
4
opus_custom_h = cc.has_header('opus/opus_custom.h', dependencies: opus_dep)
5
+opus_custom_lib = cc.has_function('opus_custom_encoder_ctl', dependencies: opus_dep)
6
+
7
# One would imagine that opus_dep is a requirement but for some reason it's not, so we need to manually check that
8
-if opus_dep.found() and opus_custom_h
9
+if opus_dep.found() and opus_custom_h and opus_custom_lib
10
opus_custom_dep = declare_dependency(compile_args: '-DHAVE_OPUS_CUSTOM', dependencies: opus_dep)
11
else
12
opus_custom_dep = dependency('', required: false)
13
pipewire-0.3.84.tar.gz/src/modules/module-pipe-tunnel.c -> pipewire-0.3.85.tar.gz/src/modules/module-pipe-tunnel.c
Changed
169
1
2
* ## Module Options
3
*
4
* - `tunnel.mode`: the desired tunnel to create. (Default `playback`)
5
+ * - `tunnel.may-pause`: if the tunnel stream is allowed to pause on xrun
6
* - `pipe.filename`: the filename of the pipe.
7
* - `stream.props`: Extra properties for the local stream.
8
*
9
10
* When `tunnel.mode` is `source`, a source node is created. Samples read from
11
* the the pipe will be made available on the source.
12
*
13
+ * `tunnel.may-pause` allows the tunnel stream to become inactive (paused) when
14
+ * there is no data in the fifo or when the fifo is full. For `capture` and
15
+ * `playback` `tunnel.mode` this is by default true. For `source` and `sink`
16
+ * `tunnel.mode`, this is by default false. A paused stream will consume no
17
+ * CPU and will resume when the fifo becomes readable or writable again.
18
+ *
19
* When `pipe.filename` is not given, a default fifo in `/tmp/fifo_input` or
20
* `/tmp/fifo_output` will be created that can be written and read respectively,
21
* depending on the selected `tunnel.mode`.
22
23
* { name = libpipewire-module-pipe-tunnel
24
* args = {
25
* tunnel.mode = playback
26
+ * #tunnel.may-pause = true
27
* # Set the pipe name to tunnel to
28
* pipe.filename = "/tmp/fifo_output"
29
* #audio.format=<sample format>
30
31
"( audio.channels=<number of channels> ) " \
32
"( audio.position=<channel map> ) " \
33
"( tunnel.mode=capture|playback|sink|source )" \
34
+ "( tunnel.may-pause=<bool, if the stream can pause> )" \
35
"( pipe.filename=<filename> )" \
36
"( stream.props=<properties> ) "
37
38
39
40
struct impl {
41
struct pw_context *context;
42
+ struct pw_loop *main_loop;
43
struct pw_loop *data_loop;
44
45
#define MODE_PLAYBACK 0
46
47
unsigned int do_disconnect:1;
48
unsigned int driving:1;
49
unsigned int have_sync:1;
50
+ unsigned int may_pause:1;
51
+ unsigned int paused:1;
52
53
struct spa_ringbuffer ring;
54
void *buffer;
55
56
break;
57
case PW_STREAM_STATE_PAUSED:
58
if (impl->direction == PW_DIRECTION_OUTPUT) {
59
- pw_loop_update_io(impl->data_loop, impl->socket, 0);
60
+ pw_loop_update_io(impl->data_loop, impl->socket, impl->paused ? SPA_IO_IN : 0);
61
set_timeout(impl, 0);
62
}
63
break;
64
65
}
66
}
67
68
+static int do_pause(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
69
+ size_t size, void *user_data)
70
+{
71
+ struct impl *impl = user_data;
72
+ const bool *paused = data;
73
+ pw_log_info("set paused: %d", *paused);
74
+ impl->paused = *paused;
75
+ pw_stream_set_active(impl->stream, !*paused);
76
+ return 0;
77
+}
78
+
79
+static void pause_stream(struct impl *impl, bool paused)
80
+{
81
+ if (!impl->may_pause)
82
+ return;
83
+ if (impl->direction == PW_DIRECTION_INPUT)
84
+ pw_loop_update_io(impl->data_loop, impl->socket, paused ? SPA_IO_OUT : 0);
85
+ pw_loop_invoke(impl->main_loop, do_pause, 1, &paused, sizeof(bool), false, impl);
86
+}
87
+
88
static void playback_stream_process(void *data)
89
{
90
struct impl *impl = data;
91
92
continue;
93
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
94
/* Don't continue writing */
95
- pw_log_debug("pipe (%s) overrun: %m",
96
- impl->filename);
97
+ pw_log_debug("pipe (%s) overrun: %m", impl->filename);
98
+ pause_stream(impl, true);
99
break;
100
} else {
101
pw_log_warn("Failed to write to pipe (%s): %m",
102
103
104
if (avail < (int32_t)size) {
105
memset(bd->data, 0, size);
106
- if (avail > 0)
107
+ if (avail >= 0) {
108
pw_log_warn("underrun %d < %u", avail, size);
109
+ pause_stream(impl, true);
110
+ }
111
impl->have_sync = false;
112
}
113
if (avail > (int32_t)RINGBUFFER_SIZE) {
114
115
paramsn_params++ = spa_format_audio_raw_build(&b,
116
SPA_PARAM_EnumFormat, &impl->info);
117
118
+ impl->paused = false;
119
+
120
if ((res = pw_stream_connect(impl->stream,
121
impl->direction,
122
PW_ID_ANY,
123
124
pw_loop_update_io(impl->data_loop, impl->socket, 0);
125
return;
126
}
127
+ if (impl->paused)
128
+ pause_stream(impl, false);
129
if (mask & SPA_IO_IN)
130
handle_pipe_read(impl);
131
}
132
133
134
impl->module = module;
135
impl->context = context;
136
+ impl->main_loop = pw_context_get_main_loop(context);
137
data_loop = pw_context_get_data_loop(context);
138
impl->data_loop = pw_data_loop_get_loop(data_loop);
139
140
141
if (spa_streq(str, "capture")) {
142
impl->mode = MODE_CAPTURE;
143
impl->direction = PW_DIRECTION_INPUT;
144
+ impl->may_pause = true;
145
} else if (spa_streq(str, "playback")) {
146
impl->mode = MODE_PLAYBACK;
147
impl->direction = PW_DIRECTION_OUTPUT;
148
+ impl->may_pause = true;
149
}else if (spa_streq(str, "sink")) {
150
impl->mode = MODE_SINK;
151
impl->direction = PW_DIRECTION_INPUT;
152
+ impl->may_pause = false;
153
media_class = "Audio/Sink";
154
} else if (spa_streq(str, "source")) {
155
impl->mode = MODE_SOURCE;
156
impl->direction = PW_DIRECTION_OUTPUT;
157
+ impl->may_pause = false;
158
media_class = "Audio/Source";
159
} else {
160
pw_log_error("invalid tunnel.mode '%s'", str);
161
res = -EINVAL;
162
goto error;
163
}
164
+ if ((str = pw_properties_get(props, "tunnel.may-pause")) != NULL)
165
+ impl->may_pause = spa_atob(str);
166
167
if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL)
168
pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
169
pipewire-0.3.84.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.85.tar.gz/src/modules/module-protocol-native.c
Changed
17
1
2
{
3
struct pw_core *core = proxy->core;
4
struct client *impl = SPA_CONTAINER_OF(core->conn, struct client, this);
5
+ ensure_loop(impl->context->main_loop);
6
assert_single_pod(builder);
7
marshal_core_footers(&impl->footer_state, core, builder);
8
return core->send_seq = pw_protocol_native_connection_end(impl->connection, builder);
9
10
{
11
struct client_data *data = resource->client->user_data;
12
struct pw_impl_client *client = resource->client;
13
+ ensure_loop(client->context->main_loop);
14
assert_single_pod(builder);
15
marshal_client_footers(&data->footer_state, client, builder);
16
return client->send_seq = pw_protocol_native_connection_end(data->connection, builder);
17
pipewire-0.3.84.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.85.tar.gz/src/modules/module-raop-sink.c
Changed
18
1
2
if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL)
3
pw_properties_setf(props, PW_KEY_NODE_NAME, "raop_sink.%s.%s.%s",
4
hostname, ip, port);
5
+ if (pw_properties_get(props, PW_KEY_MEDIA_NAME) == NULL)
6
+ pw_properties_setf(props, PW_KEY_MEDIA_NAME, "RAOP to %s", name);
7
if (pw_properties_get(props, PW_KEY_NODE_DESCRIPTION) == NULL)
8
pw_properties_setf(props, PW_KEY_NODE_DESCRIPTION, "%s", name);
9
if (pw_properties_get(props, PW_KEY_NODE_LATENCY) == NULL)
10
11
copy_props(impl, props, PW_KEY_NODE_VIRTUAL);
12
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
13
copy_props(impl, props, PW_KEY_MEDIA_FORMAT);
14
+ copy_props(impl, props, PW_KEY_MEDIA_NAME);
15
copy_props(impl, props, "net.mtu");
16
copy_props(impl, props, "rtp.sender-ts-offset");
17
copy_props(impl, props, "sess.media");
18
pipewire-0.3.84.tar.gz/src/modules/module-rt.c -> pipewire-0.3.85.tar.gz/src/modules/module-rt.c
Changed
186
1
2
* - `rlimits.enabled`: enable the use of rtlimits, default true.
3
* - `rtportal.enabled`: enable the use of realtime portal, default true
4
* - `rtkit.enabled`: enable the use of rtkit, default true
5
+ * - `uclamp.min`: the minimum utilisation value the scheduler should consider
6
+ * - `uclamp.max`: the maximum utilisation value the scheduler should consider
7
8
* The nice level is by default set to an invalid value so that clients don't
9
* automatically have the nice level raised.
10
11
* #rlimits.enabled = true
12
* #rtportal.enabled = true
13
* #rtkit.enabled = true
14
+ * #uclamp.min = 0
15
+ * #uclamp.max = 1024
16
* }
17
* flags = ifexists nofail
18
* }
19
20
#define DEFAULT_RT_TIME_SOFT -1
21
#define DEFAULT_RT_TIME_HARD -1
22
23
+#define DEFAULT_UCLAMP_MIN 0
24
+#define DEFAULT_UCLAMP_MAX 1024
25
+
26
#define MODULE_USAGE "( nice.level=<priority: default "SPA_STRINGIFY(DEFAULT_NICE_LEVEL)"(don't change)> ) " \
27
"( rt.prio=<priority: default "SPA_STRINGIFY(DEFAULT_RT_PRIO)"> ) " \
28
"( rt.time.soft=<in usec: default "SPA_STRINGIFY(DEFAULT_RT_TIME_SOFT)"> ) " \
29
"( rt.time.hard=<in usec: default "SPA_STRINGIFY(DEFAULT_RT_TIME_HARD)"> ) " \
30
"( rlimits.enabled=<default true> ) " \
31
"( rtportal.enabled=<default true> ) " \
32
- "( rtkit.enabled=<default true> ) "
33
+ "( rtkit.enabled=<default true> ) " \
34
+ "( uclamp.min=<default "SPA_STRINGIFY(DEFAULT_UCLAMP_MIN)"> ) " \
35
+ "( uclamp.max=<default "SPA_STRINGIFY(DEFAULT_UCLAMP_MAX)"> )"
36
37
static const struct spa_dict_item module_props = {
38
{ PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" },
39
40
rlim_t rt_time_soft;
41
rlim_t rt_time_hard;
42
43
+ int uclamp_min;
44
+ int uclamp_max;
45
+
46
struct spa_hook module_listener;
47
48
unsigned rlimits_enabled:1;
49
50
int err, old_policy, new_policy, min, max;
51
struct sched_param old_sched_params;
52
struct sched_param new_sched_params;
53
+ struct rlimit old_rlim;
54
+ struct rlimit no_rlim = { -1, -1 };
55
int try = 0;
56
57
if (!impl->rlimits_enabled)
58
59
if ((old_policy & PW_SCHED_RESET_ON_FORK) != 0)
60
new_policy |= PW_SCHED_RESET_ON_FORK;
61
62
+ /* Disable RLIMIT_RTTIME while trying new_policy. */
63
+ if ((err = getrlimit(RLIMIT_RTTIME, &old_rlim)) < 0)
64
+ pw_log_debug("getrlimit() failed: %s", spa_strerror(err));
65
+ if ((err = setrlimit(RLIMIT_RTTIME, &no_rlim)) < 0)
66
+ pw_log_debug("setrlimit() failed: %s", spa_strerror(err));
67
+
68
if (pthread_setschedparam(pthread_self(), new_policy, &new_sched_params) == 0) {
69
impl->rt_prio = new_sched_params.sched_priority;
70
pthread_setschedparam(pthread_self(), old_policy, &old_sched_params);
71
+ if ((err = setrlimit(RLIMIT_RTTIME, &old_rlim)) < 0)
72
+ pw_log_debug("setrlimit() failed: %s", spa_strerror(err));
73
return true;
74
}
75
+ if ((err = setrlimit(RLIMIT_RTTIME, &old_rlim)) < 0)
76
+ pw_log_debug("setrlimit() failed: %s", spa_strerror(err));
77
}
78
pw_log_info("Can't set rt prio to %d: %m (try increasing rlimits)", (int)priority);
79
return false;
80
81
return res;
82
}
83
84
-static int set_rlimit(struct impl *impl)
85
+static int set_rlimit(struct rlimit *rlim)
86
{
87
int res = 0;
88
89
- if (setrlimit(RLIMIT_RTTIME, &impl->rl) < 0)
90
+ if (setrlimit(RLIMIT_RTTIME, rlim) < 0)
91
res = -errno;
92
93
if (res < 0)
94
pw_log_debug("setrlimit() failed: %s", spa_strerror(res));
95
else
96
pw_log_debug("rt.time.soft:%"PRIi64" rt.time.hard:%"PRIi64,
97
- (int64_t)impl->rl.rlim_cur, (int64_t)impl->rl.rlim_max);
98
+ (int64_t)rlim->rlim_cur, (int64_t)rlim->rlim_max);
99
100
return res;
101
}
102
103
impl->rl.rlim_cur = SPA_MIN(impl->rl.rlim_cur, impl->rttime_max);
104
impl->rl.rlim_max = SPA_MIN(impl->rl.rlim_max, impl->rttime_max);
105
106
- set_rlimit(impl);
107
+ set_rlimit(&impl->rl);
108
109
return 0;
110
}
111
#endif /* HAVE_DBUS */
112
113
+int set_uclamp(int uclamp_min, int uclamp_max, pid_t pid) {
114
+#ifdef __linux__
115
+ int ret;
116
+ struct sched_attr {
117
+ uint32_t size;
118
+ uint32_t sched_policy;
119
+ uint64_t sched_flags;
120
+ int32_t sched_nice;
121
+ uint32_t sched_priority;
122
+ uint64_t sched_runtime;
123
+ uint64_t sched_deadline;
124
+ uint64_t sched_period;
125
+ uint32_t sched_util_min;
126
+ uint32_t sched_util_max;
127
+ } attr;
128
+
129
+ ret = syscall(SYS_sched_getattr, pid, &attr, sizeof(struct sched_attr), 0);
130
+ if (ret) {
131
+ pw_log_warn("Could not retrieve scheduler attributes: %d", -errno);
132
+ return -errno;
133
+ }
134
+
135
+ /* SCHED_FLAG_KEEP_POLICY |
136
+ * SCHED_FLAG_KEEP_PARAMS |
137
+ * SCHED_FLAG_UTIL_CLAMP_MIN |
138
+ * SCHED_FLAG_UTIL_CLAMP_MAX */
139
+ attr.sched_flags = 0x8 | 0x10 | 0x20 | 0x40;
140
+ attr.sched_util_min = uclamp_min;
141
+ attr.sched_util_max = uclamp_max;
142
+
143
+ ret = syscall(SYS_sched_setattr, pid, &attr, 0);
144
+
145
+ if (ret) {
146
+ pw_log_warn("Could not set scheduler attributes: %d", -errno);
147
+ return -errno;
148
+ }
149
+ return 0;
150
+#else
151
+ pw_log_warn("Setting UCLAMP values is only supported on Linux");
152
+ return -EOPNOTSUPP;
153
+#endif /* __linux__ */
154
+}
155
+
156
+
157
SPA_EXPORT
158
int pipewire__module_init(struct pw_impl_module *module, const char *args)
159
{
160
161
impl->rlimits_enabled = pw_properties_get_bool(props, "rlimits.enabled", true);
162
impl->rtportal_enabled = pw_properties_get_bool(props, "rtportal.enabled", true);
163
impl->rtkit_enabled = pw_properties_get_bool(props, "rtkit.enabled", true);
164
+ impl->uclamp_min = pw_properties_get_int32(props, "uclamp.min", DEFAULT_UCLAMP_MIN);
165
+ impl->uclamp_max = pw_properties_get_int32(props, "uclamp.max", DEFAULT_UCLAMP_MAX);
166
167
impl->rl.rlim_cur = impl->rt_time_soft;
168
impl->rl.rlim_max = impl->rt_time_hard;
169
170
use_rtkit = can_use_rtkit;
171
}
172
if (!use_rtkit)
173
- set_rlimit(impl);
174
+ set_rlimit(&impl->rl);
175
+
176
+ if (impl->uclamp_max > 1024) {
177
+ pw_log_warn("uclamp.max out of bounds. Got %d, clamping to 1024.", impl->uclamp_max);
178
+ impl->uclamp_max = 1024;
179
+ }
180
+
181
+ if (impl->uclamp_min || impl->uclamp_max < 1024)
182
+ set_uclamp(impl->uclamp_min, impl->uclamp_max, impl->main_pid);
183
184
#ifdef HAVE_DBUS
185
impl->use_rtkit = use_rtkit;
186
pipewire-0.3.84.tar.gz/src/pipewire/context.c -> pipewire-0.3.85.tar.gz/src/pipewire/context.c
Changed
77
1
2
PW_LOG_TOPIC_EXTERN(log_context);
3
#define PW_LOG_TOPIC_DEFAULT log_context
4
5
+#define MAX_HOPS 64
6
+
7
/** \cond */
8
struct impl {
9
struct pw_context this;
10
11
* and groups to active nodes and make them recursively runnable as well.
12
*/
13
static inline int run_nodes(struct pw_context *context, struct pw_impl_node *node,
14
- struct spa_list *nodes, enum pw_direction direction)
15
+ struct spa_list *nodes, enum pw_direction direction, int hop)
16
{
17
struct pw_impl_node *t;
18
struct pw_impl_port *p;
19
struct pw_impl_link *l;
20
21
+ if (hop == MAX_HOPS) {
22
+ pw_log_warn("exceeded hops (%d)", hop);
23
+ return -EIO;
24
+ }
25
+
26
pw_log_debug("node %p: '%s' direction:%s", node, node->name,
27
pw_direction_as_string(direction));
28
29
30
if (!t->active || !l->prepared ||
31
(!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction)))
32
continue;
33
+ if (t->driving && p->node == t)
34
+ continue;
35
36
pw_log_debug(" peer %p: '%s'", t, t->name);
37
t->runnable = true;
38
- run_nodes(context, t, nodes, direction);
39
+ run_nodes(context, t, nodes, direction, hop + 1);
40
}
41
}
42
} else {
43
44
if (!t->active || !l->prepared ||
45
(!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction)))
46
continue;
47
+ if (t->driving && p->node == t)
48
+ continue;
49
50
pw_log_debug(" peer %p: '%s'", t, t->name);
51
t->runnable = true;
52
- run_nodes(context, t, nodes, direction);
53
+ run_nodes(context, t, nodes, direction, hop + 1);
54
}
55
}
56
}
57
58
pw_log_debug(" group %p: '%s'", t, t->name);
59
t->runnable = true;
60
if (!t->driving)
61
- run_nodes(context, t, nodes, direction);
62
+ run_nodes(context, t, nodes, direction, hop + 1);
63
}
64
}
65
return 0;
66
67
}
68
spa_list_for_each(n, collect, sort_link)
69
if (!n->driving && n->runnable) {
70
- run_nodes(context, n, collect, PW_DIRECTION_OUTPUT);
71
- run_nodes(context, n, collect, PW_DIRECTION_INPUT);
72
+ run_nodes(context, n, collect, PW_DIRECTION_OUTPUT, 0);
73
+ run_nodes(context, n, collect, PW_DIRECTION_INPUT, 0);
74
}
75
76
return 0;
77
pipewire-0.3.84.tar.gz/src/pipewire/impl-client.h -> pipewire-0.3.85.tar.gz/src/pipewire/impl-client.h
Changed
19
1
2
3
/** \page page_client_impl Client Implementation
4
*
5
+ * \see \ref pw_impl_client
6
+ *
7
* \section sec_page_client_impl_overview Overview
8
*
9
* The \ref pw_impl_client object is created by a protocol implementation when
10
11
* Each client has its own list of resources it is bound to along with
12
* a mapping between the client types and server types.
13
*
14
- * See: \ref page_client_impl
15
+ * \see \ref page_client_impl
16
*/
17
18
/**
19
pipewire-0.3.84.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.85.tar.gz/src/pipewire/impl-link.c
Changed
16
1
2
3
impl->activated = false;
4
pw_log_info("(%s) deactivated", this->name);
5
- link_update_state(this, this->destroyed ?
6
- PW_LINK_STATE_INIT : PW_LINK_STATE_PAUSED,
7
- 0, NULL);
8
+
9
+ if (this->info.state < PW_LINK_STATE_PAUSED || this->destroyed)
10
+ link_update_state(this, PW_LINK_STATE_INIT, 0, NULL);
11
+ else
12
+ link_update_state(this, PW_LINK_STATE_PAUSED, 0, NULL);
13
return 0;
14
}
15
16
pipewire-0.3.84.tar.gz/src/pipewire/proxy.h -> pipewire-0.3.85.tar.gz/src/pipewire/proxy.h
Changed
19
1
2
3
/** \page page_proxy Proxy
4
*
5
+ * \see \ref pw_proxy
6
+ *
7
* \section sec_page_proxy_overview Overview
8
*
9
* The proxy object is a client side representation of a resource
10
11
* invoked by the client to PipeWire messages. Events will call the handlers
12
* set in listener.
13
*
14
- * See \ref page_proxy
15
+ * \see \ref page_proxy
16
*/
17
18
/**
19
pipewire-0.3.84.tar.gz/src/pipewire/stream.h -> pipewire-0.3.85.tar.gz/src/pipewire/stream.h
Changed
19
1
2
3
/** \page page_streams Streams
4
*
5
+ * \see \ref pw_stream
6
+ *
7
* \section sec_overview Overview
8
*
9
* \ref pw_stream "Streams" are used to exchange data with the
10
11
* The stream object provides a convenient way to send and
12
* receive data streams from/to PipeWire.
13
*
14
- * See also \ref page_streams and \ref api_pw_core
15
+ * \see \ref page_streams, \ref api_pw_core
16
*/
17
18
/**
19
pipewire-0.3.84.tar.gz/src/pipewire/thread-loop.h -> pipewire-0.3.85.tar.gz/src/pipewire/thread-loop.h
Changed
19
1
2
3
/** \page page_thread_loop Thread Loop
4
*
5
+ * \see \ref pw_thread_loop
6
+ *
7
* \section sec_thread_loop_overview Overview
8
*
9
* The threaded loop implementation is a special wrapper around the
10
11
* All of the loop callbacks will be executed with the loop
12
* lock held.
13
*
14
- * See also \ref page_thread_loop
15
+ * \see \ref page_thread_loop
16
*/
17
18
/**
19
pipewire-0.3.84.tar.gz/src/pipewire/utils.c -> pipewire-0.3.85.tar.gz/src/pipewire/utils.c
Changed
10
1
2
* \since 0.3.84
3
*/
4
SPA_EXPORT
5
-int pw_strv_find(char **a, char *b)
6
+int pw_strv_find(char **a, const char *b)
7
{
8
int i;
9
if (a == NULL || b == NULL)
10
pipewire-0.3.84.tar.gz/src/pipewire/utils.h -> pipewire-0.3.85.tar.gz/src/pipewire/utils.h
Changed
10
1
2
3
char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens);
4
5
-int pw_strv_find(char **a, char *b);
6
+int pw_strv_find(char **a, const char *b);
7
8
int pw_strv_find_common(char **a, char **b);
9
10
pipewire-0.3.84.tar.gz/src/tools/pw-top.c -> pipewire-0.3.85.tar.gz/src/tools/pw-top.c
Changed
10
1
2
}
3
4
static const struct pw_node_events node_events = {
5
- PW_VERSION_NODE,
6
+ PW_VERSION_NODE_EVENTS,
7
.info = node_info,
8
.param = node_param,
9
};
10