From patchwork Thu Nov 24 11:35:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 17873 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 9A9A0BDE6B for ; Thu, 24 Nov 2022 11:36:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5CB106331A; Thu, 24 Nov 2022 12:36:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669289777; bh=9o/V3AcCFQQCjFd7DyXHh3v+yATuP0jJdvr8p2re2wE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=EpWfrbgLRJIs3tXqcZKzhUkA//hULHWLO7A+wEK0RCiJaVw8Aj8G9GynzFLO3WTRg 0emnsBzvzPySZsr4EOQRyq1Q2ZomIxBptL7kePLA/7ZUqprvnu40aYbpd9AggRFwS/ oFRNLEFcuDmnHVLZV5tLUoX7FeLxWLBqhQm4g5IsYexVwtgM3ETarVpJvMu2wGuxhs BS6FhN0Y1eGZJyrRXH1aMzraRXOhwVX0Fqq1/U7oBESBokXbKm18vHiFRu+9h6Nmd3 fmyl1fqclruwb6ZVWHy8cPFaA12RsE4ro556xkvNbAE92p3/RY5h/Zwj8aGDHka9Dg 5HjcoTGbdCghA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DDEA06331C for ; Thu, 24 Nov 2022 12:36:14 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="bnYXQ8NC"; dkim-atps=neutral Received: from pyrite.tail37cf.ts.net (h175-177-042-159.catv02.itscom.jp [175.177.42.159]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5AFE1BC0; Thu, 24 Nov 2022 12:36:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1669289774; bh=9o/V3AcCFQQCjFd7DyXHh3v+yATuP0jJdvr8p2re2wE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bnYXQ8NC9joMcHGrXKlNkHKDunjmwz1qIeY8I5llwsMvWmxxjxGCqNYHNzmwSOLKP bxc63AEmd9a00TGXe+AGzeOK9E4Ly1LLHAmdrs8+pSR6h/qUuwrO3enqCyikjW9bRw 4yDAaCZ4No2wTooYK0ao/EGYdH7CzW8kxHyXKbo8= To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Nov 2022 20:35:45 +0900 Message-Id: <20221124113550.2182342-8-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221124113550.2182342-1-paul.elder@ideasonboard.com> References: <20221124113550.2182342-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 07/12] utils: libtuning: parsers: Add raspberrypi parser X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Paul Elder via libcamera-devel From: Paul Elder Reply-To: Paul Elder Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Reviewed-by: Laurent Pinchart --- Changes in v3: - style fixes - add file description - remove indirection from fake polymorphism Changes in v2: - fix python errors - fix style - add SPDX and copyright - don't put black level in the processed config, as raspberrypi ctt's config format uses -1 as a magical value to tell ctt to use the value from the image, but in our Image loading function it already does, and uses this config value to override it if its present - Don't validate module config in parser, instead libtuning will do it; parser just converts the key from string to module instance --- utils/tuning/libtuning/parsers/__init__.py | 5 + .../libtuning/parsers/raspberrypi_parser.py | 93 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 utils/tuning/libtuning/parsers/raspberrypi_parser.py diff --git a/utils/tuning/libtuning/parsers/__init__.py b/utils/tuning/libtuning/parsers/__init__.py index e69de29b..9d20d2fc 100644 --- a/utils/tuning/libtuning/parsers/__init__.py +++ b/utils/tuning/libtuning/parsers/__init__.py @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2022, Paul Elder + +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 +# +# 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