[{"id":34696,"web_url":"https://patchwork.libcamera.org/comment/34696/","msgid":"<23b07750-dfe5-4790-8ca0-82e4b59db93b@ideasonboard.com>","date":"2025-06-27T14:00:44","subject":"Re: [PATCH v11 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. 06. 24. 10:36 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>          target: TARGET\n>          pipeline_handler:\n\nThis seems a bit limiting to me. The same configuration cannot be used\nfor vc4 and pisp. I feel like something like\n\n   rpi:\n     bcm2835:\n       ...\n     pisp:\n       ...\n\nwould be better. I am not sure how the two could be best reconciled.\nMaybe a `platformName` variable/function in the case class that specifies\na string_view/const char * describing the target. It could then be used\nto select the right object in the dictionary and/or to validate the target\nin $LIBCAMERA_RPI_CONFIG_FILE.\n\n\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     | 60 +++++++++++--------\n>   .../pipeline/rpi/common/pipeline_base.h       |  2 +-\n>   src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 14 +----\n>   src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 14 +----\n>   4 files changed, 42 insertions(+), 48 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 e14d3b913..a316ef297 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> @@ -1085,37 +1087,42 @@ int CameraData::loadPipelineConfiguration()\n>   \t};\n>   \n>   \t/* Initial configuration of the platform, in case no config file is present */\n> -\tplatformPipelineConfigure({});\n> +\tstd::optional<std::string> empty;\n> +\tplatformPipelineConfigure({}, empty);\n\nWhy does this not take `const std::optional<std::string>&`?\nThen you could just do `platformPipelineConfigure({}, {})`.\n\n\nRegards,\nBarnabás Pőcze\n\n\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>   \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[\"pipeline_handler\"]);\n>   \n>   \tif (phConfig.contains(\"disable_startup_frame_drops\"))\n>   \t\tLOG(RPI, Warning)\n> @@ -1131,7 +1138,10 @@ int CameraData::loadPipelineConfiguration()\n>   \t\tfrontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n>   \t}\n>   \n> -\treturn platformPipelineConfigure(root);\n> +\tstd::optional<std::string> target = (root\n> +\t\t\t\t\t\t     ? (*root)[\"target\"].get<std::string>()\n> +\t\t\t\t\t\t     : config.get<std::string>(\"target\"));\n> +\treturn platformPipelineConfigure(phConfig, target);\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 4c5743e04..34684d882 100644\n> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> @@ -96,7 +96,7 @@ public:\n>   \tvirtual V4L2VideoDevice::Formats rawFormats() const = 0;\n>   \tvirtual V4L2VideoDevice *frontendDevice() = 0;\n>   \n> -\tvirtual int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) = 0;\n> +\tvirtual int platformPipelineConfigure(const YamlObject &phConfig, 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..54d885c8a 100644\n> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> @@ -743,7 +743,7 @@ public:\n>   \tCameraConfiguration::Status\n>   \tplatformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n>   \n> -\tint platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n> +\tint platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) override;\n>   \n>   \tvoid platformStart() override;\n>   \tvoid platformStop() override;\n> @@ -1331,7 +1331,7 @@ 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(const YamlObject &phConfig, std::optional<std::string> &target)\n>   {\n>   \tconfig_ = {\n>   \t\t.numCfeConfigStatsBuffers = 12,\n> @@ -1340,23 +1340,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>   \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..714110c7e 100644\n> --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> @@ -67,7 +67,7 @@ public:\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, std::optional<std::string> &target) override;\n>   \n>   \tvoid platformStart() override;\n>   \tvoid platformStop() override;\n> @@ -493,30 +493,22 @@ 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(const YamlObject &phConfig, std::optional<std::string> &target)\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>   \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 94B36C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 27 Jun 2025 14:01:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C9F6F68E04;\n\tFri, 27 Jun 2025 16:00:58 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0303E68E04\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 27 Jun 2025 16:00:50 +0200 (CEST)","from [192.168.33.12] (185.221.143.107.nat.pool.zt.hu\n\t[185.221.143.107])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EAA4D13E2;\n\tFri, 27 Jun 2025 16:00:30 +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=\"UdHUV0OV\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1751032831;\n\tbh=A4VFvjMR/IMKxdTwxyOYnuMz1SkRYg7lE8FbsU+DZ7A=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=UdHUV0OVSzzNSOm/snr/4SBPsPX5qv+0QcSnjjIIvwR7WtNUI931BOR/wWojMKtX2\n\tgYnxjV9uVhxGzSJTGsgqTcMcE60Khw8SyKEhaxvcpTLFkZZ1Bb7hlvywRWHnnU/3aP\n\tozCd2QNPMa/OkWu3nOT8ELNtKicn19xTc8Z6QPZU=","Message-ID":"<23b07750-dfe5-4790-8ca0-82e4b59db93b@ideasonboard.com>","Date":"Fri, 27 Jun 2025 16:00:44 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v11 04/12] config: Look up rpi configuration in the\n\tconfiguration file","To":"Milan Zamazal <mzamazal@redhat.com>, libcamera-devel@lists.libcamera.org,\n\tNaushir Patuck <naush@raspberrypi.com>,\n\tDavid Plowman <david.plowman@raspberrypi.com>","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20250624083612.27230-1-mzamazal@redhat.com>\n\t<20250624083612.27230-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":"<20250624083612.27230-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":34713,"web_url":"https://patchwork.libcamera.org/comment/34713/","msgid":"<85bjq9vuzh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-06-27T19:34:58","subject":"Re: [PATCH v11 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. 06. 24. 10:36 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>>          target: TARGET\n>>          pipeline_handler:\n>\n> This seems a bit limiting to me. The same configuration cannot be used\n> for vc4 and pisp. I feel like something like\n>\n>   rpi:\n>     bcm2835:\n>       ...\n>     pisp:\n>       ...\n>\n> would be better. I am not sure how the two could be best reconciled.\n> Maybe a `platformName` variable/function in the case class that specifies\n> a string_view/const char * describing the target. It could then be used\n> to select the right object in the dictionary and/or to validate the target\n> in $LIBCAMERA_RPI_CONFIG_FILE.\n\nI'm not sure either, which is why I kept it simple in the first version.\nI'd like to hear opinion from the rpi people here before messing with\nthe implementation, what structure of the YAML configuration they\nprefer.\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>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>   .../pipeline/rpi/common/pipeline_base.cpp     | 60 +++++++++++--------\n>>   .../pipeline/rpi/common/pipeline_base.h       |  2 +-\n>>   src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 14 +----\n>>   src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 14 +----\n>>   4 files changed, 42 insertions(+), 48 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 e14d3b913..a316ef297 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>>   @@ -1085,37 +1087,42 @@ int CameraData::loadPipelineConfiguration()\n>>   \t};\n>>     \t/* Initial configuration of the platform, in case no config file is present */\n>> -\tplatformPipelineConfigure({});\n>> +\tstd::optional<std::string> empty;\n>> +\tplatformPipelineConfigure({}, empty);\n>\n> Why does this not take `const std::optional<std::string>&`?\n> Then you could just do `platformPipelineConfigure({}, {})`.\n\nAh, right, thanks.\n\n> Regards,\n> Barnabás Pőcze\n>\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>>   -\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>>   \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[\"pipeline_handler\"]);\n>>     \tif (phConfig.contains(\"disable_startup_frame_drops\"))\n>>   \t\tLOG(RPI, Warning)\n>> @@ -1131,7 +1138,10 @@ int CameraData::loadPipelineConfiguration()\n>>   \t\tfrontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n>>   \t}\n>>   -\treturn platformPipelineConfigure(root);\n>> +\tstd::optional<std::string> target = (root\n>> +\t\t\t\t\t\t     ? (*root)[\"target\"].get<std::string>()\n>> +\t\t\t\t\t\t     : config.get<std::string>(\"target\"));\n>> +\treturn platformPipelineConfigure(phConfig, target);\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 4c5743e04..34684d882 100644\n>> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n>> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n>> @@ -96,7 +96,7 @@ public:\n>>   \tvirtual V4L2VideoDevice::Formats rawFormats() const = 0;\n>>   \tvirtual V4L2VideoDevice *frontendDevice() = 0;\n>>   -\tvirtual int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) = 0;\n>> +\tvirtual int platformPipelineConfigure(const YamlObject &phConfig, 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..54d885c8a 100644\n>> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n>> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n>> @@ -743,7 +743,7 @@ public:\n>>   \tCameraConfiguration::Status\n>>   \tplatformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n>>   -\tint platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n>> +\tint platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) override;\n>>     \tvoid platformStart() override;\n>>   \tvoid platformStop() override;\n>> @@ -1331,7 +1331,7 @@ PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n>>   \treturn status;\n>>   }\n>>   -int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n>> +int PiSPCameraData::platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target)\n>>   {\n>>   \tconfig_ = {\n>>   \t\t.numCfeConfigStatsBuffers = 12,\n>> @@ -1340,23 +1340,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>>   \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..714110c7e 100644\n>> --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> @@ -67,7 +67,7 @@ public:\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, std::optional<std::string> &target) override;\n>>     \tvoid platformStart() override;\n>>   \tvoid platformStop() override;\n>> @@ -493,30 +493,22 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig\n>>   \treturn status;\n>>   }\n>>   -int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n>> +int Vc4CameraData::platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target)\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>>   \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 45773BDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 27 Jun 2025 19:40:14 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C47A668E04;\n\tFri, 27 Jun 2025 21:40:12 +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 B0C0868DE5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 27 Jun 2025 21:40:10 +0200 (CEST)","from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n\t[209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-10-Wk-T_S77NFWUv-eceTs6NQ-1; Fri, 27 Jun 2025 15:35:05 -0400","by mail-wr1-f69.google.com with SMTP id\n\tffacd0b85a97d-3a4f8fd1847so1011366f8f.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 27 Jun 2025 12:35:04 -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-3a88c7e6f74sm3513337f8f.3.2025.06.27.12.34.59\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 27 Jun 2025 12:34:59 -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=\"RrlPFPMv\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1751053209;\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=zEOEvVcr8B8uo6PKKCOBE58PVvrJKHSV2OqkLne6Y4E=;\n\tb=RrlPFPMv9R+H73Fe+QiW4KUohkVqY2zsdD2ssNaI5FBGbS8EZ78vSAa/pnHY2ATBLVUnpV\n\thilNT0dgXNcMoi8YhyD1Sr7RDFguUXYjQN2trjGgxCnHhCk5bFkThIzOKFkqB1kZq6koB7\n\tonuSsCb4ubPsUvo2uDgCjxxUgOvgKQ4=","X-MC-Unique":"Wk-T_S77NFWUv-eceTs6NQ-1","X-Mimecast-MFC-AGG-ID":"Wk-T_S77NFWUv-eceTs6NQ_1751052904","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1751052904; x=1751657704;\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=QBtR4JtXTnbUIVqpucuP6pDGdmTn+lz5yTNZqGsmrrw=;\n\tb=Renh41P+qpLhsefvLhr2o8VrmOCTFktC/flzRz/cTqi1x7vw9Pk9anBMTiBmIP8XAM\n\tL+x/nI1i88wZb9j20QHmWRGbSmhcfOydBrOqB+OIeA46thfnXig005/p7Wemqzvf1hUO\n\t6i2e+yScfC7SGSbGXx+Hy8tvf0HXo/RbyLxA3amyoJXUHXe1WClKNVzip4L6tPl1RgOq\n\tES64ufgDd3CjJrFHTZl95Uxz370ZApPKv94FblnDmEYYJxbxJfQzoq4dGoXp+fmiZHPF\n\tQo+BCLGHcIvUMMlcp4Mxst2vL4fSKUs7QiTFBk6XDVeqeVfVFaWi4GWbjD4mBjoOJF2K\n\tu5TA==","X-Gm-Message-State":"AOJu0Yy0KOKs1UVwVlU3IT94NXbEYdScFL7ju3IVJE/XNU/ZyYfadC04\n\tJvNEEgL7F4aC3zpS7BTNTgm6t0gly1e7mV8E01XioIz57scmvVk5yrgHF+WJSgO0o9R/7eGTBaz\n\tAPkkn8hjXCdKU3NNSiUeNrmyc9mnt/vDk7e6fqS2qJHict9zcGNhZSACsJvhhR6IYyJUzzEh7Rn\n\tc=","X-Gm-Gg":"ASbGncsPyw0ShGP/3CiIHjQAUccGoGV3JGlQuaQNg5N0VOg8tm9CUy6a5ofQDcKaPTx\n\tgySJeif1dgBi0SqlEQmefP1R+kHkRIV3idg9t4+AXhD3AiQ0ULcaV5BoT1SBhGuEI08OJhZt1Bt\n\tNMBrFQ2xmdRZ6vYYDTuEa/T6ORnlW92PB3s575MLQaWKY9YRwo/c1018ABgBeJzgUjOPTKUlkgW\n\tcC7OhJpuGO25hkPkBs4PCmoGPZWnocrbE/Y0pR9gIOxGZ5whZ4rzza8lmGO7eXhkyja3TzoSTqM\n\tAScdk8TcbG5VDJnfBoPfnXVuDiyzbT5Zs/xBAUFR9IhmXNt6xZ4umR+pu2cwxnBCRwsV3ZyFNZ8\n\t=","X-Received":["by 2002:adf:9dd2:0:b0:3a4:d939:62f8 with SMTP id\n\tffacd0b85a97d-3a8ffcc9955mr3688667f8f.32.1751052902106; \n\tFri, 27 Jun 2025 12:35:02 -0700 (PDT)","by 2002:adf:9dd2:0:b0:3a4:d939:62f8 with SMTP id\n\tffacd0b85a97d-3a8ffcc9955mr3688619f8f.32.1751052900143; \n\tFri, 27 Jun 2025 12:35:00 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IF/a46cHfIsjYVZKRsozXqY0JTjpYSA3skdomyk5Br5biDLS1hLIb0Sap+qDtye8tA2h7pdjw==","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,  Naushir Patuck\n\t<naush@raspberrypi.com>, David Plowman <david.plowman@raspberrypi.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,  Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>","Subject":"Re: [PATCH v11 04/12] config: Look up rpi configuration in the\n\tconfiguration file","In-Reply-To":"<23b07750-dfe5-4790-8ca0-82e4b59db93b@ideasonboard.com> (\n\t=?utf-8?b?IkJhcm5hYsOhcyBQxZFjemUiJ3M=?= message of \"Fri,\n\t27 Jun 2025  16:00:44 +0200\")","References":"<20250624083612.27230-1-mzamazal@redhat.com>\n\t<20250624083612.27230-5-mzamazal@redhat.com>\n\t<23b07750-dfe5-4790-8ca0-82e4b59db93b@ideasonboard.com>","Date":"Fri, 27 Jun 2025 21:34:58 +0200","Message-ID":"<85bjq9vuzh.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":"QFisokhnB2aTy9O70-fiMYwBx3s1jDAsS-zRIleOess_1751052904","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>"}},{"id":34733,"web_url":"https://patchwork.libcamera.org/comment/34733/","msgid":"<CAEmqJPqjR91My+jz8=UYdf_7xPOKjSdmjcaMvtcPBrwBgwhypw@mail.gmail.com>","date":"2025-06-30T10:02:01","subject":"Re: [PATCH v11 04/12] config: Look up rpi configuration in the\n\tconfiguration file","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Milan and Barnabás,\n\n\nOn Fri, 27 Jun 2025 at 20:35, Milan Zamazal <mzamazal@redhat.com> wrote:\n>\n> Hi Barnabás,\n>\n> thank you for review.\n>\n> Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:\n>\n> > Hi\n> >\n> > 2025. 06. 24. 10:36 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> >>          target: TARGET\n> >>          pipeline_handler:\n> >\n> > This seems a bit limiting to me. The same configuration cannot be used\n> > for vc4 and pisp. I feel like something like\n> >\n> >   rpi:\n> >     bcm2835:\n> >       ...\n> >     pisp:\n> >       ...\n> >\n> > would be better. I am not sure how the two could be best reconciled.\n> > Maybe a `platformName` variable/function in the case class that specifies\n> > a string_view/const char * describing the target. It could then be used\n> > to select the right object in the dictionary and/or to validate the target\n> > in $LIBCAMERA_RPI_CONFIG_FILE.\n>\n> I'm not sure either, which is why I kept it simple in the first version.\n> I'd like to hear opinion from the rpi people here before messing with\n> the implementation, what structure of the YAML configuration they\n> prefer.\n\nWe definitely want to have different settings for bcm2835 and pisp.  I\nlike the structure Barnabás proposed above.  I should (hopefully!) be\nrelatively simple to get a target string for the target through the\npipeline handler.  Sorry this is more work than originally expected.\n\nRegards,\nNaush\n\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> >> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> >> ---\n> >>   .../pipeline/rpi/common/pipeline_base.cpp     | 60 +++++++++++--------\n> >>   .../pipeline/rpi/common/pipeline_base.h       |  2 +-\n> >>   src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 14 +----\n> >>   src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 14 +----\n> >>   4 files changed, 42 insertions(+), 48 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 e14d3b913..a316ef297 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> >>   @@ -1085,37 +1087,42 @@ int CameraData::loadPipelineConfiguration()\n> >>      };\n> >>      /* Initial configuration of the platform, in case no config file is present */\n> >> -    platformPipelineConfigure({});\n> >> +    std::optional<std::string> empty;\n> >> +    platformPipelineConfigure({}, empty);\n> >\n> > Why does this not take `const std::optional<std::string>&`?\n> > Then you could just do `platformPipelineConfigure({}, {})`.\n>\n> Ah, right, thanks.\n>\n> > Regards,\n> > Barnabás Pőcze\n> >\n> >\n> >>   +  std::unique_ptr<YamlObject> root;\n> >>      char const *configFromEnv = utils::secure_getenv(\"LIBCAMERA_RPI_CONFIG_FILE\");\n> >> -    if (!configFromEnv || *configFromEnv == '\\0')\n> >> -            return 0;\n> >> -\n> >> -    std::string filename = std::string(configFromEnv);\n> >> -    File file(filename);\n> >> -\n> >> -    if (!file.open(File::OpenModeFlag::ReadOnly)) {\n> >> -            LOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n> >> -                              << \", using defaults\";\n> >> -            return 0;\n> >> -    }\n> >> +    if (configFromEnv && *configFromEnv != '\\0') {\n> >> +            std::string filename = std::string(configFromEnv);\n> >> +            File file(filename);\n> >> +\n> >> +            if (!file.open(File::OpenModeFlag::ReadOnly)) {\n> >> +                    LOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n> >> +                                      << \", using defaults\";\n> >> +                    return 0;\n> >> +            }\n> >>   -  LOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n> >> +            LOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n> >>   -  std::unique_ptr<YamlObject> root = YamlParser::parse(file);\n> >> -    if (!root) {\n> >> -            LOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n> >> -            return 0;\n> >> -    }\n> >> +            root = YamlParser::parse(file);\n> >> +            if (!root) {\n> >> +                    LOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n> >> +                    return 0;\n> >> +            }\n> >>   -  std::optional<double> ver = (*root)[\"version\"].get<double>();\n> >> -    if (!ver || *ver != 1.0) {\n> >> -            LOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n> >> -                              << *ver;\n> >> -            return 0;\n> >> +            std::optional<double> ver = (*root)[\"version\"].get<double>();\n> >> +            if (!ver || *ver != 1.0) {\n> >> +                    LOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n> >> +                                      << *ver;\n> >> +                    return 0;\n> >> +            }\n> >>      }\n> >>   -  const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n> >> +    GlobalConfiguration::Configuration config =\n> >> +            pipe()->cameraManager()->_d()->configuration().configuration()[\"pipeline\"][\"rpi\"];\n> >> +    const YamlObject &phConfig = (root\n> >> +                                          ? (*root)[\"pipeline_handler\"]\n> >> +                                          : config[\"pipeline_handler\"]);\n> >>      if (phConfig.contains(\"disable_startup_frame_drops\"))\n> >>              LOG(RPI, Warning)\n> >> @@ -1131,7 +1138,10 @@ int CameraData::loadPipelineConfiguration()\n> >>              frontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n> >>      }\n> >>   -  return platformPipelineConfigure(root);\n> >> +    std::optional<std::string> target = (root\n> >> +                                                 ? (*root)[\"target\"].get<std::string>()\n> >> +                                                 : config.get<std::string>(\"target\"));\n> >> +    return platformPipelineConfigure(phConfig, target);\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 4c5743e04..34684d882 100644\n> >> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> >> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> >> @@ -96,7 +96,7 @@ public:\n> >>      virtual V4L2VideoDevice::Formats rawFormats() const = 0;\n> >>      virtual V4L2VideoDevice *frontendDevice() = 0;\n> >>   -  virtual int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) = 0;\n> >> +    virtual int platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) = 0;\n> >>      std::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..54d885c8a 100644\n> >> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> >> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> >> @@ -743,7 +743,7 @@ public:\n> >>      CameraConfiguration::Status\n> >>      platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n> >>   -  int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n> >> +    int platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) override;\n> >>      void platformStart() override;\n> >>      void platformStop() override;\n> >> @@ -1331,7 +1331,7 @@ PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n> >>      return status;\n> >>   }\n> >>   -int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n> >> +int PiSPCameraData::platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target)\n> >>   {\n> >>      config_ = {\n> >>              .numCfeConfigStatsBuffers = 12,\n> >> @@ -1340,23 +1340,15 @@ int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject>\n> >>              .disableHdr = false,\n> >>      };\n> >>   -  if (!root)\n> >> +    if (!phConfig)\n> >>              return 0;\n> >>   -  std::optional<double> ver = (*root)[\"version\"].get<double>();\n> >> -    if (!ver || *ver != 1.0) {\n> >> -            LOG(RPI, Error) << \"Unexpected configuration file version reported\";\n> >> -            return -EINVAL;\n> >> -    }\n> >> -\n> >> -    std::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n> >>      if (target != \"pisp\") {\n> >>              LOG(RPI, Error) << \"Unexpected target reported: expected \\\"pisp\\\", got \"\n> >>                              << (target ? target->c_str() : \"(unknown)\");\n> >>              return -EINVAL;\n> >>      }\n> >>   -  const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n> >>      config_.numCfeConfigStatsBuffers =\n> >>              phConfig[\"num_cfe_config_stats_buffers\"].get<unsigned int>(config_.numCfeConfigStatsBuffers);\n> >>      config_.numCfeConfigQueue =\n> >> diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> >> index e99a7edf8..714110c7e 100644\n> >> --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> >> +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> >> @@ -67,7 +67,7 @@ public:\n> >>      CameraConfiguration::Status platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n> >> override;\n> >>   -  int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n> >> +    int platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) override;\n> >>      void platformStart() override;\n> >>      void platformStop() override;\n> >> @@ -493,30 +493,22 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig\n> >>      return status;\n> >>   }\n> >>   -int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n> >> +int Vc4CameraData::platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target)\n> >>   {\n> >>      config_ = {\n> >>              .minUnicamBuffers = 2,\n> >>              .minTotalUnicamBuffers = 4,\n> >>      };\n> >>   -  if (!root)\n> >> +    if (!phConfig)\n> >>              return 0;\n> >>   -  std::optional<double> ver = (*root)[\"version\"].get<double>();\n> >> -    if (!ver || *ver != 1.0) {\n> >> -            LOG(RPI, Error) << \"Unexpected configuration file version reported\";\n> >> -            return -EINVAL;\n> >> -    }\n> >> -\n> >> -    std::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n> >>      if (target != \"bcm2835\") {\n> >>              LOG(RPI, Error) << \"Unexpected target reported: expected \\\"bcm2835\\\", got \"\n> >>                              << (target ? target->c_str() : \"(unknown)\");\n> >>              return -EINVAL;\n> >>      }\n> >>   -  const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n> >>      config_.minUnicamBuffers =\n> >>              phConfig[\"min_unicam_buffers\"].get<unsigned int>(config_.minUnicamBuffers);\n> >>      config_.minTotalUnicamBuffers =\n>","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 A3C3BC3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 30 Jun 2025 10:02:38 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 724C068E09;\n\tMon, 30 Jun 2025 12:02:37 +0200 (CEST)","from mail-vs1-xe32.google.com (mail-vs1-xe32.google.com\n\t[IPv6:2607:f8b0:4864:20::e32])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 787FD68E00\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 30 Jun 2025 12:02:35 +0200 (CEST)","by mail-vs1-xe32.google.com with SMTP id\n\tada2fe7eead31-4e9ab124fa8so173115137.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 30 Jun 2025 03:02:35 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"PmNxaM1h\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1751277754; x=1751882554;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=9hJQCeQPA5ktBSnlcYNB1ot9QzzAX3rQBWZu52h4DcE=;\n\tb=PmNxaM1hXEpSRsqOm1KyO7aXc7AfDxtJ/BODNvYjytG7/uUBxu871N1k73jx4yE5Ww\n\tgCFbEiayyCekdMiVnKgzlwUGacuxjXMhUQdwUg3GE8d378qYGE7PCkbz9tQLo8xlJLiQ\n\taNYqwM8aKWx6Y6GXvZdxmv308JyCCcKOCAyQsLcnRS8BHq7zYHNmGQsMYI0WpiwKiXhk\n\tirUFFm7+YdQwKgHhfR01q08JGrfRGn0XdpK+XoxF9Gb4HndLofJSSBELXUWCoKGuTU5M\n\tAAzb16r59bNq/ofX7nsDX+lLDB6i0LoQkHFoNtbUsz3eKzFepFG4R90ZI4Wmt/URtZdH\n\tIoHg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1751277754; x=1751882554;\n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=9hJQCeQPA5ktBSnlcYNB1ot9QzzAX3rQBWZu52h4DcE=;\n\tb=Po28WLSLkptun/atdOgzvtcVL2TsoZixyPRFs/JI3+Z2hRQ7zAuC2HLdhCBC1iE5jz\n\tCLmqG0qi7b1h6dzEiB31+UqMKQLe4HKwo5AViz2VeQnDPhWqZRc5qRWbId+JeCmrz9jk\n\t0aYxgIID08crbwTYSMBYXZ9+UMsXJluexkR68GKZcU+vYYWe2vSL9cj4pnlRLUaAXqeh\n\ttV0E2U4TgSBsndjizr1nNwTQt1jPmgqXg0YnNzopc0oLWfbuzEEKIS/UW1YF5rU6yb4h\n\tiRcX8TEOS9nGVlg79zdHhH4saIbev+hKGCCkNhqoqWquEUB+N0wO0vggVu1ipP+a1jX0\n\tqv1A==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCWclM3y9JG35wHfnXWpHiwbdAKSN9qNIlBU1ZH1wqwD/4FwG+XwNMdjU/nlufOghhct3wsibSN7ylklySqYwNg=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YwRUnBMwMJ4Rz/VWql2isXboB4AZICHEdko8artlI1CZjEBbrGE\n\tcLZXMJPztj33kfcLnBgphEANzdwXd9B5O2I18vm9Cvu/jDqAt/rJRbRim21jV2p2VgWVkfpk53j\n\tWBdfGyg6LNlsiAHJmNeA1d92mvy2FKDOr83MpafW5LQ==","X-Gm-Gg":"ASbGncv9iTQbUBRi6rp4r1PuelNpT9aQWZAQy6JewG/AjFR07idY8sDIhGzwvcLsLTD\n\tIK+PLTqyybie4Rv1gzDvWgMLkWZ4ivEil/Kf+SO7Zm1ew7yvObQ9awXHzakZaKjAelALVxvOydu\n\tWXevJ1oNrLKXIQ1E31zVUOCcocBnpK//rkCLnLNfnQ5OLNHVAxbyawVO7LhL9IOgmnkhIh15PUa\n\tEI=","X-Google-Smtp-Source":"AGHT+IEyR6RTI2LaMV2ldlKrrxShCs5HW6DvnrO6JvjZ4TvkylJBVXr4j+QXrosek3sF76p0Pov1DOyUJIcKS1oH5FM=","X-Received":"by 2002:a05:6102:5492:b0:4eb:efc6:73f with SMTP id\n\tada2fe7eead31-4efa8a52c33mr1109794137.5.1751277754118;\n\tMon, 30 Jun 2025 03:02:34 -0700 (PDT)","MIME-Version":"1.0","References":"<20250624083612.27230-1-mzamazal@redhat.com>\n\t<20250624083612.27230-5-mzamazal@redhat.com>\n\t<23b07750-dfe5-4790-8ca0-82e4b59db93b@ideasonboard.com>\n\t<85bjq9vuzh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","In-Reply-To":"<85bjq9vuzh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Mon, 30 Jun 2025 11:02:01 +0100","X-Gm-Features":"Ac12FXz9k4A4tgdruYAyvUxryjH8cFcF13wg5lvWuT0OXUrlC3MjtsfSXzhQjgQ","Message-ID":"<CAEmqJPqjR91My+jz8=UYdf_7xPOKjSdmjcaMvtcPBrwBgwhypw@mail.gmail.com>","Subject":"Re: [PATCH v11 04/12] config: Look up rpi configuration in the\n\tconfiguration file","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org, David Plowman\n\t<david.plowman@raspberrypi.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.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>"}},{"id":34746,"web_url":"https://patchwork.libcamera.org/comment/34746/","msgid":"<854ivxdubf.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-06-30T17:15:48","subject":"Re: [PATCH v11 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 Naush,\n\nNaushir Patuck <naush@raspberrypi.com> writes:\n\n> Hi Milan and Barnabás,\n>\n>\n> On Fri, 27 Jun 2025 at 20:35, Milan Zamazal <mzamazal@redhat.com> wrote:\n>>\n>> Hi Barnabás,\n>>\n>> thank you for review.\n>>\n>> Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:\n>>\n>> > Hi\n>> >\n>> > 2025. 06. 24. 10:36 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>> >>          target: TARGET\n>> >>          pipeline_handler:\n>> >\n>> > This seems a bit limiting to me. The same configuration cannot be used\n>> > for vc4 and pisp. I feel like something like\n>> >\n>> >   rpi:\n>> >     bcm2835:\n>> >       ...\n>> >     pisp:\n>> >       ...\n>> >\n>> > would be better. I am not sure how the two could be best reconciled.\n>> > Maybe a `platformName` variable/function in the case class that specifies\n>> > a string_view/const char * describing the target. It could then be used\n>> > to select the right object in the dictionary and/or to validate the target\n>> > in $LIBCAMERA_RPI_CONFIG_FILE.\n>>\n>> I'm not sure either, which is why I kept it simple in the first version.\n>> I'd like to hear opinion from the rpi people here before messing with\n>> the implementation, what structure of the YAML configuration they\n>> prefer.\n>\n> We definitely want to have different settings for bcm2835 and pisp.  I\n> like the structure Barnabás proposed above.\n\nOK, thank you for clarification.\n\n> I should (hopefully!) be relatively simple to get a target string for\n> the target through the pipeline handler.  \n\nYes, it is.\n\n> Sorry this is more work than originally expected.\n\nNo problem, it's not a complicated change.\n\n> Regards,\n> Naush\n>\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>> >> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> >> ---\n>> >>   .../pipeline/rpi/common/pipeline_base.cpp     | 60 +++++++++++--------\n>> >>   .../pipeline/rpi/common/pipeline_base.h       |  2 +-\n>> >>   src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 14 +----\n>> >>   src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 14 +----\n>> >>   4 files changed, 42 insertions(+), 48 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 e14d3b913..a316ef297 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>> >>   @@ -1085,37 +1087,42 @@ int CameraData::loadPipelineConfiguration()\n>> >>      };\n>> >>      /* Initial configuration of the platform, in case no config file is present */\n>> >> -    platformPipelineConfigure({});\n>> >> +    std::optional<std::string> empty;\n>> >> +    platformPipelineConfigure({}, empty);\n>> >\n>> > Why does this not take `const std::optional<std::string>&`?\n>> > Then you could just do `platformPipelineConfigure({}, {})`.\n>>\n>> Ah, right, thanks.\n>>\n>> > Regards,\n>> > Barnabás Pőcze\n>> >\n>> >\n>> >>   +  std::unique_ptr<YamlObject> root;\n>> >>      char const *configFromEnv = utils::secure_getenv(\"LIBCAMERA_RPI_CONFIG_FILE\");\n>> >> -    if (!configFromEnv || *configFromEnv == '\\0')\n>> >> -            return 0;\n>> >> -\n>> >> -    std::string filename = std::string(configFromEnv);\n>> >> -    File file(filename);\n>> >> -\n>> >> -    if (!file.open(File::OpenModeFlag::ReadOnly)) {\n>> >> -            LOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n>> >> -                              << \", using defaults\";\n>> >> -            return 0;\n>> >> -    }\n>> >> +    if (configFromEnv && *configFromEnv != '\\0') {\n>> >> +            std::string filename = std::string(configFromEnv);\n>> >> +            File file(filename);\n>> >> +\n>> >> +            if (!file.open(File::OpenModeFlag::ReadOnly)) {\n>> >> +                    LOG(RPI, Warning) << \"Failed to open configuration file '\" << filename << \"'\"\n>> >> +                                      << \", using defaults\";\n>> >> +                    return 0;\n>> >> +            }\n>> >>   -  LOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n>> >> +            LOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n>> >>   -  std::unique_ptr<YamlObject> root = YamlParser::parse(file);\n>> >> -    if (!root) {\n>> >> -            LOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n>> >> -            return 0;\n>> >> -    }\n>> >> +            root = YamlParser::parse(file);\n>> >> +            if (!root) {\n>> >> +                    LOG(RPI, Warning) << \"Failed to parse configuration file, using defaults\";\n>> >> +                    return 0;\n>> >> +            }\n>> >>   -  std::optional<double> ver = (*root)[\"version\"].get<double>();\n>> >> -    if (!ver || *ver != 1.0) {\n>> >> -            LOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n>> >> -                              << *ver;\n>> >> -            return 0;\n>> >> +            std::optional<double> ver = (*root)[\"version\"].get<double>();\n>> >> +            if (!ver || *ver != 1.0) {\n>> >> +                    LOG(RPI, Warning) << \"Unexpected configuration file version reported: \"\n>> >> +                                      << *ver;\n>> >> +                    return 0;\n>> >> +            }\n>> >>      }\n>> >>   -  const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>> >> +    GlobalConfiguration::Configuration config =\n>> >> +            pipe()->cameraManager()->_d()->configuration().configuration()[\"pipeline\"][\"rpi\"];\n>> >> +    const YamlObject &phConfig = (root\n>> >> +                                          ? (*root)[\"pipeline_handler\"]\n>> >> +                                          : config[\"pipeline_handler\"]);\n>> >>      if (phConfig.contains(\"disable_startup_frame_drops\"))\n>> >>              LOG(RPI, Warning)\n>> >> @@ -1131,7 +1138,10 @@ int CameraData::loadPipelineConfiguration()\n>> >>              frontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n>> >>      }\n>> >>   -  return platformPipelineConfigure(root);\n>> >> +    std::optional<std::string> target = (root\n>> >> +                                                 ? (*root)[\"target\"].get<std::string>()\n>> >> +                                                 : config.get<std::string>(\"target\"));\n>> >> +    return platformPipelineConfigure(phConfig, target);\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 4c5743e04..34684d882 100644\n>> >> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n>> >> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n>> >> @@ -96,7 +96,7 @@ public:\n>> >>      virtual V4L2VideoDevice::Formats rawFormats() const = 0;\n>> >>      virtual V4L2VideoDevice *frontendDevice() = 0;\n>> >>   -  virtual int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) = 0;\n>> >> +    virtual int platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) = 0;\n>> >>      std::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..54d885c8a 100644\n>> >> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n>> >> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n>> >> @@ -743,7 +743,7 @@ public:\n>> >>      CameraConfiguration::Status\n>> >>      platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n>> >>   -  int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n>> >> +    int platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) override;\n>> >>      void platformStart() override;\n>> >>      void platformStop() override;\n>> >> @@ -1331,7 +1331,7 @@ PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n>> >>      return status;\n>> >>   }\n>> >>   -int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n>> >> +int PiSPCameraData::platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target)\n>> >>   {\n>> >>      config_ = {\n>> >>              .numCfeConfigStatsBuffers = 12,\n>> >> @@ -1340,23 +1340,15 @@ int PiSPCameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject>\n>> >>              .disableHdr = false,\n>> >>      };\n>> >>   -  if (!root)\n>> >> +    if (!phConfig)\n>> >>              return 0;\n>> >>   -  std::optional<double> ver = (*root)[\"version\"].get<double>();\n>> >> -    if (!ver || *ver != 1.0) {\n>> >> -            LOG(RPI, Error) << \"Unexpected configuration file version reported\";\n>> >> -            return -EINVAL;\n>> >> -    }\n>> >> -\n>> >> -    std::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n>> >>      if (target != \"pisp\") {\n>> >>              LOG(RPI, Error) << \"Unexpected target reported: expected \\\"pisp\\\", got \"\n>> >>                              << (target ? target->c_str() : \"(unknown)\");\n>> >>              return -EINVAL;\n>> >>      }\n>> >>   -  const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>> >>      config_.numCfeConfigStatsBuffers =\n>> >>              phConfig[\"num_cfe_config_stats_buffers\"].get<unsigned int>(config_.numCfeConfigStatsBuffers);\n>> >>      config_.numCfeConfigQueue =\n>> >> diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> >> index e99a7edf8..714110c7e 100644\n>> >> --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> >> +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n>> >> @@ -67,7 +67,7 @@ public:\n>> >>      CameraConfiguration::Status platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n>> >> override;\n>> >>   -  int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;\n>> >> +    int platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target) override;\n>> >>      void platformStart() override;\n>> >>      void platformStop() override;\n>> >> @@ -493,30 +493,22 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig\n>> >>      return status;\n>> >>   }\n>> >>   -int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &root)\n>> >> +int Vc4CameraData::platformPipelineConfigure(const YamlObject &phConfig, std::optional<std::string> &target)\n>> >>   {\n>> >>      config_ = {\n>> >>              .minUnicamBuffers = 2,\n>> >>              .minTotalUnicamBuffers = 4,\n>> >>      };\n>> >>   -  if (!root)\n>> >> +    if (!phConfig)\n>> >>              return 0;\n>> >>   -  std::optional<double> ver = (*root)[\"version\"].get<double>();\n>> >> -    if (!ver || *ver != 1.0) {\n>> >> -            LOG(RPI, Error) << \"Unexpected configuration file version reported\";\n>> >> -            return -EINVAL;\n>> >> -    }\n>> >> -\n>> >> -    std::optional<std::string> target = (*root)[\"target\"].get<std::string>();\n>> >>      if (target != \"bcm2835\") {\n>> >>              LOG(RPI, Error) << \"Unexpected target reported: expected \\\"bcm2835\\\", got \"\n>> >>                              << (target ? target->c_str() : \"(unknown)\");\n>> >>              return -EINVAL;\n>> >>      }\n>> >>   -  const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>> >>      config_.minUnicamBuffers =\n>> >>              phConfig[\"min_unicam_buffers\"].get<unsigned int>(config_.minUnicamBuffers);\n>> >>      config_.minTotalUnicamBuffers =\n>>","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 EB301C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 30 Jun 2025 17:15:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CC8BD68E09;\n\tMon, 30 Jun 2025 19:15:56 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8AA6068E00\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 30 Jun 2025 19:15:54 +0200 (CEST)","from mail-wm1-f72.google.com (mail-wm1-f72.google.com\n\t[209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-395-lBk7obAdNXmJDWBMNDbMfA-1; Mon, 30 Jun 2025 13:15:51 -0400","by mail-wm1-f72.google.com with SMTP id\n\t5b1f17b1804b1-451d5600a54so32939655e9.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 30 Jun 2025 10:15:51 -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-3a892e59720sm10895433f8f.73.2025.06.30.10.15.48\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 30 Jun 2025 10:15:49 -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=\"M4+ZG3ZT\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1751303753;\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=c5mggEiIOecpwXMP6ftc5/0YGCQkvQR4GeLxGuLYoVc=;\n\tb=M4+ZG3ZTOl7BVYg9EWcTknlz8m/98MbDmnsi31mPPhaUfyDzWlpsdwZM2fdvXVLIuTlHY9\n\tlfZZdqFQ09cMP0qag9CoSazWVpiGD+g6XlVry4xjDHnqPmcvIQCmwOu4gU1TrHrtkrFklL\n\tJNhD8xiCijmI073T4LdKCLIoyE2Yb0s=","X-MC-Unique":"lBk7obAdNXmJDWBMNDbMfA-1","X-Mimecast-MFC-AGG-ID":"lBk7obAdNXmJDWBMNDbMfA_1751303751","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1751303751; x=1751908551;\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=z88Q/ya2cuUHiXB0H8D6mTvAtZOxxzZ4qQs4YzoDPv4=;\n\tb=HFJejQWZppWWY2R7jKu/E2AY4W2efHlbwk5jq0HmiHZHgr5uB37Kcq3ejWkv+uA7gg\n\tVMOOb9Zgmnzf0dPcmRaT+TgB8nSLT1P6xxN0oVF1nvbsNLfXfvG3+pj8UxdvAscBhoLF\n\tBrKdeJkB8ymIoHYFy3ioKsbC1Y/jC52KhMrV6hmMxio03Z8G7gWQheU5DVrU50kRy1jB\n\t2ovMVWaR4AKW3fvJ1mhq9ECRwW4mtu/JA+zxZbijmFqIgj2cdbb72ztOTPiL2trbu3AI\n\tfwjkONkPueFZURjWGbHBjOMKZGhRljqhf5zTmGwISnDRyMaX6EkfqP2tTlkRqHaeP0W7\n\tbuEA==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCUD8CDDI1XfSkhK7hGsTbX5FfiiJG4uS8RrzfS/i3mxFzBhGv21ffgWjsyRljSO/CZ6dvFuxAInTvlrZiREymU=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YwrKmt8YGHJ5tWHy7M4AGPaicQeHEkgoI/g3YVUleR91044lk27\n\t53a6zHqGUSMdQ4roEczquEep9uHpIV64DdJv7A0NH1/Z+HXegtxFdsYz6/0lDNaeUhfUTDxEWVa\n\tNTZiTUMLatG5DYyRznhmysa9oGr5SLtGcEnvzVOszA7DFzHcvXglKOzUxoQZsXtCx8zq17XNhf4\n\tI=","X-Gm-Gg":"ASbGnct6FnRvuW3YYVlknCaMY4EB8Th4dlwYU3jjy7/nTmjckKJJx0KsEsV1p8cqO0V\n\txH9p1KzA/4jlszT/XARPG05NlO4+6prWmPZWrNQf34Z2kS/hyO2qlYIj6cC5jVT5f3sGpezECO3\n\tKkEdUKoqz6e+sR+l3oTgmyYg7oauWrppQYEgY7gTrIcCEdRXJstldP+gN/U1Rw53uKNpnItBgAR\n\ti+RNDofFRziONzx1GPKJgwskNLYUd0Vcn+ovw6HW8X8w6+4EU0Gsr0PutH9BBssEntmRYW1KsVN\n\tmVf/uipibUuaZgeoYEDNUcudItW8u4W3Gl3RV/uFx2JyrHEM5qk4spmCttRSRaaktOG2sSvfmFs\n\t=","X-Received":["by 2002:a05:600c:8708:b0:44b:eb56:1d45 with SMTP id\n\t5b1f17b1804b1-4538ee2e912mr159161975e9.15.1751303750470; \n\tMon, 30 Jun 2025 10:15:50 -0700 (PDT)","by 2002:a05:600c:8708:b0:44b:eb56:1d45 with SMTP id\n\t5b1f17b1804b1-4538ee2e912mr159161605e9.15.1751303749912; \n\tMon, 30 Jun 2025 10:15:49 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IGSHN7ZGjcGuQeuVk1WrtE6D8M3oWH4Nu0qs2EgGemLG1OihbxEtJI5VAdR1wiMhfoDyA/EWg==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Naushir Patuck <naush@raspberrypi.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org, David Plowman\n\t<david.plowman@raspberrypi.com>,  Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>","Subject":"Re: [PATCH v11 04/12] config: Look up rpi configuration in the\n\tconfiguration file","In-Reply-To":"<CAEmqJPqjR91My+jz8=UYdf_7xPOKjSdmjcaMvtcPBrwBgwhypw@mail.gmail.com>\n\t(Naushir Patuck's message of \"Mon, 30 Jun 2025 11:02:01 +0100\")","References":"<20250624083612.27230-1-mzamazal@redhat.com>\n\t<20250624083612.27230-5-mzamazal@redhat.com>\n\t<23b07750-dfe5-4790-8ca0-82e4b59db93b@ideasonboard.com>\n\t<85bjq9vuzh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>\n\t<CAEmqJPqjR91My+jz8=UYdf_7xPOKjSdmjcaMvtcPBrwBgwhypw@mail.gmail.com>","Date":"Mon, 30 Jun 2025 19:15:48 +0200","Message-ID":"<854ivxdubf.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":"EyBl12XsvGp9nrSLbEOxyQVImM4MLT6mAL_sYsdyopQ_1751303751","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>"}}]