docs: add documentation on device, default-nodes and linking scripts

This commit is contained in:
George Kiagiadakis
2023-09-29 16:14:08 +03:00
parent 493be2fae6
commit 2f89c64b7f
10 changed files with 238 additions and 0 deletions

View File

@@ -27,6 +27,12 @@ Table of Contents
c_api.rst
lua_api.rst
.. toctree::
:maxdepth: 2
:caption: Scripting
scripts/existing_scripts.rst
.. toctree::
:maxdepth: 2
:caption: Resources

View File

@@ -17,3 +17,4 @@ subdir('c_api')
subdir('lua_api')
subdir('configuration')
subdir('design')
subdir('scripts')

View File

@@ -0,0 +1,3 @@
.. _default_nodes_scripts:
.. include:: ../../../src/scripts/default-nodes/README.rst

View File

@@ -0,0 +1,3 @@
.. _device_scripts:
.. include:: ../../../src/scripts/device/README.rst

View File

@@ -0,0 +1,15 @@
.. _existing_scripts:
Existing Scripts
================
This section documents all the existing lua scripts that are shipped with
WirePlumber, including information on the hooks that they provide and
information on how to extend the logic with additional custom scripts & hooks.
.. toctree::
:maxdepth: 1
default_nodes.rst
device.rst
linking.rst

View File

@@ -0,0 +1,3 @@
.. _linking_scripts:
.. include:: ../../../src/scripts/linking/README.rst

View File

@@ -0,0 +1,10 @@
# you need to add here any files you add to the toc directory as well
sphinx_files += files(
'existing_scripts.rst',
'default_nodes.rst',
meson.current_source_dir()/'..'/'..'/'..'/'src'/'scripts'/'default-nodes'/'README.rst',
'device.rst',
meson.current_source_dir()/'..'/'..'/'..'/'src'/'scripts'/'device'/'README.rst',
'linking.rst',
meson.current_source_dir()/'..'/'..'/'..'/'src'/'scripts'/'linking'/'README.rst',
)

View File

@@ -0,0 +1,76 @@
Default Nodes Scripts
=====================
These scripts contain logic to select default source and sink nodes and also
manage user preferences regarding those.
Hooks
-----
Management of the default source and sink nodes is implemented by scanning all
the available nodes in the graph and assigning them a priority based on certain
logic. The node with the highest priority in each category becomes the default.
Scanning is implemented using a "rescan-for-default-nodes" event.
The "default-nodes/rescan-trigger" hook is the one that monitors graph changes
and schedules "rescan-for-default-nodes". Then, the "default-nodes/rescan"
hook is executed for the "rescan-for-default-nodes" event and it pushes a
"select-default-node" event for each one of the categories where a default node
is required:
- Audio sink
- Audio source
- Video source
.. csv-table:: Hooks triggered by changes in the graph
:header: "Hook name", "File", "Triggered by", "Action"
"default-nodes/rescan-trigger", "rescan.lua", "linkables added/removed or default.configured.* metadata changed", "schedule rescan-for-default-nodes"
"default-nodes/store-configured-default-nodes", "state-default-nodes.lua", "default.configured.* metadata changed", "stores user selections in the state file"
"default-nodes/metadata-added", "state-default-nodes.lua", "metadata object created", "restores default.configured.* values from the state file"
.. csv-table:: Hooks for the rescan-for-default-nodes event, in order of execution
:header: "Hook name", "File", "Description"
"m-standard-event-source/rescan-done", "module-standard-event-source.c", "clears the rescan_scheduled flag"
"default-nodes/rescan", "rescan.lua", "schedules select-default-node for each category"
.. csv-table:: Hooks for the select-default-node event, in order of execution
:header: "Hook name", "File", "Description"
"default-nodes/find-best-default-node", "find-best-default-node.lua", "prioritizes nodes based on their 'priority.session' property"
"default-nodes/find-selected-default-node", "find-selected-default-node.lua", "prioritizes the current 'default.configured.*' node, i.e. the current user selection"
"default-nodes/find-stored-default-node", "state-default-nodes.lua", "prioritizes past user selections from the state file"
"default-nodes/apply-default-node", "apply-default-node.lua", "sets the highest priority selected node as the default in the metadata"
.. note::
The actual order of the "default-nodes/find-\*" hooks is not defined and doesn't matter.
The only thing that matters is that "default-nodes/apply-default-node" is the last hook.
select-default-node event
-------------------------
High priority event to select the default node for a given category
(media.type & direction combination).
In this event, each hook is tasked to find the highest priority node of the
category it runs for. In order to do that, a list of available nodes is
calculated in advance, by the "default-nodes/rescan" hook, and passed on to
each of the "select-default-node" hooks via event data. Each hook then has
to go through this list and select a node, placing it in the "selected-node"
event data together with its priority number in "selected-node-priority".
The next hook, then, may override the "selected-node" and "selected-node-priority"
with something else, but only if the new priority is higher than the old one.
.. csv-table:: Event properties
:header: "Property name", "Description"
"default-node.type", "the suffix of the metadata keys related to this default node ('audio.sink', 'audio.source' or 'video.source')"
.. csv-table:: Exchanged event data
:header: "Name", "Description"
"available-nodes", "JSON array of all selectable nodes, with each element containing all node properties"
"selected-node", "the selected node's 'node.name' (string)"
"selected-node-priority", "the priority (integer)"

View File

