Files
wireplumber/src/scripts/create-item.lua
George Kiagiadakis e76c67c45c policy: refactor/improve policy-node & session items to fix linking to monitors
* populate most session item properties from create-item.lua to keep
  things more compact and readable
* use a standard naming scheme for the session item properties
* use session item properties instead of node properties in policy-node.lua
* improve policy-node's performance by converting the properties dictionary
  less times for each session item
* refactor some policy logic and make things slighly more readable
* change the accepted values for 'context' in wp_si_linkable_get_ports();
  use "input" and "output" to keep things clear, because the previous use
  of NULL and "reverse" were implying that a node has only one "standard"
  direction, but this is complicated for sinks w/ monitors and duplex nodes
* allow using monitors (which are Audio/Sink nodes in fact) as sources
* treat Audio/Duplex nodes as sinks, like p-m-s does
* respect the "stream.capture.sink" property of streams

Fixes #66
2021-10-08 00:26:41 +03:00

109 lines
2.7 KiB
Lua

-- WirePlumber
--
-- Copyright © 2021 Collabora Ltd.
-- @author Julian Bouzas <julian.bouzas@collabora.com>
--
-- SPDX-License-Identifier: MIT
-- Receive script arguments from config.lua
local config = ...
items = {}
function configProperties(node)
local np = node.properties
local properties = {
["item.node"] = node,
["item.plugged.usec"] = GLib.get_monotonic_time(),
["item.features.no-dsp"] = config["audio.no-dsp"],
["item.features.monitor"] = true,
["item.features.control-port"] = false,
["node.id"] = node["bound-id"],
["client.id"] = np["client.id"],
["object.path"] = np["object.path"],
}
for k, v in pairs(np) do
if k:find("^node") or k:find("^stream") or k:find("^media") then
properties[k] = v
end
end
local media_class = properties["media.class"] or ""
if not properties["media.type"] then
for _, i in ipairs({ "Audio", "Video", "Midi" }) do
if media_class:find(i) then
properties["media.type"] = i
break
end
end
end
properties["item.node.type"] =
media_class:find("^Stream/") and "stream" or "device"
if media_class:find("Sink") or
media_class:find("Input") or
media_class:find("Duplex") then
properties["item.node.direction"] = "input"
elseif media_class:find("Source") or media_class:find("Output") then
properties["item.node.direction"] = "output"
end
return properties
end
function addItem (node, item_type)
local id = node["bound-id"]
-- create item
items[id] = SessionItem ( item_type )
-- configure item
if not items[id]:configure(configProperties(node)) then
Log.warning(items[id], "failed to configure item for node " .. tostring(id))
return
end
-- activate item
items[id]:activate (Features.ALL, function (item)
Log.info(item, "activated item for node " .. tostring(id))
item:register ()
end)
end
nodes_om = ObjectManager {
Interest {
type = "node",
Constraint { "media.class", "#", "Stream/*", type = "pw-global" },
},
Interest {
type = "node",
Constraint { "media.class", "#", "Video/*", type = "pw-global" },
},
Interest {
type = "node",
Constraint { "media.class", "#", "Audio/*", type = "pw-global" },
Constraint { "wireplumber.is-endpoint", "-", type = "pw" },
},
}
nodes_om:connect("object-added", function (om, node)
local media_class = node.properties['media.class']
if string.find (media_class, "Audio") then
addItem (node, "si-audio-adapter")
else
addItem (node, "si-node")
end
end)
nodes_om:connect("object-removed", function (om, node)
local id = node["bound-id"]
if items[id] then
items[id]:remove ()
items[id] = nil
end
end)
nodes_om:activate()