[{"id":35937,"web_url":"https://patchwork.libcamera.org/comment/35937/","msgid":"<20250921043254.GE30137@pendragon.ideasonboard.com>","date":"2025-09-21T04:32:54","subject":"Re: [PATCH v18 04/12] pipeline: rpi: Look up rpi configuration in\n\tthe configuration file","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Sep 12, 2025 at 04:29:05PM +0200, Milan Zamazal wrote:\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>     pipelines:\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> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n\nThis is missing review from David or Naush (on CC). I'll move the patch\nto the end of the series to be able to apply the rest already.\n\n> ---\n>  .../pipeline/rpi/common/pipeline_base.cpp     | 59 +++++++++++--------\n>  .../pipeline/rpi/common/pipeline_base.h       |  3 +-\n>  src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 26 +++-----\n>  src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 26 +++-----\n>  4 files changed, 56 insertions(+), 58 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 c209aa596..a4a018268 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> @@ -1093,35 +1095,46 @@ int CameraData::loadPipelineConfiguration()\n>  \t/* Initial configuration of the platform, in case no config file is present */\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> +\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> -\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> +\t\tLOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n>  \n> -\tLOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\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::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\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> -\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<std::string> t = (*root)[\"target\"].get<std::string>();\n> +\t\tif (t != target()) {\n> +\t\t\tLOG(RPI, Error) << \"Unexpected target reported: expected \\\"\"\n> +\t\t\t\t\t<< target() << \"\\\", got \" << (t ? t->c_str() : \"(unknown)\");\n> +\t\t\treturn -EINVAL;\n> +\t\t}\n>  \t}\n>  \n> -\tconst YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n> +\tGlobalConfiguration::Configuration config =\n> +\t\tpipe()->cameraManager()->_d()->configuration().configuration()[\"pipelines\"][\"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> @@ -1137,7 +1150,7 @@ int CameraData::loadPipelineConfiguration()\n>  \t\tfrontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n>  \t}\n>  \n> -\treturn platformPipelineConfigure(root);\n> +\treturn platformPipelineConfigure(phConfig);\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..ffbede798 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,9 @@ public:\n>  \tvirtual V4L2VideoDevice::Formats ispFormats() const = 0;\n>  \tvirtual V4L2VideoDevice::Formats rawFormats() const = 0;\n>  \tvirtual V4L2VideoDevice *frontendDevice() = 0;\n> +\tvirtual const std::string &target() const = 0;\n>  \n> -\tvirtual int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) = 0;\n> +\tvirtual int platformPipelineConfigure(const YamlObject &phConfig) = 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 082724c5a..0fb7c3fe8 100644\n> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> @@ -740,10 +740,16 @@ public:\n>  \t\treturn cfe_[Cfe::Output0].dev();\n>  \t}\n>  \n> +\tconst std::string &target() const override\n> +\t{\n> +\t\tstatic const std::string target = \"pisp\";\n> +\t\treturn target;\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(const YamlObject &phConfig) override;\n>  \n>  \tvoid platformStart() override;\n>  \tvoid platformStop() override;\n> @@ -1331,7 +1337,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)\n>  {\n>  \tconfig_ = {\n>  \t\t.numCfeConfigStatsBuffers = 12,\n> @@ -1340,23 +1346,9 @@ 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 99d43bd0a..71c425373 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> +\tconst std::string &target() const override\n> +\t{\n> +\t\tstatic const std::string target = \"bcm2835\";\n> +\t\treturn target;\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) override;\n>  \n>  \tvoid platformStart() override;\n>  \tvoid platformStop() override;\n> @@ -493,30 +499,16 @@ 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)\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 5AA61C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 21 Sep 2025 04:33:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 10EDE6B59C;\n\tSun, 21 Sep 2025 06:33:27 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DD0DD62C35\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 21 Sep 2025 06:33:24 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 2383D1FD3; \n\tSun, 21 Sep 2025 06:32:03 +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=\"pDNlZ+3L\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758429123;\n\tbh=5I/4YSV34Ikd5xt0uQsVzt7fxtWnef+3oFnWv1nq7Ig=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=pDNlZ+3LimtakhLxwUz6iH5Osaq9LPV10ITz+EezxshOHONmvJmgvrtEGt1f6oxGU\n\t3nbJW8c9LPVFT1KzESUEPuoJ+VDCRhmqmNGwnSUijHmFnQhgjeg4sHvI8gU5N36zr2\n\tgcDkuwOTtGKVwAT41SqkvmEQ4IxEwXhvMOwu3X30=","Date":"Sun, 21 Sep 2025 07:32:54 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?=\n\t<barnabas.pocze@ideasonboard.com>, Paul Elder\n\t<paul.elder@ideasonboard.com>, David Plowman\n\t<david.plowman@raspberrypi.com>, Naushir Patuck <naush@raspberrypi.com>","Subject":"Re: [PATCH v18 04/12] pipeline: rpi: Look up rpi configuration in\n\tthe configuration file","Message-ID":"<20250921043254.GE30137@pendragon.ideasonboard.com>","References":"<20250912142915.53949-1-mzamazal@redhat.com>\n\t<20250912142915.53949-5-mzamazal@redhat.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20250912142915.53949-5-mzamazal@redhat.com>","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":35945,"web_url":"https://patchwork.libcamera.org/comment/35945/","msgid":"<CAEmqJPo9m2yv79mCU=SGOYzxT8gjROv6iwAFQnc7ybGZ+sD3hQ@mail.gmail.com>","date":"2025-09-22T08:38:59","subject":"Re: [PATCH v18 04/12] pipeline: rpi: Look up rpi configuration in\n\tthe configuration file","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Milan,\n\nThank you for this work.  It looks to be a better solution than we\ncurrently have!\n\n\nOn Fri, 12 Sept 2025 at 15:29, Milan Zamazal <mzamazal@redhat.com> wrote:\n\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>     pipelines:\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> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n\n> ---\n>  .../pipeline/rpi/common/pipeline_base.cpp     | 59 +++++++++++--------\n>  .../pipeline/rpi/common/pipeline_base.h       |  3 +-\n>  src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 26 +++-----\n>  src/libcamera/pipeline/rpi/vc4/vc4.cpp        | 26 +++-----\n>  4 files changed, 56 insertions(+), 58 deletions(-)\n>\n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> index c209aa596..a4a018268 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> @@ -1093,35 +1095,46 @@ int CameraData::loadPipelineConfiguration()\n>         /* Initial configuration of the platform, in case no config file\n> is present */\n>         platformPipelineConfigure({});\n>\n> +       std::unique_ptr<YamlObject> root;\n>         char const *configFromEnv =\n> 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> +       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\n> file '\" << filename << \"'\"\n> +                                         << \", using defaults\";\n> +                       return 0;\n> +               }\n>\n> -       if (!file.open(File::OpenModeFlag::ReadOnly)) {\n> -               LOG(RPI, Warning) << \"Failed to open configuration file '\"\n> << filename << \"'\"\n> -                                 << \", using defaults\";\n> -               return 0;\n> -       }\n> +               LOG(RPI, Info) << \"Using configuration file '\" << filename\n> << \"'\";\n>\n> -       LOG(RPI, Info) << \"Using configuration file '\" << filename << \"'\";\n> +               root = YamlParser::parse(file);\n> +               if (!root) {\n> +                       LOG(RPI, Warning) << \"Failed to parse\n> configuration file, using defaults\";\n> +                       return 0;\n> +               }\n>\n> -       std::unique_ptr<YamlObject> root = YamlParser::parse(file);\n> -       if (!root) {\n> -               LOG(RPI, Warning) << \"Failed to parse configuration file,\n> using defaults\";\n> -               return 0;\n> -       }\n> +               std::optional<double> ver =\n> (*root)[\"version\"].get<double>();\n> +               if (!ver || *ver != 1.0) {\n> +                       LOG(RPI, Warning) << \"Unexpected configuration\n> file version reported: \"\n> +                                         << *ver;\n> +                       return 0;\n> +               }\n>\n> -       std::optional<double> ver = (*root)[\"version\"].get<double>();\n> -       if (!ver || *ver != 1.0) {\n> -               LOG(RPI, Warning) << \"Unexpected configuration file\n> version reported: \"\n> -                                 << *ver;\n> -               return 0;\n> +               std::optional<std::string> t =\n> (*root)[\"target\"].get<std::string>();\n> +               if (t != target()) {\n> +                       LOG(RPI, Error) << \"Unexpected target reported:\n> expected \\\"\"\n> +                                       << target() << \"\\\", got \" << (t ?\n> t->c_str() : \"(unknown)\");\n> +                       return -EINVAL;\n> +               }\n>         }\n>\n> -       const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n> +       GlobalConfiguration::Configuration config =\n> +\n>  pipe()->cameraManager()->_d()->configuration().configuration()[\"pipelines\"][\"rpi\"];\n> +       const YamlObject &phConfig = (root\n> +                                             ? (*root)[\"pipeline_handler\"]\n> +                                             :\n> config[target()][\"pipeline_handler\"]);\n>\n>         if (phConfig.contains(\"disable_startup_frame_drops\"))\n>                 LOG(RPI, Warning)\n> @@ -1137,7 +1150,7 @@ int CameraData::loadPipelineConfiguration()\n>\n> frontendDevice()->setDequeueTimeout(config_.cameraTimeoutValue * 1ms);\n>         }\n>\n> -       return platformPipelineConfigure(root);\n> +       return platformPipelineConfigure(phConfig);\n>  }\n>\n>  int CameraData::loadIPA(ipa::RPi::InitResult *result)\n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> index 4bce4ec4f..ffbede798 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,9 @@ public:\n>         virtual V4L2VideoDevice::Formats ispFormats() const = 0;\n>         virtual V4L2VideoDevice::Formats rawFormats() const = 0;\n>         virtual V4L2VideoDevice *frontendDevice() = 0;\n> +       virtual const std::string &target() const = 0;\n>\n> -       virtual int platformPipelineConfigure(const\n> std::unique_ptr<YamlObject> &root) = 0;\n> +       virtual int platformPipelineConfigure(const YamlObject &phConfig)\n> = 0;\n>\n>         std::unique_ptr<ipa::RPi::IPAProxyRPi> ipa_;\n>\n> diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> index 082724c5a..0fb7c3fe8 100644\n> --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n> @@ -740,10 +740,16 @@ public:\n>                 return cfe_[Cfe::Output0].dev();\n>         }\n>\n> +       const std::string &target() const override\n> +       {\n> +               static const std::string target = \"pisp\";\n> +               return target;\n> +       }\n> +\n>         CameraConfiguration::Status\n>         platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n> override;\n>\n> -       int platformPipelineConfigure(const std::unique_ptr<YamlObject>\n> &root) override;\n> +       int platformPipelineConfigure(const YamlObject &phConfig) override;\n>\n>         void platformStart() override;\n>         void platformStop() override;\n> @@ -1331,7 +1337,7 @@\n> PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig)\n> const\n>         return status;\n>  }\n>\n> -int PiSPCameraData::platformPipelineConfigure(const\n> std::unique_ptr<YamlObject> &root)\n> +int PiSPCameraData::platformPipelineConfigure(const YamlObject &phConfig)\n>  {\n>         config_ = {\n>                 .numCfeConfigStatsBuffers = 12,\n> @@ -1340,23 +1346,9 @@ int PiSPCameraData::platformPipelineConfigure(const\n> std::unique_ptr<YamlObject>\n>                 .disableHdr = false,\n>         };\n>\n> -       if (!root)\n> +       if (!phConfig)\n>                 return 0;\n>\n> -       std::optional<double> ver = (*root)[\"version\"].get<double>();\n> -       if (!ver || *ver != 1.0) {\n> -               LOG(RPI, Error) << \"Unexpected configuration file version\n> reported\";\n> -               return -EINVAL;\n> -       }\n> -\n> -       std::optional<std::string> target =\n> (*root)[\"target\"].get<std::string>();\n> -       if (target != \"pisp\") {\n> -               LOG(RPI, Error) << \"Unexpected target reported: expected\n> \\\"pisp\\\", got \"\n> -                               << (target ? target->c_str() :\n> \"(unknown)\");\n> -               return -EINVAL;\n> -       }\n> -\n> -       const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>         config_.numCfeConfigStatsBuffers =\n>                 phConfig[\"num_cfe_config_stats_buffers\"].get<unsigned\n> int>(config_.numCfeConfigStatsBuffers);\n>         config_.numCfeConfigQueue =\n> diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n> index 99d43bd0a..71c425373 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>                 return unicam_[Unicam::Image].dev();\n>         }\n>\n> +       const std::string &target() const override\n> +       {\n> +               static const std::string target = \"bcm2835\";\n> +               return target;\n> +       }\n> +\n>         void platformFreeBuffers() override\n>         {\n>         }\n>\n>         CameraConfiguration::Status\n> platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;\n>\n> -       int platformPipelineConfigure(const std::unique_ptr<YamlObject>\n> &root) override;\n> +       int platformPipelineConfigure(const YamlObject &phConfig) override;\n>\n>         void platformStart() override;\n>         void platformStop() override;\n> @@ -493,30 +499,16 @@ CameraConfiguration::Status\n> Vc4CameraData::platformValidate(RPi::RPiCameraConfig\n>         return status;\n>  }\n>\n> -int Vc4CameraData::platformPipelineConfigure(const\n> std::unique_ptr<YamlObject> &root)\n> +int Vc4CameraData::platformPipelineConfigure(const YamlObject &phConfig)\n>  {\n>         config_ = {\n>                 .minUnicamBuffers = 2,\n>                 .minTotalUnicamBuffers = 4,\n>         };\n>\n> -       if (!root)\n> +       if (!phConfig)\n>                 return 0;\n>\n> -       std::optional<double> ver = (*root)[\"version\"].get<double>();\n> -       if (!ver || *ver != 1.0) {\n> -               LOG(RPI, Error) << \"Unexpected configuration file version\n> reported\";\n> -               return -EINVAL;\n> -       }\n> -\n> -       std::optional<std::string> target =\n> (*root)[\"target\"].get<std::string>();\n> -       if (target != \"bcm2835\") {\n> -               LOG(RPI, Error) << \"Unexpected target reported: expected\n> \\\"bcm2835\\\", got \"\n> -                               << (target ? target->c_str() :\n> \"(unknown)\");\n> -               return -EINVAL;\n> -       }\n> -\n> -       const YamlObject &phConfig = (*root)[\"pipeline_handler\"];\n>         config_.minUnicamBuffers =\n>                 phConfig[\"min_unicam_buffers\"].get<unsigned\n> int>(config_.minUnicamBuffers);\n>         config_.minTotalUnicamBuffers =\n> --\n> 2.51.0\n>\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 9BDC6C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 22 Sep 2025 08:39:37 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6A6386B5F9;\n\tMon, 22 Sep 2025 10:39:36 +0200 (CEST)","from mail-vk1-xa36.google.com (mail-vk1-xa36.google.com\n\t[IPv6:2607:f8b0:4864:20::a36])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EC2D66B58E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 22 Sep 2025 10:39:32 +0200 (CEST)","by mail-vk1-xa36.google.com with SMTP id\n\t71dfb90a1353d-54a717fafafso141265e0c.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 22 Sep 2025 01:39:32 -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=\"DeS0sMQK\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1758530371; x=1759135171;\n\tdarn=lists.libcamera.org; \n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:from:to:cc:subject:date:message-id:reply-to;\n\tbh=37Arphpez+yzK0QWNlz7FsP159qmnPm5JHklj7qnBXQ=;\n\tb=DeS0sMQKpFTnV8ohl2l2yHcuk+3m4ymjToGiGeSsc7GsDbCK1No8ceBTb1wqEo5rlE\n\tyrifRfRRgxjjZ0PRd5a5IVTzahMC7u1AhCISA1IPAu8qJ8Y6QUuUc5ahuUcu9/fe3H1/\n\tYwCUKWQXXIMX3lOiEq7zL5gnO1qro2s4/udjVHtaQH2s39lGNVn54SSr3rpKdAE8kcrO\n\tQloAfemejDrrDvPl+AbhI9SdbI8hVTqyG0tJgNy1Oxq/x08NziXGW9iomh0u83SxLEUV\n\tzYLxKcPsRRZnSctvDZn+6DK+iUg6MbId7fprC8ZR2k1CWoDvFx6DYSXTiAH2khiZFGCH\n\txCEw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1758530372; x=1759135172;\n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:x-gm-message-state:from:to:cc:subject:date:message-id\n\t:reply-to;\n\tbh=37Arphpez+yzK0QWNlz7FsP159qmnPm5JHklj7qnBXQ=;\n\tb=NMSPb7wsQHLCd4nZCLiO0iCPWkFOquqfZjbqV056QuFuHTioeAgujTpeX49XKyLyWc\n\twGHPla461IihR5DmvZsyT866cmPaoEd1FyfD5FnCmM7lq2g/Q6rTrqntqLMMRze8RiQk\n\tI9xg9eGZwymZJOOaMunMDoZtg/guz7/QNoz1/k7q9Q2oOerUtae5P7PvzU3Dp6AM6u5b\n\tjBU+ehZPQTxd9oY0/1vTCU7cfzSUG7q3Z5hyMzlZ3yEC6kEgy0MIkB2nX5Yk0dZSVmOU\n\t1YiqR/drmKFKvKXSDyRLAzzBLzGqBGuWDbHmTTjv+rN3eN+fwvGmHnAwO8Ldzr9qvpMC\n\tzzYQ==","X-Gm-Message-State":"AOJu0YxBw/I4mhMw4aLNv/gaYANNeVdsiQVgzhTkPbZHJAz/7bkrjDh6\n\tIBbPVIPn5FBBHcYfxutLUGSQBaqYswzJqj0mIZmXU5w63H4V4h6VfC/df6IpuP2e5biF+/qieiT\n\tz7tZ426blHP8ZlDrVCPSrEntCJDBLUO+rDwmBs+kvhw==","X-Gm-Gg":"ASbGncs8Xc5kk7et5gr6dIU3RDzQ/4EBjWCMXj1+B2ScE4DmB5qEuTyAXTm53Y/er2A\n\tMCHXRcrOnCr2m0vB3o8C/yNWIHhD6OPGImSrM18yjPZ1pfS6d3Xww+GIROmJ0LEtUe2aDqSzFV7\n\tkn4eF/cXY68YVsqwesnOZHw/00QnddmozHX2/eKemUVMF4bFpE0QhT6lTl4grnVkfkinWnCu19R\n\t3wQ117i9LrvBhBcBg9t5gy5/hXWcOjx7Vtlc3o=","X-Google-Smtp-Source":"AGHT+IFlVf1/upqefHzMydpQDiTJMBWuiD2ze5gx4/0pZNiHOl36CIUP+Jfguqn6kyqzbcGEkTjrNbjqXKUADIh6A/U=","X-Received":"by 2002:a05:6102:3f41:b0:4ec:c510:e014 with SMTP id\n\tada2fe7eead31-588bc924ffemr1482066137.0.1758530371521;\n\tMon, 22 Sep 2025 01:39:31 -0700 (PDT)","MIME-Version":"1.0","References":"<20250912142915.53949-1-mzamazal@redhat.com>\n\t<20250912142915.53949-5-mzamazal@redhat.com>","In-Reply-To":"<20250912142915.53949-5-mzamazal@redhat.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Mon, 22 Sep 2025 09:38:59 +0100","X-Gm-Features":"AS18NWD4HJI6S_eyKsxLP19Ou2M8fLZPeeqLvwWmeMS6g5cZbt3F4_Kwus-CE48","Message-ID":"<CAEmqJPo9m2yv79mCU=SGOYzxT8gjROv6iwAFQnc7ybGZ+sD3hQ@mail.gmail.com>","Subject":"Re: [PATCH v18 04/12] pipeline: rpi: Look up rpi configuration in\n\tthe configuration file","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?=\n\t<barnabas.pocze@ideasonboard.com>, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>, Paul Elder\n\t<paul.elder@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"0000000000001f24de063f5fc222\"","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>"}}]