When applying new routes, we always want the save property to be false because
it is done by WirePlumber (not the user). WirePlumber applies routes when
restoring them from the state file, or when finding the best routes after the
profile has changed. In both cases, it does not make sense to set save=true.
If the user changed the volume on a ACP 'Headphones' route to a value different
than 100%, and then unplugs the jack headset, the ACP 'Headphones' route becomes
unavailable with volume set to 100% and the save flag not cleared.
Since the save flag is not cleared when the ACP 'Headphones' route becomes
unavailable, WirePlumber will save it with 100% volume, overriding the previous
volume value set by the user. This is not ideal because the volume will be
restored to 100% by WirePlumber when plugging back the headset.
This change fixes this by never saving routes that are not available.
The Route params changed event can be emitted before the EnumRoute params with
some devices, causing wrong evaluation of the routes because their cached info
is not updated. This change always enumerates the EnumRoute params before
evaluating them to make sure the cache info is always valid.
Fixes: #762
When current output target of a media player application is removed, it
can be useful if playback is paused (to avoid e.g. music playback to
going to speakers when headset is accidentally unplugged). Android etc.
implement a policy like this.
Add a policy script that monitors stream target removals. When it
detects a media player application that is linked to a no longer present
output target, it checks whether the stream is associated with a media
player seen in MPRIS. If yes, it sends MPRIS Pause() command to the
media player.
Enable this policy by default.
Some PCM devices can expose multiple nodes with same session priorities but
different route priorities. This improves the default nodes logic to also check
the route priorities when the session priorities are the same.
If the managed node needs to emit events before it is bound, Wireplumber
treats it as destroyed and ignores the events. Add the node as pending
before it is bound so the node can run set_param on events that happen
before it gets bound.
Signed-off-by: Richard Acayan <mailingradian@gmail.com>
The linking-utils module already implements a way to check for available routes,
this patch uses it in default-nodes/rescan.lua to remove redundant code.
It's possible that managed_node.properties["node.name"] == nil if the
node is gone.
The removeDevice call above has already cleared the node names, so no
need to do it again.
This allows grouping audio streams that have a pw-audio-namespace ancestor
process name. The grouping is done by creating a loopback filter for each group
or namespace. Those loopback filters are then linked in between the actual
stream and device nodes. A '--target-object' flag is also supported in the
ancestor process name to define a target for the loopback stream node.
stream-restore should not be touching node properties of the Bluetooth
mic / device set / offload / ALSA UCM split loopback nodes. Those are
controlled by Route settings on the device.
Set device.routes and state.restore-props=false as appropriate to avoid
that.
Instruct ACP to provide information about UCM SplitPCM channel
splitting instead of doing it with alsa-lib plugins.
Use the provided information to load loopbacks that create virtual sinks
that do the channel remapping from UCM.
Node name deduplication relying on presence of node objects creates race
conditions, as the name cannot be marked unused if the node object was
not created or was destroyed.
Use separate (device_id, node_id) -> name table to track name ownership
separately from the existence of node objects.
Also clear up the reserved names when device is destroyed, by the
monitor or device reservation. In these cases "object-removed" for
nodes is not called, so this fixes names leaking when e.g. pw-reserve is
used.
In cases where a Node is created asynchronously and associated with the
Device later, set the id pending so that we don't miss ObjectConfig
events.
The "set Route again" workaround is also not needed, moreover it was not
reliable before either since the Device might issue ObjectConfig only
for changed properties.
If loopback is emitted after the SCO node, e.g. when A2DP profile
connects late, recreate the SCO node.
This ensures the underlying SCO node is hidden when the loopback is
present.
This seems to be an omission from when we transferred the default device
properties from the config file on to the Lua script. Both auto-profile
and auto-port are meant to be disabled, so that we can apply our own
management logic.
Fixes: #734
When node activation fails, it won't be created and its object-removed
signal can be called with some properties missing. This breaks node
name deduplication, causing error
wplua: [string "alsa.lua"]:182: attempt to concatenate a nil value (local 'node_name')
It occurs e.g. when switching ALSA device profile, while some
application has opened the device with ALSA and is keeping it busy.
Fix by handling the activation failure, and tolerating missing property
in object-removed.
This patch adds a 500ms timeout callback to switch to HSP/HFP when a stream
starts capturing BT audio. This avoids quickly switching from A2DP to HSP/HFP
back and forth if an application just wants to probe the BT source for a short
period of time.
See #634
The actual deduplication only checked the first device. Extend it to the
full list, as intended.
Fixes: 848b6326 (monitor-utils: Rework camera deduplication code)
The previous code made some invalid assumptions and was rather
complicated. Rework and simplify it.
The approach work as follows:
1. Once a new device gets registered, store its data in a list of pending
devices.
2. Start a timer. On timeout, we check all pending devices and depulicate
according to our heuristic. The timer gets reset whenever a device is
added in order to avoid race conditions.
3. On timeout, add the pending devices to categories. For now: UVC cameras
from the V4L2 plugin, libcamera cameras and other cameras from the V4L2
plugin.
4. Then process the different categories in order of preference and store
their V4L2 device IDs in a list for each plugin.
5. Before creating a camera, check that the V4L2 device(s) it uses are not
yet used by a already existing camera from the other plugin.
While on it, drop support for Pipewire versions that don't report V4L2
device IDs at all.
Closes https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/689
Closes https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/708
Handle only devices associated with Bluetooth loopback nodes.
Make sure the node.link-group iteration cannot get stuck if there is a
loop in the link graph.
This patch removes the manually created object managers in the BT profile
autoswitch logic, and instead uses the object managers from the event source,
simplifying the logic a bit.
The intention here is to fix a Bluetooth bug where changing between different
profiles momentarily causes streams to be linked to an internal speaker.
Unfortunately, this case is not handled by the event dispatcher because some
signals are emitted using idle callbacks, and therefore we have to rely on
extra logic in rescan.lua to solve the problem.
The previous assumption that any target with "device.intended-roles"
should be managed by the role-based policy is wrong, as for example
Bluetooth SCO nodes always have "device.intended-roles = Communication"
and some ALSA devices managed by ACP also do. This is meant to be used
as a hint for the desktop policy (it's been there in PulseAudio as well)
and does not necessarily mean that a role-priority-based policy should
be applied on all links to those devices.
Instead, use a new property to explicitly mark all the targets that
are meant to be managed by the role-based policy and respect that in
all places where we check for a potential role-based policy link.
Fixes: #682
This way of definining dependencies ensures that if we remove one
of the find-* hooks from the config, the rest of them will continue
to work in the expected order. Previously, removing one of them
would break the entire chain.
Also, move the example from linking.conf to media-role-nodes.conf,
as it's more relevant there, and make sure the setting is constantly
read back in the Lua script, so that runtime changes can work.