@@ -0,0 +1,71 @@
Device Profile/Route Management Scripts
=======================================
These scripts are tasked to select appropriate profiles and routes for each
device.
Hooks
-----
.. csv-table:: Hooks triggered by changes in the graph
:header: "Hook name", "File", "Triggered by", "Action"
"device/select-profile", "select-profile.lua", "device added or EnumProfiles changed", "schedules a 'select-profile' event"
"device/select-route", "select-routes.lua", "device added or EnumRoute changed", "updates the device info cache with the latest routes and schedules a 'select-routes' event, if needed"
"device/store-user-selected-profile", "select-profile.lua", "device Profile param changed", "stores profile into the state file if it was selected by the user (profile.save == true)"
"device/store-or-restore-routes", "select-routes.lua", "device Route param changed", "stores or restores Route selections based on the current state; may push a 'select-routes' event to update properties"
.. csv-table:: Hooks for the select-profile event, in order of execution
:header: "Hook name", "File", "Description"
"device/find-stored-profile", "state-profile.lua", "selects the profile that has been stored in the state file (user's explicit selection)"
"device/find-best-profile", "find-best-profile.lua", "finds the best profile for a device based on profile priorities and availability"
"device/apply-profile", "apply-profile.lua", "applies the selected profile to the device"
.. csv-table:: Hooks for the select-routes event, in order of execution
:header: "Hook name", "File", "Description"
"device/find-stored-routes", "state-routes.lua", "restores routes selection for a newly selected profile"
"device/find-best-routes", "find-best-routes.lua", "finds the best routes based on availability and priority"
"device/apply-route-props", "state-routes.lua", "augments the selected routes to include properties stored in the state file (volume, channel map, codecs, ...)"
"device/apply-routes", "apply-routes.lua", "applies the selected routes to the device"
select-profile event
--------------------
High priority event to select a profile for a given device. The event hooks
must also apply the profile.
The event "subject" is the device (`WpDevice`) object.
This event has no special properties.
.. csv-table:: Exchanged event data
:header: "Name", "Description"
"selected-profile", "The selected profile to be set:
- Type: string, containing a JSON object
- The JSON object should contain the properties of the Profile param"
select-routes event
-------------------
High priority event to select routes for a given profile. The event hooks
must also apply the routes.
The event "subject" is the device (`WpDevice`) object.
.. csv-table:: Event Properties
:header: "Property name", "Description"
"profile.changed", "true if a new profile has been selected / false if only the available routes changed"
"profile.name", "the active profile's name"
"profile.active-device-ids", "json array of integers containing the active device IDs for which to select routes"
.. csv-table:: Exchanged event data
:header: "Name", "Description"
"selected-routes", "The selected routes to be set:
- Type: map<string, string>
- The keys are device IDs (as represented in EnumRoute)
- The values are JSON objects like this: { index: <a route index>, props: { <object with route props> } }"

View File

@@ -0,0 +1,50 @@
Linking Scripts
===============
These scripts contain all the logic for creating links between nodes.
This involves, to a large extent, deciding which links to create.
Hooks
-----
The hooks in this section are organized in 3 sub-categories. The first category
includes hooks that are triggered by changes in the graph. Some of them are tasked
to schedule a "rescan-for-linking" event, which is the lowest priority event and
its purpose is to scan through all the linkable session items and link them
to a particular target. The "rescan-for-linking" event is always scheduled to run
once for all the graph changes in a cycle. This is achieved by flagging the event
as already scheduled in the module-standard-event-source; this flag is then cleared
by a hook that runs on this event.
Selecting a target for each linkable and linking to it is deferred to another
set of hooks by pushing a "select-target" event for each linkable. This event
is the highest priority event and therefore no other changes in the graph are
processed while targets are being selected.
.. csv-table:: Hooks triggered by changes in the graph
:header: "Hook name", "File", "Triggered by", "Action"
"linking/rescan-trigger", "rescan.lua", "linkable SI added|removed", "schedules rescan-for-linking event"
"linking/linkable-removed", "rescan.lua", "linkable SI removed", "destroys links related to the removed linkable"
"linking/follow", "move-follow.lua", "metadata-changed", "schedules rescan-for-linking when the configured default sources/sinks are changed by the user"
"linking/move", "move-follow.lua", "metadata-changed", "schedules rescan-for-linking when node target metadata properties are changed"
"linking/filter-forward-format", "filter-forward-format.lua", "filter stream SI added", "configures filter nodes to have the same port format on both ends"
"linking/rescan-virtual-links", "rescan-virtual-links.lua", "link SI added, removed or metadata-changed", ""
.. csv-table:: rescan-for-linking hooks, in order of execution
:header: "Hook name", "File", "Description"
"m-standard-event-source/rescan-done", "module-standard-event-source.c", "clears the rescan_scheduled flag"
"linking/rescan", "rescan.lua", "schedules select-target for each linkable session item"
.. csv-table:: select-target hooks, in order of execution
:header: "Hook name", "File", "Description"
"linking/find-virtual-target", "find-virtual-target.lua", ""
"linking/find-defined-target", "find-defined-target.lua", "Select the target that has been defined explicitly by the 'target.object' property or metadata"
"linking/find-filter-target", "find-filter-target.lua", "Select the target of a filter node, if the subject is a filter node"
"linking/find-default-target", "find-default-target.lua", "Select the default source/sink as target"
"linking/find-best-target", "find-best-target.lua", "Select target based on priority.session"
"linking/get-filter-from-target", "get-filter-from-target.lua", "Translate the found target to a filter target that should be linked instead"
"linking/prepare-link", "prepare-link.lua", "Break existing link if needed, check if the target is available for linking; send error to the client if needed"
"linking/link-target", "link-target.lua", "Create si-standard-link session item to create links between the subject linkable and the selected target"