From patchwork Fri Jun 6 16:41:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 23500 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id EC19CC332F for ; Fri, 6 Jun 2025 16:42:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4E3F168DDF; Fri, 6 Jun 2025 18:42:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XsaOqk/8"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0EF4368DBE for ; Fri, 6 Jun 2025 18:42:20 +0200 (CEST) Received: from pb-laptop.local (185.182.215.79.nat.pool.zt.hu [185.182.215.79]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 85A1C6DC for ; Fri, 6 Jun 2025 18:42:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1749228135; bh=It+Q59xjSMgFvh2ZWYUB5X0W02YEhlkpD+do6j4AZWg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XsaOqk/8uqgc9zVp3qGOp81d4mnZ+vl+PDX1VPUXGwrdZvwlST1j6qmTA4lpYGmQv kG+6R10aKXItGLrInRa/4xOKWQatRQ3PfgZQp2S+24dN3/xfuzlYKUg3VeYIi2Hz49 TdKya/1944rfxeRTnZNlN/UiL0zxz5+CswfNj7QU= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 18/23] libcamera: pipeline: Fill `MetadataListPlan` of cameras Date: Fri, 6 Jun 2025 18:41:51 +0200 Message-ID: <20250606164156.1442682-19-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250606164156.1442682-1-barnabas.pocze@ideasonboard.com> References: <20250606164156.1442682-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Fill the newly introduced `MetadataListPlan` member of the camera's private data during initializations, similarly to the camera's `ControlInfoMap`. Signed-off-by: Barnabás Pőcze --- .../internal/software_isp/software_isp.h | 3 +- include/libcamera/ipa/ipu3.mojom | 3 +- include/libcamera/ipa/mali-c55.mojom | 3 +- include/libcamera/ipa/raspberrypi.mojom | 1 + include/libcamera/ipa/rkisp1.mojom | 2 +- include/libcamera/ipa/soft.mojom | 3 +- src/ipa/ipu3/algorithms/agc.cpp | 4 +++ src/ipa/ipu3/algorithms/awb.cpp | 12 +++++++ src/ipa/ipu3/algorithms/awb.h | 1 + src/ipa/ipu3/ipa_context.cpp | 3 ++ src/ipa/ipu3/ipa_context.h | 3 ++ src/ipa/ipu3/ipu3.cpp | 8 +++-- src/ipa/mali-c55/algorithms/agc.cpp | 5 +++ src/ipa/mali-c55/algorithms/awb.cpp | 7 ++++ src/ipa/mali-c55/algorithms/awb.h | 1 + src/ipa/mali-c55/algorithms/blc.cpp | 2 ++ src/ipa/mali-c55/ipa_context.h | 3 ++ src/ipa/mali-c55/mali-c55.cpp | 6 ++-- src/ipa/rkisp1/algorithms/agc.cpp | 10 ++++++ src/ipa/rkisp1/algorithms/awb.cpp | 4 +++ src/ipa/rkisp1/algorithms/blc.cpp | 2 ++ src/ipa/rkisp1/ipa_context.h | 1 + src/ipa/rkisp1/rkisp1.cpp | 8 +++-- src/ipa/rpi/common/ipa_base.cpp | 34 +++++++++++++++++++ src/ipa/rpi/pisp/pisp.cpp | 5 +-- src/ipa/rpi/vc4/vc4.cpp | 4 ++- src/ipa/simple/algorithms/agc.cpp | 8 +++++ src/ipa/simple/algorithms/agc.h | 1 + src/ipa/simple/algorithms/awb.cpp | 8 +++++ src/ipa/simple/algorithms/awb.h | 1 + src/ipa/simple/algorithms/blc.cpp | 3 ++ src/ipa/simple/algorithms/ccm.cpp | 3 ++ src/ipa/simple/algorithms/lut.cpp | 3 ++ src/ipa/simple/ipa_context.h | 2 ++ src/ipa/simple/soft_simple.cpp | 8 +++-- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 2 ++ src/libcamera/pipeline/ipu3/ipu3.cpp | 7 +++- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 ++- .../pipeline/rpi/common/pipeline_base.cpp | 7 ++++ src/libcamera/pipeline/simple/simple.cpp | 2 +- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 ++ src/libcamera/pipeline/vimc/vimc.cpp | 2 ++ .../pipeline/virtual/config_parser.cpp | 3 ++ src/libcamera/software_isp/software_isp.cpp | 6 ++-- 45 files changed, 190 insertions(+), 22 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 786246592..bd85f6b4b 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -41,6 +41,7 @@ class DebayerCpu; class FrameBuffer; class PixelFormat; class Stream; +class MetadataListPlan; struct StreamConfiguration; LOG_DECLARE_CATEGORY(SoftwareIsp) @@ -49,7 +50,7 @@ class SoftwareIsp : public Object { public: SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, - ControlInfoMap *ipaControls); + ControlInfoMap *ipaControls, MetadataListPlan *metadataPlan); ~SoftwareIsp(); int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom index d9a50b01d..f49b77797 100644 --- a/include/libcamera/ipa/ipu3.mojom +++ b/include/libcamera/ipa/ipu3.mojom @@ -20,7 +20,8 @@ interface IPAIPU3Interface { init(libcamera.IPASettings settings, libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) - => (int32 ret, libcamera.ControlInfoMap ipaControls); + => (int32 ret, libcamera.ControlInfoMap ipaControls, + libcamera.MetadataListPlan metadata); start() => (int32 ret); stop(); diff --git a/include/libcamera/ipa/mali-c55.mojom b/include/libcamera/ipa/mali-c55.mojom index 5d7eb4eef..7229c53e1 100644 --- a/include/libcamera/ipa/mali-c55.mojom +++ b/include/libcamera/ipa/mali-c55.mojom @@ -11,7 +11,8 @@ struct IPAConfigInfo { interface IPAMaliC55Interface { init(libcamera.IPASettings settings, IPAConfigInfo configInfo) - => (int32 ret, libcamera.ControlInfoMap ipaControls); + => (int32 ret, libcamera.ControlInfoMap ipaControls, + libcamera.MetadataListPlan metadataPlan); start() => (int32 ret); stop(); diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom index e30c70bde..69160e133 100644 --- a/include/libcamera/ipa/raspberrypi.mojom +++ b/include/libcamera/ipa/raspberrypi.mojom @@ -26,6 +26,7 @@ struct InitParams { struct InitResult { SensorConfig sensorConfig; libcamera.ControlInfoMap controlInfo; + libcamera.MetadataListPlan metadataPlan; }; struct BufferIds { diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index 043ad27ea..440a59977 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -19,7 +19,7 @@ interface IPARkISP1Interface { uint32 hwRevision, libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) - => (int32 ret, libcamera.ControlInfoMap ipaControls); + => (int32 ret, libcamera.ControlInfoMap ipaControls, libcamera.MetadataListPlan metadataPlan); start() => (int32 ret); stop(); diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index 77328c5fd..360ed668b 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -18,7 +18,8 @@ interface IPASoftInterface { libcamera.SharedFD fdParams, libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) - => (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled); + => (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled, + libcamera.MetadataListPlan metadataPlan); start() => (int32 ret); stop(); configure(IPAConfigInfo configInfo) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 39d0aebb0..e3b2acbc6 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -82,6 +82,10 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData) context.ctrlMap.merge(controls()); + context.metadataPlan.add(controls::AnalogueGain); + context.metadataPlan.add(controls::ExposureTime); + context.metadataPlan.add(controls::FrameDuration); + return 0; } diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index 55de05d9e..28e29e29c 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -197,6 +197,18 @@ Awb::Awb() Awb::~Awb() = default; +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int Awb::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) +{ + context.metadataPlan.add(controls::AwbEnable); + context.metadataPlan.add(controls::ColourGains); + context.metadataPlan.add(controls::ColourTemperature); + + return 0; +} + /** * \copydoc libcamera::ipa::Algorithm::configure */ diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h index dbf69c907..1d47bffa3 100644 --- a/src/ipa/ipu3/algorithms/awb.h +++ b/src/ipa/ipu3/algorithms/awb.h @@ -40,6 +40,7 @@ public: Awb(); ~Awb(); + int init(IPAContext &context, const YamlObject &tuningData) override; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index 3b22f7917..f0b8b5dbe 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -54,6 +54,9 @@ namespace libcamera::ipa::ipu3 { * * \var IPAContext::ctrlMap * \brief A ControlInfoMap::Map of controls populated by the algorithms + * + * \var IPAContext::metadataPlan + * \brief A MetadataListPlan populated by the algorithms */ /** diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 97fcf06cd..f4f45ef4d 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -14,6 +14,7 @@ #include #include +#include #include @@ -95,6 +96,8 @@ struct IPAContext { FCQueue frameContexts; ControlInfoMap::Map ctrlMap; + + MetadataListPlan metadataPlan; // TODO: only needed during init(), how could be removed? }; } /* namespace ipa::ipu3 */ diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 1cae08bf2..8d8811f71 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -143,7 +143,8 @@ public: int init(const IPASettings &settings, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) override; + ControlInfoMap *ipaControls, + MetadataListPlan *metadataPlan) override; int start() override; void stop() override; @@ -299,7 +300,8 @@ void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo, int IPAIPU3::init(const IPASettings &settings, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) + ControlInfoMap *ipaControls, + MetadataListPlan *metadataPlan) { camHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel); if (camHelper_ == nullptr) { @@ -348,6 +350,8 @@ int IPAIPU3::init(const IPASettings &settings, /* Initialize controls. */ updateControls(sensorInfo, sensorControls, ipaControls); + *metadataPlan = std::move(context_.metadataPlan); + return 0; } diff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp index 70667db34..bfca8f5a5 100644 --- a/src/ipa/mali-c55/algorithms/agc.cpp +++ b/src/ipa/mali-c55/algorithms/agc.cpp @@ -145,6 +145,11 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData) ); context.ctrlMap.merge(controls()); + context.metadataPlan.add(controls::ExposureTime); + context.metadataPlan.add(controls::AnalogueGain); + context.metadataPlan.add(controls::DigitalGain); + context.metadataPlan.add(controls::ColourTemperature); + return 0; } diff --git a/src/ipa/mali-c55/algorithms/awb.cpp b/src/ipa/mali-c55/algorithms/awb.cpp index 050b191b7..b5acd4390 100644 --- a/src/ipa/mali-c55/algorithms/awb.cpp +++ b/src/ipa/mali-c55/algorithms/awb.cpp @@ -29,6 +29,13 @@ Awb::Awb() { } +int Awb::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) +{ + context.metadataPlan.add(controls::ColourGains); + + return 0; +} + int Awb::configure([[maybe_unused]] IPAContext &context, [[maybe_unused]] const IPACameraSensorInfo &configInfo) { diff --git a/src/ipa/mali-c55/algorithms/awb.h b/src/ipa/mali-c55/algorithms/awb.h index 800c2e834..db59e8d79 100644 --- a/src/ipa/mali-c55/algorithms/awb.h +++ b/src/ipa/mali-c55/algorithms/awb.h @@ -18,6 +18,7 @@ public: Awb(); ~Awb() = default; + int init(IPAContext &context, const YamlObject &tuningData) override; int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override; void prepare(IPAContext &context, const uint32_t frame, diff --git a/src/ipa/mali-c55/algorithms/blc.cpp b/src/ipa/mali-c55/algorithms/blc.cpp index 2a54c86a9..0aaaae7dd 100644 --- a/src/ipa/mali-c55/algorithms/blc.cpp +++ b/src/ipa/mali-c55/algorithms/blc.cpp @@ -51,6 +51,8 @@ int BlackLevelCorrection::init([[maybe_unused]] IPAContext &context, tuningParameters_ = true; + context.metadataPlan.add(controls::SensorBlackLevels); + LOG(MaliC55Blc, Debug) << "Black levels: 00 " << offset00 << ", 01 " << offset01 << ", 10 " << offset10 << ", 11 " << offset11; diff --git a/src/ipa/mali-c55/ipa_context.h b/src/ipa/mali-c55/ipa_context.h index 5e3e2fbde..d76fdcb2b 100644 --- a/src/ipa/mali-c55/ipa_context.h +++ b/src/ipa/mali-c55/ipa_context.h @@ -9,6 +9,7 @@ #include #include +#include #include "libcamera/internal/bayer_format.h" @@ -83,6 +84,8 @@ struct IPAContext { FCQueue frameContexts; ControlInfoMap::Map ctrlMap; + + MetadataListPlan metadataPlan; // TODO: only needed during init(), how could be removed? }; } /* namespace ipa::mali_c55 */ diff --git a/src/ipa/mali-c55/mali-c55.cpp b/src/ipa/mali-c55/mali-c55.cpp index c6941a950..7006ae55c 100644 --- a/src/ipa/mali-c55/mali-c55.cpp +++ b/src/ipa/mali-c55/mali-c55.cpp @@ -46,7 +46,7 @@ public: IPAMaliC55(); int init(const IPASettings &settings, const IPAConfigInfo &ipaConfig, - ControlInfoMap *ipaControls) override; + ControlInfoMap *ipaControls, MetadataListPlan *metadataPlan) override; int start() override; void stop() override; int configure(const IPAConfigInfo &ipaConfig, uint8_t bayerOrder, @@ -96,7 +96,7 @@ std::string IPAMaliC55::logPrefix() const } int IPAMaliC55::init(const IPASettings &settings, const IPAConfigInfo &ipaConfig, - ControlInfoMap *ipaControls) + ControlInfoMap *ipaControls, MetadataListPlan *metadataPlan) { camHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel); if (!camHelper_) { @@ -131,6 +131,8 @@ int IPAMaliC55::init(const IPASettings &settings, const IPAConfigInfo &ipaConfig updateControls(ipaConfig.sensorInfo, ipaConfig.sensorControls, ipaControls); + *metadataPlan = std::move(context_.metadataPlan); + return 0; } diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 137a07500..22db11b24 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -159,6 +159,16 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData) context.ctrlMap[&controls::AeEnable] = ControlInfo(false, true, true); context.ctrlMap.merge(controls()); + context.metadataPlan.add(controls::AnalogueGain); + context.metadataPlan.add(controls::ExposureTime); + context.metadataPlan.add(controls::FrameDuration); + context.metadataPlan.add(controls::FrameDuration); + context.metadataPlan.add(controls::ExposureTimeMode); + context.metadataPlan.add(controls::AnalogueGainMode); + context.metadataPlan.add(controls::AeMeteringMode); + context.metadataPlan.add(controls::AeExposureMode); + context.metadataPlan.add(controls::AeConstraintMode); + return 0; } diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index 399fb51be..aaaa3cced 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -117,6 +117,10 @@ int Awb::init(IPAContext &context, const YamlObject &tuningData) const auto &src = awbAlgo_->controls(); cmap.insert(src.begin(), src.end()); + context.metadataPlan.add(controls::AwbEnable); + context.metadataPlan.add(controls::ColourGains); + context.metadataPlan.add(controls::ColourTemperature); + return 0; } diff --git a/src/ipa/rkisp1/algorithms/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp index 98cb7145e..3288f24e3 100644 --- a/src/ipa/rkisp1/algorithms/blc.cpp +++ b/src/ipa/rkisp1/algorithms/blc.cpp @@ -103,6 +103,8 @@ int BlackLevelCorrection::init(IPAContext &context, const YamlObject &tuningData << ", green (blue) " << blackLevelGreenB_ << ", blue " << blackLevelBlue_; + context.metadataPlan.add(controls::SensorBlackLevels); + return 0; } diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index f0d504215..cd4b98921 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -200,6 +200,7 @@ struct IPAContext { FCQueue frameContexts; ControlInfoMap::Map ctrlMap; + MetadataListPlan metadataPlan; // TODO: only needed during init(), how could be removed? DebugMetadata debugMetadata; diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 1ed7d7d92..88c454ea1 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -54,7 +54,8 @@ public: int init(const IPASettings &settings, unsigned int hwRevision, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) override; + ControlInfoMap *ipaControls, + MetadataListPlan *metadataPlan) override; int start() override; void stop() override; @@ -135,7 +136,8 @@ std::string IPARkISP1::logPrefix() const int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) + ControlInfoMap *ipaControls, + MetadataListPlan *metadataPlan) { /* \todo Add support for other revisions */ switch (hwRevision) { @@ -204,6 +206,8 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision, /* Initialize controls. */ updateControls(sensorInfo, sensorControls, ipaControls); + *metadataPlan = std::move(context_.metadataPlan); + return 0; } diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index e0f8b7e78..032d6c43b 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -180,6 +180,40 @@ int32_t IpaBase::init(const IPASettings &settings, const InitParams ¶ms, Ini result->controlInfo = ControlInfoMap(std::move(ctrlMap), controls::controls); + // TODO: only set those that can be reported by configured algorithms? + // TODO: move this somewhere else? + result->metadataPlan.add(controls::AnalogueGainMode); + result->metadataPlan.add(controls::ExposureTimeMode); + result->metadataPlan.add(controls::ExposureTime); + result->metadataPlan.add(controls::AnalogueGain); + result->metadataPlan.add(controls::AeMeteringMode); + result->metadataPlan.add(controls::AeConstraintMode); + result->metadataPlan.add(controls::AeExposureMode); + result->metadataPlan.add(controls::ExposureValue); + result->metadataPlan.add(controls::AwbEnable); + result->metadataPlan.add(controls::AwbMode); + result->metadataPlan.add(controls::ColourGains); + result->metadataPlan.add(controls::Brightness); + result->metadataPlan.add(controls::Contrast); + result->metadataPlan.add(controls::Saturation); + result->metadataPlan.add(controls::Sharpness); + result->metadataPlan.add(controls::draft::NoiseReductionMode); + result->metadataPlan.add(controls::FrameDuration); + result->metadataPlan.add(controls::SensorTemperature); + result->metadataPlan.add(controls::LensPosition); + result->metadataPlan.add(controls::DigitalGain); + result->metadataPlan.add(controls::AeState); + result->metadataPlan.add(controls::Lux); + result->metadataPlan.add(controls::ColourTemperature); + result->metadataPlan.add(controls::SensorBlackLevels); + result->metadataPlan.add(controls::FocusFoM); + result->metadataPlan.add(controls::ColourCorrectionMatrix); + result->metadataPlan.add(controls::AfState); + result->metadataPlan.add(controls::AfPauseState); + result->metadataPlan.add(controls::HdrMode); + result->metadataPlan.add(controls::HdrChannel); + result->metadataPlan.add(controls::FrameDurationLimits); + return platformInit(params, result); } diff --git a/src/ipa/rpi/pisp/pisp.cpp b/src/ipa/rpi/pisp/pisp.cpp index bb50a9e05..a640bec32 100644 --- a/src/ipa/rpi/pisp/pisp.cpp +++ b/src/ipa/rpi/pisp/pisp.cpp @@ -267,8 +267,7 @@ private: HdrStatus lastStitchHdrStatus_; }; -int32_t IpaPiSP::platformInit(const InitParams ¶ms, - [[maybe_unused]] InitResult *result) +int32_t IpaPiSP::platformInit(const InitParams ¶ms, InitResult *result) { const std::string &target = controller_.getTarget(); if (target != "pisp") { @@ -301,6 +300,8 @@ int32_t IpaPiSP::platformInit(const InitParams ¶ms, setDefaultConfig(); + result->metadataPlan.add(controls::rpi::PispStatsOutput, sizeof(pisp_statistics)); + return 0; } diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index ba43e4741..d02e06589 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -83,7 +83,7 @@ private: void *lsTable_; }; -int32_t IpaVc4::platformInit([[maybe_unused]] const InitParams ¶ms, [[maybe_unused]] InitResult *result) +int32_t IpaVc4::platformInit([[maybe_unused]] const InitParams ¶ms, InitResult *result) { const std::string &target = controller_.getTarget(); @@ -94,6 +94,8 @@ int32_t IpaVc4::platformInit([[maybe_unused]] const InitParams ¶ms, [[maybe_ return -EINVAL; } + result->metadataPlan.add(controls::rpi::Bcm2835StatsOutput, sizeof(bcm2835_isp_stats)); + return 0; } diff --git a/src/ipa/simple/algorithms/agc.cpp b/src/ipa/simple/algorithms/agc.cpp index c46bb0ebe..47a499be6 100644 --- a/src/ipa/simple/algorithms/agc.cpp +++ b/src/ipa/simple/algorithms/agc.cpp @@ -41,6 +41,14 @@ Agc::Agc() { } +int Agc::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) +{ + context.metadataPlan.add(controls::ExposureTime); + context.metadataPlan.add(controls::AnalogueGain); + + return 0; +} + void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, double exposureMSV) { /* diff --git a/src/ipa/simple/algorithms/agc.h b/src/ipa/simple/algorithms/agc.h index 112d9f5a1..00e70ea70 100644 --- a/src/ipa/simple/algorithms/agc.h +++ b/src/ipa/simple/algorithms/agc.h @@ -19,6 +19,7 @@ public: Agc(); ~Agc() = default; + int init(IPAContext &context, const YamlObject &tuningData) override; void process(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, const SwIspStats *stats, diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp index cf567e894..cce4585f9 100644 --- a/src/ipa/simple/algorithms/awb.cpp +++ b/src/ipa/simple/algorithms/awb.cpp @@ -25,6 +25,14 @@ LOG_DEFINE_CATEGORY(IPASoftAwb) namespace ipa::soft::algorithms { +int Awb::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) +{ + context.metadataPlan.add(controls::ColourGains); + context.metadataPlan.add(controls::ColourTemperature); + + return 0; +} + int Awb::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { diff --git a/src/ipa/simple/algorithms/awb.h b/src/ipa/simple/algorithms/awb.h index ad993f39c..b8ae63dcb 100644 --- a/src/ipa/simple/algorithms/awb.h +++ b/src/ipa/simple/algorithms/awb.h @@ -19,6 +19,7 @@ public: Awb() = default; ~Awb() = default; + int init(IPAContext &context, const YamlObject &tuningData) override; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void prepare(IPAContext &context, const uint32_t frame, diff --git a/src/ipa/simple/algorithms/blc.cpp b/src/ipa/simple/algorithms/blc.cpp index 8c1e9ed08..4b9284e54 100644 --- a/src/ipa/simple/algorithms/blc.cpp +++ b/src/ipa/simple/algorithms/blc.cpp @@ -34,6 +34,9 @@ int BlackLevel::init([[maybe_unused]] IPAContext &context, */ definedLevel_ = blackLevel.value() >> 8; } + + context.metadataPlan.add(controls::SensorBlackLevels); + return 0; } diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index 0a98406c1..3cab8eaa4 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -39,6 +39,9 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData context.ccmEnabled = true; context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f); + context.metadataPlan.add(controls::ColourCorrectionMatrix); + context.metadataPlan.add(controls::Saturation); + return 0; } diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index d1d5f7271..0f99be544 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -28,6 +28,9 @@ int Lut::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) { context.ctrlMap[&controls::Contrast] = ControlInfo(0.0f, 2.0f, 1.0f); + + context.metadataPlan.add(controls::Contrast); + return 0; } diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index a471b80ae..f4ecf43db 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -12,6 +12,7 @@ #include #include +#include #include "libcamera/internal/matrix.h" #include "libcamera/internal/vector.h" @@ -97,6 +98,7 @@ struct IPAContext { IPAActiveState activeState; FCQueue frameContexts; ControlInfoMap::Map ctrlMap; + MetadataListPlan metadataPlan; // TODO: only needed during init(), how could be removed? bool ccmEnabled = false; }; diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index c94c4cd55..db721199d 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -56,7 +56,8 @@ public: const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, - bool *ccmEnabled) override; + bool *ccmEnabled, + MetadataListPlan *metadataPlan) override; int configure(const IPAConfigInfo &configInfo) override; int start() override; @@ -96,7 +97,8 @@ int IPASoftSimple::init(const IPASettings &settings, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, - bool *ccmEnabled) + bool *ccmEnabled, + MetadataListPlan *metadataPlan) { camHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel); if (!camHelper_) { @@ -190,6 +192,8 @@ int IPASoftSimple::init(const IPASettings &settings, return -EINVAL; } + *metadataPlan = std::move(context_.metadataPlan); + return 0; } diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index ecda426a6..1c6da2006 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -166,6 +166,8 @@ int ISICameraData::init() properties_ = sensor_->properties(); + metadataPlan_.add(controls::SensorTimestamp); + return 0; } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index e31e3879d..b4a4283f4 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1078,6 +1078,11 @@ int PipelineHandlerIPU3::registerCameras() if (ret) continue; + data->metadataPlan_.add(controls::draft::PipelineDepth); + data->metadataPlan_.add(controls::draft::TestPatternMode); + data->metadataPlan_.add(controls::ScalerCrop); + data->metadataPlan_.add(controls::SensorTimestamp); + const CameraSensorProperties::SensorDelays &delays = cio2->sensor()->sensorDelays(); std::unordered_map params = { { V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } }, @@ -1187,7 +1192,7 @@ int IPU3CameraData::loadIPA() ipa_->configurationFile(sensor->model() + ".yaml", "uncalibrated.yaml"); ret = ipa_->init(IPASettings{ ipaTuningFile, sensor->model() }, - sensorInfo, sensor->controls(), &ipaControls_); + sensorInfo, sensor->controls(), &ipaControls_, &metadataPlan_); if (ret) { LOG(IPU3, Error) << "Failed to initialise the IPU3 IPA"; return ret; diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 4acc091bd..19980f6d2 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -402,7 +402,7 @@ int MaliC55CameraData::loadIPA() ControlInfoMap ipaControls; ret = ipa_->init({ ipaTuningFile, sensor_->model() }, ipaConfig, - &ipaControls); + &ipaControls, &metadataPlan_); if (ret) { LOG(MaliC55, Error) << "Failed to initialise the Mali-C55 IPA"; return ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 675f0a749..34be87087 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -394,7 +394,7 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision) } ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision, - sensorInfo, sensor_->controls(), &ipaControls_); + sensorInfo, sensor_->controls(), &ipaControls_, &metadataPlan_); if (ret < 0) { LOG(RkISP1, Error) << "IPA initialization failure"; return ret; @@ -1333,6 +1333,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) updateControls(data.get()); + data->metadataPlan_.add(controls::SensorTimestamp); + std::set streams{ &data->mainPathStream_, &data->selfPathStream_, diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 1f13e5230..98507a152 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -589,6 +589,9 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config) data->controlInfo_ = ControlInfoMap(std::move(ctrlMap), result.controlInfo.idmap()); + /* Update `rpi::ScalerCrops` size for the corrent configuration. */ + data->metadataPlan_.add(controls::rpi::ScalerCrops, config->size()); + /* Setup the Video Mux/Bridge entities. */ for (auto &[device, link] : data->bridgeDevices_) { /* @@ -832,6 +835,10 @@ int PipelineHandlerBase::registerCamera(std::unique_ptr &camera /* Initialize the camera properties. */ data->properties_ = data->sensor_->properties(); + data->metadataPlan_ = std::move(result.metadataPlan); + data->metadataPlan_.add(controls::SensorTimestamp); + data->metadataPlan_.add(controls::ScalerCrop); + /* * The V4L2_CID_NOTIFY_GAINS control, if present, is used to inform the * sensor of the colour gains. It is defined to be a linear gain where diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index efb07051b..05387ca7c 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -592,7 +592,7 @@ int SimpleCameraData::init() * Instantiate Soft ISP if this is enabled for the given driver and no converter is used. */ if (!converter_ && pipe->swIspEnabled()) { - swIsp_ = std::make_unique(pipe, sensor_.get(), &controlInfo_); + swIsp_ = std::make_unique(pipe, sensor_.get(), &controlInfo_, &metadataPlan_); if (!swIsp_->isValid()) { LOG(SimplePipeline, Warning) << "Failed to create software ISP, disabling software debayering"; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 58aa0eb4c..e0036e3b5 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -603,6 +603,8 @@ int UVCCameraData::init(MediaDevice *media) controlInfo_ = ControlInfoMap(std::move(ctrls), controls::controls); + metadataPlan_.add(controls::SensorTimestamp); + /* * Close to allow camera to go into runtime-suspend, video_ will be * re-opened from acquireDevice() and validate(). diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 07273bd2b..f8a29da41 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -590,6 +590,8 @@ int VimcCameraData::init() controlInfo_ = ControlInfoMap(std::move(ctrls), controls::controls); + metadataPlan_.add(controls::SensorTimestamp); + /* Initialize the camera properties. */ properties_ = sensor_->properties(); diff --git a/src/libcamera/pipeline/virtual/config_parser.cpp b/src/libcamera/pipeline/virtual/config_parser.cpp index 1d3d9ba87..f10aea7bf 100644 --- a/src/libcamera/pipeline/virtual/config_parser.cpp +++ b/src/libcamera/pipeline/virtual/config_parser.cpp @@ -65,6 +65,9 @@ ConfigParser::parseConfigFile(File &file, PipelineHandler *pipe) controls[&controls::draft::FaceDetectMode] = ControlInfo(supportedFaceDetectModes); data->controlInfo_ = ControlInfoMap(std::move(controls), controls::controls); + + data->metadataPlan_.add(controls::SensorTimestamp); + configurations.push_back(std::move(data)); } diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 28e2a360e..6da69daf9 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -71,10 +71,11 @@ LOG_DEFINE_CATEGORY(SoftwareIsp) * \param[in] pipe The pipeline handler in use * \param[in] sensor Pointer to the CameraSensor instance owned by the pipeline * \param[out] ipaControls The IPA controls to update + * \param[out] metadataPlan The metadata plan to update * handler */ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, - ControlInfoMap *ipaControls) + ControlInfoMap *ipaControls, MetadataListPlan *metadataPlan) : dmaHeap_(DmaBufAllocator::DmaBufAllocatorFlag::CmaHeap | DmaBufAllocator::DmaBufAllocatorFlag::SystemHeap | DmaBufAllocator::DmaBufAllocatorFlag::UDmaBuf) @@ -146,7 +147,8 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, sensorInfo, sensor->controls(), ipaControls, - &ccmEnabled_); + &ccmEnabled_, + metadataPlan); if (ret) { LOG(SoftwareIsp, Error) << "IPA init failed"; debayer_.reset();