From patchwork Fri Sep 18 12:09:41 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 28351 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 9130CC335F for ; Fri, 18 Sep 2026 12:10:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CE4616875A; Fri, 18 Sep 2026 14:10:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Mz9KKNiR"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9AA3F6873E for ; Fri, 18 Sep 2026 14:09:56 +0200 (CEST) Received: from pb-laptop.local (185.221.142.0.nat.pool.zt.hu [185.221.142.0]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B901C4C39; Fri, 18 Sep 2026 14:08:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1789733293; bh=XgREJ3wUwHrCzvawsqCmeXuT8ztznevg7nGp+j3yG4s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Mz9KKNiR1CpvoXpkKPxcY29fN12xF91oue9bVP0GbSiIG/OhmcAre9+jrdySgVeh9 r1AuC+Fv4TnItYozvD8AU/Wtx094362uGjJY5kk0GtcjbwT921gYxyqXop2CIWVa/n kvwRWIue2+FRM1hh+pDoBmjsT/riZGLCx2FkT5Vg= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi Subject: [PATCH v3 13/21] ipa: rppx1: blc: Add Date: Fri, 18 Sep 2026 14:09:41 +0200 Message-ID: <20260918120949.191668-14-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260918120949.191668-1-barnabas.pocze@ideasonboard.com> References: <20260918120949.191668-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" From: Jacopo Mondi Add the algorithm to the rppx1 ipa module based on the corresponding algorithm in the rkisp1 ipa module. Signed-off-by: Jacopo Mondi --- src/ipa/rppx1/algorithms/blc.cpp | 111 +++++++++++++++++++++++++++ src/ipa/rppx1/algorithms/blc.h | 41 ++++++++++ src/ipa/rppx1/algorithms/meson.build | 1 + src/ipa/rppx1/params.h | 3 + 4 files changed, 156 insertions(+) create mode 100644 src/ipa/rppx1/algorithms/blc.cpp create mode 100644 src/ipa/rppx1/algorithms/blc.h diff --git a/src/ipa/rppx1/algorithms/blc.cpp b/src/ipa/rppx1/algorithms/blc.cpp new file mode 100644 index 0000000000..a56b834fb6 --- /dev/null +++ b/src/ipa/rppx1/algorithms/blc.cpp @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * RPP-X1 Black Level Correction control + */ + +#include "blc.h" + +#include + +#include + +#include "libcamera/internal/value_node.h" + +/** + * \file blc.h + */ + +namespace libcamera { + +namespace ipa::rppx1::algorithms { + +LOG_DEFINE_CATEGORY(RppX1Blc) + +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int BlackLevelCorrection::init(IPAContext &context, [[maybe_unused]] const ValueNode &tuningData) +{ + auto blackLevel = context.camHelper->blackLevel(); + if (!blackLevel) { + LOG(RppX1Blc, Error) + << "No black levels provided by camera sensor helper"; + return -ENOTSUP; + } + + blackLevelRed_ = *blackLevel; + blackLevelGreenR_ = *blackLevel; + blackLevelGreenB_ = *blackLevel; + blackLevelBlue_ = *blackLevel; + + LOG(RppX1Blc, Debug) + << "Black levels: red " << blackLevelRed_ + << ", green (red) " << blackLevelGreenR_ + << ", green (blue) " << blackLevelGreenB_ + << ", blue " << blackLevelBlue_; + + return 0; +} + +int BlackLevelCorrection::configure([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const IPACameraSensorInfo &configInfo) +{ + return 0; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context, + const uint32_t frame, + [[maybe_unused]] IPAFrameContext &frameContext, + RppX1Params *params) +{ + if (frame > 0) + return; + + auto config = params->block(); + config.setEnabled(true); + + config->mode = RPPX1_BLS_MODE_FIXED; + config->en_windows = RPPX1_BLS_WIN_EN_OFF; + + /* + * RPP-X1: the rppx1 specifies fixed BLS values per-color component + * matching on the input port cropping configuration. + * We have the same BLS value for all channels, so this is not relevant + * for now, but should probably be handled properly. + * + * Black level values are 16 bits, scale to the RPP-X1 PRE1 pipe + * 24-bit-domain. + */ + + config->fixed.a = static_cast(blackLevelRed_) << 8; + config->fixed.b = static_cast(blackLevelGreenR_) << 8; + config->fixed.c = static_cast(blackLevelGreenB_) << 8; + config->fixed.d = static_cast(blackLevelBlue_) << 8; +} + +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void BlackLevelCorrection::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] IPAFrameContext &frameContext, + [[maybe_unused]] const RppX1Stats *stats, + ControlList &metadata) +{ + metadata.set(controls::SensorBlackLevels, + { static_cast(blackLevelRed_), + static_cast(blackLevelGreenR_), + static_cast(blackLevelGreenB_), + static_cast(blackLevelBlue_) }); +} + +REGISTER_IPA_ALGORITHM(BlackLevelCorrection, "BlackLevelCorrection") + +} /* namespace ipa::rppx1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rppx1/algorithms/blc.h b/src/ipa/rppx1/algorithms/blc.h new file mode 100644 index 0000000000..3752166d78 --- /dev/null +++ b/src/ipa/rppx1/algorithms/blc.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * RPP-X1 Black Level Correction control + */ + +#pragma once + +#include + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::rppx1::algorithms { + +class BlackLevelCorrection : public Algorithm +{ +public: + int init(IPAContext &context, const ValueNode &tuningData) override; + int configure(IPAContext &context, + const IPACameraSensorInfo &configInfo) override; + void prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + RppX1Params *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const RppX1Stats *stats, + ControlList &metadata) override; + +private: + int16_t blackLevelRed_; + int16_t blackLevelGreenR_; + int16_t blackLevelGreenB_; + int16_t blackLevelBlue_; +}; + +} /* namespace ipa::rppx1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rppx1/algorithms/meson.build b/src/ipa/rppx1/algorithms/meson.build index 5fed9e9d50..165f0ce054 100644 --- a/src/ipa/rppx1/algorithms/meson.build +++ b/src/ipa/rppx1/algorithms/meson.build @@ -1,4 +1,5 @@ # SPDX-License-Identifier: CC0-1.0 rppx1_ipa_algorithms = files([ + 'blc.cpp', ]) diff --git a/src/ipa/rppx1/params.h b/src/ipa/rppx1/params.h index 315c8a9785..05db309914 100644 --- a/src/ipa/rppx1/params.h +++ b/src/ipa/rppx1/params.h @@ -16,6 +16,7 @@ namespace libcamera { namespace ipa::rppx1 { enum class BlockType : uint16_t { + BlsPre1, }; namespace details { @@ -32,6 +33,8 @@ struct block_type { RPPX1_PARAMS_BLOCK_TYPE_##id; \ }; +RPPX1_DEFINE_BLOCK_TYPE(BlsPre1, bls, BLS_PRE1) + struct params_traits { using id_type = BlockType;