From patchwork Fri Dec 6 17:11:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22238 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 A15C1BF415 for ; Fri, 6 Dec 2024 17:12:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 58C4767E31; Fri, 6 Dec 2024 18:12:10 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Tvdu30Z+"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 15CBF67E2E for ; Fri, 6 Dec 2024 18:12:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505128; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BI2JaovvG1AieDShyGbTYCJiB7HQNCBzSXvUx4xWhwE=; b=Tvdu30Z+pL47H9qeLT164yy9CpM2c2gra/F8oW5GN0lp0zG9UAgXTg4D0A9NuTJTFAxzJv MjpR9IF0SwrbqOjiregt/kwo8kSAnR3MVyOMiIW7pmiyXJRElBCD+l1IVmvmCpozEUg+lP IJEibLLbd9iUAVQ0v9oC5pHKrFSMFIg= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-128-Nv8ANi8KP9SIa9m0yXmiHg-1; Fri, 06 Dec 2024 12:12:06 -0500 X-MC-Unique: Nv8ANi8KP9SIa9m0yXmiHg-1 X-Mimecast-MFC-AGG-ID: Nv8ANi8KP9SIa9m0yXmiHg Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 93E201955D88; Fri, 6 Dec 2024 17:12:04 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1D8C8300019E; Fri, 6 Dec 2024 17:12:01 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 01/16] yaml: Move yaml_parser.cpp to base Date: Fri, 6 Dec 2024 18:11:32 +0100 Message-ID: <20241206171148.1189292-2-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: QOpOFrbgMy1BJzzhWrIvTNyqUOuW9NJfWRJWETwJmX8_1733505125 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Global configuration, which uses the YAML parser, will be in base. Thus YAML parser must be moved to base too. Indentation is changed in one place of the moved file to make the autoformatter and checkstyle.py happy. Signed-off-by: Milan Zamazal --- src/libcamera/base/meson.build | 14 ++++++++++++++ src/libcamera/{ => base}/yaml_parser.cpp | 13 ++++++------- src/libcamera/meson.build | 14 -------------- 3 files changed, 20 insertions(+), 21 deletions(-) rename src/libcamera/{ => base}/yaml_parser.cpp (98%) diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build index a742dfdf..94843eb9 100644 --- a/src/libcamera/base/meson.build +++ b/src/libcamera/base/meson.build @@ -24,10 +24,12 @@ libcamera_base_internal_sources = files([ 'thread.cpp', 'timer.cpp', 'utils.cpp', + 'yaml_parser.cpp', ]) libdw = dependency('libdw', required : false) libunwind = dependency('libunwind', required : false) +libyaml = dependency('yaml-0.1', required : false) if cc.has_header_symbol('execinfo.h', 'backtrace') config_h.set('HAVE_BACKTRACE', 1) @@ -41,11 +43,23 @@ if libunwind.found() config_h.set('HAVE_UNWIND', 1) endif +# Fallback to a subproject if libyaml isn't found, as it's not packaged in AOSP. +if not libyaml.found() + cmake = import('cmake') + + libyaml_vars = cmake.subproject_options() + libyaml_vars.add_cmake_defines({'CMAKE_POSITION_INDEPENDENT_CODE': 'ON'}) + libyaml_vars.append_compile_args('c', '-Wno-unused-value') + libyaml_wrap = cmake.subproject('libyaml', options : libyaml_vars) + libyaml = libyaml_wrap.dependency('yaml') +endif + libcamera_base_deps = [ libatomic, libdw, libthreads, libunwind, + libyaml, ] # Internal components must use the libcamera_base_private dependency to enable diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/base/yaml_parser.cpp similarity index 98% rename from src/libcamera/yaml_parser.cpp rename to src/libcamera/base/yaml_parser.cpp index 5ca5fb82..ea5dc45d 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/base/yaml_parser.cpp @@ -149,13 +149,12 @@ YamlObject::Getter::get(const YamlObject &obj) const template struct YamlObject::Getter || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v>> -{ + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v>> { std::optional get(const YamlObject &obj) const { if (obj.type_ != Type::Value) diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 57fde8a8..c2d112a9 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -53,7 +53,6 @@ libcamera_internal_sources = files([ 'v4l2_pixelformat.cpp', 'v4l2_subdevice.cpp', 'v4l2_videodevice.cpp', - 'yaml_parser.cpp', ]) includes = [ @@ -81,7 +80,6 @@ if not cc.has_function('dlopen') libdl = cc.find_library('dl') endif libudev = dependency('libudev', required : get_option('udev')) -libyaml = dependency('yaml-0.1', required : false) # Use one of gnutls or libcrypto (provided by OpenSSL), trying gnutls first. libcrypto = dependency('gnutls', required : false) @@ -117,17 +115,6 @@ if libudev.found() ]) endif -# Fallback to a subproject if libyaml isn't found, as it's not packaged in AOSP. -if not libyaml.found() - cmake = import('cmake') - - libyaml_vars = cmake.subproject_options() - libyaml_vars.add_cmake_defines({'CMAKE_POSITION_INDEPENDENT_CODE': 'ON'}) - libyaml_vars.append_compile_args('c', '-Wno-unused-value') - libyaml_wrap = cmake.subproject('libyaml', options : libyaml_vars) - libyaml = libyaml_wrap.dependency('yaml') -endif - control_sources = [] controls_mode_files = { @@ -187,7 +174,6 @@ libcamera_deps += [ libdl, liblttng, libudev, - libyaml, ] # We add '/' to the build_rpath as a 'safe' path to act as a boolean flag. From patchwork Fri Dec 6 17:11:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22241 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 48CDDBF415 for ; Fri, 6 Dec 2024 17:12:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D160F67E3C; Fri, 6 Dec 2024 18:12:24 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="jD97PDCb"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 38B1F67E3A for ; Fri, 6 Dec 2024 18:12:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505139; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eh6pQegfRUUskwr9af99MBjmJpjWpXEmOCINoDvDek4=; b=jD97PDCbPL1JxfeVwY1EdZCN+ORN1D1K02gwo8MdbmLuhwNx6Wo6TshS+Q5dIh69N6ypWl yLOWWEAvZlw/oTm7WX47wGPKSm9v6po+DGalD8eAH6l/yd9xveDNzw1FSoWCkS5J04n2+2 17Ajw/5mgQRm/rwpaN5RKt4+oAZWz3k= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-96-sVP_TstkPdWHdXPvFc-1_Q-1; Fri, 06 Dec 2024 12:12:12 -0500 X-MC-Unique: sVP_TstkPdWHdXPvFc-1_Q-1 X-Mimecast-MFC-AGG-ID: sVP_TstkPdWHdXPvFc-1_Q Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8C2D31954215; Fri, 6 Dec 2024 17:12:07 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2EE31300019E; Fri, 6 Dec 2024 17:12:04 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 02/16] config: Introduce global runtime configuration Date: Fri, 6 Dec 2024 18:11:33 +0100 Message-ID: <20241206171148.1189292-3-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: LljOPA5gioQ4OEkDzZ1Y9YtKOAq0mki8CEVijO5IyGs_1733505127 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Currently, libcamera can be configured in runtime using several environment variables. With introducing more and more variables, this mechanism reaches its limits. It would be simpler and more flexible if it was possible to configure libcamera in a single file. For example, there have been a request for defining pipeline precedence in runtime. We want to compile in multiple pipelines, in order to have them accessible within single packages in distributions. And then being able to select among the pipelines manually as needed based on the particular hardware or operating system environment. Having the configuration file then allows easy switching between hardware, GPU or CPU IPAs. Another possible use case is tuning image output, especially with software ISP, to user liking. For example, some users may prefer higher contrast without the need to use the corresponding knobs, if present at all, in every application. The configuration file can also be used to enable or disable experimental features and avoid the need to track local patches changing configuration options hard-wired in the code when working on new features. This patch introduces basic support for configuration files. It reads, stores and accesses the configuration. The configuration is meant to use as a hidden singleton with public access methods. It is implemented as GlobalConfiguration namespace exposing the public functions, with private functions and the configuration data hidden in an anonymous namespace. This model suits well the purpose of having a hidden singleton wrapped by public access functions. libcamera configuration can be specified using a system-wide configuration file or a user configuration file. The user configuration file takes precedence if present. There is currently no way to merge multiple configuration files, the one found is used as the only configuration file. If no configuration file is present, nothing changes to the current libcamera behavior (except for some log messages related to configuration file lookup). The configuration file is a YAML file. We already have a mechanism for handling YAML configuration files in libcamera and the given infrastructure can be reused for the purpose. However, the configuration type is abstracted to make contingent future change of the underlying class easier while retaining (most of) the original API. The configuration is versioned. This has currently no particular meaning but is likely to have its purpose in future, especially once configuration validation is introduced. The configuration YAML file looks as follows: --- version: 1 configuration: WHATEVER CONFIGURATION NEEDED There is no logging about reading the configuration file and contingent errors. This is on purpose because logging will query configuration, which can lead to various problems when done during configuration initialization. Reporting the errors will be added later. A complication arises from the fact that when the configuration is loaded, logging may be called and logging will ask for the configuration. This is error-prone and may lead to subtle problems. For this reason, the global configuration is instantiated to a pointer, with an empty configuration initially. The real configuration will be created through initialize() method. It will be clearer how it helps in the followup patch introducing logging configuration. Logging is also the most notable component from base that uses global configuration. In order to be able to do it, the global configuration must be put to base. This patch introduces just the basic idea. Actually using the configuration in the corresponding places (everything what is currently configurable via environment variables should be configurable in the file configuration) and other enhancements are implemented in the followup patches. Signed-off-by: Milan Zamazal --- .../libcamera/internal/global_configuration.h | 25 +++ include/libcamera/internal/meson.build | 1 + src/libcamera/base/global_configuration.cpp | 153 ++++++++++++++++++ src/libcamera/base/meson.build | 1 + 4 files changed, 180 insertions(+) create mode 100644 include/libcamera/internal/global_configuration.h create mode 100644 src/libcamera/base/global_configuration.cpp diff --git a/include/libcamera/internal/global_configuration.h b/include/libcamera/internal/global_configuration.h new file mode 100644 index 00000000..bed88279 --- /dev/null +++ b/include/libcamera/internal/global_configuration.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, inc. + * + * Global configuration handling + */ + +#pragma once + +#include "libcamera/internal/yaml_parser.h" + +namespace libcamera { + +namespace GlobalConfiguration { + +using Configuration = const YamlObject &; + +void initialize(); + +unsigned int version(); +Configuration configuration(); + +} /* namespace GlobalConfiguration */ + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 7d6aa8b7..cf1765bf 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -22,6 +22,7 @@ libcamera_internal_headers = files([ 'dma_buf_allocator.h', 'formats.h', 'framebuffer.h', + 'global_configuration.h', 'ipa_data_serializer.h', 'ipa_manager.h', 'ipa_module.h', diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp new file mode 100644 index 00000000..3350a26a --- /dev/null +++ b/src/libcamera/base/global_configuration.cpp @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, inc. + * + * Global configuration handling + */ + +#include "libcamera/internal/global_configuration.h" + +#include +#include + +#include +#include +#include + +#include "libcamera/internal/yaml_parser.h" + +namespace libcamera { + +namespace GlobalConfiguration { + +namespace { + +std::unique_ptr yamlConfiguration = std::make_unique(); + +bool loadFile(const std::filesystem::path &fileName) +{ + File file(fileName); + if (!file.exists()) { + return false; + } + + if (!file.open(File::OpenModeFlag::ReadOnly)) + return true; + + auto root = YamlParser::parse(file); + if (!root) + return true; + yamlConfiguration = std::move(root); + + return true; +} + +const std::vector + globalConfigurationFiles = { + std::filesystem::path(LIBCAMERA_SYSCONF_DIR) / "configuration.yaml", + std::filesystem::path("/etc/libcamera/configuration.yaml"), + }; + +void load() +{ + std::filesystem::path userConfigurationDirectory; + char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME"); + if (xdgConfigHome) { + userConfigurationDirectory = xdgConfigHome; + } else { + const char *home = utils::secure_getenv("HOME"); + if (home) + userConfigurationDirectory = + std::filesystem::path(home) / ".config"; + } + + if (!userConfigurationDirectory.empty()) { + std::filesystem::path user_configuration_file = + userConfigurationDirectory / "libcamera" / "configuration.yaml"; + if (loadFile(user_configuration_file)) + return; + } + + for (const auto &path : globalConfigurationFiles) + if (loadFile(path)) + return; +} + +Configuration get() +{ + return *yamlConfiguration; +} + +} /* namespace */ + +/** + * \brief Initialize the global configuration + * + * This must be called before global configuration is accessed. + */ +void initialize() +{ + load(); +} + +/** + * \namespace GlobalConfiguration + * \brief Support for global libcamera configuration + * + * The configuration file is a YAML file and the configuration itself is stored + * under `configuration' top-level item. + * + * The configuration file is looked up in user's home directory first and if it + * is not found then in system-wide configuration directories. If multiple + * configuration files exist then only the first one found is used and no + * configuration merging is performed. + * + * The configuration can be accessed using GlobalConfiguration::configuration(). + */ + +/** + * \typedef GlobalConfiguration::Configuration + * \brief Type representing global libcamera configuration + * + * All code outside GlobalConfiguration must use this type declaration and not + * the underlying type. + */ + +/** + * \brief Return configuration version + * + * The version is (optionally) declared in the configuration file in the + * top-level section `version', alongside `configuration'. This has currently no + * real use but may be needed in future if configuration incompatibilities + * occur. + * + * \return Configuration version as declared in the configuration file or 0 if + * no version is declared there + */ +unsigned int version() +{ + return get()["version"].get().value_or(0); +} + +/** + * \brief Return libcamera global configuration + * + * This returns the whole configuration stored in the top-level section + * `configuration' of the YAML configuration file. + * + * The requested part of the configuration can be accessed using \a YamlObject + * methods. + * + * \note \a YamlObject type itself shouldn't be used in type declarations to + * avoid trouble if we decide to change the underlying data objects in future. + * + * \return The whole configuration section + */ +Configuration configuration() +{ + return get()["configuration"]; +} + +} /* namespace GlobalConfiguration */ + +} /* namespace libcamera */ diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build index 94843eb9..4c003284 100644 --- a/src/libcamera/base/meson.build +++ b/src/libcamera/base/meson.build @@ -16,6 +16,7 @@ libcamera_base_internal_sources = files([ 'event_dispatcher_poll.cpp', 'event_notifier.cpp', 'file.cpp', + 'global_configuration.cpp', 'log.cpp', 'memfd.cpp', 'message.cpp', From patchwork Fri Dec 6 17:11:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22239 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 9014BBF415 for ; Fri, 6 Dec 2024 17:12:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 424AF67E24; Fri, 6 Dec 2024 18:12:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="OelEYaLl"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 088E467E24 for ; Fri, 6 Dec 2024 18:12:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505136; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SJ4/Qc9xBXXgL2S2k+WsK1wnYxEZpf1H7/XHSnnGZQI=; b=OelEYaLl7RvBMeQHIQVoy+YOlte8si8bYDHS5kKAZECS8l9RUsCKAbvIU1RVmAWWLy4WTU EP1EvFA9qCivvzS9GJOCwmO1ICm3FL6GblfrnZ+ZBXxInEKCub5TxnNA7kGYV3nxKkfdIM wUwHpx4ps+q+TDQ5loiRjLPhKTg/i9E= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-459-CNgGHhDjOkeua58cFbglWQ-1; Fri, 06 Dec 2024 12:12:11 -0500 X-MC-Unique: CNgGHhDjOkeua58cFbglWQ-1 X-Mimecast-MFC-AGG-ID: CNgGHhDjOkeua58cFbglWQ Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9C74619560B6; Fri, 6 Dec 2024 17:12:10 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3154A300019E; Fri, 6 Dec 2024 17:12:07 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 03/16] config: Look up logging levels in the configuration file Date: Fri, 6 Dec 2024 18:11:34 +0100 Message-ID: <20241206171148.1189292-4-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: F2pDMuZCsyHvEgV4K2h_0TqiYgpHJHaQRNLEmKCSIgU_1733505130 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In addition to LIBCAMERA_LOG_LEVELS environment variable, expose the same configuration in the configuration file. Because logging asks for configuration and configuration loading uses logging, extra care is needed. We must prevent calling any log function before configuration is loaded. Otherwise the log function would ask for configuration, it would load the configuration files and would try to log the results. Which can lead to various breakages, even quite subtle; this has been demonstrated in camera_reconfigure test when trying to make the configuration initialization more transparent, as a static variable instance with automatic initialization rather than a pointer with manual initialization() invocation. But we must log at least errors when reading the configuration. Especially, we cannot prevent logging in configuration initialization entirely because the YAML parser may log errors. But in case of an error during configuration initialization, the configuration cannot be read anyway and the statically created initial global configuration instance serves the purpose of providing some, empty configuration. Then the errors from the YAML parser can be logged. We cannot use the same mechanism for other logging in configuration initialization because then logging would read and use the empty configuration, which is not a valid configuration this time, for the whole run of libcamera. The configuration must be initialized, which is done by calling initialize() method in IPAManager constructor. A more suitable place would be CameraManager constructor but it would be too late there, the IPAManager constructor is called earlier. The configuration snippet for logging looks as follows: configuration: log: levels: LIBCAMERA_LOG_LEVELS Signed-off-by: Milan Zamazal --- src/libcamera/base/global_configuration.cpp | 30 ++++++++++++++++++--- src/libcamera/base/log.cpp | 12 +++++++-- src/libcamera/ipa_manager.cpp | 3 +++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp index 3350a26a..8d823b98 100644 --- a/src/libcamera/base/global_configuration.cpp +++ b/src/libcamera/base/global_configuration.cpp @@ -22,8 +22,15 @@ namespace GlobalConfiguration { namespace { +LOG_DEFINE_CATEGORY(Configuration) + std::unique_ptr yamlConfiguration = std::make_unique(); +/* + * Care is needed here to not log anything before the configuration is + * loaded otherwise the logger would be initialized with empty configuration. + */ + bool loadFile(const std::filesystem::path &fileName) { File file(fileName); @@ -31,12 +38,18 @@ bool loadFile(const std::filesystem::path &fileName) return false; } - if (!file.open(File::OpenModeFlag::ReadOnly)) + if (!file.open(File::OpenModeFlag::ReadOnly)) { + LOG(Configuration, Warning) + << "Failed to open configuration file " << fileName; return true; + } auto root = YamlParser::parse(file); - if (!root) + if (!root) { + LOG(Configuration, Warning) + << "Failed to parse configuration file " << fileName; return true; + } yamlConfiguration = std::move(root); return true; @@ -83,7 +96,11 @@ Configuration get() /** * \brief Initialize the global configuration * - * This must be called before global configuration is accessed. + * This function is expected to be called only once, before the configuration is + * queried for the first time. + * + * \note Most notably, the function must be called before any logging, because + * logging queries the configuration. */ void initialize() { @@ -97,6 +114,13 @@ void initialize() * The configuration file is a YAML file and the configuration itself is stored * under `configuration' top-level item. * + * Example configuration file content: + * \code{.yaml} + * configuration: + * log: + * levels: 'IPAManager:DEBUG' + * \endcode + * * The configuration file is looked up in user's home directory first and if it * is not found then in system-wide configuration directories. If multiple * configuration files exist then only the first one found is used and no diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 3a656b8f..0f676710 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #include #include +#include "libcamera/internal/global_configuration.h" + /** * \file base/log.h * \brief Logging infrastructure @@ -626,8 +629,13 @@ void Logger::parseLogFile() void Logger::parseLogLevels() { const char *debug = utils::secure_getenv("LIBCAMERA_LOG_LEVELS"); - if (!debug) - return; + if (!debug) { + const std::optional confDebug = + GlobalConfiguration::configuration()["log"]["levels"].get(); + if (!confDebug.has_value()) + return; + debug = confDebug.value().c_str(); + } for (const char *pair = debug; *debug != '\0'; pair = debug) { const char *comma = strchrnul(debug, ','); diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index cfc24d38..33ae74e8 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -16,6 +16,7 @@ #include #include +#include "libcamera/internal/global_configuration.h" #include "libcamera/internal/ipa_module.h" #include "libcamera/internal/ipa_proxy.h" #include "libcamera/internal/pipeline_handler.h" @@ -103,6 +104,8 @@ LOG_DEFINE_CATEGORY(IPAManager) */ IPAManager::IPAManager() { + GlobalConfiguration::initialize(); + #if HAVE_IPA_PUBKEY if (!pubKey_.isValid()) LOG(IPAManager, Warning) << "Public key not valid"; From patchwork Fri Dec 6 17:11:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22240 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 39AF7BF415 for ; Fri, 6 Dec 2024 17:12:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EBEE767E2E; Fri, 6 Dec 2024 18:12:21 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="S9f8oO7j"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 14C0C67E30 for ; Fri, 6 Dec 2024 18:12:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505137; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8yYo1benTvlMAA50SviUQ+PNgqjAduQH1Vhl8ZFiUBo=; b=S9f8oO7jOdMBO9niRiYI62uQHmCuZhVRtniG5TchnB55qPaQuzvn20IP3dHwYipJRmWCRu CSit0JokCkPT+cMdrldQdyWZYfd7J4z4l8FlL/fiIUZS1TjUbbXPp6jOWsI5Aj9XQcrWMX hNjox0EFvGW3KCMr3QAgnMhAgC7A6PI= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-517-a0LkBHsuNBKplZKaPz0Z4g-1; Fri, 06 Dec 2024 12:12:14 -0500 X-MC-Unique: a0LkBHsuNBKplZKaPz0Z4g-1 X-Mimecast-MFC-AGG-ID: a0LkBHsuNBKplZKaPz0Z4g Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C84101956056; Fri, 6 Dec 2024 17:12:13 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 390E7300019E; Fri, 6 Dec 2024 17:12:10 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 04/16] config: Add configuration retrieval helpers Date: Fri, 6 Dec 2024 18:11:35 +0100 Message-ID: <20241206171148.1189292-5-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: -qv9sL9RjO2GIw02qQa9ThYlaUnATsOCdwSoUOL7Q1Q_1733505133 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" They make accessing simple configuration values simpler. GlobalConfiguration::option must check for the key presence before retrieving the value using operator[] because if the key is not present then YamlObject::empty may be returned as a regular value. Signed-off-by: Milan Zamazal --- .../libcamera/internal/global_configuration.h | 6 +++ src/libcamera/base/global_configuration.cpp | 52 ++++++++++++++++++- src/libcamera/base/log.cpp | 13 ++--- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/include/libcamera/internal/global_configuration.h b/include/libcamera/internal/global_configuration.h index bed88279..07062145 100644 --- a/include/libcamera/internal/global_configuration.h +++ b/include/libcamera/internal/global_configuration.h @@ -7,6 +7,9 @@ #pragma once +#include +#include + #include "libcamera/internal/yaml_parser.h" namespace libcamera { @@ -19,6 +22,9 @@ void initialize(); unsigned int version(); Configuration configuration(); +std::optional option(const std::string &confPath); +std::optional envOption(const char *const envVariable, + const std::string &confPath); } /* namespace GlobalConfiguration */ diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp index 8d823b98..84821f26 100644 --- a/src/libcamera/base/global_configuration.cpp +++ b/src/libcamera/base/global_configuration.cpp @@ -8,6 +8,8 @@ #include "libcamera/internal/global_configuration.h" #include +#include +#include #include #include @@ -126,7 +128,10 @@ void initialize() * configuration files exist then only the first one found is used and no * configuration merging is performed. * - * The configuration can be accessed using GlobalConfiguration::configuration(). + * The configuration can be accessed using the provided helpers. Namely + * GlobalConfiguration::option() or GlobalConfiguration::envOption() to access + * individual options or GlobalConfiguration::configuration() to access the + * whole configuration. */ /** @@ -137,6 +142,51 @@ void initialize() * the underlying type. */ +/** + * \brief Return value of the configuration option identified by \a confPath + * \param[in] confPath Sequence of the YAML section names (excluding + * `configuration') leading to the requested option separated by dots + * \return A value if an item corresponding to \a confPath exists in the + * configuration file, no value otherwise + */ +std::optional option(const std::string &confPath) +{ + const YamlObject *c = &configuration(); + for (auto part : utils::split(confPath, ".")) { + c = &(*c)[part]; + if (!*c) + return {}; + } + return c->get(); +} + +/** + * \brief Return value of the configuration option from a file or environment + * \param[in] envVariable Environment variable to get the value from + * \param[in] confPath The same as in GlobalConfiguration::option + * + * This helper looks first at the given environment variable and if it is + * defined then it returns its value (even if it is empty). Otherwise it looks + * for \a confPath the same way as in GlobalConfiguration::option. Only string + * values are supported. + * + * \note Support for using environment variables to configure libcamera behavior + * is provided here mostly for backward compatibility reasons. Introducing new + * configuration environment variables is discouraged. + * + * \return A value retrieved from the given environment option or configuration + * file or no value if not found + */ +std::optional envOption( + const char *const envVariable, + const std::string &confPath) +{ + const char *envValue = utils::secure_getenv(envVariable); + if (envValue) + return std::optional{ std::string{ envValue } }; + return option(confPath); +} + /** * \brief Return configuration version * diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 0f676710..891b4ae9 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -628,14 +628,11 @@ void Logger::parseLogFile() */ void Logger::parseLogLevels() { - const char *debug = utils::secure_getenv("LIBCAMERA_LOG_LEVELS"); - if (!debug) { - const std::optional confDebug = - GlobalConfiguration::configuration()["log"]["levels"].get(); - if (!confDebug.has_value()) - return; - debug = confDebug.value().c_str(); - } + const std::optional confDebug = + GlobalConfiguration::envOption("LIBCAMERA_LOG_LEVELS", "log.levels"); + if (!confDebug.has_value()) + return; + const char *debug = confDebug.value().c_str(); for (const char *pair = debug; *debug != '\0'; pair = debug) { const char *comma = strchrnul(debug, ','); From patchwork Fri Dec 6 17:11:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22242 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 EB11EBF415 for ; Fri, 6 Dec 2024 17:12:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AB34667E3F; Fri, 6 Dec 2024 18:12:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="JJsgfPWw"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6D94F67E30 for ; Fri, 6 Dec 2024 18:12:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505143; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JhgE9foWQRItinmtojm73/9dE/66cA+E71VlRyivIB0=; b=JJsgfPWw1EIe6S6c3cYTIJEfur73VAp1gJQaxk32fXl81O8zRFEIn9bPHnpOlmyX8JPPxf y8f5ZER/d6e1rZSCPFOqc3WkKPeAAA9zGmhH2OjAccPGMKozd+qLfoA2n8vH83iF6xD42t 2IZg86FrU3DnZENuoDvdvhIBptx7u7s= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-638-Y9qUpnTsO6iEwMNVa-ClGQ-1; Fri, 06 Dec 2024 12:12:18 -0500 X-MC-Unique: Y9qUpnTsO6iEwMNVa-ClGQ-1 X-Mimecast-MFC-AGG-ID: Y9qUpnTsO6iEwMNVa-ClGQ Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 02D0A19560B6; Fri, 6 Dec 2024 17:12:17 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 63ADB3000238; Fri, 6 Dec 2024 17:12:14 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 05/16] config: Look up log file in configuration file Date: Fri, 6 Dec 2024 18:11:36 +0100 Message-ID: <20241206171148.1189292-6-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 2NHtlAE8xxOG4cIcjxDeVEn44De_Zv_F_nxNerjZPnE_1733505137 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This requires change in LIBCAMERA_LOG_FILE interpretation so that we can disable the log file in isolated processes. If LIBCAMERA_LOG_FILE is defined but empty, it means there is no log file, even if defined in the configuration file. This should cause no compatibility trouble since opening a file with an empty name makes little sense. The configuration snippet: configuration: log: file: FILENAME Signed-off-by: Milan Zamazal --- src/libcamera/base/global_configuration.cpp | 1 + src/libcamera/base/log.cpp | 13 +++++++++---- src/libcamera/process.cpp | 11 ++++++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp index 84821f26..073096b5 100644 --- a/src/libcamera/base/global_configuration.cpp +++ b/src/libcamera/base/global_configuration.cpp @@ -120,6 +120,7 @@ void initialize() * \code{.yaml} * configuration: * log: + * file: syslog * levels: 'IPAManager:DEBUG' * \endcode * diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 891b4ae9..07352f6c 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -607,16 +607,21 @@ Logger::Logger() */ void Logger::parseLogFile() { - const char *file = utils::secure_getenv("LIBCAMERA_LOG_FILE"); - if (!file) + std::optional file = + GlobalConfiguration::envOption("LIBCAMERA_LOG_FILE", "log.file"); + if (!file.has_value()) return; - if (!strcmp(file, "syslog")) { + auto fileValue = file.value(); + if (fileValue == "") + return; + + if (fileValue == "syslog") { logSetTarget(LoggingTargetSyslog); return; } - logSetFile(file, false); + logSetFile(fileValue.c_str(), false); } /** diff --git a/src/libcamera/process.cpp b/src/libcamera/process.cpp index bc9833f4..c034044c 100644 --- a/src/libcamera/process.cpp +++ b/src/libcamera/process.cpp @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -23,6 +25,8 @@ #include #include +#include "libcamera/internal/global_configuration.h" + /** * \file process.h * \brief Process object @@ -261,9 +265,10 @@ int Process::start(const std::string &path, closeAllFdsExcept(fds); - const char *file = utils::secure_getenv("LIBCAMERA_LOG_FILE"); - if (file && strcmp(file, "syslog")) - unsetenv("LIBCAMERA_LOG_FILE"); + std::optional file = + GlobalConfiguration::envOption("LIBCAMERA_LOG_FILE", "log.file"); + if (file.has_value() && file.value() != "syslog") + setenv("LIBCAMERA_LOG_FILE", "", 1); const char **argv = new const char *[args.size() + 2]; unsigned int len = args.size(); From patchwork Fri Dec 6 17:11:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22243 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 94D9CBF415 for ; Fri, 6 Dec 2024 17:12:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4630167E2E; Fri, 6 Dec 2024 18:12:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="LLXj4fxQ"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 814C667E3A for ; Fri, 6 Dec 2024 18:12:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505144; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IvX09nZv25waA+hlUHoIYwhx8WIfXgEfAjpCAAHj9Kw=; b=LLXj4fxQe+Bb0B6O7WumLYjNKc8uolrOYqzJsn7wS7B6Wugrs80OadkE2f/oCwTUFEqkRU dcHD9ALVdpT/h63jE0hWP8pH5yOkbOKPH6MOzIDOtd/+wlAFKhQbFCfpTOu8Hb2mzeBMZX kV8ZKzd6ZnCWnJ0PioOgIzQqtNUP1ow= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-340-EXMdyDz6PNSzW8E51a8i0Q-1; Fri, 06 Dec 2024 12:12:21 -0500 X-MC-Unique: EXMdyDz6PNSzW8E51a8i0Q-1 X-Mimecast-MFC-AGG-ID: EXMdyDz6PNSzW8E51a8i0Q Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EB38D1956059; Fri, 6 Dec 2024 17:12:19 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7F723300019E; Fri, 6 Dec 2024 17:12:17 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 06/16] config: Look up log color configuration in configuration file Date: Fri, 6 Dec 2024 18:11:37 +0100 Message-ID: <20241206171148.1189292-7-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: GevTvslEuKUS5WZIPfubLyMXUrl0ju3AKe1vmUTknrQ_1733505140 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The configuration snippet: configuration: log: color: BOOL In order to use the global configuration access helper for a boolean value, we must make a template from it. To make the template visible, we must implement it in the header file, otherwise undefined reference error would be reported when linking. We don't implement envOption helper for boolean here, because we would have to deal with a specific value interpretation in this particular case. Signed-off-by: Milan Zamazal --- .../libcamera/internal/global_configuration.h | 27 ++++++++++++++++++- src/libcamera/base/global_configuration.cpp | 19 ++++--------- src/libcamera/base/log.cpp | 2 ++ 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/global_configuration.h b/include/libcamera/internal/global_configuration.h index 07062145..a6e21a2d 100644 --- a/include/libcamera/internal/global_configuration.h +++ b/include/libcamera/internal/global_configuration.h @@ -10,6 +10,8 @@ #include #include +#include + #include "libcamera/internal/yaml_parser.h" namespace libcamera { @@ -22,7 +24,30 @@ void initialize(); unsigned int version(); Configuration configuration(); -std::optional option(const std::string &confPath); + +template || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v> * = nullptr> +std::optional option(const std::string &confPath) +{ + const YamlObject *c = &configuration(); + for (auto part : utils::split(confPath, ".")) { + c = &(*c)[part]; + if (!*c) + return {}; + } + return c->get(); +} + std::optional envOption(const char *const envVariable, const std::string &confPath); diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp index 073096b5..3dc31c48 100644 --- a/src/libcamera/base/global_configuration.cpp +++ b/src/libcamera/base/global_configuration.cpp @@ -14,7 +14,6 @@ #include #include -#include #include "libcamera/internal/yaml_parser.h" @@ -144,22 +143,14 @@ void initialize() */ /** + * \fn std::optional GlobalConfiguration::option(const char *const confPath) * \brief Return value of the configuration option identified by \a confPath + * \tparam T The type of the retrieved configuration value * \param[in] confPath Sequence of the YAML section names (excluding * `configuration') leading to the requested option separated by dots - * \return A value if an item corresponding to \a confPath exists in the - * configuration file, no value otherwise + * \return A value of type \a T if an item corresponding to \a confPath exists + * in the configuration file and matches type \a T, no value otherwise */ -std::optional option(const std::string &confPath) -{ - const YamlObject *c = &configuration(); - for (auto part : utils::split(confPath, ".")) { - c = &(*c)[part]; - if (!*c) - return {}; - } - return c->get(); -} /** * \brief Return value of the configuration option from a file or environment @@ -185,7 +176,7 @@ std::optional envOption( const char *envValue = utils::secure_getenv(envVariable); if (envValue) return std::optional{ std::string{ envValue } }; - return option(confPath); + return option(confPath); } /** diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 07352f6c..d522e895 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -590,6 +590,8 @@ void Logger::logSetLevel(const char *category, const char *level) Logger::Logger() { bool color = !utils::secure_getenv("LIBCAMERA_LOG_NO_COLOR"); + if (color) + color = GlobalConfiguration::option("log.color").value_or(true); logSetStream(&std::cerr, color); parseLogFile(); From patchwork Fri Dec 6 17:11:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22244 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 85143BF415 for ; Fri, 6 Dec 2024 17:12:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 42BBC67E42; Fri, 6 Dec 2024 18:12:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Y/Ct+oKh"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4E3C767E43 for ; Fri, 6 Dec 2024 18:12:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505147; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gFrvbuzQzOcSqlmQ/EiGhf9G2YDFCa5r07NQHNGFA9c=; b=Y/Ct+oKhxXd9Wz/OxFEFJlokerllx1aEPVNDlXEZ9I28k1PSD4Tzy+Uxa3zWuVj2z9O5fI 6f73q+fnnLDs9vBS+EgTYDJ5uO4B3BGy70MrxFgVzWqRxLfKYwQOzV5z8irCBmlEohK4Vu UOpyddB6o3zZ91D3UeQhP+VFUcP9yh8= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-85-IPLKHpVxPP6NqFUSCqtPaA-1; Fri, 06 Dec 2024 12:12:24 -0500 X-MC-Unique: IPLKHpVxPP6NqFUSCqtPaA-1 X-Mimecast-MFC-AGG-ID: IPLKHpVxPP6NqFUSCqtPaA Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E29FA1955DA4; Fri, 6 Dec 2024 17:12:22 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 785FC300019E; Fri, 6 Dec 2024 17:12:20 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 07/16] config: Look up rpi paths in configuration file Date: Fri, 6 Dec 2024 18:11:38 +0100 Message-ID: <20241206171148.1189292-8-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: MVgl-F-miBqLtqpgmcYGWwPvIXrdcJdrU99rZzD-Df0_1733505143 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" It may be arguable whether pipeline specific configurations belong to the global configuration file. But: - Having a single configuration file is generally easier for the user. - The original configuration via environment variables can be already considered global. - These options point to other configuration files and it makes little sense to add another configuration file to the chain. The configuration snippet: configuration: pipeline: rpi: config_file: FILENAME tuning_file: FILENAME Signed-off-by: Milan Zamazal --- .../pipeline/rpi/common/pipeline_base.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 6f278b29..12f9b2b3 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -20,6 +20,7 @@ #include #include "libcamera/internal/camera_lens.h" +#include "libcamera/internal/global_configuration.h" #include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/v4l2_subdevice.h" @@ -1101,7 +1102,12 @@ int CameraData::loadPipelineConfiguration() /* Initial configuration of the platform, in case no config file is present */ platformPipelineConfigure({}); - char const *configFromEnv = utils::secure_getenv("LIBCAMERA_RPI_CONFIG_FILE"); + std::optional configFile = + GlobalConfiguration::envOption("LIBCAMERA_RPI_CONFIG_FILE", + "pipelines.rpi.config_file"); + if (!configFile.has_value()) + return 0; + char const *configFromEnv = configFile.value().c_str(); if (!configFromEnv || *configFromEnv == '\0') return 0; @@ -1160,14 +1166,18 @@ int CameraData::loadIPA(ipa::RPi::InitResult *result) * the environment variable overrides it. */ std::string configurationFile; - char const *configFromEnv = utils::secure_getenv("LIBCAMERA_RPI_TUNING_FILE"); - if (!configFromEnv || *configFromEnv == '\0') { + const std::string confPath = + std::string("pipelines.rpi.cameras.") + sensor_->id() + std::string(".tuning_file"); + std::optional configFromEnv = + GlobalConfiguration::envOption("LIBCAMERA_RPI_TUNING_FILE", + confPath.c_str()); + if (!configFromEnv.has_value() || configFromEnv.value().empty()) { std::string model = sensor_->model(); if (isMonoSensor(sensor_)) model += "_mono"; configurationFile = ipa_->configurationFile(model + ".json"); } else { - configurationFile = std::string(configFromEnv); + configurationFile = configFromEnv.value(); } IPASettings settings(configurationFile, sensor_->model()); From patchwork Fri Dec 6 17:11:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22245 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 22C53BF415 for ; Fri, 6 Dec 2024 17:12:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D375667E36; Fri, 6 Dec 2024 18:12:35 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Q5ckdKuA"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 65AF267E2E for ; Fri, 6 Dec 2024 18:12:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505152; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C+uOJoL9MPLuoNXCwucTE/uRvPF32C657uZ9VDm1Sts=; b=Q5ckdKuA1A+bzubodGoElXiYOX3BY8+pc92bunMXQypWFZYZ2hgEar9nvygblmGZs91YgE WQWh1L/H7s8SJieaBdIrqP/Mq2dSKX1iSoBBxVVDNL/2PeDi2aDYIpacvf7AXvrZpA5QHP VeYIVVDv2zWt1XhkiBpS7tQ4QjohFQU= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-630-CjVfnyKKPSWJwpMzHihFpQ-1; Fri, 06 Dec 2024 12:12:27 -0500 X-MC-Unique: CjVfnyKKPSWJwpMzHihFpQ-1 X-Mimecast-MFC-AGG-ID: CjVfnyKKPSWJwpMzHihFpQ Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 012421954AE2; Fri, 6 Dec 2024 17:12:26 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7F585300019E; Fri, 6 Dec 2024 17:12:23 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 08/16] config: Look up IPA configurables in configuration file Date: Fri, 6 Dec 2024 18:11:39 +0100 Message-ID: <20241206171148.1189292-9-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: gFhFNDPvfWb-FzFhTDumew1bHKAkQ4Ou_zDeie7NQNE_1733505146 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The configuration snippet: configuration: ipa: config_paths: - config path 1 - config path 2 - ... module_paths: - module path 1 - module path 2 - ... force_isolation: BOOL Signed-off-by: Milan Zamazal --- .../libcamera/internal/global_configuration.h | 4 ++ src/libcamera/base/global_configuration.cpp | 51 +++++++++++++++++++ src/libcamera/ipa_manager.cpp | 32 ++++++++---- src/libcamera/ipa_proxy.cpp | 47 ++++++++--------- 4 files changed, 100 insertions(+), 34 deletions(-) diff --git a/include/libcamera/internal/global_configuration.h b/include/libcamera/internal/global_configuration.h index a6e21a2d..ffa6454c 100644 --- a/include/libcamera/internal/global_configuration.h +++ b/include/libcamera/internal/global_configuration.h @@ -48,8 +48,12 @@ std::optional option(const std::string &confPath) return c->get(); } +std::vector listOption(const std::string &confPath); std::optional envOption(const char *const envVariable, const std::string &confPath); +std::vector envListOption( + const char *const envVariable, + const std::string &confPath); } /* namespace GlobalConfiguration */ diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp index 3dc31c48..e69951b4 100644 --- a/src/libcamera/base/global_configuration.cpp +++ b/src/libcamera/base/global_configuration.cpp @@ -9,11 +9,14 @@ #include #include +#include #include #include +#include #include #include +#include #include "libcamera/internal/yaml_parser.h" @@ -152,6 +155,24 @@ void initialize() * in the configuration file and matches type \a T, no value otherwise */ +/** + * \brief Return values of the configuration option identified by \a confPath + * \tparam T The type of the retrieved configuration value + * \param[in] confPath Sequence of the YAML section names (excluding + * `configuration') leading to the requested list option, separated by dots + * \return A vector of strings (empty one if the option is not found) + */ +std::vector listOption(const std::string &confPath) +{ + const YamlObject *c = &configuration(); + for (auto part : utils::split(confPath, ".")) { + c = &(*c)[part]; + if (!*c) + return {}; + } + return c->getList().value_or(std::vector()); +} + /** * \brief Return value of the configuration option from a file or environment * \param[in] envVariable Environment variable to get the value from @@ -179,6 +200,36 @@ std::optional envOption( return option(confPath); } +/** + * \brief Return values of the configuration option from a file or environment + * \param[in] envVariable Environment variable to get the value from + * \param[in] confPath The same as in GlobalConfiguration::option + * + * This helper looks first at the given environment variable and if it is + * defined (even if it is empty) then it splits its value by semicolons and + * returns the resulting list of strings. Otherwise it looks for \a confPath the + * same way as in GlobalConfiguration::option, value of which must be a list of + * strings. + * + * \note Support for using environment variables to configure libcamera behavior + * is provided here mostly for backward compatibility reasons. Introducing new + * configuration environment variables is discouraged. + * + * \return A vector of strings retrieved from the given environment option or + * configuration file (an empty vector is returned if nothing is found) + */ +std::vector envListOption( + const char *const envVariable, + const std::string &confPath) +{ + const char *envValue = utils::secure_getenv(envVariable); + if (envValue) { + auto items = utils::split(envValue, ":"); + return std::vector(items.begin(), items.end()); + } + return listOption(confPath); +} + /** * \brief Return configuration version * diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index 33ae74e8..21753eb6 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -114,18 +115,25 @@ IPAManager::IPAManager() unsigned int ipaCount = 0; /* User-specified paths take precedence. */ - const char *modulePaths = utils::secure_getenv("LIBCAMERA_IPA_MODULE_PATH"); - if (modulePaths) { - for (const auto &dir : utils::split(modulePaths, ":")) { - if (dir.empty()) - continue; + const auto modulePaths = + GlobalConfiguration::envListOption( + "LIBCAMERA_IPA_MODULE_PATH", "ipa.module_paths"); + for (const auto &dir : modulePaths) { + if (dir.empty()) + continue; - ipaCount += addDir(dir.c_str()); - } + ipaCount += addDir(dir.c_str()); + } - if (!ipaCount) - LOG(IPAManager, Warning) - << "No IPA found in '" << modulePaths << "'"; + if (!ipaCount) { + std::string paths; + if (!modulePaths.empty()) { + paths = std::accumulate(std::next(modulePaths.begin()), + modulePaths.end(), + modulePaths[0], + [](std::string s1, std::string s2) { return s1 + ":" + s2; }); + } + LOG(IPAManager, Warning) << "No IPA found in '" << paths << "'"; } /* @@ -289,7 +297,9 @@ bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const { #if HAVE_IPA_PUBKEY char *force = utils::secure_getenv("LIBCAMERA_IPA_FORCE_ISOLATION"); - if (force && force[0] != '\0') { + if ((force && force[0] != '\0') || + (!force && GlobalConfiguration::option("ipa.force_isolation") + .value_or(false))) { LOG(IPAManager, Debug) << "Isolation of IPA module " << ipa->path() << " forced through environment variable"; diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp index 85004737..c3630de0 100644 --- a/src/libcamera/ipa_proxy.cpp +++ b/src/libcamera/ipa_proxy.cpp @@ -14,6 +14,7 @@ #include #include +#include "libcamera/internal/global_configuration.h" #include "libcamera/internal/ipa_module.h" /** @@ -107,18 +108,18 @@ std::string IPAProxy::configurationFile(const std::string &name, */ std::string ipaName = ipam_->info().name; - /* Check the environment variable first. */ - const char *confPaths = utils::secure_getenv("LIBCAMERA_IPA_CONFIG_PATH"); - if (confPaths) { - for (const auto &dir : utils::split(confPaths, ":")) { - if (dir.empty()) - continue; + /* Check the configuration first. */ + auto confPaths = + GlobalConfiguration::envListOption( + "LIBCAMERA_IPA_CONFIG_PATH", "ipa.config_paths"); + for (const auto &dir : confPaths) { + if (dir.empty()) + continue; - std::string confPath = dir + "/" + ipaName + "/" + name; - ret = stat(confPath.c_str(), &statbuf); - if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) - return confPath; - } + std::string confPath = dir + "/" + ipaName + "/" + name; + ret = stat(confPath.c_str(), &statbuf); + if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) + return confPath; } std::string root = utils::libcameraSourcePath(); @@ -182,18 +183,18 @@ std::string IPAProxy::resolvePath(const std::string &file) const { std::string proxyFile = "/" + file; - /* Check env variable first. */ - const char *execPaths = utils::secure_getenv("LIBCAMERA_IPA_PROXY_PATH"); - if (execPaths) { - for (const auto &dir : utils::split(execPaths, ":")) { - if (dir.empty()) - continue; - - std::string proxyPath = dir; - proxyPath += proxyFile; - if (!access(proxyPath.c_str(), X_OK)) - return proxyPath; - } + /* Check the configuration first. */ + const auto execPaths = + GlobalConfiguration::envListOption( + "LIBCAMERA_IPA_PROXY_PATH", "ipa.proxy_paths"); + for (const auto &dir : execPaths) { + if (dir.empty()) + continue; + + std::string proxyPath = dir; + proxyPath += proxyFile; + if (!access(proxyPath.c_str(), X_OK)) + return proxyPath; } /* From patchwork Fri Dec 6 17:11:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22246 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 EFE7CBF415 for ; Fri, 6 Dec 2024 17:12:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7F13267E48; Fri, 6 Dec 2024 18:12:36 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="iGEc3Ut9"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 07D7667E2E for ; Fri, 6 Dec 2024 18:12:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505153; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l56VQUit0RiZWzbn01z5NRFZ9h60jvB0DUpBnzufxTY=; b=iGEc3Ut9YZnYC7SSrkZ7ADYa89RmPK+IwWDtkSwqsDcGAS9Heizel6vcbWeZ2PLO2C0Nxf 72uBPSXdTmtv8BcpHbksx15cH61DtH+nLpijF36Xpepag31WKuqKgW6HBjDhW8grkOYw6H NDIuk14bri3p+AU/IefC3OVqPNsixmU= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-47-T1xREvdwO-COtTXQSfasgw-1; Fri, 06 Dec 2024 12:12:30 -0500 X-MC-Unique: T1xREvdwO-COtTXQSfasgw-1 X-Mimecast-MFC-AGG-ID: T1xREvdwO-COtTXQSfasgw Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F02AB1955F40; Fri, 6 Dec 2024 17:12:28 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 90E9F300019E; Fri, 6 Dec 2024 17:12:26 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 09/16] config: Look up RkISP1 tuning file in configuration file Date: Fri, 6 Dec 2024 18:11:40 +0100 Message-ID: <20241206171148.1189292-10-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Yno0KuIU9VlyOuxTO3nqlM3HSFvUOs4LZLGQ5YJ3s-U_1733505149 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The configuration snippet: configuration: pipeline: rkisp1: tuning_file: FILE This environment variable has not been documented. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 908724e2..92f6addd 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -39,6 +39,7 @@ #include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/global_configuration.h" #include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" @@ -376,13 +377,16 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision) * environment variable overrides it. */ std::string ipaTuningFile; - char const *configFromEnv = utils::secure_getenv("LIBCAMERA_RKISP1_TUNING_FILE"); - if (!configFromEnv || *configFromEnv == '\0') { - ipaTuningFile = - ipa_->configurationFile(sensor_->model() + ".yaml", "uncalibrated.yaml"); - } else { - ipaTuningFile = std::string(configFromEnv); - } + const std::string confPath = + std::string("pipelines.rkisp1.cameras.") + sensor_->id() + ".tuning_file"; + const auto confTuningFile = + GlobalConfiguration::envOption( + "LIBCAMERA_RKISP1_TUNING_FILE", confPath.c_str()); + if (!confTuningFile.has_value() || confTuningFile.value() == "") + ipaTuningFile = ipa_->configurationFile(sensor_->model() + ".yaml", + "uncalibrated.yaml"); + else + ipaTuningFile = confTuningFile.value(); IPACameraSensorInfo sensorInfo{}; int ret = sensor_->sensorInfo(&sensorInfo); From patchwork Fri Dec 6 17:11:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22247 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 D8671C324C for ; Fri, 6 Dec 2024 17:12:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4EC9F67E46; Fri, 6 Dec 2024 18:12:37 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="UsUYYoQR"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 487EF67E47 for ; Fri, 6 Dec 2024 18:12:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505154; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v46nrjiIizVk/BqfPQCW3HABm5tC2XmXMeGzQ/FCtww=; b=UsUYYoQRPeb6wLaHK+dbf8wQHqYunvgDSdCW7RaZqHHBvaMZ5otTtCvoVzwKldtE4Era5z jXu6HlLOtYt0EHCOIGuFGf2w/zxYqIxUByGJNiSkoMgy3dznd+PytNjVooDLoiwRDvlZrb LP4yMa9zgODGfFryc5jLb9DItiZGZbY= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-189-WwnYWH6CNMaSFvsb2VyyFw-1; Fri, 06 Dec 2024 12:12:33 -0500 X-MC-Unique: WwnYWH6CNMaSFvsb2VyyFw-1 X-Mimecast-MFC-AGG-ID: WwnYWH6CNMaSFvsb2VyyFw Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E4C531954AFF; Fri, 6 Dec 2024 17:12:31 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7B5D4300019E; Fri, 6 Dec 2024 17:12:29 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 10/16] config: Look up pipelines match list in configuration file Date: Fri, 6 Dec 2024 18:11:41 +0100 Message-ID: <20241206171148.1189292-11-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: UB8LsA2n1wl3L2Jz3R0mroS6wlPHKzbBjXhDhjaQjdI_1733505152 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Milan Zamazal --- src/libcamera/camera_manager.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index 87e6717e..3597ca4c 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -15,6 +15,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/global_configuration.h" #include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/pipeline_handler.h" @@ -110,14 +111,15 @@ void CameraManager::Private::createPipelineHandlers() * file and only fallback on environment variable or all handlers, if * there is no configuration file. */ - const char *pipesList = - utils::secure_getenv("LIBCAMERA_PIPELINES_MATCH_LIST"); - if (pipesList) { + std::optional pipesList = + GlobalConfiguration::envOption("LIBCAMERA_PIPELINES_MATCH_LIST", + "pipelines_match_list"); + if (pipesList.has_value()) { /* * When a list of preferred pipelines is defined, iterate * through the ordered list to match the enumerated devices. */ - for (const auto &pipeName : utils::split(pipesList, ",")) { + for (const auto &pipeName : utils::split(pipesList.value(), ",")) { const PipelineHandlerFactoryBase *factory; factory = PipelineHandlerFactoryBase::getFactoryByName(pipeName); if (!factory) From patchwork Fri Dec 6 17:11:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22248 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 57852BF415 for ; Fri, 6 Dec 2024 17:12:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 16AC767E35; Fri, 6 Dec 2024 18:12:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="fYKgZAnb"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2F1E267E35 for ; Fri, 6 Dec 2024 18:12:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505161; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BHdj51TQCq9HLN5+m639mE02piVBxaGpl06J7bfgeCY=; b=fYKgZAnbBihsn6csHtmtyxP7MR1vLehmjScnP/e4mlkiLGrNMj3hgnoNlzdKpJeMke4rKy EJRaKEadugnrTMqjOfdxAhJtzGc0h+yhUQI1H/uqAkuGdhwJngiybVX7huGVH49xjoCbuY MWLfovOUCdXB7+QsKOewIs2t+ahCBaA= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-106-_URpmF8ZN6Wq5qma-0XMzQ-1; Fri, 06 Dec 2024 12:12:36 -0500 X-MC-Unique: _URpmF8ZN6Wq5qma-0XMzQ-1 X-Mimecast-MFC-AGG-ID: _URpmF8ZN6Wq5qma-0XMzQ Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 036581955D8D; Fri, 6 Dec 2024 17:12:35 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 821B2300019E; Fri, 6 Dec 2024 17:12:32 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 11/16] config: Allow enabling software ISP in runtime Date: Fri, 6 Dec 2024 18:11:42 +0100 Message-ID: <20241206171148.1189292-12-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: y79xFBwbNRiC11ZNZdwvCz3oq9ImdFukl3xyMWoWRDw_1733505155 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This patch allows enabling or disabling software ISP in runtime in addition to compile time. This can be useful for software ISP testing on various platforms as well as for overriding the defaults in case the defaults don't work well (e.g. hardware ISP may or may not work on i.MX8MP depending on the kernel and libcamera patches present in the given system). The configuration is specified as follows: configuration: pipelines: simple: supported_devices: - driver: DRIVER-NAME software_isp: BOOLEAN - ... For example: configuration: pipelines: simple: supported_devices: - driver: mxc-isi software_isp: true The overall configuration of enabling or disabling software ISP may get dropped in future but this patch is still useful in the meantime. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index dae9f31f..6f0826d8 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -35,6 +35,7 @@ #include "libcamera/internal/converter.h" #include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/global_configuration.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/software_isp/software_isp.h" @@ -1574,6 +1575,17 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) } swIspEnabled_ = info->swIspEnabled; + for (GlobalConfiguration::Configuration entry : + GlobalConfiguration::configuration() + ["pipelines"]["simple"]["supported_devices"] + .asList()) { + auto name = entry["driver"].get(); + if (name == info->driver) { + swIspEnabled_ = entry["software_isp"].get().value_or(swIspEnabled_); + LOG(SimplePipeline, Debug) << "Overriding software ISP to " << swIspEnabled_; + break; + } + } /* Locate the sensors. */ std::vector sensors = locateSensors(media); From patchwork Fri Dec 6 17:11:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22249 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 3E454BF415 for ; Fri, 6 Dec 2024 17:12:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D83D967E51; Fri, 6 Dec 2024 18:12:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="FbOmdWks"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3B45167E2C for ; Fri, 6 Dec 2024 18:12:43 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505162; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FZ+GIkhDOAwC84ToRGdidjzrJAzWiMtgZoh5G/20jWA=; b=FbOmdWksz2eT0/3HC5czDSf6RSK1FlKErk0ILkUFF+IqR7zzRLwqRaamXwMpcv6aDuEfaN 004J7iY+H3Ft9E6xq0nTio4da1ezTShgCrX22NL8zrb3mvajpLufn1DWeQN3UoA5jZiiDE 7rtOXP7gPRXJQrZxPHaHku6XwCbkXs8= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-466-KzQddOisM9eluIx8LIqAkA-1; Fri, 06 Dec 2024 12:12:39 -0500 X-MC-Unique: KzQddOisM9eluIx8LIqAkA-1 X-Mimecast-MFC-AGG-ID: KzQddOisM9eluIx8LIqAkA Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 14A941955DCA; Fri, 6 Dec 2024 17:12:38 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9421C3000239; Fri, 6 Dec 2024 17:12:35 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 12/16] config: Add global configuration file documentation Date: Fri, 6 Dec 2024 18:11:43 +0100 Message-ID: <20241206171148.1189292-13-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 0VHj2kXzWopmsEAZ4bI41OMJIaG57Naux9PDEHFapzg_1733505158 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Extend (and rename) the documentation of environment variables with information about the configuration file. Signed-off-by: Milan Zamazal --- Documentation/documentation-contents.rst | 2 +- Documentation/index.rst | 4 +- Documentation/meson.build | 2 +- ...ariables.rst => runtime_configuration.rst} | 117 ++++++++++++++++-- 4 files changed, 108 insertions(+), 17 deletions(-) rename Documentation/{environment_variables.rst => runtime_configuration.rst} (63%) diff --git a/Documentation/documentation-contents.rst b/Documentation/documentation-contents.rst index 5c111849..4be3729c 100644 --- a/Documentation/documentation-contents.rst +++ b/Documentation/documentation-contents.rst @@ -7,7 +7,7 @@ * :doc:`/feature_requirements` * :doc:`/guides/application-developer` * :doc:`/python-bindings` - * :doc:`/environment_variables` + * :doc:`/runtime_configuration` * :doc:`/api-html/index` * :doc:`/code-of-conduct` * | diff --git a/Documentation/index.rst b/Documentation/index.rst index bea40660..20d46788 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -12,13 +12,13 @@ Application Writer's Guide Camera Sensor Model - Environment variables Feature Requirements IPA Writer's guide Lens driver requirements libcamera Architecture Pipeline Handler Writer's Guide Python Bindings + Runtime configuration Sensor driver requirements SoftwareISP Benchmarking Tracing guide @@ -26,4 +26,4 @@ .. toctree:: :hidden: - introduction \ No newline at end of file + introduction diff --git a/Documentation/meson.build b/Documentation/meson.build index 36ffae23..b55e25b1 100644 --- a/Documentation/meson.build +++ b/Documentation/meson.build @@ -129,7 +129,6 @@ if sphinx.found() 'conf.py', 'contributing.rst', 'documentation-contents.rst', - 'environment_variables.rst', 'feature_requirements.rst', 'guides/application-developer.rst', 'guides/ipa.rst', @@ -141,6 +140,7 @@ if sphinx.found() 'libcamera_architecture.rst', 'mali-c55.dot', 'python-bindings.rst', + 'runtime_configuration.rst', 'sensor_driver_requirements.rst', 'software-isp-benchmarking.rst', '../README.rst', diff --git a/Documentation/environment_variables.rst b/Documentation/runtime_configuration.rst similarity index 63% rename from Documentation/environment_variables.rst rename to Documentation/runtime_configuration.rst index 7da9883a..3f7a104f 100644 --- a/Documentation/environment_variables.rst +++ b/Documentation/runtime_configuration.rst @@ -2,49 +2,140 @@ .. include:: documentation-contents.rst -Environment variables +Runtime configuration ===================== -The libcamera behaviour can be tuned through environment variables. This -document lists all the available variables and describes their usage. +The libcamera behaviour can be tuned through a configuration file or +environment variables. This document lists all the configuration options +and describes their usage. + +General rules +------------- + +The configuration file is looked up in the following locations, in this +order: + +- $XDG_CONFIG_HOME/libcamera/configuration.yaml +- LIBCAMERA_SYSCONF_DIR/configuration.yaml +- /etc/libcamera/configuration.yaml + +The first configuration file found wins, contingent configuration files +in other locations are ignored. + +Settings in environment variables take precedence over settings in +configuration files. This allows overriding behaviour temporarily +without the need to modify configuration files. + +Configuration options +--------------------- + +Here is an overview of the available configuration options, in the YAML +file structure: + +:: + + configuration: + ipa: + config_paths: # full paths to directories, separated by colons + force_isolation: # true/false + module_paths: # full paths to directories, separated by colons + log: + color: # true/false for color/no-color + file: # either `syslog` or a full path + levels: # see Log levels + pipelines_match_list: # pipeline names, separated by commas + pipelines: + rkisp1: + cameras: + - CAMERA-ID: + tuning-file: # full path + rpi: + config_file: # full path + cameras: + - CAMERA-ID: + tuning-file: # full path + simple: + supported_devices: + - driver: # driver name, e.g. `mxc-isi` + software_isp: # true/false + +Configuration file example +-------------------------- + +:: + + --- + version: 1 + configuration: + ipa: + config_paths: + - /home/user/.libcamera/share/ipa + - /opt/libcamera/vendor/share/ipa + module_paths: + - /home/user/.libcamera/lib + - /opt/libcamera/vendor/lib + proxy_paths: + - /home/user/.libcamera/proxy/worker + - /opt/libcamera/vendor/proxy/worker + force_isolation: true + log: + color: false + file: syslog + levels: 'IPAManager:DEBUG' + pipelines_match_list: rkisp1,simple + pipelines: + rkisp1: + cameras: + - "/base/axi/pcie@120000/rp1/i2c@88000/imx283@1a": + tuning_file: /home/pi/imx283.json + - "/base/axi/pcie@120000/rp1/i2c@80000/imx335@1a": + tuning_file: /home/pi/imx335.json + rpi: + config_file: /usr/local/share/libcamera/pipeline/rpi/vc4/minimal_mem.yaml + simple: + supported_devices: + - driver: mxc-isi + software_isp: true List of variables ----------------- -LIBCAMERA_LOG_FILE +The corresponding configuration file paths are listed in parentheses. + +LIBCAMERA_LOG_FILE (log.file) The custom destination for log output. Example value: ``/home/{user}/camera_log.log`` -LIBCAMERA_LOG_LEVELS +LIBCAMERA_LOG_LEVELS (log.levels) Configure the verbosity of log messages for different categories (`more `__). Example value: ``*:DEBUG`` -LIBCAMERA_LOG_NO_COLOR +LIBCAMERA_LOG_NO_COLOR (log.color) Disable coloring of log messages (`more `__). -LIBCAMERA_IPA_CONFIG_PATH +LIBCAMERA_IPA_CONFIG_PATH (ipa.config_paths) Define custom search locations for IPA configurations (`more `__). Example value: ``${HOME}/.libcamera/share/ipa:/opt/libcamera/vendor/share/ipa`` -LIBCAMERA_IPA_FORCE_ISOLATION +LIBCAMERA_IPA_FORCE_ISOLATION (ipa.force_isolation) When set to a non-empty string, force process isolation of all IPA modules. Example value: ``1`` -LIBCAMERA_IPA_MODULE_PATH +LIBCAMERA_IPA_MODULE_PATH (ipa.module_paths) Define custom search locations for IPA modules (`more `__). Example value: ``${HOME}/.libcamera/lib:/opt/libcamera/vendor/lib`` -LIBCAMERA_IPA_PROXY_PATH +LIBCAMERA_IPA_PROXY_PATH (ipa.proxy_paths) Define custom full path for a proxy worker for a given executable name. Example value: ``${HOME}/.libcamera/proxy/worker:/opt/libcamera/vendor/proxy/worker`` -LIBCAMERA_PIPELINES_MATCH_LIST +LIBCAMERA_PIPELINES_MATCH_LIST (pipelines_match_list) Define an ordered list of pipeline names to be used to match the media devices in the system. The pipeline handler names used to populate the variable are the ones passed to the REGISTER_PIPELINE_HANDLER() macro in the @@ -52,7 +143,7 @@ LIBCAMERA_PIPELINES_MATCH_LIST Example value: ``rkisp1,simple`` -LIBCAMERA_RPI_CONFIG_FILE +LIBCAMERA_RPI_CONFIG_FILE (pipelines.rpi.config_file) Define a custom configuration file to use in the Raspberry Pi pipeline handler. Example value: ``/usr/local/share/libcamera/pipeline/rpi/vc4/minimal_mem.yaml`` @@ -156,7 +247,7 @@ code. IPA configuration ~~~~~~~~~~~~~~~~~ -IPA modules use configuration files to store parameters. The format and +IPA modules use their own configuration files to store parameters. The format and contents of the configuration files is specific to the IPA module. They usually contain tuning parameters for the algorithms, in JSON format. From patchwork Fri Dec 6 17:11:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22250 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 C2080BF415 for ; Fri, 6 Dec 2024 17:12:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 80CE867E36; Fri, 6 Dec 2024 18:12:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="S9iTfmhJ"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D6E5267E36 for ; Fri, 6 Dec 2024 18:12:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505166; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vs/sVv6fUEHT45dt0Ubzzpbv49xH1rvnU9EawwJ8SWs=; b=S9iTfmhJJ6hEJCQW6r//oDvsAb3owDCWAh8ll05rR557l4fo13YKJei0PwmPZLoi3eQDKE sOH3hF1qs3xoWh3F4i2TyPrq8NV4HnMW8a/bCovnXpvPRIU7oOmMQJ2SErSq8dfu/FtsUA hDhVU6KixasxWhA77tOQA/cdvQIRv7c= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-368-u7hIRw6jPAawjv6czj-_GA-1; Fri, 06 Dec 2024 12:12:42 -0500 X-MC-Unique: u7hIRw6jPAawjv6czj-_GA-1 X-Mimecast-MFC-AGG-ID: u7hIRw6jPAawjv6czj-_GA Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0E8BE1956050; Fri, 6 Dec 2024 17:12:41 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A530C3000239; Fri, 6 Dec 2024 17:12:38 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 13/16] libcamera: software_isp: Make input buffer copying configurable Date: Fri, 6 Dec 2024 18:11:44 +0100 Message-ID: <20241206171148.1189292-14-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: heXCpeM7T25IPRwMB1127EhY6xoG-aK-rKbamACE410_1733505161 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" On some platforms, working directly on the input buffer is very slow due to disabled caching. This is why we copy the input buffer into standard (cached) memory. This is an unnecessary overhead on platforms with cached buffers. Let's make input buffer copying configurable. The default is still copying, as it's overhead is much lower than contingent operations on non-cached memory. Ideally, we should improve this in future to set the default to non-copying if we can be sure under observable circumstances that we are working with cached buffers. Completes software ISP TODO #6. Signed-off-by: Milan Zamazal --- Documentation/runtime_configuration.rst | 2 ++ src/libcamera/software_isp/TODO | 11 ----------- src/libcamera/software_isp/debayer_cpu.cpp | 5 ++++- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index 3f7a104f..4a34a3f5 100644 --- a/Documentation/runtime_configuration.rst +++ b/Documentation/runtime_configuration.rst @@ -55,6 +55,7 @@ file structure: - CAMERA-ID: tuning-file: # full path simple: + copy_input_buffer: # true/false supported_devices: - driver: # driver name, e.g. `mxc-isi` software_isp: # true/false @@ -93,6 +94,7 @@ Configuration file example rpi: config_file: /usr/local/share/libcamera/pipeline/rpi/vc4/minimal_mem.yaml simple: + copy_input_buffer: false supported_devices: - driver: mxc-isi software_isp: true diff --git a/src/libcamera/software_isp/TODO b/src/libcamera/software_isp/TODO index a50db668..2c919f44 100644 --- a/src/libcamera/software_isp/TODO +++ b/src/libcamera/software_isp/TODO @@ -71,17 +71,6 @@ per-frame buffers like we do for hardware ISPs. --- -6. Input buffer copying configuration - -> DebayerCpu::DebayerCpu(std::unique_ptr stats) -> : stats_(std::move(stats)), gammaCorrection_(1.0) -> { -> enableInputMemcpy_ = true; - -Set this appropriately and/or make it configurable. - ---- - 7. Performance measurement configuration > void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams params) diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 31ab96ab..ce5141e8 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -22,6 +22,7 @@ #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/dma_buf_allocator.h" #include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/global_configuration.h" #include "libcamera/internal/mapped_framebuffer.h" namespace libcamera { @@ -48,7 +49,9 @@ DebayerCpu::DebayerCpu(std::unique_ptr stats) * always set it to true as the safer choice but this should be changed in * future. */ - enableInputMemcpy_ = true; + enableInputMemcpy_ = GlobalConfiguration::option( + "pipelines.simple.copy_input_buffer") + .value_or(true); /* Initialize color lookup tables */ for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) From patchwork Fri Dec 6 17:11:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22251 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 36AA0BF415 for ; Fri, 6 Dec 2024 17:12:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F238C67E42; Fri, 6 Dec 2024 18:12:51 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="eKf9mjlN"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E8B0067E42 for ; Fri, 6 Dec 2024 18:12:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505169; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8K9ZHx9H/7+Tui4s3avP/zuAB/baF8j81rQjB82n/b4=; b=eKf9mjlNp7dKpWqM1C8uqbfrjJk6xWb1KLTwyYeG9GUMkaM3RzDyNiAPdYJKNHVZdYZPIA IiYA9ih83Aum3DXFw56/rSK8syyPbAgNfKnWokuGDjBHpeMiZ0fMk4UrG93QhF6W3WjUR2 LUakWhd/JJAAy1NWU5ULFhn8twMiQx4= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-539-ba_3aTUxMaa4tx28u47Wig-1; Fri, 06 Dec 2024 12:12:45 -0500 X-MC-Unique: ba_3aTUxMaa4tx28u47Wig-1 X-Mimecast-MFC-AGG-ID: ba_3aTUxMaa4tx28u47Wig Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9C4C81955F38; Fri, 6 Dec 2024 17:12:44 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9DEC2300019E; Fri, 6 Dec 2024 17:12:41 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 14/16] libcamera: software_isp: Make measurement configurable Date: Fri, 6 Dec 2024 18:11:45 +0100 Message-ID: <20241206171148.1189292-15-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: L1crhKTWkhImygXtu250ALec5LVkz1tJyGn0u3wFy1k_1733505164 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Software ISP performs performance measurement on certain part of initial frames. Let's make this range configurable. For this purpose, this patch introduces new configuration options pipelines.simple.measure.skip and pipelines.simple.measure.number. Setting the latter one to 0 disables the measurement. Instead of the last frame, the class member and its configuration specify the number of frames to measure. This is easier to use for users and doesn't require to adjust two configuration parameters when the number of the initially skipped frames is changed. The patch also changes the names of the class members to make them more accurate. Completes software ISP TODO #7. Signed-off-by: Milan Zamazal --- Documentation/runtime_configuration.rst | 6 ++++++ src/libcamera/software_isp/TODO | 25 ---------------------- src/libcamera/software_isp/debayer_cpu.cpp | 25 ++++++++++++++-------- src/libcamera/software_isp/debayer_cpu.h | 7 +++--- 4 files changed, 25 insertions(+), 38 deletions(-) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index 4a34a3f5..e52754e5 100644 --- a/Documentation/runtime_configuration.rst +++ b/Documentation/runtime_configuration.rst @@ -56,6 +56,9 @@ file structure: tuning-file: # full path simple: copy_input_buffer: # true/false + measure: + skip: # non-negative integer, frames to skip initially + number: # non-negative integer, frames to measure supported_devices: - driver: # driver name, e.g. `mxc-isi` software_isp: # true/false @@ -95,6 +98,9 @@ Configuration file example config_file: /usr/local/share/libcamera/pipeline/rpi/vc4/minimal_mem.yaml simple: copy_input_buffer: false + measure: + skip: 50 + number: 30 supported_devices: - driver: mxc-isi software_isp: true diff --git a/src/libcamera/software_isp/TODO b/src/libcamera/software_isp/TODO index 2c919f44..f19e15ae 100644 --- a/src/libcamera/software_isp/TODO +++ b/src/libcamera/software_isp/TODO @@ -71,31 +71,6 @@ per-frame buffers like we do for hardware ISPs. --- -7. Performance measurement configuration - -> void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams params) -> /* Measure before emitting signals */ -> if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure && -> ++measuredFrames_ > DebayerCpu::kFramesToSkip) { -> timespec frameEndTime = {}; -> clock_gettime(CLOCK_MONOTONIC_RAW, &frameEndTime); -> frameProcessTime_ += timeDiff(frameEndTime, frameStartTime); -> if (measuredFrames_ == DebayerCpu::kLastFrameToMeasure) { -> const unsigned int measuredFrames = DebayerCpu::kLastFrameToMeasure - -> DebayerCpu::kFramesToSkip; -> LOG(Debayer, Info) -> << "Processed " << measuredFrames -> << " frames in " << frameProcessTime_ / 1000 << "us, " -> << frameProcessTime_ / (1000 * measuredFrames) -> << " us/frame"; -> } -> } - -I wonder if there would be a way to control at runtime when/how to -perform those measurements. Maybe that's a bit overkill. - ---- - 8. DebayerCpu cleanups > >> class DebayerCpu : public Debayer, public Object diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index ce5141e8..3fb141a4 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -53,6 +53,13 @@ DebayerCpu::DebayerCpu(std::unique_ptr stats) "pipelines.simple.copy_input_buffer") .value_or(true); + skipBeforeMeasure_ = GlobalConfiguration::option( + "pipelines.simple.measure.skip") + .value_or(skipBeforeMeasure_); + framesToMeasure_ = GlobalConfiguration::option( + "pipelines.simple.measure.number") + .value_or(framesToMeasure_); + /* Initialize color lookup tables */ for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) red_[i] = green_[i] = blue_[i] = i; @@ -532,7 +539,7 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg, lineBuffers_[i].resize(lineBufferLength_); } - measuredFrames_ = 0; + encounteredFrames_ = 0; frameProcessTime_ = 0; return 0; @@ -738,7 +745,10 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output { timespec frameStartTime; - if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure) { + bool measure = framesToMeasure_ > 0 && + encounteredFrames_ < skipBeforeMeasure_ + framesToMeasure_ && + ++encounteredFrames_ > skipBeforeMeasure_; + if (measure) { frameStartTime = {}; clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime); } @@ -780,18 +790,15 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output dmaSyncers.clear(); /* Measure before emitting signals */ - if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure && - ++measuredFrames_ > DebayerCpu::kFramesToSkip) { + if (measure) { timespec frameEndTime = {}; clock_gettime(CLOCK_MONOTONIC_RAW, &frameEndTime); frameProcessTime_ += timeDiff(frameEndTime, frameStartTime); - if (measuredFrames_ == DebayerCpu::kLastFrameToMeasure) { - const unsigned int measuredFrames = DebayerCpu::kLastFrameToMeasure - - DebayerCpu::kFramesToSkip; + if (encounteredFrames_ == skipBeforeMeasure_ + framesToMeasure_) { LOG(Debayer, Info) - << "Processed " << measuredFrames + << "Processed " << framesToMeasure_ << " frames in " << frameProcessTime_ / 1000 << "us, " - << frameProcessTime_ / (1000 * measuredFrames) + << frameProcessTime_ / (1000 * framesToMeasure_) << " us/frame"; } } diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 2c47e7c6..f3c6d730 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -153,11 +153,10 @@ private: unsigned int xShift_; /* Offset of 0/1 applied to window_.x */ bool enableInputMemcpy_; bool swapRedBlueGains_; - unsigned int measuredFrames_; + unsigned int encounteredFrames_; int64_t frameProcessTime_; - /* Skip 30 frames for things to stabilize then measure 30 frames */ - static constexpr unsigned int kFramesToSkip = 30; - static constexpr unsigned int kLastFrameToMeasure = 60; + unsigned int skipBeforeMeasure_ = 30; + unsigned int framesToMeasure_ = 30; }; } /* namespace libcamera */ From patchwork Fri Dec 6 17:11:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22252 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 03B82BF415 for ; Fri, 6 Dec 2024 17:12:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B7B1167E5A; Fri, 6 Dec 2024 18:12:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="XLBD2yCU"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 07F1867E52 for ; Fri, 6 Dec 2024 18:12:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=e6yqBySOUWYqROtcNeaWuYVdDw58Sd7aGZRQowXWJLY=; b=XLBD2yCUSr0TGJ4akxYlvQYOzHixz0Q45NiFrBdbjsQnFn+bbjznYHElBjXLopNk+pkMyb dC+A6mRNgog/+U+xVNjEiqxO9znGuWbWOnnUqZmMiZQdg8uSMbmX0rIVJ+Ipv7B3Hrw9rB YJCDKW4jV+FTDctEjlhqm08xAo7bapc= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-171-gLJuKOXjMCG25PAUtOV4JQ-1; Fri, 06 Dec 2024 12:12:48 -0500 X-MC-Unique: gLJuKOXjMCG25PAUtOV4JQ-1 X-Mimecast-MFC-AGG-ID: gLJuKOXjMCG25PAUtOV4JQ Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 94D8D19560A2; Fri, 6 Dec 2024 17:12:47 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 38714300019E; Fri, 6 Dec 2024 17:12:44 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 15/16] config: Make configuration file configurable Date: Fri, 6 Dec 2024 18:11:46 +0100 Message-ID: <20241206171148.1189292-16-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: rNfgHtrQwx6lDRnuoRJkGm5s4NnksxYsK_R2IjyvPDk_1733505167 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" To support easy switching of configurations, let's introduce LIBCAMERA_CONFIG_NAME` environment variable, which denotes: - The path of the configuration file to load if it is an absolute path; or - the path of the configuration file to load, relative to the configuration directories. If such a configuration file doesn't exist, no custom configuration is loaded. Signed-off-by: Milan Zamazal --- Documentation/runtime_configuration.rst | 8 +++++++ src/libcamera/base/global_configuration.cpp | 26 ++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index e52754e5..59211169 100644 --- a/Documentation/runtime_configuration.rst +++ b/Documentation/runtime_configuration.rst @@ -19,6 +19,14 @@ order: - LIBCAMERA_SYSCONF_DIR/configuration.yaml - /etc/libcamera/configuration.yaml +The default name of the configuration file, configuration.yaml, can be +overridden in LIBCAMERA_CONFIG_NAME environment variable. The variable +can specify just an alternative configuration file name to be looked up +in the locations above, or it can contain a whole relative or absolute +path. If an absolute path is specified then it is the only location that +is used; if the given file doesn't exist then no configuration file is +read. + The first configuration file found wins, contingent configuration files in other locations are ignored. diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp index e69951b4..f35b3dae 100644 --- a/src/libcamera/base/global_configuration.cpp +++ b/src/libcamera/base/global_configuration.cpp @@ -60,13 +60,27 @@ bool loadFile(const std::filesystem::path &fileName) } const std::vector - globalConfigurationFiles = { - std::filesystem::path(LIBCAMERA_SYSCONF_DIR) / "configuration.yaml", - std::filesystem::path("/etc/libcamera/configuration.yaml"), + globalConfigurationDirectories = { + std::filesystem::path(LIBCAMERA_SYSCONF_DIR), + std::filesystem::path("/etc/libcamera"), }; void load() { + const char *libcameraConfigName = + utils::secure_getenv("LIBCAMERA_CONFIG_NAME"); + if (!libcameraConfigName) + libcameraConfigName = ""; + std::filesystem::path configName(libcameraConfigName); + + if (configName.is_absolute()) { + loadFile(configName); + return; + } + + if (configName.empty()) + configName = std::filesystem::path("configuration.yaml"); + std::filesystem::path userConfigurationDirectory; char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME"); if (xdgConfigHome) { @@ -80,13 +94,13 @@ void load() if (!userConfigurationDirectory.empty()) { std::filesystem::path user_configuration_file = - userConfigurationDirectory / "libcamera" / "configuration.yaml"; + userConfigurationDirectory / "libcamera" / configName; if (loadFile(user_configuration_file)) return; } - for (const auto &path : globalConfigurationFiles) - if (loadFile(path)) + for (const auto &path : globalConfigurationDirectories) + if (loadFile(path / configName)) return; } From patchwork Fri Dec 6 17:11:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 22253 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 E9FE8BF415 for ; Fri, 6 Dec 2024 17:12:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9D5C967E5F; Fri, 6 Dec 2024 18:12:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Xv1uY6ZV"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B56A067E59 for ; Fri, 6 Dec 2024 18:12:57 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733505176; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K+RdvnxY9IIThPLu5rDGMot90CrGupAyqZMph+CFr5w=; b=Xv1uY6ZVUnL5cJDfei2eiwXKbIipZpWkQYB5jch0rThdCuclYGA0OOCLEWHakYoWyHx1GN TTQDL4KfORp2hVHO4cajY1UcFsTH3KmNYcwLhRo8Kc4xqAW5K+B653xigkuQlQq019b8Ij L24bqZrKkMYPX4v0AMdGmM5nDokGoHE= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-633-9vN6BmUgMc6LIT74eSi4iw-1; Fri, 06 Dec 2024 12:12:52 -0500 X-MC-Unique: 9vN6BmUgMc6LIT74eSi4iw-1 X-Mimecast-MFC-AGG-ID: 9vN6BmUgMc6LIT74eSi4iw Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C01101956055; Fri, 6 Dec 2024 17:12:50 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.224.27]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 39484300019E; Fri, 6 Dec 2024 17:12:47 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Laurent Pinchart Subject: [PATCH v6 16/16] config: Make configuration directories configurable Date: Fri, 6 Dec 2024 18:11:47 +0100 Message-ID: <20241206171148.1189292-17-mzamazal@redhat.com> In-Reply-To: <20241206171148.1189292-1-mzamazal@redhat.com> References: <20241206171148.1189292-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 6I0Y4JTnDGn7LakNfsLRlaw8GFTfOq01Owyakscr1NY_1733505170 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" A newly introduced LIBCAMERA_CONFIG_DIR environment variable specifies a directory or a list of directories separated by colons where to look for the libcamera configuration file before trying the standard locations. Signed-off-by: Milan Zamazal --- Documentation/runtime_configuration.rst | 5 +++++ src/libcamera/base/global_configuration.cpp | 17 +++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index 59211169..c73d02e3 100644 --- a/Documentation/runtime_configuration.rst +++ b/Documentation/runtime_configuration.rst @@ -19,6 +19,11 @@ order: - LIBCAMERA_SYSCONF_DIR/configuration.yaml - /etc/libcamera/configuration.yaml +If LIBCAMERA_CONFIG_DIR environment variable is non-empty then it +specifies additional directories where to look for the configuration +file, before looking at the standard locations. It can be a single +directory or multiple directories separated by colons. + The default name of the configuration file, configuration.yaml, can be overridden in LIBCAMERA_CONFIG_NAME environment variable. The variable can specify just an alternative configuration file name to be looked up diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp index f35b3dae..315ea7ad 100644 --- a/src/libcamera/base/global_configuration.cpp +++ b/src/libcamera/base/global_configuration.cpp @@ -59,12 +59,6 @@ bool loadFile(const std::filesystem::path &fileName) return true; } -const std::vector - globalConfigurationDirectories = { - std::filesystem::path(LIBCAMERA_SYSCONF_DIR), - std::filesystem::path("/etc/libcamera"), - }; - void load() { const char *libcameraConfigName = @@ -81,6 +75,17 @@ void load() if (configName.empty()) configName = std::filesystem::path("configuration.yaml"); + const char *const configDir = utils::secure_getenv("LIBCAMERA_CONFIG_DIR"); + std::vector globalConfigurationDirectories; + if (configDir) + for (auto const &path : utils::split(configDir, ":")) + if (!path.empty()) + globalConfigurationDirectories.push_back(path); + globalConfigurationDirectories.push_back( + std::filesystem::path(LIBCAMERA_SYSCONF_DIR)); + globalConfigurationDirectories.push_back( + std::filesystem::path("/etc/libcamera")); + std::filesystem::path userConfigurationDirectory; char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME"); if (xdgConfigHome) {