summaryrefslogtreecommitdiff
path: root/utils/tuning
diff options
context:
space:
mode:
authorPaul Elder <paul.elder@ideasonboard.com>2022-10-06 20:19:59 +0900
committerPaul Elder <paul.elder@ideasonboard.com>2022-11-25 15:37:44 +0900
commit49dfb9ae43c42558fd6cde49893574c795de0b95 (patch)
tree50fa5bc2a8a7924b7c17659b9ab71f2df10e7cda /utils/tuning
parentf715a75843edece43acc97a64567d656e9c6df44 (diff)
utils: libtuning: parsers: Add raspberrypi parser
Add a parser to libtuning for parsing configuration files that are the same format as raspberrypi's ctt's configuration files. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'utils/tuning')
-rw-r--r--utils/tuning/libtuning/parsers/__init__.py2
-rw-r--r--utils/tuning/libtuning/parsers/raspberrypi_parser.py93
2 files changed, 95 insertions, 0 deletions
diff --git a/utils/tuning/libtuning/parsers/__init__.py b/utils/tuning/libtuning/parsers/__init__.py
index 9ccabb0e..9d20d2fc 100644
--- a/utils/tuning/libtuning/parsers/__init__.py
+++ b/utils/tuning/libtuning/parsers/__init__.py
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022, Paul Elder <paul.elder@ideasonboard.com>
+
+from libtuning.parsers.raspberrypi_parser import RaspberryPiParser
diff --git a/utils/tuning/libtuning/parsers/raspberrypi_parser.py b/utils/tuning/libtuning/parsers/raspberrypi_parser.py
new file mode 100644
index 00000000..d26586ba
--- /dev/null
+++ b/utils/tuning/libtuning/parsers/raspberrypi_parser.py
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2022, Paul Elder <paul.elder@ideasonboard.com>
+#
+# raspberrypi_parser.py - Parser for Raspberry Pi config file format
+
+from .parser import Parser
+
+import json
+import numbers
+
+import libtuning.utils as utils
+
+
+class RaspberryPiParser(Parser):
+ def __init__(self):
+ super().__init__()
+
+ # The string in the 'disable' and 'plot' lists are formatted as
+ # 'rpi.{module_name}'.
+ # @brief Enumerate, as a module, @a listt if its value exists in @a dictt
+ # and it is the name of a valid module in @a modules
+ def _enumerate_rpi_modules(self, listt, dictt, modules):
+ for x in listt:
+ name = x.replace('rpi.', '')
+ if name not in dictt:
+ continue
+ module = utils.get_module_by_typename(modules, name)
+ if module is not None:
+ yield module
+
+ def _valid_macbeth_option(self, value):
+ if not isinstance(value, dict):
+ return False
+
+ if list(value.keys()) != ['small', 'show']:
+ return False
+
+ for val in value.values():
+ if not isinstance(val, numbers.Number):
+ return False
+
+ return True
+
+ def parse(self, config_file: str, modules: list) -> (dict, list):
+ with open(config_file, 'r') as config_json:
+ config = json.load(config_json)
+
+ disable = []
+ for module in self._enumerate_rpi_modules(config['disable'], config, modules):
+ disable.append(module)
+ # Remove the disabled module's config too
+ config.pop(module.name)
+ config.pop('disable')
+
+ # The raspberrypi config format has 'plot' map to a list of module
+ # names which should be plotted. libtuning has each module contain the
+ # plot information in itself so do this conversion.
+
+ for module in self._enumerate_rpi_modules(config['plot'], config, modules):
+ # It's fine to set the value of a potentially disabled module, as
+ # the object still exists at this point
+ module.appendValue('debug', 'plot')
+ config.pop('plot')
+
+ # Convert the keys from module name to module instance
+
+ new_config = {}
+
+ for module_name in config:
+ module = utils.get_module_by_type_name(modules, module_name)
+ if module is not None:
+ new_config[module] = config[module_name]
+
+ new_config['general'] = {}
+
+ if 'blacklevel' in config:
+ if not isinstance(config['blacklevel'], numbers.Number):
+ raise TypeError('Config "blacklevel" must be a number')
+ # Raspberry Pi's ctt config has magic blacklevel value -1 to mean
+ # "get it from the image metadata". Since we already do that in
+ # Image, don't save it to the config here.
+ if config['blacklevel'] >= 0:
+ new_config['general']['blacklevel'] = config['blacklevel']
+
+ if 'macbeth' in config:
+ if not self._valid_macbeth_option(config['macbeth']):
+ raise TypeError('Config "macbeth" must be a dict: {"small": number, "show": number}')
+ new_config['general']['macbeth'] = config['macbeth']
+ else:
+ new_config['general']['macbeth'] = {'small': 0, 'show': 0}
+
+ return new_config, disable