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 48
pipewire-aptx.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Wed Nov 27 09:05:48 UTC 2024 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 1.2.7
6
+
7
+-------------------------------------------------------------------
8
Thu Nov 7 09:26:42 UTC 2024 - Bjørn Lie <zaitor@opensuse.org>
9
10
- Update to version 1.2.6
11
pipewire-aptx.spec
Changed
10
1
2
%define minimum_version 1.2.0
3
4
Name: pipewire-aptx
5
-Version: 1.2.6
6
+Version: 1.2.7
7
Release: 0
8
Summary: PipeWire Bluetooth aptX codec plugin
9
License: MIT
10
_service
Changed
10
1
2
<service name="download_url">
3
<param name="host">gitlab.freedesktop.org</param>
4
<param name="protocol">https</param>
5
- <param name="path">/pipewire/pipewire/-/archive/1.2.6/pipewire-1.2.6.tar.bz2</param>
6
+ <param name="path">/pipewire/pipewire/-/archive/1.2.7/pipewire-1.2.7.tar.bz2</param>
7
</service>
8
</services>
9
\ No newline at end of file
10
_service:download_url:pipewire-1.2.6.tar.bz2/NEWS -> _service:download_url:pipewire-1.2.7.tar.bz2/NEWS
Changed
68
1
2
+# PipeWire 1.2.7 (2024-11-26)
3
+
4
+This is a bugfix release that is API and ABI compatible with the previous
5
+1.2.x and 1.0.x releases.
6
+
7
+## Highlights
8
+ - Backport support for lazy scheduling.
9
+ - Handle the case where processing would stop when an ALSA driver is
10
+ destroyed.
11
+ - Add support for v4l2loopback in the v4l2 plugin.
12
+ - Small bug fixes and improvements.
13
+
14
+## PipeWire
15
+ - Invalidate the proxy ID when removed.
16
+ - Backport support for lazy scheduling.
17
+ - Fix profiler stats for async nodes.
18
+ - Fix EARLY_PROCESS again in pw-stream. (#3480)
19
+
20
+## Modules
21
+ - Fix a crasher issue when nodes are created in the wrong order in
22
+ module-filter-chain.
23
+ - Fix unmap bug in lv2 uri tables.
24
+ - Add ratelimit to jack-tunnel xruns.
25
+ - Remove hardcoded limit in filter-chain sofa plugin.
26
+ - Handle the MTU size correctly in module-rtp and handle large MTUs.
27
+ (#4396)
28
+ - Fix JSON float parsing errors in equalizer module. (#4418)
29
+
30
+## SPA
31
+ - Fix crash in audiotestsrc when using spa-inspect (#4365).
32
+ - Improve JSON float infinity checks.
33
+ - Improve resampler performace a little.
34
+ - Make audioconvert only output when there is something to output.
35
+ - Fix regression in v4l2 port flags which would disable support for
36
+ EXPBUF.
37
+ - Handle the case where an ALSA driver is destroyed and the follower
38
+ becomes a driver. Processing would stop. (#4401)
39
+ - Add support for v4l2loopback in the v4l2 plugin.
40
+
41
+## Pulse-server
42
+ - Give a better error message when running out of fds.
43
+ - Ensure positive latency reporting.
44
+
45
+## GStreamer
46
+ - Fix memory leak in deviceprovider.
47
+ - Fix locking when emitting an error.
48
+
49
+## Tools
50
+ - Fix pw-dot link labels.
51
+
52
+Older versions:
53
+
54
+
55
# PipeWire 1.2.6 (2024-10-23)
56
57
This is a bugfix release that is API and ABI compatible with the previous
58
59
## Docs
60
- Backport docs from master.
61
62
-Older versions:
63
-
64
-
65
# PipeWire 1.2.5 (2024-09-27)
66
67
This is an important bugfix release that is API and ABI compatible with the
68
_service:download_url:pipewire-1.2.6.tar.bz2/doc/dox/api/spa-pod.dox -> _service:download_url:pipewire-1.2.7.tar.bz2/doc/dox/api/spa-pod.dox
Changed
78
1
2
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
3
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
4
// audio/raw properties
5
- SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(
6
+ SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(4, // 4 values follow
7
SPA_AUDIO_FORMAT_S16, // default
8
SPA_AUDIO_FORMAT_S16, // alternative1
9
SPA_AUDIO_FORMAT_S32, // alternative2
10
- SPA_AUDIO_FORMAT_f32 // alternative3
11
+ SPA_AUDIO_FORMAT_F32 // alternative3
12
),
13
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(
14
44100, // default
15
16
To parse properties in an object:
17
18
\code{.c}
19
-uint32_t type, subtype, format, rate, channels;
20
+uint32_t id, type, subtype, format, rate, channels;
21
spa_pod_parser_get_object(&p,
22
- SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
23
+ SPA_TYPE_OBJECT_Format, &id,
24
SPA_FORMAT_mediaType, SPA_POD_Id(&type),
25
SPA_FORMAT_mediaSubtype, SPA_POD_Id(&subtype),
26
SPA_FORMAT_AUDIO_format, SPA_POD_Id(&format),
27
28
and when they are not present, the variables will not be changed.
29
30
\code{.c}
31
-uint32_t type, subtype, format, rate = 0, channels = 0;
32
+uint32_t id, type, subtype, format, rate = 0, channels = 0;
33
spa_pod_parser_get_object(&p,
34
- SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
35
+ SPA_TYPE_OBJECT_Format, &id,
36
SPA_FORMAT_mediaType, SPA_POD_Id(&type),
37
SPA_FORMAT_mediaSubtype, SPA_POD_Id(&subtype),
38
SPA_FORMAT_AUDIO_format, SPA_POD_Id(&format),
39
40
Here is an example of parsing the format values as a POD:
41
42
\code{.c}
43
-uint32_t type, subtype;
44
+uint32_t id, type, subtype;
45
struct spa_pod *format;
46
spa_pod_parser_get_object(&p,
47
- SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
48
+ SPA_TYPE_OBJECT_Format, &id,
49
SPA_FORMAT_mediaType, SPA_POD_Id(&type),
50
SPA_FORMAT_mediaSubtype, SPA_POD_Id(&subtype),
51
SPA_FORMAT_AUDIO_format, SPA_POD_Pod(&format));
52
53
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
54
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
55
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
56
- SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(
57
+ SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(4, // 4 values follow
58
SPA_AUDIO_FORMAT_S16, // default
59
SPA_AUDIO_FORMAT_S16, // alternative1
60
SPA_AUDIO_FORMAT_S32, // alternative2
61
- SPA_AUDIO_FORMAT_f32 // alternative3
62
+ SPA_AUDIO_FORMAT_F32 // alternative3
63
));
64
65
filter = spa_pod_builder_add_object(&b,
66
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
67
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
68
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
69
- SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(
70
+ SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(3, // 3 values follow
71
SPA_AUDIO_FORMAT_S16, // default
72
SPA_AUDIO_FORMAT_S16, // alternative1
73
- SPA_AUDIO_FORMAT_f64 // alternative2
74
+ SPA_AUDIO_FORMAT_F64 // alternative2
75
));
76
77
struct spa_pod *result;
78
_service:download_url:pipewire-1.2.6.tar.bz2/doc/dox/internals/scheduling.dox -> _service:download_url:pipewire-1.2.7.tar.bz2/doc/dox/internals/scheduling.dox
Changed
145
1
2
extra eventfd to signal the server that the graph completed. This is used by the
3
server to generate the profiler info.
4
5
+## Lazy scheduling
6
+
7
+Normally, a driver will wake up the graph and all the followers need to process
8
+the data in sync. There are cases where:
9
+
10
+ 1. the follower might not be ready to process the data
11
+ 2. the driver rate is not ideal, the follower rate is better
12
+ 3. the driver might not know when new data is available in the follower and
13
+ might wake up the graph too often.
14
+
15
+In these cases, the driver and follower roles need to be reversed and a mechanism
16
+needs to be provided so that the follower can know when it is worth processing the
17
+graph.
18
+
19
+For notifying when the graph is ready to be processed, (non driver) nodes can send
20
+a RequestProcess event which will arrive as a RequestProcess command in the driver.
21
+The driver can then decide to run the graph or not.
22
+
23
+When the graph is started or partially controlled by RequestProcess events and
24
+commands we say we have lazy scheduling. The driver is not always scheduling according
25
+to its own rhythm but also depending on the follower.
26
+
27
+We can't just enable lazy scheduling when no follower will emit RequestProcess events
28
+or when no driver will listen for RequestProcess commands. Two new node properties are
29
+defined:
30
+
31
+ - node.supports-lazy = 0 | 1 | ...
32
+
33
+ 0 means lazy scheduling as a driver is not supported
34
+ >1 means lazy scheduling as a driver is supported with increasing preference
35
+
36
+ - node.supports-request
37
+
38
+ 0 means request events as a follower are not supported
39
+ >1 means request events as a follower are supported with increasing preference
40
+
41
+ We can only enable lazy scheduling when both the driver and (at least one) follower
42
+ has the node.supports-lazy and node.supports-request property respectively.
43
+
44
+ Node can end up as a driver (is_driver()) and lazy scheduling can be enabled (is_lazy()),
45
+ which results in the following cases:
46
+
47
+ driver producer
48
+ -> node.driver = true
49
+ -> is_driving() && !is_lazy()
50
+ -> calls trigger_process() to start the graph
51
+
52
+ lazy producer
53
+ -> node.driver = true
54
+ -> node.supports-lazy = 1
55
+ -> is_driving() && is_lazy()
56
+ -> listens for RequestProcess and calls trigger_process() to start the graph
57
+
58
+ requesting producer
59
+ -> node.supports-request = 1
60
+ -> !is_driving() && is_lazy()
61
+ -> emits RequestProcess to suggest starting the graph
62
+
63
+ follower producer
64
+ -> !is_driving() && !is_lazy()
65
+
66
+
67
+ driver consumer
68
+ -> node.driver = true
69
+ -> is_driving() && !is_lazy()
70
+ -> calls trigger_process() to start the graph
71
+
72
+ lazy consumer
73
+ -> node.driver = true
74
+ -> node.supports-lazy = 1
75
+ -> is_driving() && is_lazy()
76
+ -> listens for RequestProcess and calls trigger_process() to start the graph
77
+
78
+ requesting consumer
79
+ -> node.supports-request = 1
80
+ -> !is_driving() && is_lazy()
81
+ -> emits RequestProcess to suggest starting the graph
82
+
83
+ follower consumer
84
+ -> !is_driving() && !is_lazy()
85
+
86
+
87
+Some use cases:
88
+
89
+ 1. Screensharing - driver producer, follower consumer
90
+ - The producer starts the graph when a new frame is available.
91
+ - The consumer consumes the new frames.
92
+ -> throttles to the rate of the producer and idles when no frames
93
+ are available.
94
+
95
+ producer
96
+ - node.driver = true
97
+
98
+ consumer
99
+ - node.driver = false
100
+
101
+ -> producer selected as driver, consumer is simple follower.
102
+ lazy scheduling inactive (no lazy driver or no request follower)
103
+
104
+
105
+ 2. headless server - requesting producer, (semi) lazy driver consumer
106
+
107
+ - The producer emits RequestProcess when new frames are available.
108
+ - The consumer requests new frames from the producer according to its
109
+ refresh rate when there are RequestProcess commands.
110
+ -> this throttles the framerate to the consumer but idles when there is
111
+ no activity on the producer.
112
+
113
+ producer
114
+ - node.driver = true
115
+ - node.supports-request = 1
116
+
117
+ consumer
118
+ - node.driver = true
119
+ - node.supports-lazy = 2
120
+
121
+ -> consumer is selected as driver (lazy > request)
122
+ lazy scheduling active (1 lazy driver and at least 1 request follower)
123
+
124
+
125
+ 3. frame encoder - lazy driver producer, requesting follower consumer
126
+
127
+ - The consumer pulls a frame when it is ready to encode the next one.
128
+ - The producer produces the next frame on demand.
129
+ -> throttles the speed to the consumer without idle.
130
+
131
+ producer
132
+ - node.driver = true
133
+ - node.supports-lazy = 1
134
+
135
+ consumer
136
+ - node.driver = true
137
+ - node.supports-request = 1
138
+
139
+ -> producer is selected as driver (lazy <= request)
140
+ lazy scheduling active (1 lazy driver and at least 1 request follower)
141
+
142
+
143
+
144
*/
145
_service:download_url:pipewire-1.2.6.tar.bz2/meson.build -> _service:download_url:pipewire-1.2.7.tar.bz2/meson.build
Changed
8
1
2
project('pipewire', 'c' ,
3
- version : '1.2.6',
4
+ version : '1.2.7',
5
license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ,
6
meson_version : '>= 0.61.1',
7
default_options : 'warning_level=3',
8
_service:download_url:pipewire-1.2.6.tar.bz2/pipewire-alsa/alsa-plugins/ctl_pipewire.c -> _service:download_url:pipewire-1.2.7.tar.bz2/pipewire-alsa/alsa-plugins/ctl_pipewire.c
Changed
10
1
2
param = spa_pod_builder_pop(&b, &f0);
3
4
pw_log_debug("set device %d mute/volume for node %d", dg->id, g->id);
5
- pw_device_set_param((struct pw_node*)dg->proxy,
6
+ pw_device_set_param((struct pw_device*)dg->proxy,
7
SPA_PARAM_Route, 0, param);
8
} else {
9
if (!SPA_FLAG_IS_SET(g->permissions, PW_PERM_W | PW_PERM_X))
10
_service:download_url:pipewire-1.2.6.tar.bz2/pipewire-jack/src/pipewire-jack.c -> _service:download_url:pipewire-1.2.7.tar.bz2/pipewire-jack/src/pipewire-jack.c
Changed
10
1
2
pw_proxy_add_listener(proxy,
3
&c->metadata->proxy_listener,
4
&metadata_proxy_events, c);
5
- pw_metadata_add_listener(proxy,
6
+ pw_metadata_add_listener(c->metadata->proxy,
7
&c->metadata->listener,
8
&metadata_events, c);
9
do_sync = true;
10
_service:download_url:pipewire-1.2.6.tar.bz2/pipewire-v4l2/src/pipewire-v4l2.c -> _service:download_url:pipewire-1.2.7.tar.bz2/pipewire-v4l2/src/pipewire-v4l2.c
Changed
10
1
2
}
3
4
param = spa_pod_builder_pop(&b, &f0);
5
- pw_node_set_param(file->node->proxy, SPA_PARAM_Props, 0, param);
6
+ pw_node_set_param((struct pw_node*)file->node->proxy, SPA_PARAM_Props, 0, param);
7
8
found = true;
9
pw_log_info("ctrl 0x%08" PRIx32 " set ok", arg->id);
10
_service:download_url:pipewire-1.2.6.tar.bz2/spa/include/spa/node/io.h -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/include/spa/node/io.h
Changed
9
1
2
struct spa_io_clock {
3
#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /* graph is freewheeling */
4
#define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /* recovering from xrun */
5
+#define SPA_IO_CLOCK_FLAG_LAZY (1u<<2) /* lazy scheduling */
6
uint32_t flags; /**< Clock flags */
7
uint32_t id; /**< Unique clock id, set by host application */
8
char name64; /**< Clock name prefixed with API, set by node when it receives
9
_service:download_url:pipewire-1.2.6.tar.bz2/spa/include/spa/utils/json.h -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/include/spa/utils/json.h
Changed
14
1
2
static inline char *spa_json_format_float(char *str, int size, float val)
3
{
4
if (SPA_UNLIKELY(!isnormal(val))) {
5
- if (val == INFINITY)
6
- val = FLT_MAX;
7
- else if (val == -INFINITY)
8
- val = FLT_MIN;
9
+ if (isinf(val))
10
+ val = signbit(val) ? FLT_MIN : FLT_MAX;
11
else
12
val = 0.0f;
13
}
14
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/alsa/alsa-pcm-sink.c -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/alsa/alsa-pcm-sink.c
Changed
15
1
2
if (this->n_buffers == 0)
3
return -EIO;
4
5
+ this->want_started = true;
6
if ((res = spa_alsa_start(this)) < 0)
7
return res;
8
break;
9
case SPA_NODE_COMMAND_Suspend:
10
case SPA_NODE_COMMAND_Pause:
11
+ this->want_started = false;
12
if ((res = spa_alsa_pause(this)) < 0)
13
return res;
14
break;
15
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/alsa/alsa-pcm-source.c -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/alsa/alsa-pcm-source.c
Changed
15
1
2
if (this->n_buffers == 0)
3
return -EIO;
4
5
+ this->want_started = true;
6
if ((res = spa_alsa_start(this)) < 0)
7
return res;
8
break;
9
case SPA_NODE_COMMAND_Pause:
10
case SPA_NODE_COMMAND_Suspend:
11
+ this->want_started = false;
12
if ((res = spa_alsa_pause(this)) < 0)
13
return res;
14
break;
15
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
73
1
2
char card_name256;
3
4
snprintf(card_name, sizeof(card_name), "hw:%d", state->card_index);
5
+ spa_log_debug(state->log, "Trying to open ctl device '%s'", card_name);
6
7
err = snd_ctl_open(&state->ctl, card_name, SND_CTL_NONBLOCK);
8
if (err < 0) {
9
10
state->multi_rate = true;
11
state->htimestamp = false;
12
state->htimestamp_max_errors = MAX_HTIMESTAMP_ERROR;
13
+ state->card_index = SPA_ID_INVALID;
14
+
15
for (i = 0; info && i < info->n_items; i++) {
16
const char *k = info->itemsi.key;
17
const char *s = info->itemsi.value;
18
19
alsa_set_param(state, k, s);
20
}
21
}
22
+
23
+ if (state->card_index == SPA_ID_INVALID) {
24
+ /* If we don't have a card index, see if we have a *:<idx> string */
25
+ sscanf(state->props.device, "%*^::%u", &state->card_index);
26
+ if (state->card_index == SPA_ID_INVALID) {
27
+ spa_log_error(state->log, "Could not determine card index, maybe set %s",
28
+ SPA_KEY_API_ALSA_CARD);
29
+ return -EINVAL;
30
+ }
31
+ }
32
+
33
if (state->clock_name0 == '\0')
34
snprintf(state->clock_name, sizeof(state->clock_name),
35
"api.alsa.%s-%u",
36
37
reset_buffers(state);
38
state->alsa_sync = true;
39
state->alsa_sync_warning = false;
40
- state->alsa_recovering = false;
41
state->alsa_started = false;
42
43
return 0;
44
45
}
46
avail = state->threshold * 2;
47
}
48
- } else {
49
- state->alsa_recovering = false;
50
}
51
*delay = avail;
52
53
54
rt->driver = state->driver;
55
spa_log_debug(state->log, "state:%p -> driver:%p", state, state->driver);
56
57
- if(state->linked && state->matching) {
58
+ if(state->linked && state->matching)
59
try_unlink(state);
60
- }
61
}
62
if (state->following) {
63
remove_sources(state);
64
65
setup_matching(state);
66
if (state->started)
67
spa_loop_invoke(state->data_loop, do_state_sync, 0, NULL, 0, true, state);
68
+ else if (state->want_started)
69
+ spa_alsa_start(state);
70
71
freewheel = pos != NULL && SPA_FLAG_IS_SET(pos->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL);
72
if (state->freewheel != freewheel) {
73
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/alsa/alsa-pcm.h -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/alsa/alsa-pcm.h
Changed
17
1
2
unsigned int opened:1;
3
unsigned int prepared:1;
4
unsigned int started:1;
5
+ unsigned int want_started:1;
6
snd_pcm_t *hndl;
7
8
bool have_format;
9
10
unsigned int alsa_started:1;
11
unsigned int alsa_sync:1;
12
unsigned int alsa_sync_warning:1;
13
- unsigned int alsa_recovering:1;
14
unsigned int following:1;
15
unsigned int matching:1;
16
unsigned int resample:1;
17
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/audioconvert/audioconvert.c -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/audioconvert/audioconvert.c
Changed
10
1
2
}
3
4
dir = &this->dirSPA_DIRECTION_OUTPUT;
5
- if (SPA_LIKELY(n_samples > 0 && (this->out_offset >= max_out || flush_out))) {
6
+ if (SPA_LIKELY(this->out_offset > 0 && (this->out_offset >= max_out || flush_out))) {
7
/* queue output buffers */
8
for (i = 0; i < dir->n_ports; i++) {
9
port = GET_OUT_PORT(this, i);
10
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/audioconvert/resample-native-impl.h -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/audioconvert/resample-native-impl.h
Changed
117
1
2
{ \
3
struct native_data *data = r->data; \
4
uint32_t index, n_taps = data->n_taps, n_taps2 = n_taps/2; \
5
- uint32_t c, olen = *out_len, ilen = *in_len; \
6
- \
7
- if (r->channels == 0) \
8
- return; \
9
+ uint32_t c, olen = *out_len, ilen = *in_len, ch = r->channels; \
10
\
11
index = ioffs; \
12
if (ooffs < olen && index + n_taps <= ilen) { \
13
uint32_t to_copy = SPA_MIN(olen - ooffs, \
14
ilen - (index + n_taps) + 1); \
15
- for (c = 0; c < r->channels; c++) { \
16
+ for (c = 0; c < ch; c++) { \
17
const float *s = srcc; \
18
float *d = dstc; \
19
spa_memcpy(&dooffs, &sindex + n_taps2, \
20
21
*out_len = ooffs; \
22
}
23
24
-#define INC(index,phase,n_phases) \
25
- index += inc; \
26
- phase += frac; \
27
- if (phase >= n_phases) { \
28
- phase -= n_phases; \
29
- index += 1; \
30
+#define INC(index,phase,n_phases) \
31
+ index += inc; \
32
+ phase += frac; \
33
+ if (phase >= n_phases) { \
34
+ phase -= n_phases; \
35
+ index += 1; \
36
}
37
38
#define MAKE_RESAMPLER_FULL(arch) \
39
40
uint32_t n_taps = data->n_taps, stride = data->filter_stride_os; \
41
uint32_t index, phase, n_phases = data->out_rate; \
42
uint32_t c, o, olen = *out_len, ilen = *in_len; \
43
- uint32_t inc = data->inc, frac = data->frac; \
44
- \
45
- if (r->channels == 0) \
46
- return; \
47
- \
48
- for (c = 0; c < r->channels; c++) { \
49
- const float *s = srcc; \
50
- float *d = dstc; \
51
- \
52
- index = ioffs; \
53
- phase = (uint32_t)data->phase; \
54
+ uint32_t inc = data->inc, frac = data->frac, ch = r->channels; \
55
\
56
- for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
57
+ index = ioffs; \
58
+ phase = (uint32_t)data->phase; \
59
+ for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
60
+ float *filter = &data->filterphase * stride; \
61
+ for (c = 0; c < ch; c++) { \
62
+ const float *s = srcc; \
63
+ float *d = dstc; \
64
inner_product_##arch(&do, &sindex, \
65
- &data->filterphase * stride, \
66
- n_taps); \
67
- INC(index, phase, n_phases); \
68
+ filter, n_taps); \
69
} \
70
+ INC(index, phase, n_phases); \
71
} \
72
*in_len = index; \
73
*out_len = o; \
74
75
uint32_t n_phases = data->n_phases, out_rate = data->out_rate; \
76
uint32_t n_taps = data->n_taps; \
77
uint32_t c, o, olen = *out_len, ilen = *in_len; \
78
- uint32_t inc = data->inc, frac = data->frac; \
79
+ uint32_t inc = data->inc, frac = data->frac, ch = r->channels; \
80
float phase; \
81
\
82
- if (r->channels == 0) \
83
- return; \
84
- \
85
- for (c = 0; c < r->channels; c++) { \
86
- const float *s = srcc; \
87
- float *d = dstc; \
88
- \
89
- index = ioffs; \
90
- phase = data->phase; \
91
- \
92
- for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
93
- float ph = phase * n_phases / out_rate; \
94
- uint32_t offset = (uint32_t)floorf(ph); \
95
+ index = ioffs; \
96
+ phase = data->phase; \
97
+ for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
98
+ float ph = phase * n_phases / out_rate; \
99
+ uint32_t offset = (uint32_t)floorf(ph); \
100
+ float *filter0 = &data->filter(offset+0) * stride; \
101
+ float *filter1 = &data->filter(offset+1) * stride; \
102
+ float pho = ph - offset; \
103
+ for (c = 0; c < ch; c++) { \
104
+ const float *s = srcc; \
105
+ float *d = dstc; \
106
inner_product_ip_##arch(&do, &sindex, \
107
- &data->filter(offset + 0) * stride, \
108
- &data->filter(offset + 1) * stride, \
109
- ph - offset, n_taps); \
110
- INC(index, phase, out_rate); \
111
+ filter0, filter1, pho, n_taps); \
112
} \
113
+ INC(index, phase, out_rate); \
114
} \
115
*in_len = index; \
116
*out_len = o; \
117
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/audiotestsrc/audiotestsrc.c -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/audiotestsrc/audiotestsrc.c
Changed
20
1
2
this = (struct impl *) handle;
3
4
this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
5
+
6
this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
7
+ if (this->data_loop == NULL) {
8
+ spa_log_error(this->log, "%p: could not find a data loop", this);
9
+ return -EINVAL;
10
+ }
11
+
12
this->data_system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataSystem);
13
+ if (this->data_system == NULL) {
14
+ spa_log_error(this->log, "%p: could not find a data system", this);
15
+ return -EINVAL;
16
+ }
17
18
for (i = 0; info && i < info->n_items; i++) {
19
const char *k = info->itemsi.key;
20
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/v4l2/v4l2-source.c -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/v4l2/v4l2-source.c
Changed
33
1
2
struct spa_meta_videotransform *vt;
3
struct v4l2_buffer v4l2_buffer;
4
void *ptr;
5
+ void *mmap_ptr;
6
};
7
8
#define MAX_CONTROLS 64
9
10
bool alloc_buffers;
11
bool probed_expbuf;
12
bool have_expbuf;
13
+ bool first_buffer;
14
+ uint32_t max_buffers;
15
16
bool next_fmtdesc;
17
struct v4l2_fmtdesc fmtdesc;
18
19
return -EIO;
20
if (result.index > 0)
21
return 0;
22
+ if (port->max_buffers == 0)
23
+ return -EIO;
24
25
param = spa_pod_builder_add_object(&b.b,
26
SPA_TYPE_OBJECT_ParamBuffers, id,
27
- SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(4, 1, MAX_BUFFERS),
28
+ SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(SPA_MIN(4u, port->max_buffers),
29
+ 1, port->max_buffers),
30
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
31
SPA_PARAM_BUFFERS_size, SPA_POD_Int(port->fmt.fmt.pix.sizeimage),
32
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(port->fmt.fmt.pix.bytesperline));
33
_service:download_url:pipewire-1.2.6.tar.bz2/spa/plugins/v4l2/v4l2-utils.c -> _service:download_url:pipewire-1.2.7.tar.bz2/spa/plugins/v4l2/v4l2-utils.c
Changed
182
1
2
spa_log_error(this->log, "'%s' VIDIOC_QBUF: %m", this->props.device);
3
return -err;
4
}
5
-
6
return 0;
7
}
8
9
10
if (SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_MAPPED)) {
11
munmap(b->ptr, d0.maxsize);
12
}
13
+ if (b->mmap_ptr)
14
+ munmap(b->mmap_ptr, b->v4l2_buffer.length);
15
if (SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_ALLOCATED)) {
16
spa_log_debug(this->log, "close %d", (int) d0.fd);
17
close(d0.fd);
18
19
spa_zero(reqbuf);
20
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
21
reqbuf.memory = V4L2_MEMORY_MMAP;
22
- reqbuf.count = 2;
23
+ reqbuf.count = port->max_buffers = MAX_BUFFERS;
24
25
if (xioctl(dev->fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
26
spa_log_error(this->log, "'%s' VIDIOC_REQBUFS: %m", this->props.device);
27
return -errno;
28
}
29
+ port->max_buffers = reqbuf.count;
30
31
spa_zero(expbuf);
32
expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
33
34
size->width = fmt.fmt.pix.width;
35
size->height = fmt.fmt.pix.height;
36
37
+ probe_expbuf(this);
38
+
39
port->fmt = fmt;
40
port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_RATE;
41
port->info.flags = (port->alloc_buffers ? SPA_PORT_FLAG_CAN_ALLOC_BUFFERS : 0) |
42
43
port->info.rate.num = streamparm.parm.capture.timeperframe.numerator;
44
port->info.rate.denom = streamparm.parm.capture.timeperframe.denominator;
45
46
- probe_expbuf(this);
47
-
48
return match ? 0 : 1;
49
}
50
51
52
if (xioctl(dev->fd, VIDIOC_DQBUF, &buf) < 0)
53
return -errno;
54
55
+ spa_log_trace(this->log, "v4l2 %p: have output %d/%d", this, buf.index, buf.sequence);
56
+
57
/* Drop the first frame in order to work around common firmware
58
* timestamp issues */
59
- if (buf.sequence == 0) {
60
- xioctl(dev->fd, VIDIOC_QBUF, &buf);
61
+ if (port->first_buffer) {
62
+ port->first_buffer = false;
63
+ if (xioctl(dev->fd, VIDIOC_QBUF, &buf) < 0)
64
+ spa_log_warn(this->log, "v4l2 %p: error qbuf: %m", this);
65
return 0;
66
}
67
68
pts = SPA_TIMEVAL_TO_NSEC(&buf.timestamp);
69
- spa_log_trace(this->log, "v4l2 %p: have output %d", this, buf.index);
70
71
if (this->clock) {
72
/* FIXME, we should follow the driver clock and target_ values.
73
74
75
d = b->outbuf->datas;
76
d0.chunk->offset = 0;
77
- d0.chunk->size = buf.bytesused;
78
+ d0.chunk->size = SPA_MIN(buf.bytesused, d0.maxsize);
79
d0.chunk->stride = port->fmt.fmt.pix.bytesperline;
80
d0.chunk->flags = 0;
81
if (buf.flags & V4L2_BUF_FLAG_ERROR)
82
d0.chunk->flags |= SPA_CHUNK_FLAG_CORRUPTED;
83
84
+ if (b->mmap_ptr && b->ptr)
85
+ memcpy(b->ptr, b->mmap_ptr, d0.chunk->size);
86
+
87
spa_list_append(&port->queue, &b->link);
88
return 0;
89
}
90
91
struct spa_io_buffers *io;
92
struct port *port = &this->out_ports0;
93
struct buffer *b;
94
+ int res;
95
96
if (source->rmask & SPA_IO_ERR) {
97
struct port *port = &this->out_ports0;
98
99
return;
100
}
101
102
- if (mmap_read(this) < 0)
103
+ if ((res = mmap_read(this)) < 0) {
104
+ spa_log_warn(this->log, "v4l2 %p: mmap read error:%s", this, spa_strerror(res));
105
return;
106
+ }
107
108
if (spa_list_is_empty(&port->queue))
109
return;
110
111
reqbuf.count = n_buffers;
112
113
if (xioctl(dev->fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
114
- spa_log_error(this->log, "'%s' VIDIOC_REQBUFS %m", this->props.device);
115
- return -errno;
116
+ if (port->memtype != V4L2_MEMORY_USERPTR) {
117
+ spa_log_error(this->log, "'%s' VIDIOC_REQBUFS %m", this->props.device);
118
+ return -errno;
119
+ }
120
+ /* some drivers (v4l2loopback) don't support USERPTR
121
+ * and so we need to try again with MMAP and memcpy */
122
+ port->memtype = V4L2_MEMORY_MMAP;
123
+ spa_zero(reqbuf);
124
+ reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
125
+ reqbuf.memory = port->memtype;
126
+ reqbuf.count = n_buffers;
127
+
128
+ if (xioctl(dev->fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
129
+ spa_log_error(this->log, "'%s' VIDIOC_REQBUFS %m", this->props.device);
130
+ return -errno;
131
+ }
132
}
133
spa_log_debug(this->log, "got %d buffers", reqbuf.count);
134
if (reqbuf.count < n_buffers) {
135
136
b->v4l2_buffer.memory = port->memtype;
137
b->v4l2_buffer.index = i;
138
139
- if (port->memtype == V4L2_MEMORY_USERPTR) {
140
+ if (port->memtype == V4L2_MEMORY_USERPTR ||
141
+ port->memtype == V4L2_MEMORY_MMAP) {
142
if (d0.data == NULL) {
143
void *data;
144
145
146
else
147
b->ptr = d0.data;
148
149
- b->v4l2_buffer.m.userptr = (unsigned long) b->ptr;
150
- b->v4l2_buffer.length = d0.maxsize;
151
+ if (port->memtype == V4L2_MEMORY_USERPTR) {
152
+ b->v4l2_buffer.m.userptr = (unsigned long) b->ptr;
153
+ b->v4l2_buffer.length = d0.maxsize;
154
+ }
155
+ else {
156
+ if (xioctl(dev->fd, VIDIOC_QUERYBUF, &b->v4l2_buffer) < 0) {
157
+ spa_log_error(this->log, "'%s' VIDIOC_QUERYBUF: %m", this->props.device);
158
+ return -errno;
159
+ }
160
+ b->mmap_ptr = mmap(NULL,
161
+ b->v4l2_buffer.length,
162
+ PROT_READ, MAP_PRIVATE,
163
+ dev->fd, b->v4l2_buffer.m.offset);
164
+ if (b->mmap_ptr == MAP_FAILED) {
165
+ spa_log_error(this->log, "'%s' mmap: %m", this->props.device);
166
+ return -errno;
167
+ }
168
+ }
169
}
170
else if (port->memtype == V4L2_MEMORY_DMABUF) {
171
b->v4l2_buffer.m.fd = d0.fd;
172
173
174
spa_log_debug(this->log, "starting");
175
176
+ port->first_buffer = true;
177
+ mmap_read(this);
178
+
179
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
180
if (xioctl(dev->fd, VIDIOC_STREAMON, &type) < 0) {
181
spa_log_error(this->log, "'%s' VIDIOC_STREAMON: %m", this->props.device);
182
_service:download_url:pipewire-1.2.6.tar.bz2/src/examples/video-play-pull.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/examples/video-play-pull.c
Changed
44
1
2
enable_timeouts(data, false);
3
break;
4
case PW_STREAM_STATE_STREAMING:
5
- enable_timeouts(data, true);
6
+ printf("driving:%d lazy:%d\n",
7
+ pw_stream_is_driving(data->stream),
8
+ pw_stream_is_lazy(data->stream));
9
+ if (pw_stream_is_driving(data->stream) != pw_stream_is_lazy(data->stream))
10
+ enable_timeouts(data, true);
11
break;
12
default:
13
break;
14
15
static void on_timeout(void *userdata, uint64_t expirations)
16
{
17
struct data *data = userdata;
18
- if (!data->have_request_process)
19
- pw_stream_trigger_process(data->stream);
20
+ pw_stream_trigger_process(data->stream);
21
}
22
23
static void
24
25
struct data *data = _data;
26
switch (SPA_NODE_COMMAND_ID(command)) {
27
case SPA_NODE_COMMAND_RequestProcess:
28
- data->have_request_process = true;
29
- enable_timeouts(data, false);
30
+ pw_log_trace("%p trigger", data);
31
pw_stream_trigger_process(data->stream);
32
break;
33
default:
34
35
props = pw_properties_new(PW_KEY_MEDIA_TYPE, "Video",
36
PW_KEY_MEDIA_CATEGORY, "Capture",
37
PW_KEY_MEDIA_ROLE, "Camera",
38
- PW_KEY_PRIORITY_DRIVER, "10000",
39
+ PW_KEY_NODE_SUPPORTS_LAZY, "1",
40
+ PW_KEY_NODE_SUPPORTS_REQUEST, "1",
41
NULL),
42
data.path = argc > 1 ? argv1 : NULL;
43
if (data.path)
44
_service:download_url:pipewire-1.2.6.tar.bz2/src/examples/video-src.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/examples/video-src.c
Changed
25
1
2
interval.tv_sec = 0;
3
interval.tv_nsec = 40 * SPA_NSEC_PER_MSEC;
4
5
- pw_loop_update_timer(pw_main_loop_get_loop(data->loop),
6
- data->timer, &timeout, &interval, false);
7
+ printf("driving:%d lazy:%d\n",
8
+ pw_stream_is_driving(data->stream),
9
+ pw_stream_is_lazy(data->stream));
10
+
11
+ if (pw_stream_is_driving(data->stream) != pw_stream_is_lazy(data->stream))
12
+ pw_loop_update_timer(pw_main_loop_get_loop(data->loop),
13
+ data->timer, &timeout, &interval, false);
14
break;
15
}
16
default:
17
18
data.stream = pw_stream_new(data.core, "video-src",
19
pw_properties_new(
20
PW_KEY_MEDIA_CLASS, "Video/Source",
21
+ PW_KEY_NODE_SUPPORTS_REQUEST, "1",
22
NULL));
23
24
params0 = spa_pod_builder_add_object(&b,
25
_service:download_url:pipewire-1.2.6.tar.bz2/src/gst/gstpipewiredeviceprovider.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/gst/gstpipewiredeviceprovider.c
Changed
10
1
2
static void do_add_nodes(GstPipeWireDeviceProvider *self)
3
{
4
struct node_data *nd;
5
- GList *new_devices = NULL;
6
+ g_autoptr (GList) new_devices = NULL;
7
GList *l;
8
9
spa_list_for_each(nd, &self->nodes, link) {
10
_service:download_url:pipewire-1.2.6.tar.bz2/src/gst/gstpipewiresrc.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/gst/gstpipewiresrc.c
Changed
21
1
2
GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
3
("%s", error_string),
4
("This element did not produce valid caps"));
5
+ pw_thread_loop_lock (pwsrc->stream->core->loop);
6
pw_stream_set_error (pwsrc->stream->pwstream, -EINVAL, "%s", error_string);
7
+ pw_thread_loop_unlock (pwsrc->stream->core->loop);
8
return FALSE;
9
}
10
no_common_caps:
11
12
GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
13
("%s", error_string),
14
("This element does not have formats in common with the peer"));
15
+ pw_thread_loop_lock (pwsrc->stream->core->loop);
16
pw_stream_set_error (pwsrc->stream->pwstream, -EPIPE, "%s", error_string);
17
+ pw_thread_loop_unlock (pwsrc->stream->core->loop);
18
return FALSE;
19
}
20
connect_error:
21
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-filter-chain.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-filter-chain.c
Changed
126
1
2
#define DEFAULT_RATE 48000
3
4
struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
5
- struct dsp_ops *dsp, const char *path, const char *config);
6
+ struct dsp_ops *dsp, const char *path, const struct spa_dict *info);
7
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
8
- struct dsp_ops *dsp, const char *path, const char *config);
9
+ struct dsp_ops *dsp, const char *path, const struct spa_dict *info);
10
11
struct plugin {
12
struct spa_list link;
13
14
struct pw_context *context;
15
16
struct pw_impl_module *module;
17
+ struct pw_properties *props;
18
19
struct spa_hook module_listener;
20
21
22
pw_log_error("can't load plugin type '%s': %m", type);
23
pl = NULL;
24
} else {
25
- pl = plugin_func(support, n_support, &impl->dsp, path, NULL);
26
+ pl = plugin_func(support, n_support, &impl->dsp, path, &impl->props->dict);
27
}
28
if (pl == NULL)
29
goto exit;
30
31
struct link *link;
32
struct descriptor *desc;
33
const struct fc_descriptor *d;
34
+ const struct fc_plugin *p;
35
uint32_t i, j, max_samples = impl->quantum_limit;
36
int res;
37
float *sd, *dd;
38
39
40
graph->instantiated = true;
41
42
+ /* first make instances */
43
spa_list_for_each(node, &graph->node_list, link) {
44
-
45
node_cleanup(node);
46
47
desc = node->desc;
48
d = desc->desc;
49
- if (d->flags & FC_DESCRIPTOR_SUPPORTS_NULL_DATA) {
50
- sd = dd = NULL;
51
- }
52
- else {
53
- sd = impl->silence_data;
54
- dd = impl->discard_data;
55
- }
56
+ p = desc->plugin->plugin;
57
58
for (i = 0; i < node->n_hndl; i++) {
59
pw_log_info("instantiate %s %d rate:%lu", d->name, i, impl->rate);
60
errno = EINVAL;
61
- if ((node->hndli = d->instantiate(d, impl->rate, i, node->config)) == NULL) {
62
+ if ((node->hndli = d->instantiate(p, d, impl->rate, i, node->config)) == NULL) {
63
pw_log_error("cannot create plugin instance %d rate:%lu: %m", i, impl->rate);
64
res = -errno;
65
goto error;
66
}
67
+ }
68
+ }
69
+
70
+ /* then link ports and activate */
71
+ spa_list_for_each(node, &graph->node_list, link) {
72
+ desc = node->desc;
73
+ d = desc->desc;
74
+ if (d->flags & FC_DESCRIPTOR_SUPPORTS_NULL_DATA) {
75
+ sd = dd = NULL;
76
+ }
77
+ else {
78
+ sd = impl->silence_data;
79
+ dd = impl->discard_data;
80
+ }
81
+ for (i = 0; i < node->n_hndl; i++) {
82
for (j = 0; j < desc->n_input; j++) {
83
port = &node->input_portj;
84
d->connect_port(node->hndli, port->p, sd);
85
86
spa_list_consume(pl, &impl->plugin_func_list, link)
87
free_plugin_func(pl);
88
89
+ pw_properties_free(impl->props);
90
free(impl->silence_data);
91
free(impl->discard_data);
92
free(impl);
93
94
pw_log_error( "can't create properties: %m");
95
goto error;
96
}
97
+ impl->props = props;
98
99
impl->capture_props = pw_properties_new(NULL, NULL);
100
impl->playback_props = pw_properties_new(NULL, NULL);
101
102
pw_context_get_properties(impl->context),
103
"default.clock.quantum-limit", 8192u);
104
105
+ pw_properties_setf(props, "clock.quantum-limit", "%u", impl->quantum_limit);
106
+
107
impl->silence_data = calloc(impl->quantum_limit, sizeof(float));
108
if (impl->silence_data == NULL) {
109
res = -errno;
110
111
pw_log_error("can't connect: %m");
112
goto error;
113
}
114
- pw_properties_free(props);
115
116
pw_proxy_add_listener((struct pw_proxy*)impl->core,
117
&impl->core_proxy_listener,
118
119
return 0;
120
121
error:
122
- pw_properties_free(props);
123
impl_destroy(impl);
124
return res;
125
}
126
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-filter-chain/builtin_plugin.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-filter-chain/builtin_plugin.c
Changed
197
1
2
3
#define MAX_RATES 32u
4
5
-static struct dsp_ops *dsp_ops;
6
+struct plugin {
7
+ struct fc_plugin plugin;
8
+ struct dsp_ops *dsp_ops;
9
+};
10
11
struct builtin {
12
+ struct plugin *plugin;
13
unsigned long rate;
14
float *port64;
15
16
17
float accum;
18
};
19
20
-static void *builtin_instantiate(const struct fc_descriptor * Descriptor,
21
+static void *builtin_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
22
unsigned long SampleRate, int index, const char *config)
23
{
24
struct builtin *impl;
25
26
if (impl == NULL)
27
return NULL;
28
29
+ impl->plugin = (struct plugin *) plugin;
30
impl->rate = SampleRate;
31
32
return impl;
33
34
{
35
struct builtin *impl = Instance;
36
float *in = impl->port1, *out = impl->port0;
37
- dsp_ops_copy(dsp_ops, out, in, SampleCount);
38
+ dsp_ops_copy(impl->plugin->dsp_ops, out, in, SampleCount);
39
}
40
41
static struct fc_port copy_ports = {
42
43
srcn_src = in;
44
gainsn_src++ = gain;
45
}
46
- dsp_ops_mix_gain(dsp_ops, out, src, gains, n_src, SampleCount);
47
+ dsp_ops_mix_gain(impl->plugin->dsp_ops, out, src, gains, n_src, SampleCount);
48
}
49
50
static struct fc_port mixer_ports = {
51
52
*
53
* }
54
*/
55
-static void *bq_instantiate(const struct fc_descriptor * Descriptor,
56
+static void *bq_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
57
unsigned long SampleRate, int index, const char *config)
58
{
59
struct builtin *impl;
60
61
if (impl == NULL)
62
return NULL;
63
64
+ impl->plugin = (struct plugin *) plugin;
65
impl->rate = SampleRate;
66
impl->b0 = impl->a0 = 1.0f;
67
impl->type = bq_type_from_name(Descriptor->name);
68
69
if (impl->freq != freq || impl->Q != Q || impl->gain != gain)
70
bq_freq_update(impl, impl->type, freq, Q, gain);
71
}
72
- dsp_ops_biquad_run(dsp_ops, bq, out, in, samples);
73
+ dsp_ops_biquad_run(impl->plugin->dsp_ops, bq, out, in, samples);
74
}
75
76
/** bq_lowpass */
77
78
79
/** convolve */
80
struct convolver_impl {
81
+ struct plugin *plugin;
82
unsigned long rate;
83
float *port64;
84
85
86
return samples;
87
}
88
89
-static float *resample_buffer(float *samples, int *n_samples,
90
+static float *resample_buffer(struct dsp_ops *dsp_ops, float *samples, int *n_samples,
91
unsigned long in_rate, unsigned long out_rate, uint32_t quality)
92
{
93
#ifdef HAVE_SPA_PLUGINS
94
95
#endif
96
}
97
98
-static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
99
+static void * convolver_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
100
unsigned long SampleRate, int index, const char *config)
101
{
102
struct convolver_impl *impl;
103
104
rate = SampleRate;
105
samples = read_closest(filenames, gain, delay, offset,
106
length, channel, &rate, &n_samples);
107
- if (samples != NULL && rate != SampleRate)
108
- samples = resample_buffer(samples, &n_samples,
109
+ if (samples != NULL && rate != SampleRate) {
110
+ struct plugin *p = (struct plugin *) plugin;
111
+ samples = resample_buffer(p->dsp_ops, samples, &n_samples,
112
rate, SampleRate, resample_quality);
113
+ }
114
}
115
116
for (i = 0; i < MAX_RATES; i++)
117
118
if (impl == NULL)
119
goto error;
120
121
+ impl->plugin = (struct plugin *) plugin;
122
impl->rate = SampleRate;
123
124
- impl->conv = convolver_new(dsp_ops, blocksize, tailsize, samples, n_samples);
125
+ impl->conv = convolver_new(impl->plugin->dsp_ops, blocksize, tailsize, samples, n_samples);
126
if (impl->conv == NULL)
127
goto error;
128
129
130
131
/** delay */
132
struct delay_impl {
133
+ struct plugin *plugin;
134
unsigned long rate;
135
float *port4;
136
137
138
free(impl);
139
}
140
141
-static void *delay_instantiate(const struct fc_descriptor * Descriptor,
142
+static void *delay_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
143
unsigned long SampleRate, int index, const char *config)
144
{
145
struct delay_impl *impl;
146
147
if (impl == NULL)
148
return NULL;
149
150
+ impl->plugin = (struct plugin *) plugin;
151
impl->rate = SampleRate;
152
impl->buffer_samples = (uint32_t)(max_delay * impl->rate);
153
pw_log_info("max-delay:%f seconds rate:%lu samples:%d", max_delay, impl->rate, impl->buffer_samples);
154
155
float *ctrl = impl->port3, *notify = impl->port2;
156
157
if (in != NULL && out != NULL)
158
- dsp_ops_linear(dsp_ops, out, in, mult, add, SampleCount);
159
+ dsp_ops_linear(impl->plugin->dsp_ops, out, in, mult, add, SampleCount);
160
161
if (ctrl != NULL && notify != NULL)
162
notify0 = ctrl0 * mult + add;
163
164
165
srcn_src++ = in;
166
}
167
- dsp_ops_mult(dsp_ops, out, src, n_src, SampleCount);
168
+ dsp_ops_mult(impl->plugin->dsp_ops, out, src, n_src, SampleCount);
169
}
170
171
static struct fc_port mult_ports = {
172
173
return NULL;
174
}
175
176
-static struct fc_plugin builtin_plugin = {
177
- .make_desc = builtin_make_desc
178
-};
179
+static void builtin_plugin_unload(struct fc_plugin *p)
180
+{
181
+ free(p);
182
+}
183
184
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
185
- struct dsp_ops *dsp, const char *plugin, const char *config)
186
+ struct dsp_ops *dsp, const char *plugin, const struct spa_dict *info)
187
{
188
- dsp_ops = dsp;
189
+ struct plugin *impl = calloc (1, sizeof (struct plugin));
190
+ impl->plugin.make_desc = builtin_make_desc;
191
+ impl->plugin.unload = builtin_plugin_unload;
192
+ impl->dsp_ops = dsp;
193
pffft_select_cpu(dsp->cpu_flags);
194
- return &builtin_plugin;
195
+ return (struct fc_plugin *) impl;
196
}
197
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-filter-chain/convolver.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-filter-chain/convolver.c
Changed
201
1
2
3
#include <math.h>
4
5
-static struct dsp_ops *dsp;
6
-
7
struct convolver1 {
8
+ struct dsp_ops *dsp;
9
+
10
int blockSize;
11
int segSize;
12
int segCount;
13
14
free(*((void **)p - 1));
15
}
16
17
-static inline void fft_cpx_clear(float *v, int size)
18
+static inline void fft_cpx_clear(struct dsp_ops *dsp, float *v, int size)
19
{
20
dsp_ops_clear(dsp, v, size * 2);
21
}
22
23
{
24
int i;
25
for (i = 0; i < conv->segCount; i++)
26
- fft_cpx_clear(conv->segmentsi, conv->fftComplexSize);
27
- dsp_ops_clear(dsp, conv->overlap, conv->blockSize);
28
- dsp_ops_clear(dsp, conv->inputBuffer, conv->segSize);
29
- fft_cpx_clear(conv->pre_mult, conv->fftComplexSize);
30
- fft_cpx_clear(conv->conv, conv->fftComplexSize);
31
+ fft_cpx_clear(conv->dsp, conv->segmentsi, conv->fftComplexSize);
32
+ dsp_ops_clear(conv->dsp, conv->overlap, conv->blockSize);
33
+ dsp_ops_clear(conv->dsp, conv->inputBuffer, conv->segSize);
34
+ fft_cpx_clear(conv->dsp, conv->pre_mult, conv->fftComplexSize);
35
+ fft_cpx_clear(conv->dsp, conv->conv, conv->fftComplexSize);
36
conv->inputBufferFill = 0;
37
conv->current = 0;
38
}
39
40
-static struct convolver1 *convolver1_new(int block, const float *ir, int irlen)
41
+static struct convolver1 *convolver1_new(struct dsp_ops *dsp, int block, const float *ir, int irlen)
42
{
43
struct convolver1 *conv;
44
int i;
45
46
if (irlen == 0)
47
return conv;
48
49
+ conv->dsp = dsp;
50
conv->blockSize = next_power_of_two(block);
51
conv->segSize = 2 * conv->blockSize;
52
conv->segCount = (irlen + conv->blockSize-1) / conv->blockSize;
53
conv->fftComplexSize = (conv->segSize / 2) + 1;
54
55
- conv->fft = dsp_ops_fft_new(dsp, conv->segSize, true);
56
+ conv->fft = dsp_ops_fft_new(conv->dsp, conv->segSize, true);
57
if (conv->fft == NULL)
58
goto error;
59
- conv->ifft = dsp_ops_fft_new(dsp, conv->segSize, true);
60
+ conv->ifft = dsp_ops_fft_new(conv->dsp, conv->segSize, true);
61
if (conv->ifft == NULL)
62
goto error;
63
64
65
conv->segmentsi = fft_cpx_alloc(conv->fftComplexSize);
66
conv->segmentsIri = fft_cpx_alloc(conv->fftComplexSize);
67
68
- dsp_ops_copy(dsp, conv->fft_buffer, &iri * conv->blockSize, copy);
69
+ dsp_ops_copy(conv->dsp, conv->fft_buffer, &iri * conv->blockSize, copy);
70
if (copy < conv->segSize)
71
- dsp_ops_clear(dsp, conv->fft_buffer + copy, conv->segSize - copy);
72
+ dsp_ops_clear(conv->dsp, conv->fft_buffer + copy, conv->segSize - copy);
73
74
- dsp_ops_fft_run(dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIri);
75
+ dsp_ops_fft_run(conv->dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIri);
76
}
77
conv->pre_mult = fft_cpx_alloc(conv->fftComplexSize);
78
conv->conv = fft_cpx_alloc(conv->fftComplexSize);
79
80
fft_cpx_free(conv->segmentsIri);
81
}
82
if (conv->fft)
83
- dsp_ops_fft_free(dsp, conv->fft);
84
+ dsp_ops_fft_free(conv->dsp, conv->fft);
85
if (conv->ifft)
86
- dsp_ops_fft_free(dsp, conv->ifft);
87
+ dsp_ops_fft_free(conv->dsp, conv->ifft);
88
if (conv->fft_buffer)
89
fft_free(conv->fft_buffer);
90
free(conv->segments);
91
92
int i, processed = 0;
93
94
if (conv == NULL || conv->segCount == 0) {
95
- dsp_ops_clear(dsp, output, len);
96
+ dsp_ops_clear(conv->dsp, output, len);
97
return len;
98
}
99
100
101
const int processing = SPA_MIN(len - processed, conv->blockSize - conv->inputBufferFill);
102
const int inputBufferPos = conv->inputBufferFill;
103
104
- dsp_ops_copy(dsp, conv->inputBuffer + inputBufferPos, input + processed, processing);
105
+ dsp_ops_copy(conv->dsp, conv->inputBuffer + inputBufferPos, input + processed, processing);
106
if (inputBufferPos == 0 && processing < conv->blockSize)
107
- dsp_ops_clear(dsp, conv->inputBuffer + processing, conv->blockSize - processing);
108
+ dsp_ops_clear(conv->dsp, conv->inputBuffer + processing, conv->blockSize - processing);
109
110
- dsp_ops_fft_run(dsp, conv->fft, 1, conv->inputBuffer, conv->segmentsconv->current);
111
+ dsp_ops_fft_run(conv->dsp, conv->fft, 1, conv->inputBuffer, conv->segmentsconv->current);
112
113
if (conv->segCount > 1) {
114
if (conv->inputBufferFill == 0) {
115
int indexAudio = (conv->current + 1) % conv->segCount;
116
117
- dsp_ops_fft_cmul(dsp, conv->fft, conv->pre_mult,
118
+ dsp_ops_fft_cmul(conv->dsp, conv->fft, conv->pre_mult,
119
conv->segmentsIr1,
120
conv->segmentsindexAudio,
121
conv->fftComplexSize, conv->scale);
122
123
for (i = 2; i < conv->segCount; i++) {
124
indexAudio = (conv->current + i) % conv->segCount;
125
126
- dsp_ops_fft_cmuladd(dsp, conv->fft,
127
+ dsp_ops_fft_cmuladd(conv->dsp, conv->fft,
128
conv->pre_mult,
129
conv->pre_mult,
130
conv->segmentsIri,
131
132
conv->fftComplexSize, conv->scale);
133
}
134
}
135
- dsp_ops_fft_cmuladd(dsp, conv->fft,
136
+ dsp_ops_fft_cmuladd(conv->dsp, conv->fft,
137
conv->conv,
138
conv->pre_mult,
139
conv->segmentsconv->current,
140
conv->segmentsIr0,
141
conv->fftComplexSize, conv->scale);
142
} else {
143
- dsp_ops_fft_cmul(dsp, conv->fft,
144
+ dsp_ops_fft_cmul(conv->dsp, conv->fft,
145
conv->conv,
146
conv->segmentsconv->current,
147
conv->segmentsIr0,
148
conv->fftComplexSize, conv->scale);
149
}
150
151
- dsp_ops_fft_run(dsp, conv->ifft, -1, conv->conv, conv->fft_buffer);
152
+ dsp_ops_fft_run(conv->dsp, conv->ifft, -1, conv->conv, conv->fft_buffer);
153
154
- dsp_ops_sum(dsp, output + processed, conv->fft_buffer + inputBufferPos,
155
+ dsp_ops_sum(conv->dsp, output + processed, conv->fft_buffer + inputBufferPos,
156
conv->overlap + inputBufferPos, processing);
157
158
conv->inputBufferFill += processing;
159
if (conv->inputBufferFill == conv->blockSize) {
160
conv->inputBufferFill = 0;
161
162
- dsp_ops_copy(dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize);
163
+ dsp_ops_copy(conv->dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize);
164
165
conv->current = (conv->current > 0) ? (conv->current - 1) : (conv->segCount - 1);
166
}
167
168
169
struct convolver
170
{
171
+ struct dsp_ops *dsp;
172
int headBlockSize;
173
int tailBlockSize;
174
struct convolver1 *headConvolver;
175
176
convolver1_reset(conv->headConvolver);
177
if (conv->tailConvolver0) {
178
convolver1_reset(conv->tailConvolver0);
179
- dsp_ops_clear(dsp, conv->tailOutput0, conv->tailBlockSize);
180
- dsp_ops_clear(dsp, conv->tailPrecalculated0, conv->tailBlockSize);
181
+ dsp_ops_clear(conv->dsp, conv->tailOutput0, conv->tailBlockSize);
182
+ dsp_ops_clear(conv->dsp, conv->tailPrecalculated0, conv->tailBlockSize);
183
}
184
if (conv->tailConvolver) {
185
convolver1_reset(conv->tailConvolver);
186
- dsp_ops_clear(dsp, conv->tailOutput, conv->tailBlockSize);
187
- dsp_ops_clear(dsp, conv->tailPrecalculated, conv->tailBlockSize);
188
+ dsp_ops_clear(conv->dsp, conv->tailOutput, conv->tailBlockSize);
189
+ dsp_ops_clear(conv->dsp, conv->tailPrecalculated, conv->tailBlockSize);
190
}
191
conv->tailInputFill = 0;
192
conv->precalculatedPos = 0;
193
194
struct convolver *conv;
195
int head_ir_len;
196
197
- dsp = dsp_ops;
198
-
199
if (head_block == 0 || tail_block == 0)
200
return NULL;
201
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-filter-chain/ladspa_plugin.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-filter-chain/ladspa_plugin.c
Changed
19
1
2
const LADSPA_Descriptor *d;
3
};
4
5
-static void *ladspa_instantiate(const struct fc_descriptor *desc,
6
+static void *ladspa_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor *desc,
7
unsigned long SampleRate, int index, const char *config)
8
{
9
struct descriptor *d = (struct descriptor *)desc;
10
11
}
12
13
struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
14
- struct dsp_ops *dsp, const char *plugin, const char *config)
15
+ struct dsp_ops *dsp, const char *plugin, const struct spa_dict *info)
16
{
17
struct fc_plugin *pl = NULL;
18
19
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-filter-chain/lv2_plugin.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-filter-chain/lv2_plugin.c
Changed
28
1
2
URITable *table = (URITable*)handle;
3
4
if (urid > 0 && urid <= pw_array_get_len(&table->array, char*))
5
- return *pw_array_get_unchecked(&table->array, urid, char*);
6
+ return *pw_array_get_unchecked(&table->array, urid - 1, char*);
7
return NULL;
8
}
9
10
11
return LV2_WORKER_SUCCESS;
12
}
13
14
-static void *lv2_instantiate(const struct fc_descriptor *desc,
15
+static void *lv2_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor *desc,
16
unsigned long SampleRate, int index, const char *config)
17
{
18
struct descriptor *d = (struct descriptor*)desc;
19
20
21
SPA_EXPORT
22
struct fc_plugin *pipewire__filter_chain_plugin_load(const struct spa_support *support, uint32_t n_support,
23
- struct dsp_ops *ops, const char *plugin_uri, const char *config)
24
+ struct dsp_ops *dsp, const char *plugin_uri, const struct spa_dict *info)
25
{
26
struct context *c;
27
const LilvPlugins *plugins;
28
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-filter-chain/plugin.h -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-filter-chain/plugin.h
Changed
19
1
2
uint32_t n_ports;
3
struct fc_port *ports;
4
5
- void *(*instantiate) (const struct fc_descriptor *desc,
6
+ void *(*instantiate) (const struct fc_plugin *plugin, const struct fc_descriptor *desc,
7
unsigned long SampleRate, int index, const char *config);
8
9
void (*cleanup) (void *instance);
10
11
#define FC_PLUGIN_LOAD_FUNC "pipewire__filter_chain_plugin_load"
12
13
typedef struct fc_plugin *(fc_plugin_load_func)(const struct spa_support *support, uint32_t n_support,
14
- struct dsp_ops *dsp, const char *path, const char *config);
15
+ struct dsp_ops *dsp, const char *path, const struct spa_dict *info);
16
17
18
#endif /* PLUGIN_H */
19
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-filter-chain/sofa_plugin.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-filter-chain/sofa_plugin.c
Changed
132
1
2
3
#include <mysofa.h>
4
5
-#define MAX_SAMPLES 8192u
6
-
7
-static struct dsp_ops *dsp_ops;
8
-static struct spa_loop *data_loop;
9
-static struct spa_loop *main_loop;
10
+struct plugin {
11
+ struct fc_plugin plugin;
12
+ struct dsp_ops *dsp_ops;
13
+ struct spa_loop *data_loop;
14
+ struct spa_loop *main_loop;
15
+ uint32_t quantum_limit;
16
+};
17
18
struct spatializer_impl {
19
+ struct plugin *plugin;
20
unsigned long rate;
21
float *port6;
22
int n_samples, blocksize, tailsize;
23
24
struct convolver *r_conv3;
25
};
26
27
-static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
28
+static void * spatializer_instantiate(const struct fc_plugin *plugin, const struct fc_descriptor * Descriptor,
29
unsigned long SampleRate, int index, const char *config)
30
{
31
struct spatializer_impl *impl;
32
33
errno = ENOMEM;
34
return NULL;
35
}
36
+ impl->plugin = (struct plugin *) plugin;
37
38
while (spa_json_get_string(&it1, key, sizeof(key)) > 0) {
39
if (spa_streq(key, "blocksize")) {
40
41
pw_log_info("using n_samples:%u %d:%d blocksize sofa:%s", impl->n_samples,
42
impl->blocksize, impl->tailsize, filename);
43
44
- impl->tmp0 = calloc(MAX_SAMPLES, sizeof(float));
45
- impl->tmp1 = calloc(MAX_SAMPLES, sizeof(float));
46
+ impl->tmp0 = calloc(impl->plugin->quantum_limit, sizeof(float));
47
+ impl->tmp1 = calloc(impl->plugin->quantum_limit, sizeof(float));
48
impl->rate = SampleRate;
49
return impl;
50
error:
51
52
if (impl->r_conv2)
53
convolver_free(impl->r_conv2);
54
55
- impl->l_conv2 = convolver_new(dsp_ops, impl->blocksize, impl->tailsize,
56
+ impl->l_conv2 = convolver_new(impl->plugin->dsp_ops, impl->blocksize, impl->tailsize,
57
left_ir, impl->n_samples);
58
- impl->r_conv2 = convolver_new(dsp_ops, impl->blocksize, impl->tailsize,
59
+ impl->r_conv2 = convolver_new(impl->plugin->dsp_ops, impl->blocksize, impl->tailsize,
60
right_ir, impl->n_samples);
61
62
free(left_ir);
63
64
pw_log_error("reloading left or right convolver failed");
65
return;
66
}
67
- spa_loop_invoke(data_loop, do_switch, 1, NULL, 0, true, impl);
68
+ spa_loop_invoke(impl->plugin->data_loop, do_switch, 1, NULL, 0, true, impl);
69
}
70
71
struct free_data {
72
73
struct spatializer_impl *impl = Instance;
74
75
if (impl->interpolate) {
76
- uint32_t len = SPA_MIN(SampleCount, MAX_SAMPLES);
77
+ uint32_t len = SPA_MIN(SampleCount, impl->plugin->quantum_limit);
78
struct free_data free_data;
79
float *l = impl->tmp0, *r = impl->tmp1;
80
81
82
impl->l_conv1 = impl->r_conv1 = NULL;
83
impl->interpolate = false;
84
85
- spa_loop_invoke(main_loop, do_free, 1, &free_data, sizeof(free_data), false, impl);
86
+ spa_loop_invoke(impl->plugin->main_loop, do_free, 1, &free_data, sizeof(free_data), false, impl);
87
} else if (impl->l_conv0 && impl->r_conv0) {
88
convolver_run(impl->l_conv0, impl->port2, impl->port0, SampleCount);
89
convolver_run(impl->r_conv0, impl->port2, impl->port1, SampleCount);
90
91
return NULL;
92
}
93
94
-static struct fc_plugin builtin_plugin = {
95
- .make_desc = sofa_make_desc
96
-};
97
+static void sofa_plugin_unload(struct fc_plugin *p)
98
+{
99
+ free(p);
100
+}
101
102
SPA_EXPORT
103
struct fc_plugin *pipewire__filter_chain_plugin_load(const struct spa_support *support, uint32_t n_support,
104
- struct dsp_ops *dsp, const char *plugin, const char *config)
105
+ struct dsp_ops *dsp, const char *plugin, const struct spa_dict *info)
106
{
107
- dsp_ops = dsp;
108
+ struct plugin *impl = calloc(1, sizeof (struct plugin));
109
+
110
+ impl->plugin.make_desc = sofa_make_desc;
111
+ impl->plugin.unload = sofa_plugin_unload;
112
+
113
+ impl->quantum_limit = 8192u;
114
+
115
+ for (uint32_t i = 0; info && i < info->n_items; i++) {
116
+ const char *k = info->itemsi.key;
117
+ const char *s = info->itemsi.value;
118
+ if (spa_streq(k, "clock.quantum-limit"))
119
+ spa_atou32(s, &impl->quantum_limit, 0);
120
+ }
121
+ impl->dsp_ops = dsp;
122
pffft_select_cpu(dsp->cpu_flags);
123
124
- data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
125
- main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
126
+ impl->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
127
+ impl->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
128
129
- return &builtin_plugin;
130
+ return (struct fc_plugin *) impl;
131
}
132
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-jack-tunnel.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-jack-tunnel.c
Changed
108
1
2
#include <spa/utils/result.h>
3
#include <spa/utils/string.h>
4
#include <spa/utils/json.h>
5
+#include <spa/utils/ratelimit.h>
6
#include <spa/debug/types.h>
7
#include <spa/pod/builder.h>
8
#include <spa/param/audio/format-utils.h>
9
10
struct spa_hook core_proxy_listener;
11
struct spa_hook core_listener;
12
13
+ struct spa_ratelimit rate_limit;
14
+
15
struct spa_io_position *position;
16
17
struct stream source;
18
19
uint32_t samplerate;
20
21
jack_client_t *client;
22
- jack_nframes_t frame_time;
23
+ jack_nframes_t current_frames;
24
25
uint32_t pw_xrun;
26
uint32_t jack_xrun;
27
28
else
29
do_volume(dst, src, &s->volume, i, n_samples);
30
}
31
- pw_log_trace_fp("done %u %u", impl->frame_time, n_samples);
32
+ pw_log_trace_fp("done %u %u", impl->current_frames, n_samples);
33
if (impl->mode & MODE_SINK) {
34
impl->done = true;
35
jack.cycle_signal(impl->client, 0);
36
37
uint32_t i, n_samples = position->clock.duration;
38
39
if (impl->mode == MODE_SOURCE && !impl->triggered) {
40
- pw_log_trace_fp("done %u", impl->frame_time);
41
+ pw_log_trace_fp("done %u", impl->current_frames);
42
impl->done = true;
43
jack.cycle_signal(impl->client, 0);
44
return;
45
46
jack_nframes_t nframes;
47
48
while (true) {
49
+ jack_nframes_t current_frames;
50
+ jack_time_t current_usecs;
51
+ jack_time_t next_usecs;
52
+ float period_usecs;
53
+
54
nframes = jack.cycle_wait (impl->client);
55
56
+ jack.get_cycle_times(impl->client,
57
+ ¤t_frames, ¤t_usecs,
58
+ &next_usecs, &period_usecs);
59
+
60
+ impl->current_frames = current_frames;
61
+
62
source_running = impl->source.running;
63
sink_running = impl->sink.running;
64
65
- impl->frame_time = jack.frame_time(impl->client);
66
-
67
pw_log_trace_fp("process %d %u %u %p %d", nframes, source_running,
68
- sink_running, impl->position, impl->frame_time);
69
+ sink_running, impl->position, current_frames);
70
71
if (impl->new_xrun) {
72
- pw_log_warn("Xrun JACK:%u PipeWire:%u", impl->jack_xrun, impl->pw_xrun);
73
+ int suppressed;
74
+ if ((suppressed = spa_ratelimit_test(&impl->rate_limit, current_usecs)) >= 0) {
75
+ pw_log_warn("Xrun: current_frames:%u JACK:%u PipeWire:%u (%d suppressed)",
76
+ current_frames, impl->jack_xrun, impl->pw_xrun, suppressed);
77
+ }
78
impl->new_xrun = false;
79
}
80
81
if (impl->position) {
82
struct spa_io_clock *c = &impl->position->clock;
83
- jack_nframes_t current_frames;
84
- jack_time_t current_usecs;
85
- jack_time_t next_usecs;
86
- float period_usecs;
87
jack_position_t pos;
88
uint64_t t1, t2, t3;
89
int64_t d1;
90
91
- jack.get_cycle_times(impl->client,
92
- ¤t_frames, ¤t_usecs,
93
- &next_usecs, &period_usecs);
94
-
95
/* convert from JACK (likely MONOTONIC_RAW) to MONOTONIC */
96
t1 = get_time_nsec(impl) / 1000;
97
t2 = jack.get_time();
98
99
impl->main_loop = pw_context_get_main_loop(context);
100
impl->system = impl->main_loop->system;
101
102
+ impl->rate_limit.interval = 2 * SPA_USEC_PER_SEC;
103
+ impl->rate_limit.burst = 1;
104
+
105
impl->source.impl = impl;
106
impl->source.direction = PW_DIRECTION_OUTPUT;
107
impl->sink.impl = impl;
108
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-parametric-equalizer.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-parametric-equalizer.c
Changed
60
1
2
#include "config.h"
3
4
#include <spa/utils/result.h>
5
+#include <spa/utils/json.h>
6
#include <spa/param/audio/raw.h>
7
8
#include <pipewire/impl.h>
9
10
.destroy = filter_chain_module_destroy,
11
};
12
13
-void init_eq_node(FILE *f, const char *node_desc) {
14
+void init_eq_node(FILE *f, const char *node_desc)
15
+{
16
fprintf(f, "{\n");
17
fprintf(f, "node.description = \"%s\"\n", node_desc);
18
fprintf(f, "media.name = \"%s\"\n", node_desc);
19
20
fprintf(f, "nodes = \n");
21
}
22
23
-void add_eq_node(FILE *f, struct eq_node_param *param, uint32_t eq_band_idx) {
24
+void add_eq_node(FILE *f, struct eq_node_param *param, uint32_t eq_band_idx)
25
+{
26
+ char str164, str264;
27
+
28
fprintf(f, "{\n");
29
fprintf(f, "type = builtin\n");
30
fprintf(f, "name = eq_band_%d\n", eq_band_idx);
31
32
fprintf(f, "label = bq_peaking\n");
33
}
34
35
- fprintf(f, "control = { \"Freq\" = %d \"Q\" = %f \"Gain\" = %f }\n", param->freq, param->q_fact, param->gain);
36
+ fprintf(f, "control = { \"Freq\" = %d \"Q\" = %s \"Gain\" = %s }\n", param->freq,
37
+ spa_json_format_float(str1, sizeof(str1), param->q_fact),
38
+ spa_json_format_float(str2, sizeof(str2), param->gain));
39
40
fprintf(f, "}\n");
41
}
42
43
-void end_eq_node(struct impl *impl, FILE *f, uint32_t number_of_nodes) {
44
+void end_eq_node(struct impl *impl, FILE *f, uint32_t number_of_nodes)
45
+{
46
fprintf(f, "\n");
47
48
fprintf(f, "links = \n");
49
50
* Use a field width of 6 for gain and Q to account for any
51
* possible zeros.
52
*/
53
- if (sscanf(line, "%*s %*d: %3s %3s %*s %5d %*s %*s %6f %*s %*c %6f", eq_param.filter, eq_param.filter_type, &eq_param.freq, &eq_param.gain, &eq_param.q_fact) == 5) {
54
+ if (sscanf(line, "%*s %*d: %3s %3s %*s %5d %*s %*s %6f %*s %*c %6f",
55
+ eq_param.filter, eq_param.filter_type, &eq_param.freq,
56
+ &eq_param.gain, &eq_param.q_fact) == 5) {
57
if (strcmp(eq_param.filter, "ON") == 0) {
58
add_eq_node(memstream, &eq_param, eq_band_idx);
59
60
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-profiler.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-profiler.c
Changed
16
1
2
spa_pod_builder_add_struct(&b,
3
SPA_POD_Int(t->id),
4
SPA_POD_String(t->name),
5
- SPA_POD_Long(a->signal_time),
6
- SPA_POD_Long(na->signal_time),
7
- SPA_POD_Long(na->awake_time),
8
- SPA_POD_Long(na->finish_time),
9
+ SPA_POD_Long(a->prev_signal_time),
10
+ SPA_POD_Long(n->async ? na->prev_signal_time : na->signal_time),
11
+ SPA_POD_Long(n->async ? na->prev_awake_time : na->awake_time),
12
+ SPA_POD_Long(n->async ? na->prev_finish_time : na->finish_time),
13
SPA_POD_Int(na->status),
14
SPA_POD_Fraction(&latency),
15
SPA_POD_Int(na->xrun_count));
16
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-protocol-pulse/manager.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-protocol-pulse/manager.c
Changed
10
1
2
value = NULL;
3
}
4
5
- pw_metadata_set_property(metadata->proxy,
6
+ pw_metadata_set_property((struct pw_metadata*)metadata->proxy,
7
subject, key, type, value);
8
return 0;
9
}
10
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c
Changed
45
1
2
uint32_t channel;
3
struct timeval tv, now;
4
struct stream *stream;
5
+ uint64_t delay;
6
int res;
7
8
if ((res = message_get(m,
9
10
11
gettimeofday(&now, NULL);
12
13
+ delay = SPA_CLAMP(stream->delay, 0, INT64_MAX);
14
+
15
reply = reply_new(client, tag);
16
message_put(reply,
17
- TAG_USEC, stream->delay, /* sink latency + queued samples */
18
+ TAG_USEC, delay, /* sink latency + queued samples */
19
TAG_USEC, 0LL, /* always 0 */
20
TAG_BOOLEAN, stream->playing_for > 0 &&
21
!stream->corked, /* playing state */
22
23
uint32_t channel;
24
struct timeval tv, now;
25
struct stream *stream;
26
+ uint64_t delay;
27
int res;
28
29
if ((res = message_get(m,
30
31
32
33
gettimeofday(&now, NULL);
34
+
35
+ delay = SPA_CLAMP(stream->delay, 0, INT64_MAX);
36
+
37
reply = reply_new(client, tag);
38
message_put(reply,
39
TAG_USEC, 0LL, /* monitor latency */
40
- TAG_USEC, stream->delay, /* source latency + queued */
41
+ TAG_USEC, delay, /* source latency + queued */
42
TAG_BOOLEAN, !stream->corked, /* playing state */
43
TAG_TIMEVAL, &tv,
44
TAG_TIMEVAL, &now,
45
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-protocol-pulse/server.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-protocol-pulse/server.c
Changed
28
1
2
int client_fd, val;
3
struct client *client = NULL;
4
const char *client_access = NULL;
5
+ const char *error_reason = NULL;
6
pid_t pid;
7
8
length = sizeof(name);
9
10
11
if (server->n_clients >= server->max_clients) {
12
close(client_fd);
13
+ error_reason = "too many client application connections";
14
errno = ECONNREFUSED;
15
goto error;
16
}
17
18
return;
19
20
error:
21
- pw_log_error("server %p: failed to create client: %m", server);
22
+ pw_log_error("server %p: %s: %m", server,
23
+ error_reason ? error_reason : "failed to create client");
24
+
25
if (client)
26
client_free(client);
27
}
28
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-rtp-source.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-rtp-source.c
Changed
63
1
2
socklen_t src_len;
3
struct spa_source *source;
4
5
+ uint8_t *buffer;
6
+ size_t buffer_size;
7
+
8
unsigned receiving:1;
9
unsigned last_receiving:1;
10
};
11
12
{
13
struct impl *impl = data;
14
ssize_t len;
15
- uint8_t buffer2048;
16
17
if (mask & SPA_IO_IN) {
18
- if ((len = recv(fd, buffer, sizeof(buffer), 0)) < 0)
19
+ if ((len = recv(fd, impl->buffer, impl->buffer_size, 0)) < 0)
20
goto receive_error;
21
22
if (len < 12)
23
goto short_packet;
24
25
if (SPA_LIKELY(impl->stream)) {
26
- if (rtp_stream_receive_packet(impl->stream, buffer, len) < 0)
27
+ if (rtp_stream_receive_packet(impl->stream, impl->buffer, len) < 0)
28
goto receive_error;
29
}
30
31
32
pw_log_warn("recv error: %m");
33
return;
34
short_packet:
35
- pw_log_warn("short packet received");
36
+ pw_log_warn("short packet of len %zd received", len);
37
return;
38
}
39
40
41
pw_properties_free(impl->stream_props);
42
pw_properties_free(impl->props);
43
44
+ free(impl->buffer);
45
free(impl->ifname);
46
free(impl);
47
}
48
49
goto out;
50
}
51
52
+ impl->buffer_size = rtp_stream_get_mtu(impl->stream);
53
+ impl->buffer = calloc(1, impl->buffer_size);
54
+ if (impl->buffer == NULL) {
55
+ res = -errno;
56
+ pw_log_error("can't create packet buffer of size %zd: %m", impl->buffer_size);
57
+ goto out;
58
+ }
59
+
60
pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
61
62
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_info));
63
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-rtp/midi.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-rtp/midi.c
Changed
27
1
2
struct rtp_header header;
3
struct rtp_midi_header midi_header;
4
struct iovec iov3;
5
- uint32_t len, prev_offset, base;
6
+ uint32_t len, prev_offset, base, max_size;
7
8
spa_zero(header);
9
header.v = 2;
10
11
iov2.iov_len = 0;
12
13
prev_offset = len = base = 0;
14
+ max_size = impl->payload_size - sizeof(midi_header);
15
16
SPA_POD_SEQUENCE_FOREACH(sequence, c) {
17
void *ev;
18
19
20
offset = c->offset * impl->rate / rate;
21
22
- if (len > 0 && (len + size > impl->mtu ||
23
+ if (len > 0 && (len + size > max_size ||
24
offset - base > impl->psamples)) {
25
/* flush packet when we have one and when it's either
26
* too large or has too much data. */
27
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-rtp/stream.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-rtp/stream.c
Changed
47
1
2
uint32_t ts_offset;
3
uint32_t psamples;
4
uint32_t mtu;
5
+ uint32_t payload_size;
6
7
struct spa_ringbuffer ring;
8
uint8_t bufferBUFFER_SIZE;
9
10
11
impl->payload = pw_properties_get_uint32(props, "rtp.payload", impl->payload);
12
impl->mtu = pw_properties_get_uint32(props, "net.mtu", DEFAULT_MTU);
13
+ if (impl->mtu <= PACKET_HEADER_SIZE) {
14
+ pw_log_error("invalid MTU %d, using %d", impl->mtu, DEFAULT_MTU);
15
+ impl->mtu = DEFAULT_MTU;
16
+ }
17
+ impl->payload_size = impl->mtu - PACKET_HEADER_SIZE;
18
19
impl->seq = pw_rand32();
20
21
22
pw_log_warn("rtp.ptime doesn't match rtp.framecount. Choosing rtp.ptime");
23
}
24
} else {
25
- impl->psamples = impl->mtu / impl->stride;
26
+ impl->psamples = impl->payload_size / impl->stride;
27
impl->psamples = SPA_CLAMP(impl->psamples, min_samples, max_samples);
28
if (direction == PW_DIRECTION_INPUT) {
29
pw_properties_set(props, "rtp.ptime",
30
31
uint16_t rtp_stream_get_seq(struct rtp_stream *s)
32
{
33
struct impl *impl = (struct impl*)s;
34
-
35
return impl->seq;
36
}
37
38
+size_t rtp_stream_get_mtu(struct rtp_stream *s)
39
+{
40
+ struct impl *impl = (struct impl*)s;
41
+ return impl->mtu;
42
+}
43
+
44
void rtp_stream_set_first(struct rtp_stream *s)
45
{
46
struct impl *impl = (struct impl*)s;
47
_service:download_url:pipewire-1.2.6.tar.bz2/src/modules/module-rtp/stream.h -> _service:download_url:pipewire-1.2.7.tar.bz2/src/modules/module-rtp/stream.h
Changed
20
1
2
#define ERROR_MSEC 2.0f
3
#define DEFAULT_SESS_LATENCY 100.0f
4
5
+/* 28 bytes IP/UDP, 12 bytes RTP header */
6
+#define PACKET_HEADER_SIZE (12+28)
7
+
8
#define DEFAULT_MTU 1280
9
#define DEFAULT_MIN_PTIME 2.0f
10
#define DEFAULT_MAX_PTIME 20.0f
11
12
13
uint16_t rtp_stream_get_seq(struct rtp_stream *s);
14
15
+size_t rtp_stream_get_mtu(struct rtp_stream *s);
16
+
17
void rtp_stream_set_first(struct rtp_stream *s);
18
19
void rtp_stream_set_error(struct rtp_stream *s, int res, const char *error);
20
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/context.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/context.c
Changed
29
1
2
uint64_t quantum_stamp = 0, rate_stamp = 0;
3
bool force_rate, force_quantum, restore_rate = false, restore_quantum = false;
4
bool do_reconfigure = false, need_resume, was_target_pending;
5
+ bool have_request = false;
6
const uint32_t *node_rates;
7
uint32_t node_n_rates, node_def_rate;
8
uint32_t node_max_quantum, node_min_quantum, node_def_quantum, node_rate_quantum;
9
10
context, s, running, s->runnable, rate.num, rate.denom,
11
latency.num, latency.denom, s->name);
12
13
+ if (running && s != n && s->supports_request > 0)
14
+ have_request = true;
15
+
16
s->moved = false;
17
}
18
19
20
n->target_rate = n->rt.position->clock.target_rate;
21
}
22
23
+ SPA_FLAG_UPDATE(n->rt.position->clock.flags,
24
+ SPA_IO_CLOCK_FLAG_LAZY, have_request && n->supports_lazy > 0);
25
+
26
pw_log_debug("%p: driver %p running:%d runnable:%d quantum:%u rate:%u (%"PRIu64"/%u)'%s'",
27
context, n, running, n->runnable, target_quantum, target_rate,
28
n->rt.position->clock.target_duration,
29
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/filter.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/filter.c
Changed
14
1
2
return filter->node->driving;
3
}
4
5
+SPA_EXPORT
6
+bool pw_filter_is_lazy(struct pw_filter *filter)
7
+{
8
+ return filter->node->lazy;
9
+}
10
+
11
static int
12
do_trigger_process(struct spa_loop *loop,
13
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
14
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/filter.h -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/filter.h
Changed
12
1
2
* available (output) or needed (input). Since 0.3.66 */
3
bool pw_filter_is_driving(struct pw_filter *filter);
4
5
+/** Check if the graph is using lazy scheduling.
6
+ * Since 1.2.7 */
7
+bool pw_filter_is_lazy(struct pw_filter *filter);
8
+
9
/** Trigger a push/pull on the filter. One iteration of the graph will
10
* be scheduled and process() will be called. Since 0.3.66 */
11
int pw_filter_trigger_process(struct pw_filter *filter);
12
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/impl-node.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/impl-node.c
Changed
48
1
2
pw_log_debug("%p: start node driving:%d driver:%d prepared:%d", this,
3
this->driving, this->driver, this->rt.prepared);
4
5
+ this->lazy = this->rt.position && SPA_FLAG_IS_SET(this->rt.position->clock.flags,
6
+ SPA_IO_CLOCK_FLAG_LAZY);
7
+
8
if (!(this->driving && this->driver)) {
9
impl->pending_play = true;
10
res = spa_node_send_command(this->node,
11
12
spa_list_for_each_safe(n, t, &context->driver_list, driver_link) {
13
if (n->priority_driver < node->priority_driver)
14
break;
15
+ if (n->priority_driver == 0 && node->priority_driver == 0) {
16
+ /* no priority is set, we prefer the driver that does
17
+ * lazy scheduling. */
18
+ if (n->supports_request > 0 && node->supports_lazy > 0) {
19
+ if (n->supports_request <= node->supports_lazy)
20
+ break;
21
+ }
22
+ }
23
}
24
spa_list_append(&n->driver_link, &node->driver_link);
25
pw_context_emit_driver_added(context, node);
26
27
}
28
}
29
}
30
+ node->supports_lazy = pw_properties_get_uint32(node->properties, PW_KEY_NODE_SUPPORTS_LAZY, 0);
31
+ node->supports_request = pw_properties_get_uint32(node->properties, PW_KEY_NODE_SUPPORTS_REQUEST, 0);
32
33
if ((str = pw_properties_get(node->properties, PW_KEY_NODE_NAME)) &&
34
(node->name == NULL || !spa_streq(node->name, str))) {
35
36
} else {
37
all_ready &= ta->pending_sync == false;
38
}
39
+ ta->prev_signal_time = ta->signal_time;
40
+ ta->prev_awake_time = ta->awake_time;
41
+ ta->prev_finish_time = ta->finish_time;
42
}
43
44
- a->prev_signal_time = a->signal_time;
45
node->driver_start = nsec;
46
47
a->sync_timeout = SPA_MIN(min_timeout, DEFAULT_SYNC_TIMEOUT);
48
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/keys.h -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/keys.h
Changed
17
1
2
#define PW_KEY_NODE_DRIVER "node.driver" /**< node can drive the graph. When the node is
3
* selected as the driver, it needs to start
4
* the graph periodically. */
5
+#define PW_KEY_NODE_SUPPORTS_LAZY "node.supports-lazy" /**< the node can be a lazy driver. It will listen
6
+ * to RequestProcess commands and take them into
7
+ * account when deciding to start the graph.
8
+ * A value of 0 disables support, a value of > 0
9
+ * enables with increasing preference. */
10
+#define PW_KEY_NODE_SUPPORTS_REQUEST "node.supports-request" /**< The node supports emiting RequestProcess events
11
+ * when it wants the graph to be scheduled.
12
+ * A value of 0 disables support, a value of > 0
13
+ * enables with increasing preference. */
14
#define PW_KEY_NODE_DRIVER_ID "node.driver-id" /**< the node id of the node assigned as driver
15
* for this node */
16
#define PW_KEY_NODE_ASYNC "node.async" /**< the node wants async scheduling */
17
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/private.h -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/private.h
Changed
31
1
2
uint32_t segment_owner16; /* id of owners for each segment info struct.
3
* nodes that want to update segment info need to
4
* CAS their node id in this array. */
5
- uint32_t padding11; /* must be 0 */
6
+ uint64_t prev_awake_time;
7
+ uint64_t prev_finish_time;
8
+ uint32_t padding7; /* must be 0 */
9
+
10
uint32_t client_version; /* verions of client, see above */
11
uint32_t server_version; /* verions of server, see above */
12
13
14
15
char *name; /** for debug */
16
17
+ uint32_t supports_lazy; /**< lazy driver preference */
18
+ uint32_t supports_request; /**< request follower preference */
19
+
20
uint32_t priority_driver; /** priority for being driver */
21
char **groups; /** groups to schedule this node in */
22
char **link_groups; /** groups this node is linked to */
23
24
unsigned int sync:1; /**< the sync-groups are active */
25
unsigned int transport:1; /**< the transport is active */
26
unsigned int async:1; /**< async processing, one cycle latency */
27
+ unsigned int lazy:1; /**< the graph is lazy scheduling */
28
29
uint32_t port_user_data_size; /**< extra size for port user data */
30
31
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/proxy.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/proxy.c
Changed
11
1
2
if (proxy->core)
3
pw_map_remove(&proxy->core->objects, proxy->id);
4
proxy->in_map = false;
5
+
6
+ /* Make sure any future method calls fail */
7
+ proxy->id = SPA_ID_INVALID;
8
}
9
}
10
11
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/stream.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/stream.c
Changed
23
1
2
if ((b = get_buffer(stream, io->buffer_id)) != NULL) {
3
pw_log_trace_fp("%p: recycle buffer %d", stream, b->id);
4
queue_push(impl, &impl->dequeued, b);
5
+ if (impl->early_process)
6
+ ask_more = true;
7
}
8
9
/* pop new buffer */
10
11
return stream->node->driving;
12
}
13
14
+SPA_EXPORT
15
+bool pw_stream_is_lazy(struct pw_stream *stream)
16
+{
17
+ return stream->node->lazy;
18
+}
19
+
20
static int
21
do_trigger_driver(struct spa_loop *loop,
22
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
23
_service:download_url:pipewire-1.2.6.tar.bz2/src/pipewire/stream.h -> _service:download_url:pipewire-1.2.7.tar.bz2/src/pipewire/stream.h
Changed
54
1
2
* available (output) or needed (input). Since 0.3.34 */
3
bool pw_stream_is_driving(struct pw_stream *stream);
4
5
+/** Check if the graph is using lazy scheduling. If the stream is
6
+ * driving according to \ref pw_stream_is_driving(), then it should
7
+ * consider taking into account the RequestProcess commands when
8
+ * driving the graph.
9
+ *
10
+ * If the stream is not driving, it should send out RequestProcess
11
+ * events with \ref pw_stream_emit_event() or indirectly with
12
+ * \ref pw_stream_trigger_process() to suggest a new graph cycle
13
+ * to the driver.
14
+ *
15
+ * It is not a requirement that all RequestProcess events/commands
16
+ * need to start a graph cycle.
17
+ * Since 1.2.7 */
18
+bool pw_stream_is_lazy(struct pw_stream *stream);
19
+
20
/** Trigger a push/pull on the stream. One iteration of the graph will
21
- * be scheduled. If it successfully finishes, process() will be called.
22
- * It is possible for the graph iteration to not finish, so
23
+ * be scheduled when the stream is driving according to
24
+ * \ref pw_stream_is_driving(). If it successfully finishes, process()
25
+ * will be called and the trigger_done event will be emitted. It is
26
+ * possible for the graph iteration to not finish, so
27
* pw_stream_trigger_process() needs to be called again even if process()
28
- * is not called.
29
+ * and trigger_done is not called.
30
*
31
* If there is a deadline after which the stream will have xrun,
32
* pw_stream_trigger_process() should be called then, whether or not
33
- * process() has been called. Sound hardware will xrun if there is
34
- * any delay in audio processing, so the ALSA plugin triggers the
35
+ * process()/trigger_done has been called. Sound hardware will xrun if
36
+ * there is any delay in audio processing, so the ALSA plugin triggers the
37
* graph every quantum to ensure audio keeps flowing. Drivers that
38
* do not have a deadline, such as the freewheel driver, should
39
* use a timeout to ensure that forward progress keeps being made.
40
41
* the graph is taking 3x longer than normal, it is likely that it
42
* is hung and should be retriggered.
43
*
44
+ * Streams that are not drivers according to \ref pw_stream_is_driving()
45
+ * can also call this method. The result is that a RequestProcess event
46
+ * is sent to the driver. If the graph is lazy scheduling according to
47
+ * \ref pw_stream_is_lazy(), this might result in a graph cycle by the
48
+ * driver. If the graph is not lazy scheduling and the stream is not a
49
+ * driver, this method will have no effect.
50
+ *
51
* Since 0.3.34 */
52
int pw_stream_trigger_process(struct pw_stream *stream);
53
54
_service:download_url:pipewire-1.2.6.tar.bz2/src/tools/pw-dot.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/tools/pw-dot.c
Changed
14
1
2
dot_data_add_string(dd, "\\loutput_node_id: ");
3
dot_data_add_uint32(dd, info->output_node_id);
4
dot_data_add_string(dd, "\\linput_node_id: ");
5
- dot_data_add_uint32(dd, info->output_node_id);
6
+ dot_data_add_uint32(dd, info->input_node_id);
7
dot_data_add_string(dd, "\\loutput_port_id: ");
8
dot_data_add_uint32(dd, info->output_port_id);
9
- dot_data_add_string(dd, "\\linput_node_id: ");
10
+ dot_data_add_string(dd, "\\linput_port_id: ");
11
dot_data_add_uint32(dd, info->input_port_id);
12
dot_data_add_string(dd, "\\lstate: ");
13
dot_data_add_string_escaped(dd, pw_link_state_as_string(info->state));
14
_service:download_url:pipewire-1.2.6.tar.bz2/src/tools/pw-dump.c -> _service:download_url:pipewire-1.2.7.tar.bz2/src/tools/pw-dump.c
Changed
10
1
2
if ((o = find_object(d, id)) == NULL)
3
return;
4
5
- if (!d->pattern || object_matches(o, d->pattern)) {
6
+ if (d->monitor && (!d->pattern || object_matches(o, d->pattern))) {
7
d->state = STATE_FIRST;
8
if (d->state == STATE_FIRST)
9
put_begin(d, NULL, "", 0);
10