mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-01-23 17:40:23 +01:00
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.
125 lines
3.8 KiB
Lua
125 lines
3.8 KiB
Lua
-- WirePlumber
|
|
--
|
|
-- Copyright © 2022 Collabora Ltd.
|
|
--
|
|
-- SPDX-License-Identifier: MIT
|
|
--
|
|
-- remove the existing link if needed, check the properties of target, which
|
|
-- indicate it is not available for linking. If no target is available, send
|
|
-- down an error to the corresponding client.
|
|
|
|
lutils = require ("linking-utils")
|
|
cutils = require ("common-utils")
|
|
log = Log.open_topic ("s-linking")
|
|
|
|
SimpleEventHook {
|
|
name = "linking/prepare-link",
|
|
interests = {
|
|
EventInterest {
|
|
Constraint { "event.type", "=", "select-target" },
|
|
},
|
|
},
|
|
execute = function (event)
|
|
local source, _, si, si_props, si_flags, target =
|
|
lutils:unwrap_select_target_event (event)
|
|
|
|
local si_id = si.id
|
|
local reconnect = not cutils.parseBool (si_props ["node.dont-reconnect"])
|
|
local exclusive = cutils.parseBool (si_props ["node.exclusive"])
|
|
local si_must_passthrough = cutils.parseBool (si_props ["item.node.encoded-only"])
|
|
|
|
log:info (si, string.format ("handling item %d: %s (%s)", si_id,
|
|
tostring (si_props ["node.name"]), tostring (si_props ["node.id"])))
|
|
|
|
-- Check if item is linked to proper target, otherwise re-link
|
|
if si_flags.peer_id then
|
|
if target and si_flags.peer_id == target.id then
|
|
log:info (si, "... already linked to proper target")
|
|
|
|
-- Check this also here, in case in default targets changed
|
|
if Settings.get_boolean ("linking.follow-default-target") and
|
|
si_flags.has_node_defined_target then
|
|
lutils.checkFollowDefault (si, target)
|
|
end
|
|
|
|
target = nil
|
|
goto done
|
|
end
|
|
|
|
local link = lutils.lookupLink (si_id, si_flags.peer_id)
|
|
if reconnect then
|
|
if link ~= nil then
|
|
-- remove old link
|
|
if ((link:get_active_features () & Feature.SessionItem.ACTIVE) == 0)
|
|
then
|
|
-- remove also not yet activated links: they might never become
|
|
-- active, and we need not wait for it to become active
|
|
log:warning (link, "Link was not activated before removing")
|
|
end
|
|
si_flags.peer_id = nil
|
|
link:remove ()
|
|
log:info (si, "... moving to new target")
|
|
end
|
|
else
|
|
if link ~= nil then
|
|
log:info (si, "... dont-reconnect, not moving")
|
|
goto done
|
|
end
|
|
end
|
|
end
|
|
|
|
-- if the stream has dont-reconnect and was already linked before,
|
|
-- don't link it to a new target
|
|
if not reconnect and si_flags.was_handled then
|
|
target = nil
|
|
goto done
|
|
end
|
|
|
|
-- check target's availability
|
|
if target then
|
|
local target_is_linked, target_is_exclusive = lutils.isLinked (target)
|
|
if target_is_exclusive then
|
|
log:info (si, "... target is linked exclusively")
|
|
target = nil
|
|
end
|
|
|
|
if target_is_linked then
|
|
if exclusive or si_must_passthrough then
|
|
log:info (si, "... target is already linked, cannot link exclusively")
|
|
target = nil
|
|
else
|
|
-- disable passthrough, we can live without it
|
|
si_flags.can_passthrough = false
|
|
end
|
|
end
|
|
end
|
|
|
|
if not target then
|
|
log:info (si, "... target not found, reconnect:" .. tostring (reconnect))
|
|
|
|
local node = si:get_associated_proxy ("node")
|
|
if reconnect and si_flags.was_handled then
|
|
log:info (si, "... waiting reconnect")
|
|
return
|
|
end
|
|
|
|
local linger = cutils.parseBool (si_props ["node.linger"])
|
|
|
|
if linger then
|
|
log:info (si, "... node linger")
|
|
return
|
|
end
|
|
|
|
lutils.sendClientError (event, node, -2,
|
|
reconnect and "no target node available" or "target not found")
|
|
|
|
if not reconnect then
|
|
log:info (si, "... destroy node")
|
|
node:request_destroy ()
|
|
end
|
|
end
|
|
|
|
::done::
|
|
event:set_data ("target", target)
|
|
end
|
|
}:register ()
|