endpoints: Switch endpoints config to JSON

- Move the endpoints defination to wireplumber.conf under a new section
  in the form of two JSON objects, namely endpoints and
  endpoints-roles.
- Treat the endpoint objects as settings, for the sake of loading,
  parsing and querying.
- m-settings loads the objects and WpSettings parses them as any other
  settings.
- Make the following changes in endpoint scripts.
   - Get the endpoint settings using the _get_string() API.
   - Parse and use the data.
   - Remove references to the config/lua
- Remove the endpoints defination in config/lua
This commit is contained in:
Ashok Sidipotu 2022-05-19 06:02:22 +05:30 committed by Julian Bouzas
parent ff3b5fe828
commit 2f60077460
6 changed files with 144 additions and 110 deletions

View file

@ -146,10 +146,10 @@ do_parse_settings (void *data, const char *location,
g_auto (GValue) item = G_VALUE_INIT;
if (!wp_spa_json_is_object (json)) {
/* "wireplumber.settings" section has to be a JSON object element. */
/* section has to be a JSON object element. */
wp_transition_return_error (transition, g_error_new (
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
"failed to parse \"wireplumber.settings\" settings cannot be loaded"));
"failed to parse the section"));
return -EINVAL;
}
@ -186,6 +186,12 @@ do_parse_settings (void *data, const char *location,
return 0;
}
static int
do_parse_endpoints (void *data, const char *location,
const char *section, const char *str, size_t len)
{
do_parse_settings (data, location, section, str, len);
}
static void
on_metadata_activated (WpMetadata * m, GAsyncResult * res, gpointer user_data)
@ -230,6 +236,22 @@ on_metadata_activated (WpMetadata * m, GAsyncResult * res, gpointer user_data)
return;
}
if (pw_context_conf_section_for_each (pw_ctx, "wireplumber.endpoints",
do_parse_endpoints, &data) < 0)
return;
if (data.count == 0) {
/*
* either the "wireplumber.endpoints" is not found or not defined as a
* valid JSON object element.
*/
wp_transition_return_error (transition, g_error_new (
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
"No endpoints present in the context conf file: endpoints "
"are not loaded"));
return;
}
if (!self->use_persistent_storage) {
/* use parsed settings from .conf file */

View file

@ -1,95 +0,0 @@
-- uncomment to enable role-based endpoints
-- this is not yet ready for desktop use
--
--[[
default_policy.policy.roles = {
["Capture"] = {
["alias"] = { "Multimedia", "Music", "Voice", "Capture" },
["priority"] = 25,
["action.default"] = "cork",
["action.capture"] = "mix",
["media.class"] = "Audio/Source",
},
["Multimedia"] = {
["alias"] = { "Movie", "Music", "Game" },
["priority"] = 25,
["action.default"] = "cork",
},
["Speech-Low"] = {
["priority"] = 30,
["action.default"] = "cork",
["action.Speech-Low"] = "mix",
},
["Custom-Low"] = {
["priority"] = 35,
["action.default"] = "cork",
["action.Custom-Low"] = "mix",
},
["Navigation"] = {
["priority"] = 50,
["action.default"] = "duck",
["action.Navigation"] = "mix",
},
["Speech-High"] = {
["priority"] = 60,
["action.default"] = "cork",
["action.Speech-High"] = "mix",
},
["Custom-High"] = {
["priority"] = 65,
["action.default"] = "cork",
["action.Custom-High"] = "mix",
},
["Communication"] = {
["priority"] = 75,
["action.default"] = "cork",
["action.Communication"] = "mix",
},
["Emergency"] = {
["alias"] = { "Alert" },
["priority"] = 99,
["action.default"] = "cork",
["action.Emergency"] = "mix",
},
}
default_policy.endpoints = {
["endpoint.capture"] = {
["media.class"] = "Audio/Source",
["role"] = "Capture",
},
["endpoint.multimedia"] = {
["media.class"] = "Audio/Sink",
["role"] = "Multimedia",
},
["endpoint.speech_low"] = {
["media.class"] = "Audio/Sink",
["role"] = "Speech-Low",
},
["endpoint.custom_low"] = {
["media.class"] = "Audio/Sink",
["role"] = "Custom-Low",
},
["endpoint.navigation"] = {
["media.class"] = "Audio/Sink",
["role"] = "Navigation",
},
["endpoint.speech_high"] = {
["media.class"] = "Audio/Sink",
["role"] = "Speech-High",
},
["endpoint.custom_high"] = {
["media.class"] = "Audio/Sink",
["role"] = "Custom-High",
},
["endpoint.communication"] = {
["media.class"] = "Audio/Sink",
["role"] = "Communication",
},
["endpoint.emergency"] = {
["media.class"] = "Audio/Sink",
["role"] = "Emergency",
},
}
]]--

View file

@ -141,3 +141,95 @@ wireplumber.settings = {
persistent.settings = false
}
wireplumber.endpoints = {
# endpoints = {
# endpoint.capture = {
# media.class = "Audio/Source"
# role = "Capture"
# }
# endpoint.multimedia = {
# media.class = "Audio/Sink"
# role = "Multimedia"
# }
# endpoint.speech_low = {
# media.class = "Audio/Sink"
# role = "Speech-Low"
# }
# endpoint.custom_low = {
# media.class = "Audio/Sink"
# role = "Custom-Low"
# }
# endpoint.navigation = {
# media.class = "Audio/Sink"
# role = "Navigation"
# }
# endpoint.speech_high = {
# media.class = "Audio/Sink"
# role = "Speech-High"
# }
# endpoint.custom_high = {
# media.class = "Audio/Sink"
# role = "Custom-High"
# }
# endpoint.communication = {
# media.class = "Audio/Sink"
# role = "Communication"
# }
# endpoint.emergency = {
# media.class = "Audio/Sink"
# role = "Emergency"
# }
# }
# endpoints-roles = {
# Capture = {
# alias = [ "Multimedia", "Music", "Voice", "Capture" ]
# priority = 25
# action.default = "cork"
# action.capture = "mix"
# media.class = "Audio/Source"
# }
# Multimedia = {
# alias = [ "Movie" "Music" "Game" ]
# priority = 25
# action.default = "cork"
# }
# Speech-Low = {
# priority = 30
# action.default = "cork"
# action.Speech-Low = "mix"
# }
# Custom-Low = {
# priority = 35
# action.default = "cork"
# action.Custom-Low = "mix"
# }
# Navigation = {
# priority = 50
# action.default = "duck"
# action.Navigation = "mix"
# }
# Speech-High = {
# priority = 60
# action.default = "cork"
# action.Speech-High = "mix"
# }
# Custom-High = {
# priority = 65
# action.default = "cork"
# action.Custom-High = "mix"
# }
# Communication = {
# priority = 75
# action.default = "cork"
# action.Communication = "mix"
# }
# Emergency = {
# alias = [ "Alert" ]
# priority = 99
# action.default = "cork"
# action.Emergency = "mix"
# }
# }
}

View file

@ -6,12 +6,18 @@
-- SPDX-License-Identifier: MIT
local config = ... or {}
config.roles = config.roles or {}
local roles = {}
config["duck.level"] = config["duck.level"] or 0.3
local endpoint_roles_setting = Settings.get_string ("endpoints-roles")
if endpoint_roles_setting then
json = Json.Raw (endpoint_roles_setting)
roles = json:parse ()
end
function findRole(role)
if role and not config.roles[role] then
for r, p in pairs(config.roles) do
if role and not roles[role] then
for r, p in pairs(roles) do
if type(p.alias) == "table" then
for i = 1, #(p.alias), 1 do
if role == p.alias[i] then
@ -25,17 +31,17 @@ function findRole(role)
end
function priorityForRole(role)
local r = role and config.roles[role] or nil
local r = role and roles[role] or nil
return r and r.priority or 0
end
function getAction(dominant_role, other_role)
-- default to "mix" if the role is not configured
if not dominant_role or not config.roles[dominant_role] then
if not dominant_role or not roles[dominant_role] then
return "mix"
end
local role_config = config.roles[dominant_role]
local role_config = roles[dominant_role]
return role_config["action." .. other_role]
or role_config["action.default"]
or "mix"

View file

@ -6,8 +6,12 @@
-- SPDX-License-Identifier: MIT
-- Receive script arguments from config.lua
local config = ... or {}
config.roles = config.roles or {}
local roles = {}
local endpoint_roles_setting = Settings.get_string ("endpoints-roles")
if endpoint_roles_setting then
json = Json.Raw (endpoint_roles_setting)
roles = json:parse ()
end
local self = {}
self.scanning = false
@ -38,9 +42,9 @@ function scheduleRescan ()
end
function findRole(role, tmc)
if role and not config.roles[role] then
if role and not roles[role] then
-- find the role with matching alias
for r, p in pairs(config.roles) do
for r, p in pairs(roles) do
-- default media class can be overridden in the role config data
mc = p["media.class"] or "Audio/Sink"
if (type(p.alias) == "table" and tmc == mc) then
@ -55,7 +59,7 @@ function findRole(role, tmc)
-- otherwise get the lowest priority role
local lowest_priority_p = nil
local lowest_priority_r = nil
for r, p in pairs(config.roles) do
for r, p in pairs(roles) do
mc = p["media.class"] or "Audio/Sink"
if tmc == mc and (lowest_priority_p == nil or
p.priority < lowest_priority_p.priority) then

View file

@ -6,7 +6,12 @@
-- SPDX-License-Identifier: MIT
-- Receive script arguments from config.lua
local endpoints_config = ...
local endpoints = {}
local endpoint_setting = Settings.get_string ("endpoints")
if endpoint_setting then
json = Json.Raw (endpoint_setting)
endpoints = json:parse ()
end
function createEndpoint (factory_name, properties)
-- create endpoint
@ -30,7 +35,7 @@ function createEndpoint (factory_name, properties)
end
for name, properties in pairs(endpoints_config) do
for name, properties in pairs(endpoints) do
properties["name"] = name
createEndpoint ("si-audio-endpoint", properties)
end