https://gitlab.freedesktop.org/pipewire/wireplumber/-/commit/c00c5a6675b6640db13111c808eaa3251917c412 From c00c5a6675b6640db13111c808eaa3251917c412 Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Wed, 18 May 2022 10:51:41 -0400 Subject: [PATCH] alsa.lua: fix device name deduplication when reservation is enabled Fixes #241 --- src/scripts/monitors/alsa.lua | 47 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/scripts/monitors/alsa.lua b/src/scripts/monitors/alsa.lua index 01d241db..7beed3a8 100644 --- a/src/scripts/monitors/alsa.lua +++ b/src/scripts/monitors/alsa.lua @@ -11,6 +11,10 @@ local config = ... or {} -- ensure config.properties is not nil config.properties = config.properties or {} +-- 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 = {} @@ -41,16 +45,6 @@ function rulesApplyProperties(properties) end end -function findDuplicate(parent, id, property, value) - for i = 0, id - 1, 1 do - local obj = parent:get_managed_object(i) - if obj and obj.properties[property] == value then - return true - end - end - return false -end - function nonempty(str) return str ~= "" and str or nil end @@ -125,11 +119,11 @@ function createNode(parent, id, type, factory, properties) -- deduplicate nodes with the same name for counter = 2, 99, 1 do - if findDuplicate(parent, id, "node.name", properties["node.name"]) then - properties["node.name"] = name .. "." .. counter - else + if node_names_table[properties["node.name"]] ~= true then + node_names_table[properties["node.name"]] = true break end + properties["node.name"] = name .. "." .. counter end end @@ -186,6 +180,10 @@ function createDevice(parent, id, factory, properties) local device = SpaDevice(factory, properties) if device then device:connect("create-object", createNode) + device:connect("object-removed", function (parent, id) + local node = parent:get_managed_object(id) + node_names_table[node.properties["node.name"]] = nil + end) device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND) parent:store_managed_object(id, device) else @@ -205,11 +203,11 @@ function prepareDevice(parent, id, type, factory, properties) -- deduplicate devices with the same name for counter = 2, 99, 1 do - if findDuplicate(parent, id, "device.name", properties["device.name"]) then - properties["device.name"] = name .. "." .. counter - else + if device_names_table[properties["device.name"]] ~= true then + device_names_table[properties["device.name"]] = true break end + properties["device.name"] = name .. "." .. counter end -- ensure the device has a description @@ -337,16 +335,21 @@ function createMonitor () -- handle create-object to prepare device m:connect("create-object", prepareDevice) - -- if dbus reservation, handle object-removed to destroy device reservations - if rd_plugin then - m:connect("object-removed", function (parent, id) - local device = parent:get_managed_object(id) + -- handle object-removed to destroy device reservations and recycle device name + m:connect("object-removed", function (parent, id) + local device = parent:get_managed_object(id) + if rd_plugin then local rd_name = device.properties["api.dbus.ReserveDevice1"] if rd_name then rd_plugin:call("destroy-reservation", rd_name) end - end) - end + end + device_names_table[device.properties["device.name"]] = nil + end) + + -- reset the name tables to make sure names are recycled + device_names_table = {} + node_names_table = {} -- activate monitor Log.info("Activating ALSA monitor") -- GitLab