Previously when parameters were enumarated, it was checked if at least one
param was known for `id`. If not, `-ENOENT` was returned to signal that
this param id is not supported.
This is not necessarily true, since a param id might be supported, but it
might have zero params at the moment, in which case an unexpected error
would be returned.
Fix that by using `pw_param_info_find()` with the underlying impl object
to check if the param id is actually supported.
Add a port.passive = follow mode and the node.passive equivalents
out-follow, in-follow, follow.
This makes it possible to control how a port influences the state of
the peer and how the peer influences the state of the node independently.
In passive mode, the port will not make the peer runnable and will also
not become runnable when the peer activates.
In the follow mode, the port will not make the peer runnable but it will
become runnable when the peer is active.
This makes it possible to do new things like (f for follow):
Source -> (f)loopback1-in|loopback1-out(f) -> Sink
It will not make the source and sink run but when one of them start, all
will become runnable.
Or you can now better do the leak node hack that was previously used:
Source -> (f)pw-record
That will only start running when the source is activated by something
else.
With port.passive = true|false|follow there is a potential 4th case
which would activate the peer but not be activated by the peer, which is
not something that makes sense.
Sink/Source pairs should not have the same link-group otherwise the
session manager will not be able to autoconnect them with a loopback or
some other internally linked stream.
We used to skip the runnable state from driver nodes because we assume
that they will be activated from other nodes. We however need to make
this more general to all suspendable nodes.
This makes pw-play -> loopback1-sink loopback1-out -> loopback2-sink
loopback-out -> sink also work correctly because the loopback2-sink does
not activate loopback1-out then.
Fix path comparison in is_socket_unix() and don't unset LISTEN_FDS since
the function that uses it is called more than once and it was not unset
when sd_listen_fds() was used.
Fixes#5140
Instead of writing packets sequentially and losing sync on any
frame gap, compute the write position from the VBAN header's
n_frames field. Out-of-order packets land at the correct
ringbuffer offset, matching how module-rtp handles this.
Only advance the writeindex when a packet extends the frontier
so that late arrivals fill gaps without moving the pointer
backwards.
Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/5145
The sender makes an input stream for each connected client. This makes
it easier to do the per client conversion using the adapter and send
different channels to clients.
The receiver uses linear regression to map ringbuffer indexes to server
timestamps and server timestamps to client timestamps. It can then
schedule playback against its own clock.
The sync-groups are only to group nodes with the same driver but don't
make them runnable.
This avoid making v4l2 runnable (without a link) when running ardour
because ardour uses the transport, which activates the sync group.
Move the runnable state calculation out of the collect_nodes function.
They are really two different steps that doin't overlap much.
The runnable state of a node is very easy to calculate. A node is
runnable if it is linked to another node without a passive port. When we
find two runnable nodes, make them runnable, which makes all nodes
linked to them runnable, stopping at passive ports.
We don't have to check the active state of the nodes or links to group
them together. This ensures we don't swap nodes around too much when the
node or link state changes.
There is no reason to delay preparing the link (by the scheduler) when
both nodes are active, we can do that right from the start.
This makes things a bit more symetrical because deactivating a node does
not unprepare a link.
This however changes things a bit because you can no longer delay link
prepare until you activate the node. I don't know if this is actually in
use and it would probably be to delay format negotiation. The right way
do delay format negotiation is to wait until an EnumFormat is set but
that is something to improve later.
!2699 has been merged a bit prematurely and it contained things that are
not used. So remove the unused member variables, functions, fix module
usage strings, and move some functions from headers.
We can just concatenate the stream and client dict on the stack, reusing
all the strings without having to do allocations or copies.
Also filter out the object.id and object.serial from the client, we want
to keep the ones from the streams.
Instead of adding the client props to the stream props when we create
it, add them when we enumerate the streams.
This makes it possible to also have the client props in the stream props
for streams that are not created with the pulse API.
Fixes#5090
Roc-toolkit log records are captured via a callback and
written to PipeWire log with corresponding verbosity level.
The log.level config parameter limits record verbosity at
the roc-toolkit level.
Patch by Lairton Lelis da Fonseca Junior (@lairton)
Remove the hard skip for IPv4 link-local addresses and add an interface
binding (matching the existing IPv6 link-local behavior).
The host needs a link-local address on the interface (ip addr add
169.254.x.x/16 dev wlan0 or via NetworkManager +ipv4.addresses).
Fixes#4830
Socket activation uses sd_listen_fds from libsystemd, and can only be
compiled on systems with systemd.
This is an issue for Alpine / postmarketOS, where upstream has no
systemd package, but downstream depends on upstream's pipewire package
and wants to rely on socket activation. This also prevents using
socket-activation on other non-systemd distributions, including
non-Linux.
Implement equivalent functionality without a dependency on libsystemd.
This can easily be overlooked if the RTP rate equals the clock rate, which
is fairly common (for example, RTP rate and clock rate both being 48 kHz).
And, if an ASRC is active, and converting the output of the RTP source
node, the resampler's delay need to be taken into the account as well.
Clear the ringbuffer in stream_stop() when processing stops to prevent old invalid packets
from being sent when processing resumes via rtp_audio_flush_packets().
This ensures a clean state when the stream restarts.