Regular filters should be treated as regular stream / device nodes. Note that
the filter utils API is meant to be used using the direction of the main smart
filter nodes. This is why we use the target direction instead of the actual
stream direction to check if the stream session item is smart or not.
This should never happen, but there are odd cases with broken
configuration where such a device may appear and the least we can do
is not crash, at least not when the device.name is only used for
debug messages. In state-profile and other places where the name
really matters, we actually have checks in place.
Fixes: #674
We always have to destroy the restore timeout source when we want to switch to
HSP/HFP profile, even if the device is already set to HSP/HFP or has already an
input route. Apart from this, we also want to make sure there is no pending
timeout source when we are creating a new one. This should avoid an infinite
loop about switching BT profiles when capture nodes are created and destroyed
quickly.
Indexing into the subject from a node-removed event is slightly quirky.
As a result, we were not properly freeing filter chains tied to
disconnected nodes.
Change how we store the list of loaded filters and ensure they
are properly freed when their parent node is removed from the graph.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
If a source filter is used, the BT profile autoswitch does not work because
WirePlumber thinks there is always a client capturing audio from it. This patch
fixes the issue by recursively walking through the source filters that are
linked to the BT loopback source until a stream is found. If a stream is found
at the end of the chain, then it switches to HSP/HFP profile, if the stream is
not found, the profile stays to A2DP.
Copy all the node properties into the session item and customize
afterwards, instead of starting with an empty set and cherry-picking
properties... We need to cherry-pick more and more properties
overtime and it's easy to make mistakes
Otherwise it is global and it retains a reference to the `parent`
WpSpaDevice object until this function is called again, which prevents
some camera nodes - in some cases - from being destroyed
Fixes#640
Enhance the parsing logic to consider more than one device number. libcamera
devices some times use up multiple V4L2 devices, in this case libcamera should
be given a chance to enumerate the device.
Fixes#623
This patch makes the check more robust when detecting main filter nodes. This is
because some filters might append '/Internal' to their main node media class.
The direction check has also been improved to work with Video filters.
event:set_data() coerces Lua tables to properties, so that keys and
values become strings. Take into account that profile.index is a string
due to this.
Fixes WP setting the profile, even though it is already the active one.
Using parseBool is actually more broken if the property is already parsed as a
boolean, and causes the node to remain unhidden even when hide-parent = true.
Revert 2a45842169 to fix this behaviour.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Using the new Conf() constructor, we can load and parse a filter graph
from a file on disk. This is useful when, for example, maintaining a
large database of filter graphs. It also keeps wireplumber.conf.d free
from clutter.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
The cam_data structure stores a reference to the "parent" WpSpaDevice
and doesn't allow it to be destroyed when the monitor detects that
the device is no longer present. Clear it right after pushing the event
to make sure there's no dangling reference left around
Fixes: #627
We apparently store things in the <media-class>:<key>:<value>
format, while pipewire-pulse expects <media-class>.<key>:<value>
and this detail was missed in the latest refactoring.
It also seems that I forgot to ensure that restoring this metadata
key worked. The hook was there, but not registered.
Remove the hook and directly populate the metadata object when
it is activated, as it seems simpler.
Fixes: #604
The existence of props["hide-parent"] is truthy. Parse the boolean explicitly
to get the correct logic.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
This allows DSP rules to be specified in a wireplumber.conf.d file under
the node.software-dsp.rules section. Properties are specified in the
software-dsp action.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
As this DSP "policy" is intended to run on the creation/deletion
of a node, move it into the node subdir.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Prevously, we were only looking at node["global-properties"] for
properties to match on. Change this to instead run against
node.properties, so that we can use type-specific properties such as alsa.id.
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
The current code was not updated to use `clients_om`, thus never
found a client, ending up never sending client errors.
Just use the shared helper to avoid such issues in the future.
These were documented in src/scripts/lib initially because the settings-manager
scripts used to be also there and it made sense to keep them close together.
Autoswitch should make sure the saved headset profile always has an
input route. Check this on loading/saving it, otherwise reselect it.
Headset mode profile without mic used to make some sense when it wasn't
using the loopback node (ie. easy way to disable it), but now with the
loopback node this doesn't make sense any more and it's confusing if it
occurs, so we shouldn't allow it.
Profile autoswitch should support also A2DP profiles with input route,
so the loopback should not assume the source node is SCO one.
Also fix handling of AG SCO output stream nodes, which should not be
hidden as internal.
A smart filter should be considered "targetless" (i.e. interpose on
streams going to default target) only if filter.smart.target is not set.
Currently any smart filter with specified target not found is considered
such, which is wrong. This causes misbehavior, such as all recording
streams going to the bluetooth dummy source.
Fix this by doing it correctly.
And name the loopback source node the same as bluez source without 'internal'
prefix. This keeps consistency with input/output node names when switching
bluetooth profiles.
Like WirePlumber 0.4.17, we need to mark the current routes as 'active' if they
were previously not active as soon as we detect it. This avoids a possible
infinite loop that restores the routes and saves them constantly, which happens
when the device's Route param has changed more than once before the event
'select-routes' is triggered.
The boolean values of properties in rules are strings in JSON config files and
they will retain the same type when they are translated to Lua.
Use cutils.parseBool() function when they have to be interpreted as bools.
Fixes: #586
This is needed for some devices that expose both Headset and Speaker nodes, so
that the applications are automatically linked to the Headset node or Speakers
node automatically when plugging and unplugging a headset.