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 19
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Fri Dec 16 18:14:30 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.62
6
+
7
+-------------------------------------------------------------------
8
Sat Dec 3 00:09:52 UTC 2022 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 0.3.61
11
pipewire-aptx.spec
Changed
10
1
2
%define soversion 0_2
3
4
Name: pipewire-aptx
5
-Version: 0.3.61
6
+Version: 0.3.62
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
pipewire-0.3.61.tar.gz/NEWS -> pipewire-0.3.62.tar.gz/NEWS
Changed
92
1
2
+# PipeWire 0.3.62 (2022-12-09)
3
+
4
+This is a bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+ - A regression in screensharing was fixed. It was caused by a race when
9
+ activating links and driver nodes.
10
+ - Video transform metadata was added so that cameras and screen sharing
11
+ can report the video orientation and transformations.
12
+ - Support for the PulseAudio module-gsettings was added to make paprefs
13
+ work.
14
+ - Support for bluetooth offloading was added. This allows for the bluetooth
15
+ reception, decoding and playback to happen completely in hardware.
16
+ This also requires some support in WirePlumber.
17
+ - Many bugfixes and improvements.
18
+
19
+
20
+## PipeWire
21
+ - More work on stopping nodes in a more controlled way.
22
+ - Fix a race in starting nodes and drivers. In some cases the driver
23
+ node would already be started while the link to the peer node was not
24
+ ready yet. This caused regressions in screen sharing. The driver is
25
+ now only started after all the followers and links completed.
26
+ - Fix a case where a slow capture stream would not recycle buffers
27
+ anymore and stall. (#2874)
28
+ - Fix a subtle bug in pw_loop_invoke that could cause callbacks to be
29
+ delayed and cause crashes in some cases.
30
+ - Fix a case where IPC was done from the data-thread and could cause
31
+ crashes.
32
+
33
+## Tools
34
+ - Silence some expected errors in the pw-top output.
35
+
36
+## modules
37
+ - The filter-chain has seen some optimizations in the copy plugin and
38
+ the convolver.
39
+ - The zeroconf plugin will now only unpublish services from the server
40
+ that was removed.
41
+ - Fix a potential crash when stopping pw-loopback.
42
+ - Some harmless errors were turned into info messages.
43
+ - Fix some cases where pw_stream methods were called from the data-thread
44
+ that could cause segfaults. (#2633)
45
+
46
+## SPA
47
+ - There is now a video transform metadata that indicates how a video
48
+ frame was transformed (rotated/flipped). libcamera and the GStreamer
49
+ elements now have support for this metadata.
50
+ - The SPA volume plugin is now disabled from the default build.
51
+ - Handle missing control info in libcamera.
52
+ - Handle errors from loop better, don't call the callbacks on errors.
53
+ - Somewhat improve performance in some audioconvert AVX2 code for format
54
+ conversion.
55
+ - Fix PortConfig and EnumPortConfig params in audioconvert and
56
+ audioadapter to reflect what is actually going on instead of using
57
+ hardcoded values.
58
+ - Pass ignore-dB property correctly in all cases.
59
+ - Probing is now done in 48KHz again. (#2857)
60
+
61
+## Pulse-server
62
+ - IPv4 addresses are now added first to the list and exposed first with
63
+ zeroconf discover.
64
+ - module-gsettings was added to make paprefs work.
65
+ - The pulse.idle.timeout option was disabled by default and only enabled
66
+ for selected apps (speech-dispatcher) because it caused some problems
67
+ for other apps. (#2880)
68
+
69
+## JACK
70
+ - Only process valid ports. Could fix some crashes. (#2863)
71
+
72
+## Bluetooth
73
+ - Support was added for offloading bluetooth handling. Some hardware can
74
+ receive, decode and play the bluetooth audio directly in hardware.
75
+
76
+
77
+Older versions:
78
+
79
# PipeWire 0.3.61 (2022-11-24)
80
81
This is a bugfix release that is API and ABI compatible with previous
82
83
- Add option to set node.passive on jack clients. Make some quirks
84
for qsynth to make it suspend and fade out better.
85
86
-
87
-Older versions:
88
-
89
# PipeWire 0.3.60 (2022-11-10)
90
91
This is a bugfix release that is API and ABI compatible with previous
92
pipewire-0.3.61.tar.gz/meson.build -> pipewire-0.3.62.tar.gz/meson.build
Changed
18
1
2
project('pipewire', 'c' ,
3
- version : '0.3.61',
4
+ version : '0.3.62',
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
flatpak_support = glib2_dep.found()
10
cdata.set('HAVE_GLIB2', flatpak_support)
11
12
+gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : get_option('gsettings'))
13
+summary({'GIO (GSettings)': gio_dep.found()}, bool_yn: true, section: 'Misc dependencies')
14
+
15
gst_option = get_option('gstreamer')
16
gst_deps_def = {
17
'glib-2.0': {'version': '>=2.32.0'},
18
pipewire-0.3.61.tar.gz/meson_options.txt -> pipewire-0.3.62.tar.gz/meson_options.txt
Changed
21
1
2
type: 'feature',
3
value: 'enabled')
4
option('volume',
5
- description: 'Enable volume spa plugin integration',
6
+ description: 'Build the legacy volume spa plugin',
7
type: 'feature',
8
- value: 'enabled')
9
+ value: 'disabled')
10
option('vulkan',
11
description: 'Enable vulkan spa plugin integration',
12
type: 'feature',
13
14
description: 'Enable code that depends on libreadline',
15
type: 'feature',
16
value: 'auto')
17
+option('gsettings',
18
+ description: 'Enable code that depends on gsettings',
19
+ type: 'feature',
20
+ value: 'auto')
21
pipewire-0.3.61.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.62.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
19
1
2
if (pw_map_item_is_free(item))
3
continue;
4
p = item->data;
5
+ if (!p->valid)
6
+ continue;
7
spa_list_for_each(mix, &p->mix, port_link) {
8
if (SPA_LIKELY(mix->io != NULL))
9
mix->io->status = SPA_STATUS_NEED_DATA;
10
11
if (pw_map_item_is_free(item))
12
continue;
13
p = item->data;
14
+ if (!p->valid)
15
+ continue;
16
prepare_output(p, frames);
17
p->io.status = SPA_STATUS_NEED_DATA;
18
}
19
pipewire-0.3.61.tar.gz/spa/include/spa/buffer/meta.h -> pipewire-0.3.62.tar.gz/spa/include/spa/buffer/meta.h
Changed
54
1
2
3
enum spa_meta_type {
4
SPA_META_Invalid,
5
- SPA_META_Header, /**< struct spa_meta_header */
6
- SPA_META_VideoCrop, /**< struct spa_meta_region with cropping data */
7
- SPA_META_VideoDamage, /**< array of struct spa_meta_region with damage, where an invalid entry or end-of-array marks the end. */
8
- SPA_META_Bitmap, /**< struct spa_meta_bitmap */
9
- SPA_META_Cursor, /**< struct spa_meta_cursor */
10
- SPA_META_Control, /**< metadata contains a spa_meta_control
11
- * associated with the data */
12
- SPA_META_Busy, /**< don't write to buffer when count > 0 */
13
-
14
- _SPA_META_LAST, /**< not part of ABI/API */
15
+ SPA_META_Header, /**< struct spa_meta_header */
16
+ SPA_META_VideoCrop, /**< struct spa_meta_region with cropping data */
17
+ SPA_META_VideoDamage, /**< array of struct spa_meta_region with damage, where an invalid entry or end-of-array marks the end. */
18
+ SPA_META_Bitmap, /**< struct spa_meta_bitmap */
19
+ SPA_META_Cursor, /**< struct spa_meta_cursor */
20
+ SPA_META_Control, /**< metadata contains a spa_meta_control
21
+ * associated with the data */
22
+ SPA_META_Busy, /**< don't write to buffer when count > 0 */
23
+ SPA_META_VideoTransform, /**< struct spa_meta_transform */
24
+
25
+ _SPA_META_LAST, /**< not part of ABI/API */
26
};
27
28
/**
29
30
uint32_t count; /**< number of users busy with the buffer */
31
};
32
33
+enum spa_meta_videotransform_value {
34
+ SPA_META_TRANSFORMATION_None = 0, /**< no transform */
35
+ SPA_META_TRANSFORMATION_90, /**< 90 degree counter-clockwise */
36
+ SPA_META_TRANSFORMATION_180, /**< 180 degree counter-clockwise */
37
+ SPA_META_TRANSFORMATION_270, /**< 270 degree counter-clockwise */
38
+ SPA_META_TRANSFORMATION_Flipped, /**< 180 degree flipped around the vertical axis. Equivalent
39
+ * to a reflexion through the vertical line splitting the
40
+ * bufffer in two equal sized parts */
41
+ SPA_META_TRANSFORMATION_Flipped90, /**< flip then rotate around 90 degree counter-clockwise */
42
+ SPA_META_TRANSFORMATION_Flipped180, /**< flip then rotate around 180 degree counter-clockwise */
43
+ SPA_META_TRANSFORMATION_Flipped270, /**< flip then rotate around 270 degree counter-clockwise */
44
+};
45
+
46
+/** a transformation of the buffer */
47
+struct spa_meta_videotransform {
48
+ uint32_t transform; /**< orientation transformation that was applied to the buffer */
49
+};
50
+
51
/**
52
* \}
53
*/
54
pipewire-0.3.61.tar.gz/spa/include/spa/param/props.h -> pipewire-0.3.62.tar.gz/spa/include/spa/param/props.h
Changed
9
1
2
SPA_PROP_rate,
3
SPA_PROP_quality,
4
SPA_PROP_bluetoothAudioCodec,
5
+ SPA_PROP_bluetoothOffloadActive,
6
7
SPA_PROP_START_Audio = 0x10000, /**< audio related properties */
8
SPA_PROP_waveType,
9
pipewire-0.3.61.tar.gz/spa/include/spa/param/type-info.h -> pipewire-0.3.62.tar.gz/spa/include/spa/param/type-info.h
Changed
9
1
2
{ SPA_PROP_rate, SPA_TYPE_Double, SPA_TYPE_INFO_PROPS_BASE "rate", NULL },
3
{ SPA_PROP_quality, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "quality", NULL },
4
{ SPA_PROP_bluetoothAudioCodec, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "bluetoothAudioCodec", spa_type_bluetooth_audio_codec },
5
+ { SPA_PROP_bluetoothOffloadActive, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "bluetoothOffloadActive", NULL },
6
7
{ SPA_PROP_waveType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "waveType", NULL },
8
{ SPA_PROP_frequency, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "frequency", NULL },
9
pipewire-0.3.61.tar.gz/spa/plugins/aec/aec-webrtc.cpp -> pipewire-0.3.62.tar.gz/spa/plugins/aec/aec-webrtc.cpp
Changed
11
1
2
}
3
4
apm->high_pass_filter()->Enable(high_pass_filter);
5
- // Always disable drift compensation since it requires drift sampling
6
+ // Always disable drift compensation since PipeWire will already do
7
+ // drift compensation on all sinks and sources linked to this echo-canceler
8
apm->echo_cancellation()->enable_drift_compensation(false);
9
apm->echo_cancellation()->Enable(true);
10
// TODO: wire up supression levels to args
11
pipewire-0.3.61.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.62.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
70
1
2
3
struct spa_i18n *acp_i18n;
4
5
-#define DEFAULT_RATE 44100
6
+#define DEFAULT_RATE 48000
7
8
#define VOLUME_ACCURACY (PA_VOLUME_NORM/100) /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */
9
10
11
static int device_enable(pa_card *impl, pa_alsa_mapping *mapping, pa_alsa_device *dev)
12
{
13
const char *mod_name;
14
- bool ignore_dB = false;
15
uint32_t i, port_index;
16
int res;
17
18
19
20
dev->device.flags |= ACP_DEVICE_ACTIVE;
21
22
- find_mixer(impl, dev, NULL, ignore_dB);
23
+ find_mixer(impl, dev, NULL, impl->ignore_dB);
24
25
/* Synchronize priority values, as it may have changed when setting the profile */
26
for (i = 0; i < impl->card.n_ports; i++) {
27
28
if (dev->active_port)
29
dev->active_port->port.flags |= ACP_PORT_ACTIVE;
30
31
- if ((res = setup_mixer(impl, dev, ignore_dB)) < 0)
32
+ if ((res = setup_mixer(impl, dev, impl->ignore_dB)) < 0)
33
return res;
34
35
if (dev->read_volume)
36
37
struct acp_card *card;
38
const char *s, *profile_set = NULL, *profile = NULL;
39
char device_id16;
40
- bool ignore_dB = false;
41
uint32_t profile_index;
42
int res;
43
44
45
impl->use_ucm = true;
46
impl->auto_profile = true;
47
impl->auto_port = true;
48
+ impl->ignore_dB = false;
49
50
if (props) {
51
if ((s = acp_dict_lookup(props, "api.alsa.use-ucm")) != NULL)
52
53
if ((s = acp_dict_lookup(props, "api.alsa.soft-mixer")) != NULL)
54
impl->soft_mixer = spa_atob(s);
55
if ((s = acp_dict_lookup(props, "api.alsa.ignore-dB")) != NULL)
56
- ignore_dB = spa_atob(s);
57
+ impl->ignore_dB = spa_atob(s);
58
if ((s = acp_dict_lookup(props, "device.profile-set")) != NULL)
59
profile_set = s;
60
if ((s = acp_dict_lookup(props, "device.profile")) != NULL)
61
62
goto error;
63
}
64
65
- impl->profile_set->ignore_dB = ignore_dB;
66
+ impl->profile_set->ignore_dB = impl->ignore_dB;
67
68
pa_alsa_profile_set_probe(impl->profile_set, impl->ucm.mixers,
69
device_id,
70
pipewire-0.3.61.tar.gz/spa/plugins/alsa/acp/card.h -> pipewire-0.3.62.tar.gz/spa/plugins/alsa/acp/card.h
Changed
9
1
2
bool soft_mixer;
3
bool auto_profile;
4
bool auto_port;
5
+ bool ignore_dB;
6
7
pa_alsa_ucm_config ucm;
8
pa_alsa_profile_set *profile_set;
9
pipewire-0.3.61.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.62.tar.gz/spa/plugins/audioconvert/audioadapter.c
Changed
92
1
2
return 0;
3
}
4
5
+static int convert_enum_port_config(struct impl *this,
6
+ int seq, uint32_t id, uint32_t start, uint32_t num,
7
+ const struct spa_pod *filter, struct spa_pod_builder *builder)
8
+{
9
+ struct spa_pod *f1, *f2 = NULL;
10
+ int res;
11
+
12
+ f1 = spa_pod_builder_add_object(builder,
13
+ SPA_TYPE_OBJECT_ParamPortConfig, id,
14
+ SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(this->direction));
15
+
16
+ if (filter) {
17
+ if ((res = spa_pod_filter(builder, &f2, f1, filter)) < 0)
18
+ return res;
19
+ }
20
+ else {
21
+ f2 = f1;
22
+ }
23
+ return spa_node_enum_params(this->convert, seq, id, start, num, f2);
24
+}
25
+
26
static int impl_node_enum_params(void *object, int seq,
27
uint32_t id, uint32_t start, uint32_t num,
28
const struct spa_pod *filter)
29
30
31
switch (id) {
32
case SPA_PARAM_EnumPortConfig:
33
+ return convert_enum_port_config(this, seq, id, start, num, filter, &b.b);
34
case SPA_PARAM_PortConfig:
35
- res = spa_node_enum_params(this->convert, seq, id, start, num, filter);
36
- return res;
37
+ if (this->passthrough) {
38
+ switch (result.index) {
39
+ case 0:
40
+ result.param = spa_pod_builder_add_object(&b.b,
41
+ SPA_TYPE_OBJECT_ParamPortConfig, id,
42
+ SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(this->direction),
43
+ SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(
44
+ SPA_PARAM_PORT_CONFIG_MODE_passthrough));
45
+ result.next++;
46
+ break;
47
+ default:
48
+ return 0;
49
+ }
50
+ } else {
51
+ return convert_enum_port_config(this, seq, id, start, num, filter, &b.b);
52
+ }
53
+ break;
54
case SPA_PARAM_PropInfo:
55
res = follower_enum_params(this,
56
id, IDX_PropInfo, &result, filter, &b.b);
57
58
this->started = true;
59
break;
60
case SPA_NODE_COMMAND_Suspend:
61
+ this->started = false;
62
spa_log_debug(this->log, "%p: suspending", this);
63
break;
64
case SPA_NODE_COMMAND_Pause:
65
+ this->started = false;
66
spa_log_debug(this->log, "%p: pausing", this);
67
break;
68
case SPA_NODE_COMMAND_Flush:
69
70
break;
71
case SPA_NODE_COMMAND_Suspend:
72
configure_format(this, 0, NULL);
73
- SPA_FALLTHROUGH
74
+ spa_log_debug(this->log, "%p: suspended", this);
75
+ break;
76
case SPA_NODE_COMMAND_Pause:
77
- this->started = false;
78
- spa_log_debug(this->log, "%p: stopped", this);
79
+ spa_log_debug(this->log, "%p: paused", this);
80
break;
81
case SPA_NODE_COMMAND_Flush:
82
spa_log_debug(this->log, "%p: flushed", this);
83
84
spa_log_trace_fp(this->log, "%p: ready %d", this, status);
85
86
if (!this->started) {
87
- spa_log_warn(this->log, "%p: ready stopped node", this);
88
+ spa_log_info(this->log, "%p: ready stopped node", this);
89
return -EIO;
90
}
91
92
pipewire-0.3.61.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.62.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
120
1
2
struct port *portsMAX_PORTS;
3
uint32_t n_ports;
4
5
+ enum spa_direction direction;
6
enum spa_param_port_config_mode mode;
7
8
struct spa_audio_info format;
9
10
11
switch (id) {
12
case SPA_PARAM_EnumPortConfig:
13
+ {
14
+ struct dir *dir;
15
switch (result.index) {
16
case 0:
17
- param = spa_pod_builder_add_object(&b,
18
- SPA_TYPE_OBJECT_ParamPortConfig, id,
19
- SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_INPUT),
20
- SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp));
21
+ dir = &this->dirSPA_DIRECTION_INPUT;;
22
break;
23
case 1:
24
- param = spa_pod_builder_add_object(&b,
25
- SPA_TYPE_OBJECT_ParamPortConfig, id,
26
- SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT),
27
- SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp));
28
- break;
29
- case 2:
30
- param = spa_pod_builder_add_object(&b,
31
- SPA_TYPE_OBJECT_ParamPortConfig, id,
32
- SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_INPUT),
33
- SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_convert));
34
- break;
35
- case 3:
36
- param = spa_pod_builder_add_object(&b,
37
- SPA_TYPE_OBJECT_ParamPortConfig, id,
38
- SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT),
39
- SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_convert));
40
+ dir = &this->dirSPA_DIRECTION_OUTPUT;;
41
break;
42
default:
43
return 0;
44
}
45
+ param = spa_pod_builder_add_object(&b,
46
+ SPA_TYPE_OBJECT_ParamPortConfig, id,
47
+ SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(dir->direction),
48
+ SPA_PARAM_PORT_CONFIG_mode, SPA_POD_CHOICE_ENUM_Id(4,
49
+ SPA_PARAM_PORT_CONFIG_MODE_none,
50
+ SPA_PARAM_PORT_CONFIG_MODE_none,
51
+ SPA_PARAM_PORT_CONFIG_MODE_dsp,
52
+ SPA_PARAM_PORT_CONFIG_MODE_convert),
53
+ SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_CHOICE_Bool(false),
54
+ SPA_PARAM_PORT_CONFIG_control, SPA_POD_CHOICE_Bool(false));
55
break;
56
-
57
+ }
58
case SPA_PARAM_PortConfig:
59
+ {
60
+ struct dir *dir;
61
+ struct spa_pod_frame f1;
62
+
63
switch (result.index) {
64
case 0:
65
- param = spa_pod_builder_add_object(&b,
66
- SPA_TYPE_OBJECT_ParamPortConfig, id,
67
- SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_INPUT),
68
- SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(this->dirSPA_DIRECTION_INPUT.mode));
69
+ dir = &this->dirSPA_DIRECTION_INPUT;;
70
break;
71
case 1:
72
- param = spa_pod_builder_add_object(&b,
73
- SPA_TYPE_OBJECT_ParamPortConfig, id,
74
- SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT),
75
- SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(this->dirSPA_DIRECTION_OUTPUT.mode));
76
+ dir = &this->dirSPA_DIRECTION_OUTPUT;;
77
break;
78
default:
79
return 0;
80
}
81
+ spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_ParamPortConfig, id);
82
+ spa_pod_builder_add(&b,
83
+ SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(dir->direction),
84
+ SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(dir->mode),
85
+ SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_Bool(this->monitor),
86
+ SPA_PARAM_PORT_CONFIG_control, SPA_POD_Bool(dir->control),
87
+ 0);
88
+
89
+ if (dir->have_format) {
90
+ spa_pod_builder_prop(&b, SPA_PARAM_PORT_CONFIG_format, 0);
91
+ spa_format_audio_raw_build(&b, SPA_PARAM_PORT_CONFIG_format,
92
+ &dir->format.info.raw);
93
+ }
94
+ param = spa_pod_builder_pop(&b, &f0);
95
break;
96
-
97
+ }
98
case SPA_PARAM_PropInfo:
99
{
100
struct props *p = &this->props;
101
102
init_port(this, direction, 0, 0, false, false, false);
103
break;
104
}
105
+ case SPA_PARAM_PORT_CONFIG_MODE_none:
106
+ break;
107
default:
108
return -ENOTSUP;
109
}
110
111
this->props.soft.n_volumes = this->props.n_channels;
112
this->props.monitor.n_volumes = this->props.n_channels;
113
114
+ this->dirSPA_DIRECTION_INPUT.direction = SPA_DIRECTION_INPUT;
115
this->dirSPA_DIRECTION_INPUT.latency = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
116
+ this->dirSPA_DIRECTION_OUTPUT.direction = SPA_DIRECTION_OUTPUT;
117
this->dirSPA_DIRECTION_OUTPUT.latency = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
118
119
this->node.iface = SPA_INTERFACE_INIT(
120
pipewire-0.3.61.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c -> pipewire-0.3.62.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c
Changed
201
1
2
conv_s24_to_f32d_1s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
3
uint32_t n_channels, uint32_t n_samples)
4
{
5
- const int24_t *s = src;
6
+ const int8_t *s = src;
7
float *d0 = dst0;
8
uint32_t n, unrolled;
9
__m128i in;
10
__m128 out, factor = _mm_set1_ps(1.0f / S24_SCALE);
11
+ __m128i mask1 = _mm_setr_epi32(0*n_channels, 3*n_channels, 6*n_channels, 9*n_channels);
12
13
if (SPA_IS_ALIGNED(d0, 16) && n_samples > 0) {
14
unrolled = n_samples & ~3;
15
16
unrolled = 0;
17
18
for(n = 0; n < unrolled; n += 4) {
19
- in = _mm_setr_epi32(
20
- *((uint32_t*)&s0 * n_channels),
21
- *((uint32_t*)&s1 * n_channels),
22
- *((uint32_t*)&s2 * n_channels),
23
- *((uint32_t*)&s3 * n_channels));
24
+ in = _mm_i32gather_epi32((int*)s, mask1, 1);
25
in = _mm_slli_epi32(in, 8);
26
in = _mm_srai_epi32(in, 8);
27
out = _mm_cvtepi32_ps(in);
28
out = _mm_mul_ps(out, factor);
29
_mm_store_ps(&d0n, out);
30
- s += 4 * n_channels;
31
+ s += 12 * n_channels;
32
}
33
for(; n < n_samples; n++) {
34
- out = _mm_cvtsi32_ss(factor, s24_to_s32(*s));
35
+ out = _mm_cvtsi32_ss(factor, s24_to_s32(*(int24_t*)s));
36
out = _mm_mul_ss(out, factor);
37
_mm_store_ss(&d0n, out);
38
- s += n_channels;
39
+ s += 3 * n_channels;
40
}
41
}
42
43
44
conv_s24_to_f32d_2s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
45
uint32_t n_channels, uint32_t n_samples)
46
{
47
- const int24_t *s = src;
48
+ const int8_t *s = src;
49
float *d0 = dst0, *d1 = dst1;
50
uint32_t n, unrolled;
51
__m128i in2;
52
__m128 out2, factor = _mm_set1_ps(1.0f / S24_SCALE);
53
+ __m128i mask1 = _mm_setr_epi32(0*n_channels, 3*n_channels, 6*n_channels, 9*n_channels);
54
55
if (SPA_IS_ALIGNED(d0, 16) &&
56
SPA_IS_ALIGNED(d1, 16) &&
57
58
unrolled = 0;
59
60
for(n = 0; n < unrolled; n += 4) {
61
- in0 = _mm_setr_epi32(
62
- *((uint32_t*)&s0 + 0*n_channels),
63
- *((uint32_t*)&s0 + 1*n_channels),
64
- *((uint32_t*)&s0 + 2*n_channels),
65
- *((uint32_t*)&s0 + 3*n_channels));
66
- in1 = _mm_setr_epi32(
67
- *((uint32_t*)&s1 + 0*n_channels),
68
- *((uint32_t*)&s1 + 1*n_channels),
69
- *((uint32_t*)&s1 + 2*n_channels),
70
- *((uint32_t*)&s1 + 3*n_channels));
71
+ in0 = _mm_i32gather_epi32((int*)&s0, mask1, 1);
72
+ in1 = _mm_i32gather_epi32((int*)&s3, mask1, 1);
73
74
in0 = _mm_slli_epi32(in0, 8);
75
in1 = _mm_slli_epi32(in1, 8);
76
77
_mm_store_ps(&d0n, out0);
78
_mm_store_ps(&d1n, out1);
79
80
- s += 4 * n_channels;
81
+ s += 12 * n_channels;
82
}
83
for(; n < n_samples; n++) {
84
- out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*s));
85
- out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+1)));
86
+ out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+0)));
87
+ out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+1)));
88
out0 = _mm_mul_ss(out0, factor);
89
out1 = _mm_mul_ss(out1, factor);
90
_mm_store_ss(&d0n, out0);
91
_mm_store_ss(&d1n, out1);
92
- s += n_channels;
93
+ s += 3 * n_channels;
94
}
95
}
96
static void
97
conv_s24_to_f32d_4s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
98
uint32_t n_channels, uint32_t n_samples)
99
{
100
- const int24_t *s = src;
101
+ const int8_t *s = src;
102
float *d0 = dst0, *d1 = dst1, *d2 = dst2, *d3 = dst3;
103
uint32_t n, unrolled;
104
__m128i in4;
105
__m128 out4, factor = _mm_set1_ps(1.0f / S24_SCALE);
106
+ __m128i mask1 = _mm_setr_epi32(0*n_channels, 3*n_channels, 6*n_channels, 9*n_channels);
107
108
if (SPA_IS_ALIGNED(d0, 16) &&
109
SPA_IS_ALIGNED(d1, 16) &&
110
111
unrolled = 0;
112
113
for(n = 0; n < unrolled; n += 4) {
114
- in0 = _mm_setr_epi32(
115
- *((uint32_t*)&s0 + 0*n_channels),
116
- *((uint32_t*)&s0 + 1*n_channels),
117
- *((uint32_t*)&s0 + 2*n_channels),
118
- *((uint32_t*)&s0 + 3*n_channels));
119
- in1 = _mm_setr_epi32(
120
- *((uint32_t*)&s1 + 0*n_channels),
121
- *((uint32_t*)&s1 + 1*n_channels),
122
- *((uint32_t*)&s1 + 2*n_channels),
123
- *((uint32_t*)&s1 + 3*n_channels));
124
- in2 = _mm_setr_epi32(
125
- *((uint32_t*)&s2 + 0*n_channels),
126
- *((uint32_t*)&s2 + 1*n_channels),
127
- *((uint32_t*)&s2 + 2*n_channels),
128
- *((uint32_t*)&s2 + 3*n_channels));
129
- in3 = _mm_setr_epi32(
130
- *((uint32_t*)&s3 + 0*n_channels),
131
- *((uint32_t*)&s3 + 1*n_channels),
132
- *((uint32_t*)&s3 + 2*n_channels),
133
- *((uint32_t*)&s3 + 3*n_channels));
134
+ in0 = _mm_i32gather_epi32((int*)&s0, mask1, 1);
135
+ in1 = _mm_i32gather_epi32((int*)&s3, mask1, 1);
136
+ in2 = _mm_i32gather_epi32((int*)&s6, mask1, 1);
137
+ in3 = _mm_i32gather_epi32((int*)&s9, mask1, 1);
138
139
in0 = _mm_slli_epi32(in0, 8);
140
in1 = _mm_slli_epi32(in1, 8);
141
142
_mm_store_ps(&d2n, out2);
143
_mm_store_ps(&d3n, out3);
144
145
- s += 4 * n_channels;
146
+ s += 12 * n_channels;
147
}
148
for(; n < n_samples; n++) {
149
- out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*s));
150
- out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+1)));
151
- out2 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+2)));
152
- out3 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+3)));
153
+ out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+0)));
154
+ out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+1)));
155
+ out2 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+2)));
156
+ out3 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+3)));
157
out0 = _mm_mul_ss(out0, factor);
158
out1 = _mm_mul_ss(out1, factor);
159
out2 = _mm_mul_ss(out2, factor);
160
161
_mm_store_ss(&d1n, out1);
162
_mm_store_ss(&d2n, out2);
163
_mm_store_ss(&d3n, out3);
164
- s += n_channels;
165
+ s += 3 * n_channels;
166
}
167
}
168
169
170
const int32_t *s = src;
171
float *d0 = dst0, *d1 = dst1, *d2 = dst2, *d3 = dst3;
172
uint32_t n, unrolled;
173
- __m256i in4, t4;
174
+ __m256i in4;
175
__m256 out4, factor = _mm256_set1_ps(1.0f / S24_SCALE);
176
- __m256i mask1 = _mm256_setr_epi64x(0*n_channels, 0*n_channels+2, 4*n_channels, 4*n_channels+2);
177
- __m256i mask2 = _mm256_setr_epi64x(1*n_channels, 1*n_channels+2, 5*n_channels, 5*n_channels+2);
178
- __m256i mask3 = _mm256_setr_epi64x(2*n_channels, 2*n_channels+2, 6*n_channels, 6*n_channels+2);
179
- __m256i mask4 = _mm256_setr_epi64x(3*n_channels, 3*n_channels+2, 7*n_channels, 7*n_channels+2);
180
+ __m256i mask1 = _mm256_setr_epi32(0*n_channels, 1*n_channels, 2*n_channels, 3*n_channels,
181
+ 3*n_channels, 5*n_channels, 6*n_channels, 7*n_channels);
182
183
if (SPA_IS_ALIGNED(d0, 32) &&
184
SPA_IS_ALIGNED(d1, 32) &&
185
186
unrolled = 0;
187
188
for(n = 0; n < unrolled; n += 8) {
189
- in0 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask1, 4);
190
- in1 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask2, 4);
191
- in2 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask3, 4);
192
- in3 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask4, 4);
193
-
194
- t0 = _mm256_unpacklo_epi32(in0, in1); /* a0 a1 b0 b1 a4 a5 b4 b5 */
195
- t1 = _mm256_unpackhi_epi32(in0, in1); /* c0 c1 d0 d1 c4 c5 d4 d5 */
196
- t2 = _mm256_unpacklo_epi32(in2, in3); /* a2 a3 b2 b3 a6 a7 b6 b7 */
197
- t3 = _mm256_unpackhi_epi32(in2, in3); /* c2 c3 d2 d3 c6 c7 d6 d7 */
198
- in0 = _mm256_unpacklo_epi64(t0, t2); /* a0 a1 a2 a3 a4 a5 a6 a7 */
199
- in1 = _mm256_unpackhi_epi64(t0, t2); /* b0 b1 b2 b3 b4 b5 b6 b7 */
200
- in2 = _mm256_unpacklo_epi64(t1, t3); /* c0 c1 c2 c3 c4 c5 c6 c7 */
201
pipewire-0.3.61.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.62.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
160
1
2
3
struct props {
4
enum spa_bluetooth_audio_codec codec;
5
+ bool offload_active;
6
};
7
8
static void reset_props(struct props *props)
9
{
10
props->codec = 0;
11
+ props->offload_active = false;
12
}
13
14
struct impl;
15
16
unsigned int mute:1;
17
unsigned int save:1;
18
unsigned int a2dp_duplex:1;
19
+ unsigned int offload_acquired:1;
20
uint32_t n_channels;
21
int64_t latency_offset;
22
uint32_t channelsSPA_AUDIO_MAX_CHANNELS;
23
24
.volume_changed = volume_changed,
25
};
26
27
+static int node_offload_set_active(struct node *node, bool active)
28
+{
29
+ int res = 0;
30
+
31
+ if (node->transport == NULL || !node->active)
32
+ return -ENOTSUP;
33
+
34
+ if (active && !node->offload_acquired)
35
+ res = spa_bt_transport_acquire(node->transport, false);
36
+ else if (!active && node->offload_acquired)
37
+ res = spa_bt_transport_release(node->transport);
38
+
39
+ if (res >= 0)
40
+ node->offload_acquired = active;
41
+
42
+ return res;
43
+}
44
+
45
static void get_channels(struct spa_bt_transport *t, bool a2dp_duplex, uint32_t *n_channels, uint32_t *channels)
46
{
47
const struct media_codec *codec;
48
49
50
this->nodesid.impl = this;
51
this->nodesid.active = true;
52
+ this->nodesid.offload_acquired = false;
53
this->nodesid.a2dp_duplex = a2dp_duplex;
54
get_channels(t, a2dp_duplex, &this->nodesid.n_channels, this->nodesid.channels);
55
if (this->nodesid.transport)
56
57
58
for (uint32_t i = 0; i < 2; i++) {
59
struct node * node = &this->nodesi;
60
+ node_offload_set_active(node, false);
61
if (node->transport) {
62
spa_hook_remove(&node->transport_listener);
63
node->transport = NULL;
64
65
node->active = false;
66
}
67
}
68
+
69
+ this->props.offload_active = false;
70
}
71
72
static bool validate_profile(struct impl *this, uint32_t profile,
73
74
return true;
75
}
76
77
-static struct spa_pod *build_prop_info(struct impl *this, struct spa_pod_builder *b, uint32_t id)
78
+static struct spa_pod *build_prop_info_codec(struct impl *this, struct spa_pod_builder *b, uint32_t id)
79
{
80
struct spa_pod_frame f2;
81
struct spa_pod_choice *choice;
82
83
84
return spa_pod_builder_add_object(b,
85
SPA_TYPE_OBJECT_Props, id,
86
- SPA_PROP_bluetoothAudioCodec, SPA_POD_Id(p->codec));
87
+ SPA_PROP_bluetoothAudioCodec, SPA_POD_Id(p->codec),
88
+ SPA_PROP_bluetoothOffloadActive, SPA_POD_Bool(p->offload_active));
89
}
90
91
static int impl_enum_params(void *object, int seq,
92
93
{
94
switch (result.index) {
95
case 0:
96
- param = build_prop_info(this, &b, id);
97
+ param = build_prop_info_codec(this, &b, id);
98
+ break;
99
+ case 1:
100
+ param = spa_pod_builder_add_object(&b,
101
+ SPA_TYPE_OBJECT_PropInfo, id,
102
+ SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_bluetoothOffloadActive),
103
+ SPA_PROP_INFO_description, SPA_POD_String("Bluetooth audio offload active"),
104
+ SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool(false));
105
break;
106
default:
107
return 0;
108
109
return changed;
110
}
111
112
+static void apply_prop_offload_active(struct impl *this, bool active)
113
+{
114
+ bool old_value = this->props.offload_active;
115
+
116
+ this->props.offload_active = active;
117
+
118
+ for (int i = 0; i < 2; i++) {
119
+ node_offload_set_active(&this->nodesi, active);
120
+ if (!this->nodesi.offload_acquired)
121
+ this->props.offload_active = false;
122
+ }
123
+
124
+ if (this->props.offload_active != old_value) {
125
+ this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
126
+ this->paramsIDX_Props.flags ^= SPA_PARAM_INFO_SERIAL;
127
+ emit_info(this, false);
128
+ }
129
+}
130
+
131
static int impl_set_param(void *object,
132
uint32_t id, uint32_t flags,
133
const struct spa_pod *param)
134
135
case SPA_PARAM_Props:
136
{
137
uint32_t codec_id = SPA_ID_INVALID;
138
+ bool offload_active = this->props.offload_active;
139
140
if (param == NULL)
141
return 0;
142
143
if ((res = spa_pod_parse_object(param,
144
SPA_TYPE_OBJECT_Props, NULL,
145
- SPA_PROP_bluetoothAudioCodec, SPA_POD_OPT_Id(&codec_id))) < 0) {
146
+ SPA_PROP_bluetoothAudioCodec, SPA_POD_OPT_Id(&codec_id),
147
+ SPA_PROP_bluetoothOffloadActive, SPA_POD_OPT_Bool(&offload_active))) < 0) {
148
spa_log_warn(this->log, "can't parse props");
149
spa_debug_pod(0, NULL, param);
150
return res;
151
}
152
153
- spa_log_debug(this->log, "setting props codec:%d", codec_id);
154
+ spa_log_debug(this->log, "setting props codec:%d offload:%d", (int)codec_id, (int)offload_active);
155
+
156
+ apply_prop_offload_active(this, offload_active);
157
158
if (codec_id == SPA_ID_INVALID)
159
return 0;
160
pipewire-0.3.61.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.62.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
9
1
2
struct buffer buffersMAX_BUFFERS;
3
uint32_t n_buffers;
4
5
- struct spa_list free;
6
struct spa_list ready;
7
8
struct buffer *current_buffer;
9
pipewire-0.3.61.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.62.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
22
1
2
struct spa_list link;
3
struct spa_buffer *outbuf;
4
struct spa_meta_header *h;
5
+ struct spa_meta_videotransform *videotransform;
6
void *ptr;
7
};
8
9
10
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
11
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
12
break;
13
+ case 1:
14
+ param = (struct spa_pod*)spa_pod_builder_add_object(&b,
15
+ SPA_TYPE_OBJECT_ParamMeta, id,
16
+ SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoTransform),
17
+ SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_videotransform)));
18
+ break;
19
default:
20
return 0;
21
}
22
pipewire-0.3.61.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp -> pipewire-0.3.62.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp
Changed
123
1
2
return;
3
4
StreamRoles roles;
5
- roles.push_back(VideoRecording);
6
+ roles.push_back(StreamRole::VideoRecording);
7
impl->config = impl->camera->generateConfiguration(roles);
8
}
9
10
11
0);
12
13
switch (ctrl_id->type()) {
14
- case ControlTypeBool:
15
+ case ControlTypeBool: {
16
+ bool def;
17
+ if (ctrl_info.def().isNone())
18
+ def = ctrl_info.min().get<bool>();
19
+ else
20
+ def = ctrl_info.def().get<bool>();
21
+
22
spa_pod_builder_add(&b,
23
- SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool(
24
- (bool)ctrl_info.def().get<bool>()),
25
- 0);
26
- break;
27
- case ControlTypeFloat:
28
+ SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool(
29
+ def),
30
+ 0);
31
+ } break;
32
+ case ControlTypeFloat: {
33
+ float min = ctrl_info.min().get<float>();
34
+ float max = ctrl_info.max().get<float>();
35
+ float def;
36
+
37
+ if (ctrl_info.def().isNone())
38
+ def = (min + max) / 2;
39
+ else
40
+ def = ctrl_info.def().get<float>();
41
+
42
spa_pod_builder_add(&b,
43
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
44
- (float)ctrl_info.def().get<float>(),
45
- (float)ctrl_info.min().get<float>(),
46
- (float)ctrl_info.max().get<float>()),
47
+ def, min, max),
48
0);
49
- break;
50
- case ControlTypeInteger32:
51
+ } break;
52
+ case ControlTypeInteger32: {
53
+ int32_t min = ctrl_info.min().get<int32_t>();
54
+ int32_t max = ctrl_info.max().get<int32_t>();
55
+ int32_t def;
56
+
57
+ if (ctrl_info.def().isNone())
58
+ def = (min + max) / 2;
59
+ else
60
+ def = ctrl_info.def().get<int32_t>();
61
+
62
spa_pod_builder_add(&b,
63
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(
64
- (int32_t)ctrl_info.def().get<int32_t>(),
65
- (int32_t)ctrl_info.min().get<int32_t>(),
66
- (int32_t)ctrl_info.max().get<int32_t>()),
67
+ def, min, max),
68
0);
69
- break;
70
+ } break;
71
default:
72
goto next;
73
}
74
75
return -ENOTSUP;
76
}
77
78
+static const struct {
79
+ Transform libcamera_transform;
80
+ uint32_t spa_transform_value;
81
+} transform_map = {
82
+ { Transform::Identity, SPA_META_TRANSFORMATION_None },
83
+ { Transform::Rot0, SPA_META_TRANSFORMATION_None },
84
+ { Transform::HFlip, SPA_META_TRANSFORMATION_Flipped },
85
+ { Transform::VFlip, SPA_META_TRANSFORMATION_Flipped180 },
86
+ { Transform::HVFlip, SPA_META_TRANSFORMATION_180 },
87
+ { Transform::Rot180, SPA_META_TRANSFORMATION_180 },
88
+ { Transform::Transpose, SPA_META_TRANSFORMATION_Flipped90 },
89
+ { Transform::Rot90, SPA_META_TRANSFORMATION_90 },
90
+ { Transform::Rot270, SPA_META_TRANSFORMATION_270 },
91
+ { Transform::Rot180Transpose, SPA_META_TRANSFORMATION_Flipped270 },
92
+};
93
+
94
+static uint32_t libcamera_transform_to_spa_transform_value(Transform transform)
95
+{
96
+ for (const auto& t : transform_map) {
97
+ if (t.libcamera_transform == transform)
98
+ return t.spa_transform_value;
99
+ }
100
+ return SPA_META_TRANSFORMATION_None;
101
+}
102
+
103
static int
104
mmap_init(struct impl *impl, struct port *port,
105
struct spa_buffer **buffers, uint32_t n_buffers)
106
107
b->flags = BUFFER_FLAG_OUTSTANDING;
108
b->h = (struct spa_meta_header*)spa_buffer_find_meta_data(buffersi, SPA_META_Header, sizeof(*b->h));
109
110
+ b->videotransform = (struct spa_meta_videotransform*)spa_buffer_find_meta_data(
111
+ buffersi, SPA_META_VideoTransform, sizeof(*b->videotransform));
112
+ if (b->videotransform) {
113
+ b->videotransform->transform =
114
+ libcamera_transform_to_spa_transform_value(impl->config->transform);
115
+ spa_log_debug(impl->log, "Setting videotransform for buffer %d to %u (from %s)",
116
+ i, b->videotransform->transform, transformToString(impl->config->transform));
117
+
118
+ }
119
+
120
d = buffersi->datas;
121
for(j = 0; j < buffersi->n_datas; ++j) {
122
dj.type = port->memtype;
123
pipewire-0.3.61.tar.gz/spa/plugins/support/loop.c -> pipewire-0.3.62.tar.gz/spa/plugins/support/loop.c
Changed
158
1
2
uint8_t *buffer_data;
3
uint8_t buffer_memDATAS_SIZE + MAX_ALIGN;
4
5
- unsigned int flushing:1;
6
+ uint32_t flush_count;
7
unsigned int polling:1;
8
};
9
10
11
12
static void flush_items(struct impl *impl)
13
{
14
- uint32_t index;
15
+ uint32_t index, flush_count;
16
+ int32_t avail;
17
int res;
18
19
- impl->flushing = true;
20
- while (spa_ringbuffer_get_read_index(&impl->buffer, &index) > 0) {
21
+ flush_count = ++impl->flush_count;
22
+ avail = spa_ringbuffer_get_read_index(&impl->buffer, &index);
23
+ while (avail > 0) {
24
struct invoke_item *item;
25
bool block;
26
+ spa_invoke_func_t func;
27
28
item = SPA_PTROFF(impl->buffer_data, index & (DATAS_SIZE - 1), struct invoke_item);
29
block = item->block;
30
+ func = item->func;
31
32
spa_log_trace_fp(impl->log, "%p: flush item %p", impl, item);
33
- item->res = item->func ? item->func(&impl->loop,
34
- true, item->seq, item->data, item->size,
35
- item->user_data) : 0;
36
-
37
- spa_ringbuffer_read_update(&impl->buffer, index + item->item_size);
38
+ /* first we remove the function from the item so that recursive
39
+ * calls don't call the callback again. We can't update the
40
+ * read index before we call the function because then the item
41
+ * might get overwritten. */
42
+ item->func = NULL;
43
+ if (func)
44
+ item->res = func(&impl->loop, true, item->seq, item->data,
45
+ item->size, item->user_data);
46
+
47
+ /* if this function did a recursive invoke, it now flushed the
48
+ * ringbuffer and we can exit */
49
+ if (flush_count != impl->flush_count)
50
+ break;
51
+
52
+ index += item->item_size;
53
+ avail -= item->item_size;
54
+ spa_ringbuffer_read_update(&impl->buffer, index);
55
56
if (block) {
57
if ((res = spa_system_eventfd_write(impl->system, impl->ack_fd, 1)) < 0)
58
59
impl, impl->ack_fd, spa_strerror(res));
60
}
61
}
62
- impl->flushing = false;
63
}
64
65
static int
66
loop_invoke_inthread(struct impl *impl,
67
- spa_invoke_func_t func,
68
- uint32_t seq,
69
- const void *data,
70
- size_t size,
71
- bool block,
72
- void *user_data)
73
+ spa_invoke_func_t func,
74
+ uint32_t seq,
75
+ const void *data,
76
+ size_t size,
77
+ bool block,
78
+ void *user_data)
79
{
80
- if (!impl->flushing)
81
- flush_items(impl);
82
+ /* we should probably have a second ringbuffer for the in-thread pending
83
+ * callbacks. A recursive callback when flushing will insert itself
84
+ * before this one. */
85
+ flush_items(impl);
86
return func ? func(&impl->loop, true, seq, data, size, user_data) : 0;
87
}
88
89
90
int32_t filled;
91
uint32_t avail, idx, offset, l0;
92
93
+ /* the ringbuffer can only be written to from one thread, if we are
94
+ * in the same thread as the loop, don't write into the ringbuffer
95
+ * but try to emit the calback right away after flushing what we have */
96
if (impl->thread == 0 || pthread_equal(impl->thread, pthread_self()))
97
return loop_invoke_inthread(impl, func, seq, data, size, block, user_data);
98
99
100
item->size = size;
101
item->block = block;
102
item->user_data = user_data;
103
+ item->res = 0;
104
item->item_size = SPA_ROUND_UP_N(sizeof(struct invoke_item) + size, ITEM_ALIGN);
105
106
spa_log_trace_fp(impl->log, "%p: add item %p filled:%d", impl, item, filled);
107
108
uint64_t count = 0;
109
int res;
110
111
- if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0)
112
- spa_log_warn(s->impl->log, "%p: failed to read event fd:%d: %s",
113
- source, source->fd, spa_strerror(res));
114
-
115
+ if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0) {
116
+ if (res != -EAGAIN)
117
+ spa_log_warn(s->impl->log, "%p: failed to read event fd:%d: %s",
118
+ source, source->fd, spa_strerror(res));
119
+ return;
120
+ }
121
s->func.event(source->data, count);
122
}
123
124
125
int res;
126
127
if (SPA_UNLIKELY((res = spa_system_timerfd_read(s->impl->system,
128
- source->fd, &expirations)) < 0))
129
- spa_log_warn(s->impl->log, "%p: failed to read timer fd:%d: %s",
130
- source, source->fd, spa_strerror(res));
131
-
132
+ source->fd, &expirations)) < 0)) {
133
+ if (res != -EAGAIN)
134
+ spa_log_warn(s->impl->log, "%p: failed to read timer fd:%d: %s",
135
+ source, source->fd, spa_strerror(res));
136
+ return;
137
+ }
138
s->func.timer(source->data, expirations);
139
}
140
141
142
struct source_impl *s = SPA_CONTAINER_OF(source, struct source_impl, source);
143
int res, signal_number = 0;
144
145
- if ((res = spa_system_signalfd_read(s->impl->system, source->fd, &signal_number)) < 0)
146
- spa_log_warn(s->impl->log, "%p: failed to read signal fd:%d: %s",
147
- source, source->fd, spa_strerror(res));
148
-
149
+ if ((res = spa_system_signalfd_read(s->impl->system, source->fd, &signal_number)) < 0) {
150
+ if (res != -EAGAIN)
151
+ spa_log_warn(s->impl->log, "%p: failed to read signal fd:%d: %s",
152
+ source, source->fd, spa_strerror(res));
153
+ return;
154
+ }
155
s->func.signal(source->data, signal_number);
156
}
157
158
pipewire-0.3.61.tar.gz/src/daemon/pipewire-pulse.conf.in -> pipewire-0.3.62.tar.gz/src/daemon/pipewire-pulse.conf.in
Changed
27
1
2
#pulse.default.frag = 96000/48000 # 2 seconds
3
#pulse.default.tlength = 96000/48000 # 2 seconds
4
#pulse.min.quantum = 256/48000 # 5ms
5
- #pulse.idle.timeout = 5 # pause after 5s of underruns
6
+ #pulse.idle.timeout = 0 # don't pause after underruns
7
#pulse.default.format = F32
8
#pulse.default.position = FL FR
9
# These overrides are only applied when running in a vm.
10
11
}
12
{
13
# speech dispatcher asks for too small latency and then underruns.
14
- matches = { application.name = "~speech-dispatcher*" }
15
+ matches = { application.name = "~speech-dispatcher.*" }
16
actions = {
17
update-props = {
18
- pulse.min.req = 1024/48000 # 21ms
19
- pulse.min.quantum = 1024/48000 # 21ms
20
- #pulse.idle.timeout = 0
21
+ pulse.min.req = 512/48000 # 10.6ms
22
+ pulse.min.quantum = 512/48000 # 10.6ms
23
+ pulse.idle.timeout = 5 # pause after 5 seconds of underrun
24
}
25
}
26
}
27
pipewire-0.3.61.tar.gz/src/examples/video-dsp-play.c -> pipewire-0.3.62.tar.gz/src/examples/video-dsp-play.c
Changed
10
1
2
3
/* copy video image in texture */
4
sstride = buf->datas0.chunk->stride;
5
+ if (sstride == 0)
6
+ sstride = buf->datas0.chunk->size / data->position->video.size.height;
7
8
src = sdata;
9
dst = ddata;
10
pipewire-0.3.61.tar.gz/src/examples/video-play-fixate.c -> pipewire-0.3.62.tar.gz/src/examples/video-play-fixate.c
Changed
10
1
2
3
/* copy video image in texture */
4
sstride = buf->datas0.chunk->stride;
5
+ if (sstride == 0)
6
+ sstride = buf->datas0.chunk->size / data->size.height;
7
ostride = SPA_MIN(sstride, dstride);
8
9
src = sdata;
10
pipewire-0.3.61.tar.gz/src/examples/video-play-pull.c -> pipewire-0.3.62.tar.gz/src/examples/video-play-pull.c
Changed
10
1
2
}
3
4
sstride = buf->datas0.chunk->stride;
5
+ if (sstride == 0)
6
+ sstride = buf->datas0.chunk->size / data->size.height;
7
ostride = SPA_MIN(sstride, dstride);
8
9
src = sdata;
10
pipewire-0.3.61.tar.gz/src/examples/video-play-reneg.c -> pipewire-0.3.62.tar.gz/src/examples/video-play-reneg.c
Changed
10
1
2
3
/* copy video image in texture */
4
sstride = buf->datas0.chunk->stride;
5
+ if (sstride == 0)
6
+ sstride = buf->datas0.chunk->size / data->size.height;
7
ostride = SPA_MIN(sstride, dstride);
8
9
src = sdata;
10
pipewire-0.3.61.tar.gz/src/examples/video-play.c -> pipewire-0.3.62.tar.gz/src/examples/video-play.c
Changed
10
1
2
}
3
4
sstride = buf->datas0.chunk->stride;
5
+ if (sstride == 0)
6
+ sstride = buf->datas0.chunk->size / data->size.height;
7
ostride = SPA_MIN(sstride, dstride);
8
9
src = sdata;
10
pipewire-0.3.61.tar.gz/src/gst/gstpipewirepool.c -> pipewire-0.3.62.tar.gz/src/gst/gstpipewirepool.c
Changed
10
1
2
data->crop = spa_buffer_find_meta_data (b->buffer, SPA_META_VideoCrop, sizeof(*data->crop));
3
if (data->crop)
4
gst_buffer_add_video_crop_meta(buf);
5
+ data->videotransform =
6
+ spa_buffer_find_meta_data (b->buffer, SPA_META_VideoTransform, sizeof(*data->videotransform));
7
8
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf),
9
pool_data_quark,
10
pipewire-0.3.61.tar.gz/src/gst/gstpipewirepool.h -> pipewire-0.3.62.tar.gz/src/gst/gstpipewirepool.h
Changed
9
1
2
GstBuffer *buf;
3
gboolean queued;
4
struct spa_meta_region *crop;
5
+ struct spa_meta_videotransform *videotransform;
6
};
7
8
struct _GstPipeWirePool {
9
pipewire-0.3.61.tar.gz/src/gst/gstpipewiresink.c -> pipewire-0.3.62.tar.gz/src/gst/gstpipewiresink.c
Changed
9
1
2
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
3
d->chunk->offset = mem->offset;
4
d->chunk->size = mem->size;
5
+ d->chunk->stride = 0;
6
}
7
8
if ((res = pw_stream_queue_buffer (pwsink->stream, data->b)) < 0) {
9
pipewire-0.3.61.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.62.tar.gz/src/gst/gstpipewiresrc.c
Changed
87
1
2
}
3
}
4
5
+static const char * const transform_map = {
6
+ SPA_META_TRANSFORMATION_None = "rotate-0",
7
+ SPA_META_TRANSFORMATION_90 = "rotate-90",
8
+ SPA_META_TRANSFORMATION_180 = "rotate-180",
9
+ SPA_META_TRANSFORMATION_270 = "rotate-270",
10
+ SPA_META_TRANSFORMATION_Flipped = "flip-rotate-0",
11
+ SPA_META_TRANSFORMATION_Flipped90 = "flip-rotate-270",
12
+ SPA_META_TRANSFORMATION_Flipped180 = "flip-rotate-180",
13
+ SPA_META_TRANSFORMATION_Flipped270 = "flip-rotate-90",
14
+};
15
+
16
+static const char *spa_transform_value_to_gst_image_orientation(uint32_t transform_value)
17
+{
18
+ if (transform_value >= SPA_N_ELEMENTS(transform_map))
19
+ transform_value = SPA_META_TRANSFORMATION_None;
20
+
21
+ return transform_maptransform_value;
22
+}
23
+
24
static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc)
25
{
26
struct pw_buffer *b;
27
28
GstPipeWirePoolData *data;
29
struct spa_meta_header *h;
30
struct spa_meta_region *crop;
31
+ struct spa_meta_videotransform *videotransform;
32
guint i;
33
34
b = pw_stream_dequeue_buffer (pwsrc->stream);
35
36
meta->height = crop->region.size.height;
37
}
38
}
39
+
40
+ videotransform = data->videotransform;
41
+ if (videotransform) {
42
+ if (pwsrc->transform_value != videotransform->transform) {
43
+ GstEvent *tag_event;
44
+ const char* tag_string;
45
+
46
+ tag_string =
47
+ spa_transform_value_to_gst_image_orientation(videotransform->transform);
48
+
49
+ GST_LOG_OBJECT (pwsrc, "got new videotransform: %u / %s",
50
+ videotransform->transform, tag_string);
51
+
52
+ tag_event = gst_event_new_tag(gst_tag_list_new(GST_TAG_IMAGE_ORIENTATION,
53
+ tag_string, NULL));
54
+ gst_pad_push_event (GST_BASE_SRC_PAD (pwsrc), tag_event);
55
+
56
+ pwsrc->transform_value = videotransform->transform;
57
+ }
58
+ }
59
+
60
for (i = 0; i < b->buffer->n_datas; i++) {
61
struct spa_data *d = &b->buffer->datasi;
62
GstMemory *pmem = gst_buffer_peek_memory (data->buf, i);
63
64
pwsrc->negotiated = pwsrc->caps != NULL;
65
66
if (pwsrc->negotiated) {
67
- const struct spa_pod *params3;
68
+ const struct spa_pod *params4;
69
struct spa_pod_builder b = { NULL };
70
uint8_t buffer512;
71
uint32_t buffers = CLAMP (16, pwsrc->min_buffers, pwsrc->max_buffers);
72
73
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
74
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoCrop),
75
SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_region)));
76
+ params3 = spa_pod_builder_add_object (&b,
77
+ SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
78
+ SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoTransform),
79
+ SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_videotransform)));
80
81
GST_DEBUG_OBJECT (pwsrc, "doing finish format");
82
- pw_stream_update_params (pwsrc->stream, params, 3);
83
+ pw_stream_update_params (pwsrc->stream, params, SPA_N_ELEMENTS(params));
84
} else {
85
GST_WARNING_OBJECT (pwsrc, "finish format with error");
86
pw_stream_set_error (pwsrc->stream, -EINVAL, "unhandled format");
87
pipewire-0.3.61.tar.gz/src/gst/gstpipewiresrc.h -> pipewire-0.3.62.tar.gz/src/gst/gstpipewiresrc.h
Changed
10
1
2
GstPipeWirePool *pool;
3
GstClock *clock;
4
GstClockTime last_time;
5
+
6
+ enum spa_meta_videotransform_value transform_value;
7
};
8
9
struct _GstPipeWireSrcClass {
10
pipewire-0.3.61.tar.gz/src/modules/meson.build -> pipewire-0.3.62.tar.gz/src/modules/meson.build
Changed
16
1
2
cdata.set('HAVE_AVAHI', true)
3
endif
4
5
+if gio_dep.found()
6
+ pipewire_module_protocol_pulse_sources +=
7
+ 'module-protocol-pulse/modules/module-gsettings.c',
8
+
9
+ pipewire_module_protocol_pulse_deps += gio_dep
10
+ cdata.set('HAVE_GIO', true)
11
+endif
12
+
13
if flatpak_support
14
pipewire_module_protocol_pulse_deps += glib2_dep
15
endif
16
pipewire-0.3.61.tar.gz/src/modules/module-client-node/remote-node.c -> pipewire-0.3.62.tar.gz/src/modules/module-client-node/remote-node.c
Changed
10
1
2
struct timespec ts;
3
struct pw_impl_port *p;
4
5
- pw_log_trace("node %p: ready driver:%d exported:%d status:%d", node,
6
+ pw_log_trace_fp("node %p: ready driver:%d exported:%d status:%d", node,
7
node->driver, node->exported, status);
8
9
if (status & SPA_STATUS_HAVE_DATA) {
10
pipewire-0.3.61.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.62.tar.gz/src/modules/module-echo-cancel.c
Changed
17
1
2
{
3
struct impl *impl = data;
4
5
- pw_log_error("error id:%u seq:%d res:%d (%s): %s",
6
- id, seq, res, spa_strerror(res), message);
7
+ if (res == -ENOENT) {
8
+ pw_log_info("id:%u seq:%d res:%d (%s): %s",
9
+ id, seq, res, spa_strerror(res), message);
10
+ } else {
11
+ pw_log_warn("error id:%u seq:%d res:%d (%s): %s",
12
+ id, seq, res, spa_strerror(res), message);
13
+ }
14
15
if (id == PW_ID_CORE && res == -EPIPE)
16
pw_impl_module_schedule_destroy(impl->module);
17
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain.c
Changed
157
1
2
3
unsigned int n_deps;
4
unsigned int visited:1;
5
+ unsigned int disabled:1;
6
};
7
8
struct link {
9
10
const struct fc_descriptor *desc;
11
void **hndl;
12
uint32_t port;
13
+ unsigned next:1;
14
};
15
16
struct graph_hndl {
17
18
struct impl *impl = d;
19
struct pw_buffer *in, *out;
20
struct graph *graph = &impl->graph;
21
- uint32_t i, insize = 0, outsize = 0, n_hndl = graph->n_hndl;
22
+ uint32_t i, j, insize = 0, outsize = 0, n_hndl = graph->n_hndl;
23
int32_t stride = 0;
24
struct graph_port *port;
25
struct spa_data *bd;
26
27
if (in == NULL || out == NULL)
28
goto done;
29
30
- for (i = 0; i < in->buffer->n_datas; i++) {
31
+ for (i = 0, j = 0; i < in->buffer->n_datas; i++) {
32
uint32_t offs, size;
33
34
bd = &in->buffer->datasi;
35
36
offs = SPA_MIN(bd->chunk->offset, bd->maxsize);
37
size = SPA_MIN(bd->chunk->size, bd->maxsize - offs);
38
39
- port = i < graph->n_input ? &graph->inputi : NULL;
40
-
41
- if (port && port->desc)
42
- port->desc->connect_port(*port->hndl, port->port,
43
- SPA_PTROFF(bd->data, offs, void));
44
+ while (j < graph->n_input) {
45
+ port = &graph->inputj++;
46
+ if (port->desc)
47
+ port->desc->connect_port(*port->hndl, port->port,
48
+ SPA_PTROFF(bd->data, offs, void));
49
+ if (!port->next)
50
+ break;
51
52
+ }
53
insize = i == 0 ? size : SPA_MIN(insize, size);
54
stride = SPA_MAX(stride, bd->chunk->stride);
55
}
56
57
n_nodes++;
58
}
59
graph->n_input = 0;
60
- graph->input = calloc(n_input * n_hndl, sizeof(struct graph_port));
61
+ graph->input = calloc(n_input * 16 * n_hndl, sizeof(struct graph_port));
62
graph->n_output = 0;
63
graph->output = calloc(n_output * n_hndl, sizeof(struct graph_port));
64
65
66
} else {
67
struct spa_json it = *inputs;
68
while (spa_json_get_string(&it, v, sizeof(v)) > 0) {
69
- gp = &graph->inputgraph->n_input;
70
if (spa_streq(v, "null")) {
71
+ gp = &graph->inputgraph->n_input++;
72
gp->desc = NULL;
73
pw_log_info("ignore input port %d", graph->n_input);
74
} else if ((port = find_port(first, v, FC_PORT_INPUT)) == NULL) {
75
76
res = -EBUSY;
77
goto error;
78
}
79
- pw_log_info("input port %s%d:%s",
80
+
81
+ if (d->flags & FC_DESCRIPTOR_COPY) {
82
+ for (j = 0; j < desc->n_output; j++) {
83
+ struct port *p = &port->node->output_portj;
84
+ struct link *link;
85
+
86
+ gp = NULL;
87
+ spa_list_for_each(link, &p->link_list, output_link) {
88
+ struct port *peer = link->input;
89
+
90
+ pw_log_info("copy input port %s%d:%s",
91
+ port->node->name, i,
92
+ d->portsport->p.name);
93
+ peer->external = graph->n_input;
94
+ gp = &graph->inputgraph->n_input++;
95
+ gp->desc = peer->node->desc->desc;
96
+ gp->hndl = &peer->node->hndli;
97
+ gp->port = peer->p;
98
+ gp->next = true;
99
+ }
100
+ if (gp != NULL)
101
+ gp->next = false;
102
+ }
103
+ port->node->disabled = true;
104
+ } else {
105
+ pw_log_info("input port %s%d:%s",
106
port->node->name, i, d->portsport->p.name);
107
- port->external = graph->n_input;
108
- gp->desc = d;
109
- gp->hndl = &port->node->hndli;
110
- gp->port = port->p;
111
+ port->external = graph->n_input;
112
+ gp = &graph->inputgraph->n_input++;
113
+ gp->desc = d;
114
+ gp->hndl = &port->node->hndli;
115
+ gp->port = port->p;
116
+ gp->next = false;
117
+ }
118
}
119
- graph->n_input++;
120
}
121
}
122
if (outputs == NULL) {
123
124
desc = node->desc;
125
d = desc->desc;
126
127
- for (i = 0; i < n_hndl; i++) {
128
- gh = &graph->hndlgraph->n_hndl++;
129
- gh->hndl = &node->hndli;
130
- gh->desc = d;
131
-
132
+ if (!node->disabled) {
133
+ for (i = 0; i < n_hndl; i++) {
134
+ gh = &graph->hndlgraph->n_hndl++;
135
+ gh->hndl = &node->hndli;
136
+ gh->desc = d;
137
+ }
138
}
139
for (i = 0; i < desc->n_output; i++) {
140
spa_list_for_each(link, &node->output_porti.link_list, output_link)
141
142
{
143
struct impl *impl = data;
144
145
- pw_log_error("error id:%u seq:%d res:%d (%s): %s",
146
- id, seq, res, spa_strerror(res), message);
147
+ if (res == -ENOENT) {
148
+ pw_log_info("message id:%u seq:%d res:%d (%s): %s",
149
+ id, seq, res, spa_strerror(res), message);
150
+ } else {
151
+ pw_log_warn("error id:%u seq:%d res:%d (%s): %s",
152
+ id, seq, res, spa_strerror(res), message);
153
+ }
154
155
if (id == PW_ID_CORE && res == -EPIPE)
156
pw_impl_module_schedule_destroy(impl->module);
157
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
56
1
2
3
static const struct fc_descriptor copy_desc = {
4
.name = "copy",
5
+ .flags = FC_DESCRIPTOR_COPY,
6
7
.n_ports = 2,
8
.ports = copy_ports,
9
10
static void bq_run(struct builtin *impl, unsigned long samples, int type)
11
{
12
struct biquad *bq = &impl->bq;
13
- unsigned long i;
14
float *out = impl->port0;
15
float *in = impl->port1;
16
float freq = impl->port20;
17
float Q = impl->port30;
18
float gain = impl->port40;
19
- float x1, x2, y1, y2;
20
- float b0, b1, b2, a1, a2;
21
22
if (impl->freq != freq || impl->Q != Q || impl->gain != gain) {
23
impl->freq = freq;
24
25
impl->gain = gain;
26
biquad_set(bq, type, freq * 2 / impl->rate, Q, gain);
27
}
28
- x1 = bq->x1;
29
- x2 = bq->x2;
30
- y1 = bq->y1;
31
- y2 = bq->y2;
32
- b0 = bq->b0;
33
- b1 = bq->b1;
34
- b2 = bq->b2;
35
- a1 = bq->a1;
36
- a2 = bq->a2;
37
- for (i = 0; i < samples; i++) {
38
- float x = ini;
39
- float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
40
- outi = y;
41
- x2 = x1;
42
- x1 = x;
43
- y2 = y1;
44
- y1 = y;
45
- }
46
-#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x))
47
- bq->x1 = F(x1);
48
- bq->x2 = F(x2);
49
- bq->y1 = F(y1);
50
- bq->y2 = F(y2);
51
-#undef F
52
+ dsp_ops_biquad_run(&dsp_ops, bq, out, in, samples);
53
}
54
55
/** bq_lowpass */
56
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/convolver.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/convolver.c
Changed
53
1
2
3
int convolver_run(struct convolver *conv, const float *input, float *output, int length)
4
{
5
- int i;
6
-
7
convolver1_run(conv->headConvolver, input, output, length);
8
9
if (conv->tailInput) {
10
11
int remaining = length - processed;
12
int processing = SPA_MIN(remaining, conv->headBlockSize - (conv->tailInputFill % conv->headBlockSize));
13
14
- const int sumBegin = processed;
15
- const int sumEnd = processed + processing;
16
-
17
- if (conv->tailPrecalculated0) {
18
- int precalculatedPos = conv->precalculatedPos;
19
- for (i = sumBegin; i < sumEnd; i++) {
20
- outputi += conv->tailPrecalculated0precalculatedPos;
21
- precalculatedPos++;
22
- }
23
- }
24
-
25
- if (conv->tailPrecalculated) {
26
- int precalculatedPos = conv->precalculatedPos;
27
- for (i = sumBegin; i < sumEnd; i++) {
28
- outputi += conv->tailPrecalculatedprecalculatedPos;
29
- precalculatedPos++;
30
- }
31
- }
32
+ if (conv->tailPrecalculated0)
33
+ fft_sum(&outputprocessed, &outputprocessed,
34
+ &conv->tailPrecalculated0conv->precalculatedPos,
35
+ processing);
36
+ if (conv->tailPrecalculated)
37
+ fft_sum(&outputprocessed, &outputprocessed,
38
+ &conv->tailPrecalculatedconv->precalculatedPos,
39
+ processing);
40
conv->precalculatedPos += processing;
41
42
fft_copy(conv->tailInput + conv->tailInputFill, input + processed, processing);
43
44
if (conv->tailPrecalculated &&
45
conv->tailInputFill == conv->tailBlockSize) {
46
SPA_SWAP(conv->tailPrecalculated, conv->tailOutput);
47
- convolver1_run(conv->tailConvolver, conv->tailInput, conv->tailOutput, conv->tailBlockSize);
48
+ convolver1_run(conv->tailConvolver, conv->tailInput,
49
+ conv->tailOutput, conv->tailBlockSize);
50
}
51
if (conv->tailInputFill == conv->tailBlockSize) {
52
conv->tailInputFill = 0;
53
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c
Changed
47
1
2
#include <string.h>
3
#include <stdio.h>
4
#include <math.h>
5
+#include <float.h>
6
7
#include <spa/utils/defs.h>
8
9
10
}
11
}
12
}
13
+
14
+void dsp_biquad_run_c(struct dsp_ops *ops, struct biquad *bq,
15
+ float *out, const float *in, uint32_t n_samples)
16
+{
17
+ float x1, x2, y1, y2;
18
+ float b0, b1, b2, a1, a2;
19
+ uint32_t i;
20
+
21
+ x1 = bq->x1;
22
+ x2 = bq->x2;
23
+ y1 = bq->y1;
24
+ y2 = bq->y2;
25
+ b0 = bq->b0;
26
+ b1 = bq->b1;
27
+ b2 = bq->b2;
28
+ a1 = bq->a1;
29
+ a2 = bq->a2;
30
+ for (i = 0; i < n_samples; i++) {
31
+ float x = ini;
32
+ float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
33
+ outi = y;
34
+ x2 = x1;
35
+ x1 = x;
36
+ y2 = y1;
37
+ y1 = y;
38
+ }
39
+#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x))
40
+ bq->x1 = F(x1);
41
+ bq->x2 = F(x2);
42
+ bq->y1 = F(y1);
43
+ bq->y2 = F(y2);
44
+#undef F
45
+}
46
+
47
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/dsp-ops.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/dsp-ops.c
Changed
32
1
2
void * SPA_RESTRICT dst,
3
const void * SPA_RESTRICT src,
4
float gain, uint32_t n_src, uint32_t n_samples);
5
+ void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq,
6
+ float *out, const float *in, uint32_t n_samples);
7
};
8
9
static struct dsp_info dsp_table =
10
11
{ SPA_CPU_FLAG_SSE,
12
.copy = dsp_copy_c,
13
.mix_gain = dsp_mix_gain_sse,
14
+ .biquad_run = dsp_biquad_run_c,
15
},
16
#endif
17
{ 0,
18
.copy = dsp_copy_c,
19
.mix_gain = dsp_mix_gain_c,
20
+ .biquad_run = dsp_biquad_run_c,
21
},
22
};
23
24
25
ops->cpu_flags = info->cpu_flags;
26
ops->copy = info->copy;
27
ops->mix_gain = info->mix_gain;
28
+ ops->biquad_run = info->biquad_run;
29
ops->free = impl_dsp_ops_free;
30
31
return 0;
32
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/dsp-ops.h -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/dsp-ops.h
Changed
45
1
2
3
#include <spa/utils/defs.h>
4
5
+#include "biquad.h"
6
+
7
struct dsp_ops {
8
uint32_t cpu_flags;
9
10
11
void * SPA_RESTRICT dst,
12
const void * SPA_RESTRICT src,
13
float gain, uint32_t n_src, uint32_t n_samples);
14
+ void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq,
15
+ float *out, const float *in, uint32_t n_samples);
16
void (*free) (struct dsp_ops *ops);
17
18
const void *priv;
19
20
21
#define dsp_ops_copy(ops,...) (ops)->copy(ops, __VA_ARGS__)
22
#define dsp_ops_mix_gain(ops,...) (ops)->mix_gain(ops, __VA_ARGS__)
23
+#define dsp_ops_biquad_run(ops,...) (ops)->biquad_run(ops, __VA_ARGS__)
24
#define dsp_ops_free(ops) (ops)->free(ops)
25
26
27
#define MAKE_COPY_FUNC(arch) \
28
void dsp_copy_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \
29
- const void * SPA_RESTRICT src, uint32_t n_samples)
30
+ const void * SPA_RESTRICT src, uint32_t n_samples)
31
#define MAKE_MIX_GAIN_FUNC(arch) \
32
void dsp_mix_gain_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \
33
const void * SPA_RESTRICT src, float gain, uint32_t n_src, uint32_t n_samples)
34
+#define MAKE_BIQUAD_RUN_FUNC(arch) \
35
+void dsp_biquad_run_##arch (struct dsp_ops *ops, struct biquad *bq, \
36
+ float *out, const float *in, uint32_t n_samples)
37
38
39
MAKE_COPY_FUNC(c);
40
MAKE_MIX_GAIN_FUNC(c);
41
+MAKE_BIQUAD_RUN_FUNC(c);
42
#if defined (HAVE_SSE)
43
MAKE_MIX_GAIN_FUNC(sse);
44
#endif
45
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/plugin.h -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/plugin.h
Changed
9
1
2
struct fc_descriptor {
3
const char *name;
4
#define FC_DESCRIPTOR_SUPPORTS_NULL_DATA (1ULL << 0)
5
+#define FC_DESCRIPTOR_COPY (1ULL << 1)
6
uint64_t flags;
7
8
void (*free) (const struct fc_descriptor *desc);
9
pipewire-0.3.61.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.62.tar.gz/src/modules/module-loopback.c
Changed
75
1
2
&impl->playback_listener,
3
&out_stream_events, impl);
4
5
+ /* connect playback first to activate it before capture triggers it */
6
n_params = 0;
7
spa_pod_builder_init(&b, buffer, sizeof(buffer));
8
paramsn_params++ = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat,
9
- &impl->capture_info);
10
-
11
- if ((res = pw_stream_connect(impl->capture,
12
- PW_DIRECTION_INPUT,
13
+ &impl->playback_info);
14
+ if ((res = pw_stream_connect(impl->playback,
15
+ PW_DIRECTION_OUTPUT,
16
PW_ID_ANY,
17
PW_STREAM_FLAG_AUTOCONNECT |
18
PW_STREAM_FLAG_MAP_BUFFERS |
19
- PW_STREAM_FLAG_RT_PROCESS,
20
+ PW_STREAM_FLAG_RT_PROCESS |
21
+ PW_STREAM_FLAG_TRIGGER,
22
params, n_params)) < 0)
23
return res;
24
25
n_params = 0;
26
spa_pod_builder_init(&b, buffer, sizeof(buffer));
27
paramsn_params++ = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat,
28
- &impl->playback_info);
29
-
30
- if ((res = pw_stream_connect(impl->playback,
31
- PW_DIRECTION_OUTPUT,
32
+ &impl->capture_info);
33
+ if ((res = pw_stream_connect(impl->capture,
34
+ PW_DIRECTION_INPUT,
35
PW_ID_ANY,
36
PW_STREAM_FLAG_AUTOCONNECT |
37
PW_STREAM_FLAG_MAP_BUFFERS |
38
- PW_STREAM_FLAG_RT_PROCESS |
39
- PW_STREAM_FLAG_TRIGGER,
40
+ PW_STREAM_FLAG_RT_PROCESS,
41
params, n_params)) < 0)
42
return res;
43
44
45
{
46
struct impl *impl = data;
47
48
- pw_log_error("error id:%u seq:%d res:%d (%s): %s",
49
- id, seq, res, spa_strerror(res), message);
50
+ if (res == -ENOENT) {
51
+ pw_log_info("message id:%u seq:%d res:%d (%s): %s",
52
+ id, seq, res, spa_strerror(res), message);
53
+ } else {
54
+ pw_log_warn("error id:%u seq:%d res:%d (%s): %s",
55
+ id, seq, res, spa_strerror(res), message);
56
+ }
57
58
if (id == PW_ID_CORE && res == -EPIPE)
59
pw_impl_module_schedule_destroy(impl->module);
60
61
62
static void impl_destroy(struct impl *impl)
63
{
64
- /* disconnect both streams before destroying any of them */
65
+ /* deactivate both streams before destroying any of them */
66
if (impl->capture)
67
- pw_stream_disconnect(impl->capture);
68
+ pw_stream_set_active(impl->capture, false);
69
if (impl->playback)
70
- pw_stream_disconnect(impl->playback);
71
+ pw_stream_set_active(impl->playback, false);
72
73
if (impl->capture)
74
pw_stream_destroy(impl->capture);
75
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/module.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/module.c
Changed
47
1
2
#include <pipewire/properties.h>
3
#include <pipewire/work-queue.h>
4
5
-#include "client.h"
6
#include "defs.h"
7
#include "format.h"
8
#include "internal.h"
9
10
spa_hook_list_append(&module->listener_list, listener, events, data);
11
}
12
13
-int module_load(struct client *client, struct module *module)
14
+int module_load(struct module *module)
15
{
16
pw_log_info("load module index:%u name:%s", module->index, module->info->name);
17
if (module->info->load == NULL)
18
return -ENOTSUP;
19
/* subscription event is sent when the module does a
20
* module_emit_loaded() */
21
- return module->info->load(client, module);
22
+ return module->info->load(module);
23
}
24
25
void module_free(struct module *module)
26
27
struct impl *impl = module->impl;
28
int res = 0;
29
30
- /* Note that client can be NULL (when the module is being unloaded
31
- * internally and not by a client request */
32
-
33
pw_log_info("unload module index:%u name:%s", module->index, module->info->name);
34
35
if (module->info->unload)
36
37
return spa_streq(module->info->name, name) ? 1 : 0;
38
}
39
40
-struct module *module_create(struct client *client, const char *name, const char *args)
41
+struct module *module_create(struct impl *impl, const char *name, const char *args)
42
{
43
- struct impl *impl = client->impl;
44
const struct module_info *info;
45
struct module *module;
46
47
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/module.h -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/module.h
Changed
30
1
2
#include <spa/param/audio/raw.h>
3
#include <spa/utils/hook.h>
4
5
-#include "client.h"
6
#include "internal.h"
7
8
struct module;
9
10
unsigned int load_once:1;
11
12
int (*prepare) (struct module *module);
13
- int (*load) (struct client *client, struct module *module);
14
+ int (*load) (struct module *module);
15
int (*unload) (struct module *module);
16
17
const struct spa_dict *properties;
18
19
#define module_emit_loaded(m,r) spa_hook_list_call(&m->listener_list, struct module_events, loaded, 0, r)
20
#define module_emit_destroy(m) spa_hook_list_call(&(m)->listener_list, struct module_events, destroy, 0)
21
22
-struct module *module_create(struct client *client, const char *name, const char *args);
23
+struct module *module_create(struct impl *impl, const char *name, const char *args);
24
void module_free(struct module *module);
25
-int module_load(struct client *client, struct module *module);
26
+int module_load(struct module *module);
27
int module_unload(struct module *module);
28
void module_schedule_unload(struct module *module);
29
30
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-always-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-always-sink.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_always_sink_load(struct client *client, struct module *module)
6
+static int module_always_sink_load(struct module *module)
7
{
8
struct module_always_sink_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c
Changed
21
1
2
check_initialized(data);
3
}
4
5
-static int module_combine_sink_load(struct client *client, struct module *module)
6
+static int module_combine_sink_load(struct module *module)
7
{
8
struct module_combine_sink_data *data = module->user_data;
9
struct pw_properties *props;
10
11
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
12
const char *str;
13
14
- data->core = pw_context_connect(module->impl->context,
15
- pw_properties_copy(client->props),
16
- 0);
17
+ data->core = pw_context_connect(module->impl->context, NULL, 0);
18
if (data->core == NULL)
19
return -errno;
20
21
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-echo-cancel.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-echo-cancel.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_echo_cancel_load(struct client *client, struct module *module)
6
+static int module_echo_cancel_load(struct module *module)
7
{
8
struct module_echo_cancel_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-gsettings.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 <gio/gio.h>
27
+#include <glib.h>
28
+
29
+#include <spa/debug/mem.h>
30
+#include <pipewire/pipewire.h>
31
+#include <pipewire/thread.h>
32
+
33
+#include "../module.h"
34
+
35
+#define NAME "gsettings"
36
+
37
+PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
38
+#define PW_LOG_TOPIC_DEFAULT mod_topic
39
+
40
+#define PA_GSETTINGS_MODULE_GROUP_SCHEMA "org.freedesktop.pulseaudio.module-group"
41
+#define PA_GSETTINGS_MODULE_GROUPS_SCHEMA "org.freedesktop.pulseaudio.module-groups"
42
+#define PA_GSETTINGS_MODULE_GROUPS_PATH "/org/freedesktop/pulseaudio/module-groups/"
43
+
44
+#define MAX_MODULES 10
45
+
46
+struct module_gsettings_data {
47
+ struct module *module;
48
+
49
+ GMainContext *context;
50
+ GMainLoop *loop;
51
+ struct spa_thread *thr;
52
+
53
+ GSettings *settings;
54
+ gchar **group_names;
55
+
56
+ struct spa_list groups;
57
+};
58
+
59
+struct group {
60
+ struct spa_list link;
61
+ char *name;
62
+ struct module *module;
63
+ struct spa_hook module_listener;
64
+};
65
+
66
+struct info {
67
+ bool enabled;
68
+ char *name;
69
+ char *moduleMAX_MODULES;
70
+ char *argsMAX_MODULES;
71
+};
72
+
73
+static void clean_info(const struct info *info)
74
+{
75
+ int i;
76
+ for (i = 0; i < MAX_MODULES; i++) {
77
+ g_free(info->modulei);
78
+ g_free(info->argsi);
79
+ }
80
+ g_free(info->name);
81
+}
82
+
83
+static void unload_module(struct module_gsettings_data *d, struct group *g)
84
+{
85
+ spa_list_remove(&g->link);
86
+ g_free(g->name);
87
+ if (g->module)
88
+ module_unload(g->module);
89
+ free(g);
90
+}
91
+
92
+static void unload_group(struct module_gsettings_data *d, const char *name)
93
+{
94
+ struct group *g, *t;
95
+ spa_list_for_each_safe(g, t, &d->groups, link) {
96
+ if (spa_streq(g->name, name))
97
+ unload_module(d, g);
98
+ }
99
+}
100
+static void module_destroy(void *data)
101
+{
102
+ struct group *g = data;
103
+ if (g->module) {
104
+ spa_hook_remove(&g->module_listener);
105
+ g->module = NULL;
106
+ }
107
+}
108
+
109
+static const struct module_events module_gsettings_events = {
110
+ VERSION_MODULE_EVENTS,
111
+ .destroy = module_destroy
112
+};
113
+
114
+static int load_group(struct module_gsettings_data *d, const struct info *info)
115
+{
116
+ struct group *g;
117
+ int i, res;
118
+
119
+ for (i = 0; i < MAX_MODULES; i++) {
120
+ if (info->modulei == NULL || strlen(info->modulei) <= 0)
121
+ break;
122
+
123
+ g = calloc(1, sizeof(struct group));
124
+ if (g == NULL)
125
+ return -errno;
126
+
127
+ g->name = strdup(info->name);
128
+ g->module = module_create(d->module->impl, info->modulei, info->argsi);
129
+ if (g->module == NULL) {
130
+ pw_log_info("can't create module:%s args:%s: %m",
131
+ info->modulei, info->argsi);
132
+ } else {
133
+ module_add_listener(g->module, &g->module_listener,
134
+ &module_gsettings_events, g);
135
+ if ((res = module_load(g->module)) < 0) {
136
+ pw_log_warn("can't load module:%s args:%s: %s",
137
+ info->modulei, info->argsi,
138
+ spa_strerror(res));
139
+ }
140
+ }
141
+ spa_list_append(&d->groups, &g->link);
142
+ }
143
+ return 0;
144
+}
145
+
146
+static int
147
+do_handle_info(struct spa_loop *loop,
148
+ bool async, uint32_t seq, const void *data, size_t size, void *user_data)
149
+{
150
+ struct module_gsettings_data *d = user_data;
151
+ const struct info *info = data;
152
+
153
+ unload_group(d, info->name);
154
+ if (info->enabled)
155
+ load_group(d, info);
156
+
157
+ clean_info(info);
158
+ return 0;
159
+}
160
+
161
+static void handle_module_group(struct module_gsettings_data *d, gchar *name)
162
+{
163
+ struct impl *impl = d->module->impl;
164
+ GSettings *settings;
165
+ gchar p1024;
166
+ struct info info;
167
+ int i;
168
+
169
+ snprintf(p, sizeof(p), PA_GSETTINGS_MODULE_GROUPS_PATH"%s/", name);
170
+
171
+ settings = g_settings_new_with_path(PA_GSETTINGS_MODULE_GROUP_SCHEMA, p);
172
+ if (settings == NULL)
173
+ return;
174
+
175
+ spa_zero(info);
176
+ info.name = strdup(p);
177
+ info.enabled = g_settings_get_boolean(settings, "enabled");
178
+
179
+ for (i = 0; i < MAX_MODULES; i++) {
180
+ snprintf(p, sizeof(p), "name%d", i);
181
+ info.modulei = g_settings_get_string(settings, p);
182
+
183
+ snprintf(p, sizeof(p), "args%i", i);
184
+ info.argsi = g_settings_get_string(settings, p);
185
+ }
186
+ pw_loop_invoke(impl->loop, do_handle_info, 0,
187
+ &info, sizeof(info), false, d);
188
+
189
+ g_object_unref(G_OBJECT(settings));
190
+}
191
+
192
+static void module_group_callback(GSettings *settings, gchar *key, gpointer user_data)
193
+{
194
+ struct module_gsettings_data *d = g_object_get_data(G_OBJECT(settings), "module-data");
195
+ handle_module_group(d, user_data);
196
+}
197
+
198
+static void *do_loop(void *user_data)
199
+{
200
+ struct module_gsettings_data *d = user_data;
201
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_ladspa_sink_load(struct client *client, struct module *module)
6
+static int module_ladspa_sink_load(struct module *module)
7
{
8
struct module_ladspa_sink_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_ladspa_source_load(struct client *client, struct module *module)
6
+static int module_ladspa_source_load(struct module *module)
7
{
8
struct module_ladspa_source_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_loopback_load(struct client *client, struct module *module)
6
+static int module_loopback_load(struct module *module)
7
{
8
struct module_loopback_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-native-protocol-tcp.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-native-protocol-tcp.c
Changed
14
1
2
struct pw_array servers;
3
};
4
5
-static int module_native_protocol_tcp_load(struct client *client, struct module *module)
6
+static int module_native_protocol_tcp_load(struct module *module)
7
{
8
struct module_native_protocol_tcp_data *data = module->user_data;
9
- struct impl *impl = client->impl;
10
+ struct impl *impl = module->impl;
11
const char *address;
12
int res;
13
14
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-null-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-null-sink.c
Changed
15
1
2
.error = module_null_sink_core_error,
3
};
4
5
-static int module_null_sink_load(struct client *client, struct module *module)
6
+static int module_null_sink_load(struct module *module)
7
{
8
struct module_null_sink_data *d = module->user_data;
9
10
- d->core = pw_context_connect(module->impl->context, pw_properties_copy(client->props), 0);
11
+ d->core = pw_context_connect(module->impl->context, NULL, 0);
12
if (d->core == NULL)
13
return -errno;
14
15
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_pipe_sink_load(struct client *client, struct module *module)
6
+static int module_pipe_sink_load(struct module *module)
7
{
8
struct module_pipesink_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_pipe_source_load(struct client *client, struct module *module)
6
+static int module_pipe_source_load(struct module *module)
7
{
8
struct module_pipesrc_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-raop-discover.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-raop-discover.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_raop_discover_load(struct client *client, struct module *module)
6
+static int module_raop_discover_load(struct module *module)
7
{
8
struct module_raop_discover_data *data = module->user_data;
9
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_remap_sink_load(struct client *client, struct module *module)
6
+static int module_remap_sink_load(struct module *module)
7
{
8
struct module_remap_sink_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_remap_source_load(struct client *client, struct module *module)
6
+static int module_remap_source_load(struct module *module)
7
{
8
struct module_remap_source_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_roc_sink_input_load(struct client *client, struct module *module)
6
+static int module_roc_sink_input_load(struct module *module)
7
{
8
struct module_roc_sink_input_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_roc_sink_load(struct client *client, struct module *module)
6
+static int module_roc_sink_load(struct module *module)
7
{
8
struct module_roc_sink_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_roc_source_load(struct client *client, struct module *module)
6
+static int module_roc_source_load(struct module *module)
7
{
8
struct module_roc_source_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_rtp_recv_load(struct client *client, struct module *module)
6
+static int module_rtp_recv_load(struct module *module)
7
{
8
struct module_rtp_recv_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_rtp_send_load(struct client *client, struct module *module)
6
+static int module_rtp_send_load(struct module *module)
7
{
8
struct module_rtp_send_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-simple-protocol-tcp.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-simple-protocol-tcp.c
Changed
14
1
2
.destroy = module_destroy
3
};
4
5
-static int module_simple_protocol_tcp_load(struct client *client, struct module *module)
6
+static int module_simple_protocol_tcp_load(struct module *module)
7
{
8
struct module_simple_protocol_tcp_data *data = module->user_data;
9
- struct impl *impl = client->impl;
10
+ struct impl *impl = module->impl;
11
char *args;
12
size_t size;
13
uint32_t i;
14
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-switch-on-connect.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-switch-on-connect.c
Changed
18
1
2
.done = on_core_done,
3
};
4
5
-static int module_switch_on_connect_load(struct client *client, struct module *module)
6
+static int module_switch_on_connect_load(struct module *module)
7
{
8
- struct impl *impl = client->impl;
9
+ struct impl *impl = module->impl;
10
struct module_switch_on_connect_data *d = module->user_data;
11
int res;
12
13
- d->core = pw_context_connect(impl->context, pw_properties_copy(client->props), 0);
14
+ d->core = pw_context_connect(impl->context, NULL, 0);
15
if (d->core == NULL) {
16
res = -errno;
17
goto error;
18
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_tunnel_sink_load(struct client *client, struct module *module)
6
+static int module_tunnel_sink_load(struct module *module)
7
{
8
struct module_tunnel_sink_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_tunnel_source_load(struct client *client, struct module *module)
6
+static int module_tunnel_source_load(struct module *module)
7
{
8
struct module_tunnel_source_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-x11-bell.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-x11-bell.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_x11_bell_load(struct client *client, struct module *module)
6
+static int module_x11_bell_load(struct module *module)
7
{
8
struct module_x11_bell_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c
Changed
10
1
2
.destroy = module_destroy
3
};
4
5
-static int module_zeroconf_discover_load(struct client *client, struct module *module)
6
+static int module_zeroconf_discover_load(struct module *module)
7
{
8
struct module_zeroconf_discover_data *data = module->user_data;
9
FILE *f;
10
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c
Changed
99
1
2
3
AvahiEntryGroup *entry_group;
4
AvahiStringList *txt;
5
+ struct server *server;
6
7
const char *service_type;
8
enum service_subtype subtype;
9
10
spa_list_remove(&s->link);
11
spa_list_append(&s->userdata->pending, &s->link);
12
s->published = false;
13
+ s->server = NULL;
14
}
15
16
static void unpublish_all_services(struct module_zeroconf_publish_data *d)
17
18
return txt;
19
}
20
21
-static int find_port(struct service *s, int *proto, uint16_t *port)
22
+static struct server *find_server(struct service *s, int *proto, uint16_t *port)
23
{
24
struct module_zeroconf_publish_data *d = s->userdata;
25
struct impl *impl = d->module->impl;
26
27
if (server->addr.ss_family == AF_INET) {
28
*proto = AVAHI_PROTO_INET;
29
*port = ntohs(((struct sockaddr_in*) &server->addr)->sin_port);
30
- return 0;
31
+ return server;
32
} else if (server->addr.ss_family == AF_INET6) {
33
*proto = AVAHI_PROTO_INET6;
34
*port = ntohs(((struct sockaddr_in6*) &server->addr)->sin6_port);
35
- return 0;
36
+ return server;
37
}
38
}
39
- return -ENODEV;
40
+
41
+ return NULL;
42
}
43
44
static void publish_service(struct service *s)
45
46
int proto;
47
uint16_t port;
48
49
- if (find_port(s, &proto, &port) < 0)
50
+ struct server *server = find_server(s, &proto, &port);
51
+ if (!server)
52
return;
53
54
- pw_log_debug("found proto:%d port:%d", proto, port);
55
+ pw_log_debug("found server:%p proto:%d port:%d", server, proto, port);
56
57
if (!d->client || avahi_client_get_state(d->client) != AVAHI_CLIENT_S_RUNNING)
58
return;
59
60
61
spa_list_remove(&s->link);
62
spa_list_append(&d->published, &s->link);
63
+ s->server = server;
64
65
pw_log_info("created service: %s", s->service_name);
66
return;
67
68
{
69
struct module_zeroconf_publish_data *d = data;
70
pw_log_info("a server stopped, try republish");
71
- unpublish_all_services(d);
72
+
73
+ struct service *s, *tmp;
74
+ spa_list_for_each_safe(s, tmp, &d->published, link) {
75
+ if (s->server == server)
76
+ unpublish_service(s);
77
+ }
78
+
79
publish_pending(d);
80
}
81
82
83
.server_stopped = impl_server_stopped,
84
};
85
86
-static int module_zeroconf_publish_load(struct client *client, struct module *module)
87
+static int module_zeroconf_publish_load(struct module *module)
88
{
89
struct module_zeroconf_publish_data *data = module->user_data;
90
struct pw_loop *loop;
91
int error;
92
93
- data->core = pw_context_connect(module->impl->context,
94
- pw_properties_copy(client->props), 0);
95
+ data->core = pw_context_connect(module->impl->context, NULL, 0);
96
if (data->core == NULL) {
97
pw_log_error("failed to connect to pipewire: %m");
98
return -errno;
99
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
36
1
2
#define DEFAULT_MIN_QUANTUM "256/48000"
3
#define DEFAULT_FORMAT "F32"
4
#define DEFAULT_POSITION " FL FR "
5
-#define DEFAULT_IDLE_TIMEOUT "5"
6
+#define DEFAULT_IDLE_TIMEOUT "0"
7
8
#define MAX_FORMATS 32
9
/* The max amount of data we send in one block when capturing. In PulseAudio this
10
11
.sync = on_load_module_manager_sync,
12
};
13
14
+ struct impl *impl = client->impl;
15
const char *name, *argument;
16
struct module *module;
17
struct pending_module *pm;
18
19
pw_log_info("%s %s name:%s argument:%s",
20
client->name, commandscommand.name, name, argument);
21
22
- module = module_create(client, name, argument);
23
+ module = module_create(impl, name, argument);
24
if (module == NULL)
25
return -errno;
26
27
28
29
pw_log_debug("pending module %p: start tag:%d", pm, tag);
30
31
- r = module_load(client, module);
32
+ r = module_load(module);
33
34
module_add_listener(module, &pm->module_listener, &module_events, pm);
35
client_add_listener(client, &pm->client_listener, &client_events, pm);
36
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
20
1
2
if (len < 2)
3
return -ENOSPC;
4
5
- snprintf(ip, sizeof(ip), ":::%d", res);
6
- spa_assert_se(parse_ipv6_address(ip, (struct sockaddr_in6 *) &addr) == 0);
7
- addrs0 = addr;
8
-
9
snprintf(ip, sizeof(ip), "0.0.0.0:%d", res);
10
spa_assert_se(parse_ipv4_address(ip, (struct sockaddr_in *) &addr) == 0);
11
+ addrs0 = addr;
12
+
13
+ snprintf(ip, sizeof(ip), ":::%d", res);
14
+ spa_assert_se(parse_ipv6_address(ip, (struct sockaddr_in6 *) &addr) == 0);
15
addrs1 = addr;
16
+
17
return 2;
18
}
19
20
pipewire-0.3.61.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.62.tar.gz/src/modules/module-pulse-tunnel.c
Changed
113
1
2
uint32_t target_latency;
3
uint32_t current_latency;
4
uint32_t target_buffer;
5
+ struct spa_io_rate_match *rate_match;
6
struct spa_dll dll;
7
float max_error;
8
unsigned resync:1;
9
10
}
11
}
12
13
+static void update_rate(struct impl *impl, bool playback)
14
+{
15
+ float error, corr;
16
+
17
+ if (impl->rate_match == NULL)
18
+ return;
19
+
20
+ if (playback)
21
+ error = (float)impl->target_latency - (float)impl->current_latency;
22
+ else
23
+ error = (float)impl->current_latency - (float)impl->target_latency;
24
+ error = SPA_CLAMP(error, -impl->max_error, impl->max_error);
25
+
26
+ corr = spa_dll_update(&impl->dll, error);
27
+ pw_log_debug("error:%f corr:%f current:%u target:%u",
28
+ error, corr,
29
+ impl->current_latency, impl->target_latency);
30
+
31
+ SPA_FLAG_SET(impl->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE);
32
+ impl->rate_match->rate = corr;
33
+}
34
+
35
static void playback_stream_process(void *d)
36
{
37
struct impl *impl = d;
38
39
size, RINGBUFFER_SIZE);
40
impl->resync = true;
41
} else {
42
- float error, corr;
43
-
44
- error = (float)impl->target_latency - (float)impl->current_latency;
45
- error = SPA_CLAMP(error, -impl->max_error, impl->max_error);
46
-
47
- corr = spa_dll_update(&impl->dll, error);
48
- pw_log_debug("filled:%u target:%u error:%f corr:%f %u %u", filled,
49
- impl->target_buffer, error, corr,
50
- impl->current_latency, impl->target_latency);
51
- pw_stream_set_control(impl->stream,
52
- SPA_PROP_rate, 1, &corr, NULL);
53
+ update_rate(impl, true);
54
}
55
spa_ringbuffer_write_data(&impl->ring,
56
impl->buffer, RINGBUFFER_SIZE,
57
58
if (avail < (int32_t)size) {
59
memset(bd->data, 0, size);
60
} else {
61
- float error, corr;
62
-
63
if (avail > (int32_t)RINGBUFFER_SIZE) {
64
avail = impl->target_buffer;
65
index += avail - impl->target_buffer;
66
} else {
67
- error = (float)(impl->current_latency) - (float)impl->target_latency;
68
- error = SPA_CLAMP(error, -impl->max_error, impl->max_error);
69
-
70
- corr = spa_dll_update(&impl->dll, error);
71
-
72
- pw_log_debug("avail:%u target:%u error:%f corr:%f %u %u", avail,
73
- impl->target_buffer, error, corr,
74
- impl->current_latency, impl->target_latency);
75
- pw_stream_set_control(impl->stream,
76
- SPA_PROP_rate, 1, &corr, NULL);
77
+ update_rate(impl, false);
78
}
79
-
80
spa_ringbuffer_read_data(&impl->ring,
81
impl->buffer, RINGBUFFER_SIZE,
82
index & RINGBUFFER_MASK,
83
84
pw_stream_queue_buffer(impl->stream, buf);
85
}
86
87
+static void stream_io_changed(void *data, uint32_t id, void *area, uint32_t size)
88
+{
89
+ struct impl *impl = data;
90
+ switch (id) {
91
+ case SPA_IO_RateMatch:
92
+ impl->rate_match = area;
93
+ break;
94
+ }
95
+}
96
+
97
static const struct pw_stream_events playback_stream_events = {
98
PW_VERSION_STREAM_EVENTS,
99
.destroy = stream_destroy,
100
.state_changed = stream_state_changed,
101
+ .io_changed = stream_io_changed,
102
.process = playback_stream_process
103
};
104
105
106
PW_VERSION_STREAM_EVENTS,
107
.destroy = stream_destroy,
108
.state_changed = stream_state_changed,
109
+ .io_changed = stream_io_changed,
110
.process = capture_stream_process
111
};
112
113
pipewire-0.3.61.tar.gz/src/modules/module-rtp-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-rtp-sink.c
Changed
21
1
2
&iov1, tosend);
3
4
n = sendmsg(impl->rtp_fd, &msg, MSG_NOSIGNAL);
5
- if (n < 0)
6
- pw_log_warn("sendmsg() failed: %m");
7
+ if (n < 0) {
8
+ switch (errno) {
9
+ case ECONNREFUSED:
10
+ case ECONNRESET:
11
+ pw_log_debug("remote end not listening");
12
+ break;
13
+ default:
14
+ pw_log_warn("sendmsg() failed: %m");
15
+ break;
16
+ }
17
+ }
18
19
impl->seq++;
20
impl->timestamp += tosend / impl->frame_size;
21
pipewire-0.3.61.tar.gz/src/modules/module-rtp-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-rtp-source.c
Changed
44
1
2
struct spa_ringbuffer ring;
3
uint8_t bufferBUFFER_SIZE;
4
5
+ struct spa_io_rate_match *rate_match;
6
struct spa_dll dll;
7
uint32_t target_buffer;
8
float max_error;
9
10
pw_log_debug("avail:%u target:%u error:%f corr:%f", avail,
11
sess->target_buffer, error, corr);
12
13
- pw_stream_set_control(sess->stream,
14
- SPA_PROP_rate, 1, &corr, NULL);
15
+ if (sess->rate_match) {
16
+ SPA_FLAG_SET(sess->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE);
17
+ sess->rate_match->rate = corr;
18
+ }
19
}
20
spa_ringbuffer_read_data(&sess->ring,
21
sess->buffer,
22
23
}
24
}
25
26
+static void stream_io_changed(void *data, uint32_t id, void *area, uint32_t size)
27
+{
28
+ struct session *sess = data;
29
+ switch (id) {
30
+ case SPA_IO_RateMatch:
31
+ sess->rate_match = area;
32
+ break;
33
+ }
34
+}
35
+
36
static const struct pw_stream_events out_stream_events = {
37
PW_VERSION_STREAM_EVENTS,
38
.destroy = stream_destroy,
39
.state_changed = on_stream_state_changed,
40
+ .io_changed = stream_io_changed,
41
.process = stream_process
42
};
43
44
pipewire-0.3.61.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.62.tar.gz/src/pipewire/impl-link.c
Changed
21
1
2
pw_log_debug("%p: activate activated:%d state:%s", this, impl->activated,
3
pw_link_state_as_string(this->info.state));
4
5
- if (impl->activated || !this->prepared || !impl->inode->active ||
6
- !impl->inode->added || !impl->onode->active)
7
+ if (impl->activated || !this->prepared ||
8
+ !impl->inode->active || !impl->onode->active)
9
return 0;
10
11
if (!impl->io_set) {
12
13
spa_list_remove(&this->rt.out_mix.rt_link);
14
spa_list_remove(&this->rt.in_mix.rt_link);
15
16
- if (this->input->node != this->output->node) {
17
+ if (impl->inode != impl->onode) {
18
struct pw_node_activation_state *state;
19
20
spa_list_remove(&this->rt.target.link);
21
pipewire-0.3.61.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.62.tar.gz/src/pipewire/impl-node.c
Changed
201
1
2
this->rt.driver_target.node = NULL;
3
}
4
5
+static int
6
+do_node_add(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
7
+{
8
+ struct pw_impl_node *this = user_data;
9
+ struct pw_impl_node *driver = this->driver_node;
10
+
11
+ this->added = true;
12
+ if (this->source.loop == NULL) {
13
+ struct spa_system *data_system = this->context->data_system;
14
+ uint64_t dummy;
15
+ int res;
16
+
17
+ /* clear the eventfd in case it was written to while the node was stopped */
18
+ res = spa_system_eventfd_read(data_system, this->source.fd, &dummy);
19
+ if (SPA_UNLIKELY(res != -EAGAIN && res != 0))
20
+ pw_log_warn("%p: read failed %m", this);
21
+
22
+ spa_loop_add_source(loop, &this->source);
23
+ add_node(this, driver);
24
+ }
25
+ return 0;
26
+}
27
+
28
+static int
29
+do_node_remove(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
30
+{
31
+ struct pw_impl_node *this = user_data;
32
+ if (this->source.loop != NULL) {
33
+ spa_loop_remove_source(loop, &this->source);
34
+ remove_node(this);
35
+ }
36
+ this->added = false;
37
+ return 0;
38
+}
39
+
40
static void node_deactivate(struct pw_impl_node *this)
41
{
42
struct pw_impl_port *port;
43
struct pw_impl_link *link;
44
45
pw_log_debug("%p: deactivate", this);
46
+
47
+ /* make sure the node doesn't get woken up while not active */
48
+ pw_loop_invoke(this->data_loop, do_node_remove, 1, NULL, 0, true, this);
49
+
50
spa_list_for_each(port, &this->input_ports, link) {
51
spa_list_for_each(link, &port->links, input_link)
52
pw_impl_link_deactivate(link);
53
54
return res;
55
}
56
57
-static void node_activate_outputs(struct pw_impl_node *this)
58
+static void node_activate(struct pw_impl_node *this)
59
{
60
struct pw_impl_port *port;
61
62
63
spa_list_for_each(link, &port->links, output_link)
64
pw_impl_link_activate(link);
65
}
66
-}
67
-
68
-static void node_activate_inputs(struct pw_impl_node *this)
69
-{
70
- struct pw_impl_port *port;
71
-
72
- pw_log_debug("%p: activate", this);
73
spa_list_for_each(port, &this->input_ports, link) {
74
struct pw_impl_link *link;
75
spa_list_for_each(link, &port->links, input_link)
76
77
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
78
int res = 0;
79
80
- /* First activate the outputs so that when the node starts pushing,
81
- * we can process the outputs */
82
- node_activate_outputs(this);
83
+ node_activate(this);
84
85
if (impl->pending_state >= PW_NODE_STATE_RUNNING)
86
return 0;
87
88
impl->pending_play = true;
89
res = spa_node_send_command(this->node,
90
&SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Start));
91
+ } else {
92
+ /* driver nodes will wait until all other nodes are started before
93
+ * they are started */
94
+ res = EBUSY;
95
}
96
97
if (res < 0)
98
99
}
100
}
101
102
-static int
103
-do_node_add(struct spa_loop *loop,
104
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
105
-{
106
- struct pw_impl_node *this = user_data;
107
- struct pw_impl_node *driver = this->driver_node;
108
-
109
- if (this->source.loop == NULL) {
110
- spa_loop_add_source(loop, &this->source);
111
- add_node(this, driver);
112
- }
113
- this->added = true;
114
- return 0;
115
-}
116
-
117
-static int
118
-do_node_remove(struct spa_loop *loop,
119
- bool async, uint32_t seq, const void *data, size_t size, void *user_data)
120
-{
121
- struct pw_impl_node *this = user_data;
122
- if (this->source.loop != NULL) {
123
- spa_loop_remove_source(loop, &this->source);
124
- remove_node(this);
125
- }
126
- this->added = false;
127
- return 0;
128
-}
129
-
130
static void node_update_state(struct pw_impl_node *node, enum pw_node_state state, int res, char *error)
131
{
132
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
133
134
pw_loop_invoke(node->data_loop, do_node_remove, 1, NULL, 0, true, node);
135
}
136
}
137
- if (res >= 0) {
138
- /* now activate the inputs */
139
- node_activate_inputs(node);
140
- }
141
break;
142
case PW_NODE_STATE_IDLE:
143
case PW_NODE_STATE_SUSPENDED:
144
145
struct impl *impl = user_data;
146
struct pw_impl_node *driver = *(struct pw_impl_node **)data;
147
struct pw_impl_node *node = &impl->this;
148
- int res;
149
150
pw_log_trace("%p: driver:%p->%p", node, node->driver_node, driver);
151
152
- if ((res = spa_node_set_io(node->node,
153
- SPA_IO_Position,
154
- &driver->rt.activation->position,
155
- sizeof(struct spa_io_position))) < 0) {
156
- pw_log_debug("%p: set position: %s", node, spa_strerror(res));
157
- }
158
-
159
pw_log_trace("%p: set position %p", node, &driver->rt.activation->position);
160
node->rt.position = &driver->rt.activation->position;
161
162
163
{
164
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
165
struct pw_impl_node *old = node->driver_node;
166
+ int res;
167
+ bool was_driving;
168
169
if (driver == NULL)
170
driver = node;
171
172
old->name, old->info.id,
173
driver->name, driver->info.id);
174
}
175
+ was_driving = node->driving;
176
node->driving = node->driver && driver == node;
177
178
+ /* When a node was driver (and is waiting for all nodes to complete
179
+ * the Start command) cancel the pending state and let the new driver
180
+ * calculate a new state so that the Start command is sent to the
181
+ * node */
182
+ if (was_driving && !node->driving)
183
+ impl->pending_state = node->info.state;
184
+
185
pw_log_debug("%p: driver %p driving:%u", node,
186
driver, node->driving);
187
pw_log_info("(%s-%u) -> change driver (%s-%d -> %s-%d)",
188
189
node->driver_node = driver;
190
node->moved = true;
191
192
+ if ((res = spa_node_set_io(node->node,
193
+ SPA_IO_Position,
194
+ &driver->rt.activation->position,
195
+ sizeof(struct spa_io_position))) < 0) {
196
+ pw_log_debug("%p: set position: %s", node, spa_strerror(res));
197
+ }
198
+
199
pw_loop_invoke(node->data_loop,
200
do_move_nodes, SPA_ID_INVALID, &driver, sizeof(struct pw_impl_node *),
201
pipewire-0.3.61.tar.gz/src/pipewire/stream.c -> pipewire-0.3.62.tar.gz/src/pipewire/stream.c
Changed
67
1
2
{
3
uint32_t index;
4
5
- if (SPA_FLAG_IS_SET(buffer->flags, BUFFER_FLAG_QUEUED))
6
+ if (SPA_FLAG_IS_SET(buffer->flags, BUFFER_FLAG_QUEUED) ||
7
+ buffer->id >= stream->n_buffers)
8
return -EINVAL;
9
10
SPA_FLAG_SET(buffer->flags, BUFFER_FLAG_QUEUED);
11
12
if (impl->disconnecting && n_buffers > 0)
13
return -EIO;
14
15
+ if (n_buffers > MAX_BUFFERS)
16
+ return -EINVAL;
17
+
18
prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0);
19
20
clear_buffers(stream);
21
22
pw_log_debug("%p: got buffer id:%d datas:%d, mapped size %d", stream, i,
23
buffersi->n_datas, size);
24
}
25
+ impl->n_buffers = n_buffers;
26
27
for (i = 0; i < n_buffers; i++) {
28
struct buffer *b = &impl->buffersi;
29
30
31
pw_stream_emit_add_buffer(stream, &b->this);
32
}
33
-
34
- impl->n_buffers = n_buffers;
35
-
36
return 0;
37
}
38
39
40
if (io->status == SPA_STATUS_HAVE_DATA &&
41
(b = get_buffer(stream, io->buffer_id)) != NULL) {
42
/* push new buffer */
43
+ pw_log_trace_fp("%p: push %d %p", stream, b->id, io);
44
if (queue_push(impl, &impl->dequeued, b) == 0) {
45
copy_position(impl, impl->dequeued.incount);
46
if (b->busy)
47
48
call_process(impl);
49
}
50
}
51
- if (io->status != SPA_STATUS_NEED_DATA) {
52
+ if (io->status != SPA_STATUS_NEED_DATA || io->buffer_id == SPA_ID_INVALID) {
53
/* pop buffer to recycle */
54
if ((b = queue_pop(impl, &impl->queued))) {
55
pw_log_trace_fp("%p: recycle buffer %d", stream, b->id);
56
- } else if (io->status == -EPIPE)
57
- return io->status;
58
- io->buffer_id = b ? b->id : SPA_ID_INVALID;
59
+ io->buffer_id = b->id;
60
+ } else {
61
+ pw_log_trace_fp("%p: no buffers to recycle", stream);
62
+ io->buffer_id = SPA_ID_INVALID;
63
+ }
64
io->status = SPA_STATUS_NEED_DATA;
65
}
66
if (impl->driving && impl->using_trigger)
67
pipewire-0.3.61.tar.gz/src/tools/pw-top.c -> pipewire-0.3.62.tar.gz/src/tools/pw-top.c
Changed
27
1
2
{
3
struct data *data = _data;
4
5
- pw_log_error("error id:%u seq:%d res:%d (%s): %s",
6
- id, seq, res, spa_strerror(res), message);
7
-
8
- if (id == PW_ID_CORE && res == -EPIPE)
9
- pw_main_loop_quit(data->loop);
10
+ if (id == PW_ID_CORE) {
11
+ switch (res) {
12
+ case -EPIPE:
13
+ pw_main_loop_quit(data->loop);
14
+ break;
15
+ default:
16
+ pw_log_error("error id:%u seq:%d res:%d (%s): %s",
17
+ id, seq, res, spa_strerror(res), message);
18
+ break;
19
+ }
20
+ } else {
21
+ pw_log_info("error id:%u seq:%d res:%d (%s): %s",
22
+ id, seq, res, spa_strerror(res), message);
23
+ }
24
}
25
26
static void on_core_done(void *_data, uint32_t id, int seq)
27
pipewire-0.3.61.tar.gz/test/test-spa-buffer.c -> pipewire-0.3.62.tar.gz/test/test-spa-buffer.c
Changed
27
1
2
pwtest_int_eq(SPA_META_Cursor, 5);
3
pwtest_int_eq(SPA_META_Control, 6);
4
pwtest_int_eq(SPA_META_Busy, 7);
5
- pwtest_int_eq(_SPA_META_LAST, 8);
6
+ pwtest_int_eq(SPA_META_VideoTransform, 8);
7
+ pwtest_int_eq(_SPA_META_LAST, 9);
8
9
return PWTEST_PASS;
10
}
11
12
pwtest_int_eq(sizeof(struct spa_meta_region), 16U);
13
pwtest_int_eq(sizeof(struct spa_meta_bitmap), 20U);
14
pwtest_int_eq(sizeof(struct spa_meta_cursor), 28U);
15
+ pwtest_int_eq(sizeof(struct spa_meta_videotransform), 4U);
16
17
return PWTEST_PASS;
18
#else
19
20
fprintf(stderr, "%zd\n", sizeof(struct spa_meta_region));
21
fprintf(stderr, "%zd\n", sizeof(struct spa_meta_bitmap));
22
fprintf(stderr, "%zd\n", sizeof(struct spa_meta_cursor));
23
+ fprintf(stderr, "%zd\n", sizeof(struct spa_meta_videotransform));
24
return PWTEST_SKIP;
25
#endif
26
}
27