lua monitors: switch to wpsetttings

- switch alsa.lua, v4l2.lua & libcamera.lua
- remove the config/lua references for these scripts
- fix the wpsettings deps parsing bug.
This commit is contained in:
Ashok Sidipotu 2022-05-02 12:49:50 +05:30 committed by Julian Bouzas
parent 7d304096e5
commit 161c43b71a
15 changed files with 227 additions and 447 deletions

View file

@ -78,7 +78,8 @@ wp_settings_init (WpSettings * self)
* \param value(out): the boolean value of the setting
* \returns: TRUE if the setting is defined, FALSE otherwise
*/
gboolean wp_settings_get_boolean (WpSettings *self, const gchar *setting,
gboolean
wp_settings_get_boolean (WpSettings *self, const gchar *setting,
gboolean *value)
{
g_return_val_if_fail (self, false);
@ -105,7 +106,8 @@ gboolean wp_settings_get_boolean (WpSettings *self, const gchar *setting,
* \param value(out): the string value of the setting
* \returns: TRUE if the setting is defined, FALSE otherwise
*/
gboolean wp_settings_get_string (WpSettings *self, const gchar *setting,
gboolean
wp_settings_get_string (WpSettings *self, const gchar *setting,
const char **value)
{
g_return_val_if_fail (self, false);
@ -128,10 +130,11 @@ gboolean wp_settings_get_string (WpSettings *self, const gchar *setting,
*
* \ingroup wpsetting
* \param self the handle
* \param value(out): the integer value of the setting
* \param value(out): the integer value of the setting
* \returns: TRUE if the setting is defined, FALSE otherwise
*/
gboolean wp_settings_get_int (WpSettings *self, const gchar *setting,
*/
gboolean
wp_settings_get_int (WpSettings *self, const gchar *setting,
gint64 *val)
{
g_return_val_if_fail (self, false);
@ -168,7 +171,8 @@ gboolean wp_settings_get_int (WpSettings *self, const gchar *setting,
* \returns TRUE if there is a match for the client_props and returns the
* applied props for the match.
*/
gboolean wp_settings_apply_rule (WpSettings *self, const gchar *rule,
gboolean
wp_settings_apply_rule (WpSettings *self, const gchar *rule,
WpProperties *client_props, WpProperties *applied_props)
{
g_return_val_if_fail (self, false);
@ -195,7 +199,7 @@ gboolean wp_settings_apply_rule (WpSettings *self, const gchar *rule,
else
wp_properties_add (client_props, m->actions);
wp_debug_object (self, ". match found for rule(%s) with actions"
wp_debug_object (self, "match found for rule(%s) with actions"
"(%d)", rule, wp_properties_get_count(m->actions));
return TRUE;
@ -229,9 +233,8 @@ wp_settings_activate_get_next_step (WpObject * object,
return STEP_LOAD;
}
static
gboolean check_metadata_name (gpointer g_object,
gpointer metadata_name)
static gboolean
check_metadata_name (gpointer g_object, gpointer metadata_name)
{
if (!WP_IS_SETTINGS(g_object))
return false;

View file

@ -1,29 +0,0 @@
alsa_monitor = {}
alsa_monitor.properties = {}
alsa_monitor.rules = {}
function alsa_monitor.enable()
if alsa_monitor.enabled == false then
return
end
-- The "reserve-device" module needs to be loaded for reservation to work
if alsa_monitor.properties["alsa.reserve"] then
load_module("reserve-device")
end
load_monitor("alsa", {
properties = alsa_monitor.properties,
rules = alsa_monitor.rules,
})
if alsa_monitor.properties["alsa.midi"] then
load_monitor("alsa-midi", {
properties = alsa_monitor.properties,
})
-- The "file-monitor-api" module needs to be loaded for MIDI device monitoring
if alsa_monitor.properties["alsa.midi.monitoring"] then
load_module("file-monitor-api")
end
end
end

View file

@ -1,14 +0,0 @@
libcamera_monitor = {}
libcamera_monitor.properties = {}
libcamera_monitor.rules = {}
function libcamera_monitor.enable()
if libcamera_monitor.enabled == false then
return
end
load_monitor("libcamera", {
properties = libcamera_monitor.properties,
rules = libcamera_monitor.rules,
})
end

View file

@ -1,14 +0,0 @@
v4l2_monitor = {}
v4l2_monitor.properties = {}
v4l2_monitor.rules = {}
function v4l2_monitor.enable()
if v4l2_monitor.enabled == false then
return
end
load_monitor("v4l2", {
properties = v4l2_monitor.properties,
rules = v4l2_monitor.rules,
})
end

View file

@ -1,155 +0,0 @@
alsa_monitor.enabled = true
alsa_monitor.properties = {
-- Create a JACK device. This is not enabled by default because
-- it requires that the PipeWire JACK replacement libraries are
-- not used by the session manager, in order to be able to
-- connect to the real JACK server.
--["alsa.jack-device"] = false,
-- Reserve devices via org.freedesktop.ReserveDevice1 on D-Bus
-- Disable if you are running a system-wide instance, which
-- doesn't have access to the D-Bus user session
["alsa.reserve"] = true,
--["alsa.reserve.priority"] = -20,
--["alsa.reserve.application-name"] = "WirePlumber",
-- Enables MIDI functionality
["alsa.midi"] = true,
-- Enables monitoring of alsa MIDI devices
["alsa.midi.monitoring"] = true,
-- MIDI bridge node properties
["alsa.midi.node-properties"] = {
-- Name set for the node with ALSA MIDI ports
["node.name"] = "Midi-Bridge",
-- Removes longname/number from MIDI port names
--["api.alsa.disable-longname"] = true,
},
-- These properties override node defaults when running in a virtual machine.
-- The rules below still override those.
["vm.node.defaults"] = {
["api.alsa.period-size"] = 256,
["api.alsa.headroom"] = 8192,
},
}
alsa_monitor.rules = {
-- An array of matches/actions to evaluate.
--
-- If you want to disable some devices or nodes, you can apply properties per device as the following example.
-- The name can be found by running pw-cli ls Device, or pw-cli dump Device
--{
-- matches = {
-- {
-- { "device.name", "matches", "name_of_some_disabled_card" },
-- },
-- },
-- apply_properties = {
-- ["device.disabled"] = true,
-- },
--}
{
-- Rules for matching a device or node. It is an array of
-- properties that all need to match the regexp. If any of the
-- matches work, the actions are executed for the object.
matches = {
{
-- This matches all cards.
{ "device.name", "matches", "alsa_card.*" },
},
},
-- Apply properties on the matched object.
apply_properties = {
-- Use ALSA-Card-Profile devices. They use UCM or the profile
-- configuration to configure the device and mixer settings.
["api.alsa.use-acp"] = true,
-- Use UCM instead of profile when available. Can be
-- disabled to skip trying to use the UCM profile.
--["api.alsa.use-ucm"] = true,
-- Don't use the hardware mixer for volume control. It
-- will only use software volume. The mixer is still used
-- to mute unused paths based on the selected port.
--["api.alsa.soft-mixer"] = false,
-- Ignore decibel settings of the driver. Can be used to
-- work around buggy drivers that report wrong values.
--["api.alsa.ignore-dB"] = false,
-- The profile set to use for the device. Usually this is
-- "default.conf" but can be changed with a udev rule or here.
--["device.profile-set"] = "profileset-name",
-- The default active profile. Is by default set to "Off".
--["device.profile"] = "default profile name",
-- Automatically select the best profile. This is the
-- highest priority available profile. This is disabled
-- here and instead implemented in the session manager
-- where it can save and load previous preferences.
["api.acp.auto-profile"] = false,
-- Automatically switch to the highest priority available port.
-- This is disabled here and implemented in the session manager instead.
["api.acp.auto-port"] = false,
-- Other properties can be set here.
--["device.nick"] = "My Device",
},
},
{
matches = {
{
-- Matches all sources.
{ "node.name", "matches", "alsa_input.*" },
},
{
-- Matches all sinks.
{ "node.name", "matches", "alsa_output.*" },
},
},
apply_properties = {
--["node.nick"] = "My Node",
--["node.description"] = "My Node Description",
--["priority.driver"] = 100,
--["priority.session"] = 100,
--["node.pause-on-idle"] = false,
--["monitor.channel-volumes"] = false
--["resample.quality"] = 4,
--["resample.disable"] = false,
--["channelmix.normalize"] = false,
--["channelmix.mix-lfe"] = false,
--["channelmix.upmix"] = true,
--["channelmix.upmix-method"] = "psd", -- "none" or "simple"
--["channelmix.lfe-cutoff"] = 150,
--["channelmix.fc-cutoff"] = 12000,
--["channelmix.rear-delay"] = 12.0,
--["channelmix.stereo-widen"] = 0.0,
--["channelmix.hilbert-taps"] = 0,
--["channelmix.disable"] = false,
--["dither.noise"] = 0,
--["dither.method"] = "none", -- "rectangular", "triangular" or "shaped5"
--["audio.channels"] = 2,
--["audio.format"] = "S16LE",
--["audio.rate"] = 44100,
--["audio.allowed-rates"] = "32000,96000",
--["audio.position"] = "FL,FR",
--["api.alsa.period-size"] = 1024,
--["api.alsa.period-num"] = 2,
--["api.alsa.headroom"] = 0,
--["api.alsa.start-delay"] = 0,
--["api.alsa.disable-mmap"] = false,
--["api.alsa.disable-batch"] = false,
--["api.alsa.use-chmap"] = false,
--["api.alsa.multirate"] = true,
--["latency.internal.rate"] = 0
--["latency.internal.ns"] = 0
--["clock.name"] = "api.alsa.0"
--["session.suspend-timeout-seconds"] = 5, -- 0 disables suspend
},
},
}

View file

@ -1,36 +0,0 @@
default_access.enabled = true
default_access.properties = {
-- Enable the use of the flatpak portal integration.
-- Disable if you are running a system-wide instance, which
-- doesn't have access to the D-Bus user session
["enable-flatpak-portal"] = true,
}
default_access.rules = {
{
matches = {
{
{ "pipewire.access", "=", "flatpak" },
{ "media.category", "=", "Manager" },
},
},
default_permissions = "all",
},
{
matches = {
{
{ "pipewire.access", "=", "flatpak" },
},
},
default_permissions = "rx",
},
{
matches = {
{
{ "pipewire.access", "=", "restricted" },
},
},
default_permissions = "rx",
},
}

View file

@ -1,38 +0,0 @@
libcamera_monitor.enabled = true
libcamera_monitor.rules = {
-- An array of matches/actions to evaluate.
{
-- Rules for matching a device or node. It is an array of
-- properties that all need to match the regexp. If any of the
-- matches work, the actions are executed for the object.
matches = {
{
-- This matches all cards.
{ "device.name", "matches", "libcamera_device.*" },
},
},
-- Apply properties on the matched object.
apply_properties = {
-- ["device.nick"] = "My Device",
},
},
{
matches = {
{
-- Matches all sources.
{ "node.name", "matches", "libcamera_input.*" },
},
{
-- Matches all sinks.
{ "node.name", "matches", "libcamera_output.*" },
},
},
apply_properties = {
--["node.nick"] = "My Node",
--["priority.driver"] = 100,
--["priority.session"] = 100,
--["node.pause-on-idle"] = false,
},
},
}

View file

@ -1,38 +0,0 @@
v4l2_monitor.enabled = true
v4l2_monitor.rules = {
-- An array of matches/actions to evaluate.
{
-- Rules for matching a device or node. It is an array of
-- properties that all need to match the regexp. If any of the
-- matches work, the actions are executed for the object.
matches = {
{
-- This matches all cards.
{ "device.name", "matches", "v4l2_device.*" },
},
},
-- Apply properties on the matched object.
apply_properties = {
-- ["device.nick"] = "My Device",
},
},
{
matches = {
{
-- Matches all sources.
{ "node.name", "matches", "v4l2_input.*" },
},
{
-- Matches all sinks.
{ "node.name", "matches", "v4l2_output.*" },
},
},
apply_properties = {
--["node.nick"] = "My Node",
--["priority.driver"] = 100,
--["priority.session"] = 100,
--["node.pause-on-idle"] = false,
},
},
}

View file

@ -2,11 +2,6 @@
-- dynamic properties of pipewire objects in RAM
load_module("metadata")
-- Load devices
alsa_monitor.enable()
v4l2_monitor.enable()
libcamera_monitor.enable()
-- Track/store/restore user choices about devices
device_defaults.enable()

View file

@ -85,10 +85,26 @@ wireplumber.components = [
# The lua scripting engine
{ name = libwireplumber-module-lua-scripting, type = module }
# script which confers pemissions on the client nodes
{ name = access/access-default.lua, type = script/lua }
# module managing the portal permissions
{ name = libwireplumber-module-portal-permissionstore , type = module, deps = access.enable-flatpak-portal }
# script which confers pemissions on the portal client nodes
{ name = access/access-portal.lua, type = script/lua, deps = access.enable-flatpak-portal }
# The "reserve-device" module needs to be loaded for reservation to work
{ name = libwireplumber-module-reserve-device , type = module, deps = alsa_monitor.alsa.reserve }
{ name = monitors/alsa.lua, type = script/lua }
{ name = monitors/alsa-midi.lua, type = script/lua, deps = alsa_monitor.alsa.midi }
{ name = libwireplumber-module-file-monitor-api, type = module, deps = alsa_monitor.alsa.midi.monitoring }
{ name = monitors/libcamera.lua, type = script/lua, deps = libcamera_monitor.enable }
{ name = monitors/v4l2.lua, type = script/lua }
# The lua configuration file(s)
# Other components are loaded from there
{ name = main.lua, type = config/lua }
@ -225,9 +241,31 @@ wireplumber.settings = {
}
}
]
# Create a JACK device. This is not enabled by default because
# it requires that the PipeWire JACK replacement libraries are
# not used by the session manager, in order to be able to
# connect to the real JACK server.
# alsa_monitor.alsa.jack-device = false
# Reserve devices via org.freedesktop.ReserveDevice1 on D-Bus
alsa_monitor.alsa.reserve = true
# alsa_monitor.alsa.reserve.priority = -20
# alsa_monitor.alsa.reserve.application-name = WirePlumber
# Enables MIDI functionality
alsa_monitor.alsa.midi = true
alsa_monitor.alsa.monitoring = true
# Enables monitoring of alsa MIDI devices
alsa_monitor.alsa.midi.monitoring = true
# MIDI bridge node properties
monitor.alsa.midi.node-properties = {
# Name set for the node with ALSA MIDI ports
# node.name = "Midi-Bridge"
# Removes longname/number from MIDI port names
# api.alsa.disable-longname = true
},
alsa_monitor = [
{
@ -260,7 +298,7 @@ wireplumber.settings = {
update-props = {
#Use ALSA-Card-Profile devices. They use UCM or the profile
#configuration to configure the device and mixer settings.
api.alsa.use-acp = true,
api.alsa.use-acp = true
#Use UCM instead of profile when available. Can be
#disabled to skip trying to use the UCM profile.
@ -277,10 +315,10 @@ wireplumber.settings = {
#The profile set to use for the device. Usually this is
#"default.conf" but can be changed with a udev rule or here.
#device.profile-set = "profileset-name",
#device.profile-set = "profileset-name"
#The default active profile. Is by default set to "Off".
#device.profile = "default profile name",
#device.profile = "default profile name"
#Automatically select the best profile. This is the
#highest priority available profile. This is disabled
@ -297,6 +335,119 @@ wireplumber.settings = {
}
}
}
{
matches = [
{
# Matches all sources.
node.name = "~alsa_input.*"
}
{
# Matches all sinks.
node.name = "~alsa_output.*"
}
]
actions = {
update-props = {
# node.nick = "My Node"
# priority.driver = 100
# priority.session = 100
# node.pause-on-idle = false
# resample.quality = 4
# channelmix.normalize = false
# channelmix.mix-lfe = false
# audio.channels = 2
# audio.format = "S16LE"
# audio.rate = 44100
# audio.allowed-rates = "3200096000"
# audio.position = "FLFR"
# api.alsa.period-size = 1024
# api.alsa.headroom = 0
# api.alsa.disable-mmap = false
# api.alsa.disable-batch = false
# 0 disables suspend
# session.suspend-timeout-seconds = 5
}
}
}
]
libcamera_monitor.enable = false
libcamera_monitor = [
{
# Rules for matching a device or node. It is an array of
# properties that all need to match the regexp. If any of the
# matches work, the actions are executed for the object.
matches = [
{
# This matches all cards.
device.name = "~libcamera_device.*"
}
]
actions = {
update-props = {
# device.nick = "My Device"
}
}
}
{
matches = [
{
# Matches all sources.
node.name = "~libcamera_input.*"
}
{
# Matches all sinks.
node.name = "~libcamera_output.*"
}
]
actions = {
update-props = {
# node.nick = "My Node"
# priority.driver = 100
# priority.session = 100
# node.pause-on-idle = false
}
}
}
]
v4l2_monitor = [
{
# Rules for matching a device or node. It is an array of
# properties that all need to match the regexp. If any of the
# matches work, the actions are executed for the object.
matches = [
{
# This matches all cards.
device.name = "~v4l2_device.*"
}
]
actions = {
update-props = {
# device.nick = "My Device"
}
}
}
{
matches = [
{
# Matches all sources.
node.name = "~v4l2_input.*"
}
{
# Matches all sinks.
node.name = "~v4l2_output.*"
}
]
actions = {
update-props = {
# node.nick = "My Node"
# priority.driver = 100
# priority.session = 100
# node.pause-on-idle = false
}
}
}
]
}

View file

@ -179,7 +179,8 @@ do_load_components(void *data, const char *location, const char *section,
if (wp_spa_json_object_get (o, "deps", "s", &deps, NULL) && deps) {
gboolean value = 0;
if (!wp_settings_get_boolean (settings, deps, &value) && value) {
gboolean defined = wp_settings_get_boolean (settings, deps, &value);
if ((!defined) || (defined && !value)) {
wp_info ("deps(%s) not met for component(%s), skip loading it",
deps, name);
continue;

View file

@ -5,11 +5,8 @@
--
-- SPDX-License-Identifier: MIT
-- Receive script arguments from config.lua
local config = ... or {}
-- ensure config.properties is not nil
config.properties = config.properties or {}
local config = {}
config.node_properties = Settings.parse_object_safe ("monitor.alsa.midi.node-properties")
SND_PATH = "/dev/snd"
SEQ_NAME = "seq"
@ -21,9 +18,10 @@ fm_plugin = nil
function CreateMidiNode ()
-- Midi properties
local props = {}
if type(config.properties["alsa.midi.node-properties"]) == "table" then
props = config.properties["alsa.midi.node-properties"]
for k, v in pairs(config.node_properties) do
props[k] = v
end
props["factory.name"] = "api.alsa.seq.bridge"
props["node.name"] = props["node.name"] or "Midi-Bridge"

View file

@ -5,44 +5,36 @@
--
-- SPDX-License-Identifier: MIT
-- Receive script arguments from config.lua
local config = ... or {}
-- ensure config.properties is not nil
config.properties = config.properties or {}
local config_settings = {
["alsa.jack-device"] =
Settings.get_boolean ("alsa_monitor.alsa.jack-device"),
["alsa.reserve"] =
Settings.get_boolean ("alsa_monitor.alsa.reserve"),
["alsa.reserve.priority"] =
Settings.get_int ("alsa_monitor.alsa.reserve.priority"),
["alsa.reserve.application-name"] =
Settings.get_string ("alsa_monitor.alsa.reserve.application-name"),
["alsa.midi"] =
Settings.get_boolean ("alsa_monitor.alsa.midi"),
["alsa.midi.monitoring"] =
Settings.get_boolean ("alsa_monitor.alsa.midi.monitoring"),
["vm.node.defaults"] =
Settings.get_string ("alsa_monitor.vm.node.defaults"),
}
-- unique device/node name tables
device_names_table = nil
node_names_table = nil
-- preprocess rules and create Interest objects
for _, r in ipairs(config.rules or {}) do
r.interests = {}
for _, i in ipairs(r.matches) do
local interest_desc = { type = "properties" }
for _, c in ipairs(i) do
c.type = "pw"
table.insert(interest_desc, Constraint(c))
end
local interest = Interest(interest_desc)
table.insert(r.interests, interest)
end
r.matches = nil
end
-- applies properties from config.rules when asked to
function rulesApplyProperties(properties)
for _, r in ipairs(config.rules or {}) do
if r.apply_properties then
for _, interest in ipairs(r.interests) do
if interest:matches(properties) then
for k, v in pairs(r.apply_properties) do
properties[k] = v
end
end
end
local matched, mprops = Settings.apply_rule ("alsa_monitor", properties)
if (matched and mprops) then
for k, v in pairs(mprops) do
properties[k] = v
end
end
end
function nonempty(str)
@ -167,14 +159,14 @@ function createNode(parent, id, obj_type, factory, properties)
end
-- apply VM overrides
local vm_overrides = config.properties["vm.node.defaults"]
local vm_overrides = config_settings["vm.node.defaults"]
if nonempty(Core.get_vm_type()) and type(vm_overrides) == "table" then
for k, v in pairs(vm_overrides) do
properties[k] = v
end
end
-- apply properties from config.rules
-- apply properties from rules defined in JSON .conf file
rulesApplyProperties(properties)
if properties["node.disabled"] then
node_names_table [properties ["node.name"]] = nil
@ -276,7 +268,7 @@ function prepareDevice(parent, id, obj_type, factory, properties)
properties["device.icon-name"] = icon .. "-analog" .. (b and ("-" .. b) or "")
end
-- apply properties from config.rules
-- apply properties from rules defined in JSON .conf file
rulesApplyProperties(properties)
if properties["device.disabled"] then
device_names_table [properties ["device.name"]] = nil
@ -294,9 +286,9 @@ function prepareDevice(parent, id, obj_type, factory, properties)
local rd_name = "Audio" .. properties["api.alsa.card"]
local rd = rd_plugin:call("create-reservation",
rd_name,
config.properties["alsa.reserve.application-name"] or "WirePlumber",
config_settings["alsa.reserve.application-name"] or "WirePlumber",
properties["device.name"],
config.properties["alsa.reserve.priority"] or -20);
config_settings["alsa.reserve.priority"] or -20);
properties["api.dbus.ReserveDevice1"] = rd_name
@ -344,7 +336,7 @@ function prepareDevice(parent, id, obj_type, factory, properties)
end
function createMonitor ()
local m = SpaDevice("api.alsa.enum.udev", config.properties)
local m = SpaDevice("api.alsa.enum.udev", config_settings)
if m == nil then
Log.message("PipeWire's SPA ALSA udev plugin(\"api.alsa.enum.udev\")"
.. "missing or broken. Sound Cards cannot be enumerated")
@ -384,7 +376,7 @@ function createMonitor ()
end
-- create the JACK device (for PipeWire to act as client to a JACK server)
if config.properties["alsa.jack-device"] then
if config_settings["alsa.jack-device"] then
jack_device = Device("spa-device-factory", {
["factory.name"] = "api.jack.device",
["node.name"] = "JACK-Device",
@ -393,7 +385,7 @@ if config.properties["alsa.jack-device"] then
end
-- enable device reservation if requested
if config.properties["alsa.reserve"] then
if config_settings["alsa.reserve"] then
rd_plugin = Plugin.find("reserve-device")
end

View file

@ -5,34 +5,15 @@
--
-- SPDX-License-Identifier: MIT
local config = ... or {}
local config_settings = {}
-- preprocess rules and create Interest objects
for _, r in ipairs(config.rules or {}) do
r.interests = {}
for _, i in ipairs(r.matches) do
local interest_desc = { type = "properties" }
for _, c in ipairs(i) do
c.type = "pw"
table.insert(interest_desc, Constraint(c))
end
local interest = Interest(interest_desc)
table.insert(r.interests, interest)
end
r.matches = nil
end
-- applies properties from config.rules when asked to
-- apply properties from rules defined in JSON .conf file
function rulesApplyProperties(properties)
for _, r in ipairs(config.rules or {}) do
if r.apply_properties then
for _, interest in ipairs(r.interests) do
if interest:matches(properties) then
for k, v in pairs(r.apply_properties) do
properties[k] = v
end
end
end
local matched, mprops = Settings.apply_rule ("libcamera_monitor", properties)
if (matched and mprops) then
for k, v in pairs(mprops) do
properties[k] = v
end
end
end
@ -112,7 +93,7 @@ function createNode(parent, id, type, factory, properties)
properties["priority.session"] = priority
end
-- apply properties from config.rules
-- apply properties from rules defined in JSON .conf file
rulesApplyProperties(properties)
if properties ["node.disabled"] then
return
@ -149,7 +130,7 @@ function createDevice(parent, id, type, factory, properties)
or properties["device.product.name"]
or "Unknown device"
-- apply properties from config.rules
-- apply properties from rules defined in JSON .conf file
rulesApplyProperties(properties)
if properties ["device.disabled"] then
return
@ -165,7 +146,7 @@ function createDevice(parent, id, type, factory, properties)
end
end
monitor = SpaDevice("api.libcamera.enum.manager", config.properties or {})
monitor = SpaDevice("api.libcamera.enum.manager", config_settings or {})
if monitor then
monitor:connect("create-object", createDevice)
monitor:activate(Feature.SpaDevice.ENABLED)

View file

@ -5,34 +5,17 @@
--
-- SPDX-License-Identifier: MIT
local config = ... or {}
local config_settings = {
-- preprocess rules and create Interest objects
for _, r in ipairs(config.rules or {}) do
r.interests = {}
for _, i in ipairs(r.matches) do
local interest_desc = { type = "properties" }
for _, c in ipairs(i) do
c.type = "pw"
table.insert(interest_desc, Constraint(c))
end
local interest = Interest(interest_desc)
table.insert(r.interests, interest)
end
r.matches = nil
end
}
-- applies properties from config.rules when asked to
-- apply properties from rules defined in JSON .conf file
function rulesApplyProperties(properties)
for _, r in ipairs(config.rules or {}) do
if r.apply_properties then
for _, interest in ipairs(r.interests) do
if interest:matches(properties) then
for k, v in pairs(r.apply_properties) do
properties[k] = v
end
end
end
local matched, mprops = Settings.apply_rule ("v4l2_monitor", properties)
if (matched and mprops) then
for k, v in pairs(mprops) do
properties[k] = v
end
end
end
@ -102,7 +85,7 @@ function createNode(parent, id, type, factory, properties)
properties["priority.session"] = 1000 - (tonumber(dev) * 10)
end
-- apply properties from config.rules
-- apply properties from rules defined in JSON .conf file
rulesApplyProperties(properties)
if properties["node.disabled"] then
return
@ -139,7 +122,7 @@ function createDevice(parent, id, type, factory, properties)
or properties["device.product.name"]
or "Unknown device"
-- apply properties from config.rules
-- apply properties from rules defined in JSON .conf file
rulesApplyProperties(properties)
if properties["device.disabled"] then
return
@ -156,7 +139,7 @@ function createDevice(parent, id, type, factory, properties)
end
end
monitor = SpaDevice("api.v4l2.enum.udev", config.properties or {})
monitor = SpaDevice("api.v4l2.enum.udev", config_settings or {})
if monitor then
monitor:connect("create-object", createDevice)
monitor:activate(Feature.SpaDevice.ENABLED)