[{"id":34866,"web_url":"https://patchwork.libcamera.org/comment/34866/","msgid":"<32d8134e-c4fa-4ce9-b7e2-8107edced7d3@ideasonboard.com>","date":"2025-07-11T15:28:59","subject":"Re: [PATCH v12 04/12] config: Look up rpi configuration in the\n\tconfiguration file","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2025. 07. 02. 15:10 keltezéssel, Milan Zamazal írta:\n> Let's make rpi configuration available in the global configuration file.\n> It may be arguable whether pipeline specific configurations belong to\n> the global configuration file.  But:\n> \n> - Having a single configuration file is generally easier for the user.\n> - The original configuration via environment variables can be already\n>    considered global.\n> - This option points to other configuration files and it makes little\n>    sense to add another configuration file to the chain.\n> \n> The rpi configuration is currently placed in a separate file, specified\n> by LIBCAMERA_RPI_CONFIG_FILE environment variable.  Let's support the\n> content of the file in the global configuration file.  `version' field\n> is omitted as the global configuration file has its own version and the\n> required version in the original file has been 1.0 anyway.\n> \n> The configuration snippet:\n> \n>    configuration:\n>      pipeline:\n>        rpi:\n>          bcm2835:\n>            pipeline_handler:\n>              ...\n>          pisp:\n>            pipeline_handler:\n>              ...\n> \n> To not break current user setups, LIBCAMERA_RPI_CONFIG_FILE environment\n> variable is still supported and works as before, pointing to a separate\n> configuration file.  Just the duplicate check for the configuration file\n> version in platformPipelineConfigure methods is removed.\n> \n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>   .../pipeline/rpi/common/pipeline_base.cpp     | 59 +++++++++++--------\n>   .../pipeline/rpi/common/pipeline_base.h       |  5 +-\n>   src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 29 ++++-----\n>   src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 28 ++++-----\n>   4 files changed, 67 insertions(+), 54 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> index eafe94427..0e31066cf 100644\n> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> @@ -20,8 +20,10 @@\n>   #include <libcamera/property_ids.h>\n>   \n>   #include \"libcamera/internal/camera_lens.h\"\n> +#include \"libcamera/internal/global_configuration.h\"\n>   #include \"libcamera/internal/ipa_manager.h\"\n>   #include \"libcamera/internal/v4l2_subdevice.h\"\n> +#include \"libcamera/internal/yaml_parser.h\"\n>   \n>   using namespace std::chrono_literals;\n>   \n> @@ -1089,37 +1091,41 @@ int CameraData::loadPipelineConfiguration()\n>   \t};\n>   \n>   \t/* Initial configuration of the platform, in case no config file is present */\n> -\tplatformPipelineConfigure({});\n> +\tplatformPipelineConfigure({}, {});\n>   \n> +\tstd::unique_ptr<YamlObject> root;\n>   \tchar const *configFromEnv = utils::secure_getenv(\"LIBCAMERA_RPI_CONFIG_FILE\");\n> -\tif (!configFromEnv || *configFromEnv == '\\0')\n> -\t\treturn 0;\n> -\n> -\tstd::string filename = std::string(configFromEnv);\n> -\tFile file(filename);\n> -\n> -\tif (!file.open(File::OpenModeFlag::ReadOnly)) {\n> -\t\tLOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n> -\t\t\t\t  << \", using defaults\";\n> -\t\treturn 0;\n> -\t}\n> +\tif (configFromEnv && *configFromEnv != '\\0') {\n> +\t\tstd::string filename = std::string(configFromEnv);\n> +\t\tFile file(filename);\n> +\n> +\t\tif (!file.open(File::OpenModeFlag::ReadOnly)) {\n> +\t\t\tLOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n> +\t\t\t\t\t  << \", using defaults\";\n> +\t\t\treturn 0;\n> +\t\t}\n>   \n> -\tLOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n> +\t\tLOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n>   \n> -\tstd::unique_ptr<YamlObject> root = YamlParser::parse(file);\n> -\tif (!root) {\n> -\t\tLOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n> -\t\treturn 0;\n> -\t}\n> +\t\troot = YamlParser::parse(file);\n> +\t\tif (!root) {\n> +\t\t\tLOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n> +\t\t\treturn 0;\n> +\t\t}\n>   \n> -\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n> -\tif (!ver || *ver != 1.0) {\n> -\t\tLOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n> -\t\t\t\t  << *ver;\n> -\t\treturn 0;\n> +\t\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n> +\t\tif (!ver || *ver != 1.0) {\n> +\t\t\tLOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n> +\t\t\t\t\t  << *ver;\n> +\t\t\treturn 0;\n> +\t\t}\n\nI think `(*root)[\"target\"]` should be checked here. Or am I missing why that is\nstill done in `platformPipelineConfigure()` ?\n\n\n\n>   \t}\n>   \n> -\tconst YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n> +\tGlobalConfiguration::Configuration config =\n> +\t\tpipe()->cameraManager()->_d()->configuration().configuration()[\"pipeline\"][\"rpi\"];\n> +\tconst YamlObject &phConfig = (root\n> +\t\t\t\t\t      ? (*root)[\"pipeline_handler\"]\n> +\t\t\t\t\t      : config[target()][\"pipeline_handler\"]);\n>   \n>   \tif (phConfig.contains(\"disable_startup_frame_drops\"))\n>   \t\tLOG(RPI, Warning)\n> @@ -1135,7 +1141,10 @@ int CameraData::loadPipelineConfiguration()\n>   \t\tfrontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n>   \t}\n>   \n> -\treturn platformPipelineConfigure(root);\n> +\tstd::optional<std::string> expectedTarget = (root\n> +\t\t\t\t\t\t\t     ? (*root)[\"target\"].get<std::string>()\n> +\t\t\t\t\t\t\t     : target());\n> +\treturn platformPipelineConfigure(phConfig, expectedTarget);\n>   }\n>   \n>   int CameraData::loadIPA(ipa::RPi::InitResult *result)\n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> index 4bce4ec4f..0badce293 100644\n> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> @@ -95,8 +95,11 @@ public:\n>   \tvirtual V4L2VideoDevice::Formats ispFormats() const = 0;\n>   \tvirtual V4L2VideoDevice::Formats rawFormats() const = 0;\n>   \tvirtual V4L2VideoDevice *frontendDevice() = 0;\n> +\tvirtual std::string target() const = 0;\n>   \n> -\tvirtual int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) = 0;\n> +\tvirtual int platformPipelineConfigure(\n> +\t\tconst YamlObject &phConfig,\n> +\t\tconst std::optional<std::string> &target) = 0;\n>   \n>   \tstd::unique_ptr<ipa::RPi::IPAProxyRPi> ipa_;\n>   \n> diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> index 2df91bacf..dcb973722 100644\n> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> @@ -740,10 +740,17 @@ public:\n>   \t\treturn cfe_[Cfe::Output0].dev();\n>   \t}\n>   \n> +\tstd::string target() const override\n\nCould you please make `target` a member variable of `CameraData`\n(that is a mandatory argument of the constructor), or have this\nfunction return a `const std::string&` to a static const string,\nor have it return `const char *` / `std::string_view`?\n\n\nRegards,\nBarnabás Pőcze\n\n\n> +\t{\n> +\t\treturn \"pisp\";\n> +\t}\n> +\n>   \tCameraConfiguration::Status\n>   \tplatformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n>   \n> -\tint platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n> +\tint platformPipelineConfigure(\n> +\t\tconst YamlObject &phConfig,\n> +\t\tconst std::optional<std::string> &expectedTarget) override;\n>   \n>   \tvoid platformStart() override;\n>   \tvoid platformStop() override;\n> @@ -1331,7 +1338,9 @@ PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n>   \treturn status;\n>   }\n>   \n> -int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n> +int PiSPCameraData::platformPipelineConfigure(\n> +\tconst YamlObject &phConfig,\n> +\tconst std::optional<std::string> &expectedTarget)\n>   {\n>   \tconfig_ = {\n>   \t\t.numCfeConfigStatsBuffers = 12,\n> @@ -1340,23 +1349,15 @@ int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject>\n>   \t\t.disableHdr = false,\n>   \t};\n>   \n> -\tif (!root)\n> +\tif (!phConfig)\n>   \t\treturn 0;\n>   \n> -\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n> -\tif (!ver || *ver != 1.0) {\n> -\t\tLOG(RPI, Error) << \"Unexpected configuration file version reported\";\n> -\t\treturn -EINVAL;\n> -\t}\n> -\n> -\tstd::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n> -\tif (target != \"pisp\") {\n> -\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"pisp\\\", got \"\n> -\t\t\t\t<< (target ? target->c_str() : \"(unknown)\");\n> +\tif (expectedTarget != \"pisp\") {\n> +\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"\" << target() << \"\\\", got \"\n> +\t\t\t\t<< (expectedTarget ? expectedTarget->c_str() : \"(unknown)\");\n>   \t\treturn -EINVAL;\n>   \t}\n>   \n> -\tconst YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>   \tconfig_.numCfeConfigStatsBuffers =\n>   \t\tphConfig[\"num_cfe_config_stats_buffers\"].get<unsigned int>(config_.numCfeConfigStatsBuffers);\n>   \tconfig_.numCfeConfigQueue =\n> diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> index e99a7edf8..e00221a3a 100644\n> --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> @@ -61,13 +61,19 @@ public:\n>   \t\treturn unicam_[Unicam::Image].dev();\n>   \t}\n>   \n> +\tstd::string target() const override\n> +\t{\n> +\t\treturn \"bcm2835\";\n> +\t}\n> +\n>   \tvoid platformFreeBuffers() override\n>   \t{\n>   \t}\n>   \n>   \tCameraConfiguration::Status platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n>   \n> -\tint platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n> +\tint platformPipelineConfigure(const YamlObject &phConfig,\n> +\t\t\t\t      const std::optional<std::string> &expectedTarget) override;\n>   \n>   \tvoid platformStart() override;\n>   \tvoid platformStop() override;\n> @@ -493,30 +499,24 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig\n>   \treturn status;\n>   }\n>   \n> -int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n> +int Vc4CameraData::platformPipelineConfigure(\n> +\tconst YamlObject &phConfig,\n> +\tconst std::optional<std::string> &expectedTarget)\n>   {\n>   \tconfig_ = {\n>   \t\t.minUnicamBuffers = 2,\n>   \t\t.minTotalUnicamBuffers = 4,\n>   \t};\n>   \n> -\tif (!root)\n> +\tif (!phConfig)\n>   \t\treturn 0;\n>   \n> -\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n> -\tif (!ver || *ver != 1.0) {\n> -\t\tLOG(RPI, Error) << \"Unexpected configuration file version reported\";\n> -\t\treturn -EINVAL;\n> -\t}\n> -\n> -\tstd::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n> -\tif (target != \"bcm2835\") {\n> -\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"bcm2835\\\", got \"\n> -\t\t\t\t<< (target ? target->c_str() : \"(unknown)\");\n> +\tif (expectedTarget != target()) {\n> +\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"\" << target() << \"\\\", got \"\n> +\t\t\t\t<< (expectedTarget ? expectedTarget->c_str() : \"(unknown)\");\n>   \t\treturn -EINVAL;\n>   \t}\n>   \n> -\tconst YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>   \tconfig_.minUnicamBuffers =\n>   \t\tphConfig[\"min_unicam_buffers\"].get<unsigned int>(config_.minUnicamBuffers);\n>   \tconfig_.minTotalUnicamBuffers =","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 7321EC3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 11 Jul 2025 15:29:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1D76068F20;\n\tFri, 11 Jul 2025 17:29:04 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DB5968F16\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 11 Jul 2025 17:29:02 +0200 (CEST)","from [192.168.33.21] (185.221.140.39.nat.pool.zt.hu\n\t[185.221.140.39])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5B7492C5;\n\tFri, 11 Jul 2025 17:28:32 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"J322POqt\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1752247712;\n\tbh=ajBkfeXky6w/kjcWU9QDGOWL4a6aXwY2yHcaGaq8rZg=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=J322POqticOZ+VK+9SSDrFMjxlQdrBvo4xxRpaPl3UpFcEubtGQMcilH7p5lOLSlD\n\thrEZ83J+FNgNCX2V4jELuRfN+kpPo1Ku6WrVlThcDU112oXKIAx5+pP+j35A6NYDf1\n\tk3uMZD0DL8ZnCkOX3bjhDvaR7xUl6+3mIepS6WVM=","Message-ID":"<32d8134e-c4fa-4ce9-b7e2-8107edced7d3@ideasonboard.com>","Date":"Fri, 11 Jul 2025 17:28:59 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v12 04/12] config: Look up rpi configuration in the\n\tconfiguration file","To":"Milan Zamazal <mzamazal@redhat.com>, libcamera-devel@lists.libcamera.org","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20250702131032.47654-1-mzamazal@redhat.com>\n\t<20250702131032.47654-5-mzamazal@redhat.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20250702131032.47654-5-mzamazal@redhat.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":34870,"web_url":"https://patchwork.libcamera.org/comment/34870/","msgid":"<85ple6bjxt.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-07-11T19:34:38","subject":"Re: [PATCH v12 04/12] config: Look up rpi configuration in the\n\tconfiguration file","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi Barnabás,\n\nthank you for review.\n\nBarnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:\n\n> Hi\n>\n> 2025. 07. 02. 15:10 keltezéssel, Milan Zamazal írta:\n>> Let's make rpi configuration available in the global configuration file.\n>> It may be arguable whether pipeline specific configurations belong to\n>> the global configuration file.  But:\n>> - Having a single configuration file is generally easier for the user.\n>> - The original configuration via environment variables can be already\n>>    considered global.\n>> - This option points to other configuration files and it makes little\n>>    sense to add another configuration file to the chain.\n>> The rpi configuration is currently placed in a separate file, specified\n>> by LIBCAMERA_RPI_CONFIG_FILE environment variable.  Let's support the\n>> content of the file in the global configuration file.  `version' field\n>> is omitted as the global configuration file has its own version and the\n>> required version in the original file has been 1.0 anyway.\n>> The configuration snippet:\n>>    configuration:\n>>      pipeline:\n>>        rpi:\n>>          bcm2835:\n>>            pipeline_handler:\n>>              ...\n>>          pisp:\n>>            pipeline_handler:\n>>              ...\n>> To not break current user setups, LIBCAMERA_RPI_CONFIG_FILE environment\n>> variable is still supported and works as before, pointing to a separate\n>> configuration file.  Just the duplicate check for the configuration file\n>> version in platformPipelineConfigure methods is removed.\n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>   .../pipeline/rpi/common/pipeline_base.cpp     | 59 +++++++++++--------\n>>   .../pipeline/rpi/common/pipeline_base.h       |  5 +-\n>>   src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 29 ++++-----\n>>   src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 28 ++++-----\n>>   4 files changed, 67 insertions(+), 54 deletions(-)\n>> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n>> b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n>> index eafe94427..0e31066cf 100644\n>> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n>> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n>> @@ -20,8 +20,10 @@\n>>   #include <libcamera/property_ids.h>\n>>     #include \"libcamera/internal/camera_lens.h\"\n>> +#include \"libcamera/internal/global_configuration.h\"\n>>   #include \"libcamera/internal/ipa_manager.h\"\n>>   #include \"libcamera/internal/v4l2_subdevice.h\"\n>> +#include \"libcamera/internal/yaml_parser.h\"\n>>     using namespace std::chrono_literals;\n>>   @@ -1089,37 +1091,41 @@ int CameraData::loadPipelineConfiguration()\n>>   \t};\n>>     \t/* Initial configuration of the platform, in case no config file is present */\n>> -\tplatformPipelineConfigure({});\n>> +\tplatformPipelineConfigure({}, {});\n>>   +\tstd::unique_ptr<YamlObject> root;\n>>   \tchar const *configFromEnv = utils::secure_getenv(\"LIBCAMERA_RPI_CONFIG_FILE\");\n>> -\tif (!configFromEnv || *configFromEnv == '\\0')\n>> -\t\treturn 0;\n>> -\n>> -\tstd::string filename = std::string(configFromEnv);\n>> -\tFile file(filename);\n>> -\n>> -\tif (!file.open(File::OpenModeFlag::ReadOnly)) {\n>> -\t\tLOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n>> -\t\t\t\t  << \", using defaults\";\n>> -\t\treturn 0;\n>> -\t}\n>> +\tif (configFromEnv && *configFromEnv != '\\0') {\n>> +\t\tstd::string filename = std::string(configFromEnv);\n>> +\t\tFile file(filename);\n>> +\n>> +\t\tif (!file.open(File::OpenModeFlag::ReadOnly)) {\n>> +\t\t\tLOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n>> +\t\t\t\t\t  << \", using defaults\";\n>> +\t\t\treturn 0;\n>> +\t\t}\n>>   -\tLOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n>> +\t\tLOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n>>   -\tstd::unique_ptr<YamlObject> root = YamlParser::parse(file);\n>> -\tif (!root) {\n>> -\t\tLOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n>> -\t\treturn 0;\n>> -\t}\n>> +\t\troot = YamlParser::parse(file);\n>> +\t\tif (!root) {\n>> +\t\t\tLOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n>> +\t\t\treturn 0;\n>> +\t\t}\n>>   -\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n>> -\tif (!ver || *ver != 1.0) {\n>> -\t\tLOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n>> -\t\t\t\t  << *ver;\n>> -\t\treturn 0;\n>> +\t\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n>> +\t\tif (!ver || *ver != 1.0) {\n>> +\t\t\tLOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n>> +\t\t\t\t\t  << *ver;\n>> +\t\t\treturn 0;\n>> +\t\t}\n>\n> I think `(*root)[\"target\"]` should be checked here. Or am I missing why that is\n> still done in `platformPipelineConfigure()` ?\n\nRight, it's just my confusion, I'll fix it.\n\n>>   \t}\n>>   -\tconst YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>> +\tGlobalConfiguration::Configuration config =\n>> +\t\tpipe()->cameraManager()->_d()->configuration().configuration()[\"pipeline\"][\"rpi\"];\n>> +\tconst YamlObject &phConfig = (root\n>> +\t\t\t\t\t      ? (*root)[\"pipeline_handler\"]\n>> +\t\t\t\t\t      : config[target()][\"pipeline_handler\"]);\n>>     \tif (phConfig.contains(\"disable_startup_frame_drops\"))\n>>   \t\tLOG(RPI, Warning)\n>> @@ -1135,7 +1141,10 @@ int CameraData::loadPipelineConfiguration()\n>>   \t\tfrontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n>>   \t}\n>>   -\treturn platformPipelineConfigure(root);\n>> +\tstd::optional<std::string> expectedTarget = (root\n>> +\t\t\t\t\t\t\t     ? (*root)[\"target\"].get<std::string>()\n>> +\t\t\t\t\t\t\t     : target());\n>> +\treturn platformPipelineConfigure(phConfig, expectedTarget);\n>>   }\n>>     int CameraData::loadIPA(ipa::RPi::InitResult *result)\n>> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n>> index 4bce4ec4f..0badce293 100644\n>> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n>> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n>> @@ -95,8 +95,11 @@ public:\n>>   \tvirtual V4L2VideoDevice::Formats ispFormats() const = 0;\n>>   \tvirtual V4L2VideoDevice::Formats rawFormats() const = 0;\n>>   \tvirtual V4L2VideoDevice *frontendDevice() = 0;\n>> +\tvirtual std::string target() const = 0;\n>>   -\tvirtual int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) = 0;\n>> +\tvirtual int platformPipelineConfigure(\n>> +\t\tconst YamlObject &phConfig,\n>> +\t\tconst std::optional<std::string> &target) = 0;\n>>     \tstd::unique_ptr<ipa::RPi::IPAProxyRPi> ipa_;\n>>   diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n>> index 2df91bacf..dcb973722 100644\n>> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n>> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n>> @@ -740,10 +740,17 @@ public:\n>>   \t\treturn cfe_[Cfe::Output0].dev();\n>>   \t}\n>>   +\tstd::string target() const override\n>\n> Could you please make `target` a member variable of `CameraData`\n> (that is a mandatory argument of the constructor), or have this\n> function return a `const std::string&` to a static const string,\n\nOK, this looks suitable.\n\n> or have it return `const char *` / `std::string_view`?\n>\n>\n> Regards,\n> Barnabás Pőcze\n>\n>\n>> +\t{\n>> +\t\treturn \"pisp\";\n>> +\t}\n>> +\n>>   \tCameraConfiguration::Status\n>>   \tplatformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n>>   -\tint platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n>> +\tint platformPipelineConfigure(\n>> +\t\tconst YamlObject &phConfig,\n>> +\t\tconst std::optional<std::string> &expectedTarget) override;\n>>     \tvoid platformStart() override;\n>>   \tvoid platformStop() override;\n>> @@ -1331,7 +1338,9 @@ PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n>>   \treturn status;\n>>   }\n>>   -int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n>> +int PiSPCameraData::platformPipelineConfigure(\n>> +\tconst YamlObject &phConfig,\n>> +\tconst std::optional<std::string> &expectedTarget)\n>>   {\n>>   \tconfig_ = {\n>>   \t\t.numCfeConfigStatsBuffers = 12,\n>> @@ -1340,23 +1349,15 @@ int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject>\n>>   \t\t.disableHdr = false,\n>>   \t};\n>>   -\tif (!root)\n>> +\tif (!phConfig)\n>>   \t\treturn 0;\n>>   -\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n>> -\tif (!ver || *ver != 1.0) {\n>> -\t\tLOG(RPI, Error) << \"Unexpected configuration file version reported\";\n>> -\t\treturn -EINVAL;\n>> -\t}\n>> -\n>> -\tstd::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n>> -\tif (target != \"pisp\") {\n>> -\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"pisp\\\", got \"\n>> -\t\t\t\t<< (target ? target->c_str() : \"(unknown)\");\n>> +\tif (expectedTarget != \"pisp\") {\n>> +\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"\" << target() << \"\\\", got \"\n>> +\t\t\t\t<< (expectedTarget ? expectedTarget->c_str() : \"(unknown)\");\n>>   \t\treturn -EINVAL;\n>>   \t}\n>>   -\tconst YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>>   \tconfig_.numCfeConfigStatsBuffers =\n>>   \t\tphConfig[\"num_cfe_config_stats_buffers\"].get<unsigned int>(config_.numCfeConfigStatsBuffers);\n>>   \tconfig_.numCfeConfigQueue =\n>> diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> index e99a7edf8..e00221a3a 100644\n>> --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> @@ -61,13 +61,19 @@ public:\n>>   \t\treturn unicam_[Unicam::Image].dev();\n>>   \t}\n>>   +\tstd::string target() const override\n>> +\t{\n>> +\t\treturn \"bcm2835\";\n>> +\t}\n>> +\n>>   \tvoid platformFreeBuffers() override\n>>   \t{\n>>   \t}\n>>     \tCameraConfiguration::Status platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n>> override;\n>>   -\tint platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n>> +\tint platformPipelineConfigure(const YamlObject &phConfig,\n>> +\t\t\t\t      const std::optional<std::string> &expectedTarget) override;\n>>     \tvoid platformStart() override;\n>>   \tvoid platformStop() override;\n>> @@ -493,30 +499,24 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig\n>>   \treturn status;\n>>   }\n>>   -int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n>> +int Vc4CameraData::platformPipelineConfigure(\n>> +\tconst YamlObject &phConfig,\n>> +\tconst std::optional<std::string> &expectedTarget)\n>>   {\n>>   \tconfig_ = {\n>>   \t\t.minUnicamBuffers = 2,\n>>   \t\t.minTotalUnicamBuffers = 4,\n>>   \t};\n>>   -\tif (!root)\n>> +\tif (!phConfig)\n>>   \t\treturn 0;\n>>   -\tstd::optional<double> ver = (*root)[\"version\"].get<double>();\n>> -\tif (!ver || *ver != 1.0) {\n>> -\t\tLOG(RPI, Error) << \"Unexpected configuration file version reported\";\n>> -\t\treturn -EINVAL;\n>> -\t}\n>> -\n>> -\tstd::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n>> -\tif (target != \"bcm2835\") {\n>> -\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"bcm2835\\\", got \"\n>> -\t\t\t\t<< (target ? target->c_str() : \"(unknown)\");\n>> +\tif (expectedTarget != target()) {\n>> +\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"\" << target() << \"\\\", got \"\n>> +\t\t\t\t<< (expectedTarget ? expectedTarget->c_str() : \"(unknown)\");\n>>   \t\treturn -EINVAL;\n>>   \t}\n>>   -\tconst YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>>   \tconfig_.minUnicamBuffers =\n>>   \t\tphConfig[\"min_unicam_buffers\"].get<unsigned int>(config_.minUnicamBuffers);\n>>   \tconfig_.minTotalUnicamBuffers =","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 43CF0BE175\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 11 Jul 2025 19:34:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4F8FF68F20;\n\tFri, 11 Jul 2025 21:34:48 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A2FA068E30\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 11 Jul 2025 21:34:46 +0200 (CEST)","from mail-wr1-f72.google.com (mail-wr1-f72.google.com\n\t[209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-550-4T34AKuEM8ucsPLOtL1o1Q-1; Fri, 11 Jul 2025 15:34:41 -0400","by mail-wr1-f72.google.com with SMTP id\n\tffacd0b85a97d-3a6df0c67a6so1475724f8f.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 11 Jul 2025 12:34:41 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\tffacd0b85a97d-3b5e8e0d88dsm5347963f8f.65.2025.07.11.12.34.38\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 11 Jul 2025 12:34:39 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"H4m5nU2G\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1752262485;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=XIsWG3SlhDDDc27T43IsZgC/kbgjlHcB62EBmsb0NVc=;\n\tb=H4m5nU2GmuarJpqUwZRy0hdsaC7oeCvKxFaHs868G+ibZR9MqieWx9bj7TqScc1BMoAhxR\n\teVJ4ylzN8fDybyCR5uVuNloXrLsGJGhOdP7/BJFzyFEgkh7u7z1jLLq7hbVzFSRygnbVqD\n\tI2F//PlDqcwPKf94/UWJrVFbQ4FjTag=","X-MC-Unique":"4T34AKuEM8ucsPLOtL1o1Q-1","X-Mimecast-MFC-AGG-ID":"4T34AKuEM8ucsPLOtL1o1Q_1752262481","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1752262480; x=1752867280;\n\th=content-transfer-encoding:mime-version:user-agent:message-id:date\n\t:references:in-reply-to:subject:cc:to:from:x-gm-message-state:from\n\t:to:cc:subject:date:message-id:reply-to;\n\tbh=8aWNeZ0SoZWD5kPmI8PJjInMJ8Fc0XsuNoNh5wmwYHE=;\n\tb=fari3wyueI7HBgjHVm1D8D0LcBB/Ca+1jIkt4ka0aQ9CtExhx+wfgHH5XqgyokKayj\n\tH6ELwtqP80YI59nrdXdNSnQsbNPmizCoHwJ7scPlHxE1WRxFKUDsqNRN0zCPmEDMwDjl\n\tAewHzZn1+PV+4MJZyZvinOWeDlV4F9pNpgTraXsdK3CIs+U3yXe8vwL5wc5uFz2R8Ie+\n\tC+9LI4zAd9Zt5MFFMaxUYHhxQkmhhI2lXgDI7UhrA4nt/ANKIqDsJQklhLgSZrPJoMIu\n\tvrrEqUi27F9QQN3PmMUDDaa4xmRNV9Y6l50szT+J7fNa4soEFXBFhh01qmtPicWBO6Ms\n\tlq9w==","X-Gm-Message-State":"AOJu0YzRZ6N6oyCr8cac+JttNm9C/HXzsa0M3T1yLmM8kcg6DCmjwwDw\n\tS6cDKT1sTZgdHWeYWl/RKnxvmnwbQJDTUz+EHwqGCwETvP7vMZKWIYxJ6rbkZLZ0nLKEa/Wl94+\n\tSnkWPyne5gaJ5LPPoPxnKoA46PyQwtQoLrebG0+3E0nSeNuebYmwxWAEWYPyjcX0XlXconCrL65\n\tk=","X-Gm-Gg":"ASbGncvXyRBIWdw/IB1lJHyPohoSZTtAcA9XkULXhgbXLHgWQdpReLWy61x4uYYvuNF\n\toKPNeyyZlPzy8PlvIGdIHI5FXCEcZjCnov9VN2a70IKnybXXi4JxV7JtDiiQFGoRGh93SzLUDbl\n\tVn3CgFxrtuYk4IRGS3ogCcGyvO6W81SNku3ul61Wp+QnIr5bx0j34Tw5EVOD16atfVLnhukv2Fd\n\tFGeKAD92mapEyML/Hc1Fdbo7QuLt2KqLj9h7r1DJ0T9UTxVkyljGQemiKzRS+SEImOlAd0ElnI4\n\tR/kbaeXk1kwAOj5get4jPLauCoOLwW0zq6KkpZLEKwM3V99Q8cykm42aJkT8dl6e1l+pBqqFr2N\n\tqUFtZ2Um10A8ml9If","X-Received":["by 2002:a05:6000:43d8:b0:3b2:fe46:9812 with SMTP id\n\tffacd0b85a97d-3b5f2dccafamr1910911f8f.19.1752262480486; \n\tFri, 11 Jul 2025 12:34:40 -0700 (PDT)","by 2002:a05:6000:43d8:b0:3b2:fe46:9812 with SMTP id\n\tffacd0b85a97d-3b5f2dccafamr1910902f8f.19.1752262479950; \n\tFri, 11 Jul 2025 12:34:39 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IEP6mSag38tPZdveKrxc8IUFmOWsib51yulkmM/zcG9FL/+vNg/Jlh2VwLmT7KawfH1LQeoMQ==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,  Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>,  Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>","Subject":"Re: [PATCH v12 04/12] config: Look up rpi configuration in the\n\tconfiguration file","In-Reply-To":"<32d8134e-c4fa-4ce9-b7e2-8107edced7d3@ideasonboard.com> (\n\t=?utf-8?b?IkJhcm5hYsOhcyBQxZFjemUiJ3M=?= message of \"Fri,\n\t11 Jul 2025  17:28:59 +0200\")","References":"<20250702131032.47654-1-mzamazal@redhat.com>\n\t<20250702131032.47654-5-mzamazal@redhat.com>\n\t<32d8134e-c4fa-4ce9-b7e2-8107edced7d3@ideasonboard.com>","Date":"Fri, 11 Jul 2025 21:34:38 +0200","Message-ID":"<85ple6bjxt.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"PPbcTcJ-nIXzxIG__8iW1uq6Vq_lFC4F-y7s0boVmD4_1752262481","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"quoted-printable","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]