From patchwork Thu Feb 24 11:33:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15377 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 2B663BF415 for ; Thu, 24 Feb 2022 11:33:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 08B9D601F9; Thu, 24 Feb 2022 12:33:56 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Ln5TpxzI"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 30B03610F9 for ; Thu, 24 Feb 2022 12:33:53 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ADB1B484; Thu, 24 Feb 2022 12:33:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645702432; bh=mMJuuto1bzrXlL+ATfOahFbg6hgrOBbR0dCtYEcgtPk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ln5TpxzIhaANpCh7AHlq3ueq90wUIVSFoYyED9mineL1HJYIOu46Fp4rtX01AQlL0 rZAX4MlKaCfLcMWiL9aTk8MGteshui1LMejcZQoT6snptpotum+PUWjmeMyr/34khM arQVnxklm8bF50EtQlDoep63Bazg6NnBwK/qgDFc= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 12:33:43 +0100 Message-Id: <20220224113347.80001-2-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/5] ipa: rkisp1: Use frame counter for the request queued 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" Introduce a frameCount variable in the IPAFrameContext which increments each time a request is queued. It is reset at configure call, when the camera is started. This will allow the frameCount to be used by other algorithms, without having to keep multiple private frame counters. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Umang Jain Reviewed-by: Laurent Pinchart --- v3: - replace frameId by a frame counter - Change the date of the copyright --- src/ipa/rkisp1/ipa_context.cpp | 9 ++++++++- src/ipa/rkisp1/ipa_context.h | 4 +++- src/ipa/rkisp1/rkisp1.cpp | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 9cb2a9fd..664f572f 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2021, Ideas On Board + * Copyright (C) 2021-2022, Ideas On Board * * ipa_context.cpp - RkISP1 IPA Context */ @@ -113,4 +113,11 @@ namespace libcamera::ipa::rkisp1 { * \brief Analogue gain multiplier */ +/** + * \var IPAFrameContext::frameCount + * \brief Number of queued requests for this frame context + * + * It restarts from 0 when the camera is started. + */ + } /* namespace libcamera::ipa::rkisp1 */ diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index b94ade0c..212fa052 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2021, Ideas On Board + * Copyright (C) 2021-2022, Ideas On Board * * ipa_context.h - RkISP1 IPA Context * @@ -43,6 +43,8 @@ struct IPAFrameContext { uint32_t exposure; double gain; } sensor; + + unsigned int frameCount; }; struct IPAContext { diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 2d79f15f..f119b3f3 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -196,6 +196,8 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info, context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain_); context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain_); + context_.frameContext.frameCount = 0; + for (auto const &algo : algorithms_) { int ret = algo->configure(context_, info); if (ret) @@ -284,6 +286,7 @@ void IPARkISP1::queueRequest(unsigned int frame, rkisp1_params_cfg *params, op.op = ActionParamFilled; queueFrameAction.emit(frame, op); + context_.frameContext.frameCount++; } void IPARkISP1::updateStatistics(unsigned int frame, From patchwork Thu Feb 24 11:33:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15378 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 EEF50BF415 for ; Thu, 24 Feb 2022 11:33:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E102E61154; Thu, 24 Feb 2022 12:33:56 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="q06qM5U/"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 53F73601F9 for ; Thu, 24 Feb 2022 12:33:53 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D93E5E70; Thu, 24 Feb 2022 12:33:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645702432; bh=+wwL6yirfVOYDT15H5q9AQSn5oqquclWdLrpplCrrtI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q06qM5U/hQyU+4wR419iE/p+xeaRzcD0SQk+9nXWF1RXzq3o/uPAPhvwxENYx1ZmG UGN2SIEHb3wfO7ErZrhZZHS+J8Ojz7N4iSnTxqoquya/zx6eCI123SU16Ndx8PeenS k/n/MqyaleTHLbH/JSyNVUSoitWU6orqe2AmJPeo= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 12:33:44 +0100 Message-Id: <20220224113347.80001-3-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/5] ipa: rkisp1: Introduce Black Level Correction 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" In order to have the proper pixel levels, apply a fixed black level correction, based on the imx219 tuning file in RPi. The value is 4096 on 16 bits, and the pipeline for RkISP1 is on 12 bits, scale it. Signed-off-by: Jean-Michel Hautbois Tested-by: Peter Griffin Reviewed-by: Laurent Pinchart --- v3: - return early when it is not the first frame anymore - add a todo to remember it may need a bit of rework later - Change the date of the copyright --- src/ipa/rkisp1/algorithms/blc.cpp | 57 +++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/blc.h | 30 ++++++++++++++ src/ipa/rkisp1/algorithms/meson.build | 1 + src/ipa/rkisp1/rkisp1.cpp | 2 + 4 files changed, 90 insertions(+) create mode 100644 src/ipa/rkisp1/algorithms/blc.cpp create mode 100644 src/ipa/rkisp1/algorithms/blc.h diff --git a/src/ipa/rkisp1/algorithms/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp new file mode 100644 index 00000000..0c5948ff --- /dev/null +++ b/src/ipa/rkisp1/algorithms/blc.cpp @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * blc.cpp - RkISP1 Black Level Correction control + */ + +#include "blc.h" + +/** + * \file blc.h + */ + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +/** + * \class BlackLevelCorrection + * \brief RkISP1 Black Level Correction control + * + * The pixels output by the camera normally include a black level, because + * sensors do not always report a signal level of '0' for black. Pixels at or + * below this level should be considered black. To achieve that, the RkISP BLC + * algorithm subtracts a configurable offset from all pixels. + * + * The black level can be measured at runtime from an optical dark region of the + * camera sensor, or measured during the camera tuning process. The first option + * isn't currently supported. + */ + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void BlackLevelCorrection::prepare(IPAContext &context, + rkisp1_params_cfg *params) +{ + if (context.frameContext.frameCount > 0) + return; + /* + * Substract fixed values taken from imx219 tuning file. + * \todo Use a configuration file for it ? + */ + params->others.bls_config.enable_auto = 0; + params->others.bls_config.fixed_val.r = 256; + params->others.bls_config.fixed_val.gr = 256; + params->others.bls_config.fixed_val.gb = 256; + params->others.bls_config.fixed_val.b = 256; + + params->module_en_update |= RKISP1_CIF_ISP_MODULE_BLS; + params->module_ens |= RKISP1_CIF_ISP_MODULE_BLS; + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_BLS; +} + +} /* namespace ipa::rkisp1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/blc.h b/src/ipa/rkisp1/algorithms/blc.h new file mode 100644 index 00000000..69874d8f --- /dev/null +++ b/src/ipa/rkisp1/algorithms/blc.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * blc.h - RkISP1 Black Level Correction control + */ + +#pragma once + +#include + +#include "algorithm.h" + +namespace libcamera { + +struct IPACameraSensorInfo; + +namespace ipa::rkisp1::algorithms { + +class BlackLevelCorrection : public Algorithm +{ +public: + BlackLevelCorrection() = default; + ~BlackLevelCorrection() = default; + + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; +}; + +} /* namespace ipa::rkisp1::algorithms */ +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build index a19c1a4f..27c97731 100644 --- a/src/ipa/rkisp1/algorithms/meson.build +++ b/src/ipa/rkisp1/algorithms/meson.build @@ -2,4 +2,5 @@ rkisp1_ipa_algorithms = files([ 'agc.cpp', + 'blc.cpp', ]) diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index f119b3f3..bb3deb93 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -27,6 +27,7 @@ #include "algorithms/agc.h" #include "algorithms/algorithm.h" +#include "algorithms/blc.h" #include "libipa/camera_sensor_helper.h" #include "ipa_context.h" @@ -126,6 +127,7 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision) /* Construct our Algorithms */ algorithms_.push_back(std::make_unique()); + algorithms_.push_back(std::make_unique()); return 0; } From patchwork Thu Feb 24 11:33:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15379 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 DF177BF415 for ; Thu, 24 Feb 2022 11:33:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2C0226115A; Thu, 24 Feb 2022 12:33:58 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vqg1dhxi"; 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 6787D61145 for ; Thu, 24 Feb 2022 12:33:53 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 158C2DD; Thu, 24 Feb 2022 12:33:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645702433; bh=sMtrrj+EYo9kT3HadhZ0KuBYFvgSed4b65pLGeDwA5g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vqg1dhxi6lAUGTvGrQkctnJD9ffNy+Vy6AuBj+XTegRzSBfIM1va2A+haHCwpEuqY LWdJPMs1a/EhtTU7x5QUvIqG8qK1QcAn6ecTc5qCFk4pYcHWjvmFzgTrI0qDcmDOI2 8fjkNTI+Vk4AE0VT7MIukMW+6+vefMzvJU7NQzkg= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 12:33:45 +0100 Message-Id: <20220224113347.80001-4-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/5] ipa: libipa: Histogram: Constify the constructor span 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" The Histogram constructor does not modify the data. Pass it a Span instead of a Span. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Umang Jain Reviewed-by: Laurent Pinchart --- src/ipa/libipa/histogram.cpp | 2 +- src/ipa/libipa/histogram.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ipa/libipa/histogram.cpp b/src/ipa/libipa/histogram.cpp index 4d94571f..d8ad1c89 100644 --- a/src/ipa/libipa/histogram.cpp +++ b/src/ipa/libipa/histogram.cpp @@ -32,7 +32,7 @@ namespace ipa { * \brief Create a cumulative histogram * \param[in] data A pre-sorted histogram to be passed */ -Histogram::Histogram(Span data) +Histogram::Histogram(Span data) { cumulative_.reserve(data.size()); cumulative_.push_back(0); diff --git a/src/ipa/libipa/histogram.h b/src/ipa/libipa/histogram.h index c40a366b..164d4603 100644 --- a/src/ipa/libipa/histogram.h +++ b/src/ipa/libipa/histogram.h @@ -22,7 +22,7 @@ namespace ipa { class Histogram { public: - Histogram(Span data); + Histogram(Span data); size_t bins() const { return cumulative_.size() - 1; } uint64_t total() const { return cumulative_[cumulative_.size() - 1]; } uint64_t cumulativeFrequency(double bin) const; From patchwork Thu Feb 24 11:33:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15380 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 83CDDC3261 for ; Thu, 24 Feb 2022 11:34:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 473BB61168; Thu, 24 Feb 2022 12:33:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iJCjt3zc"; 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 9526261154 for ; Thu, 24 Feb 2022 12:33:53 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4204B104C; Thu, 24 Feb 2022 12:33:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645702433; bh=wBoNw/EYK+s+bs9nw/IQgAzt+pdWyALtzBcldHYP5qg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iJCjt3zcwzFlndWuthZwSG/xbkb4MRRkZsytWY9sjD/DbjHfxpoyWWkB4IKZ1F/1C YXhvRMZu3lU9XIfYZHpgKFqb/Ot9xW8U/XSwZ7wGKXTtPwMY6m0BUYBUJoHNo+7pRZ ZUpkRoYG+Evem9+1p4Xkz/iZmcM1Md7vuXXYzhxw= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 12:33:46 +0100 Message-Id: <20220224113347.80001-5-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 4/5] ipa: rkisp1: agc: Add a histogram-based gain 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" As for the IPU3, we can estimate the histogram of the luminance. The RkISP1 can estimate multiple ones, the R, G and B ones, the Y only one and a combination of RGB. The one we are interested by in AGC is the Y histogram. Use the hardware revision to determine the number of bins of the produced histogram, and use it to populate a vector passed down to the libipa::Histogram class. Signed-off-by: Jean-Michel Hautbois Tested-by: Peter Griffin Reviewed-by: Laurent Pinchart --- v3: - Don't copy histogram values, pass it to the Histogram class directly - Change the date of the copyright --- src/ipa/rkisp1/algorithms/agc.cpp | 94 ++++++++++++++++++++++++++----- src/ipa/rkisp1/algorithms/agc.h | 6 +- src/ipa/rkisp1/ipa_context.cpp | 3 + src/ipa/rkisp1/ipa_context.h | 1 + 4 files changed, 88 insertions(+), 16 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index dd97afc0..2e95ee05 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2021, Ideas On Board + * Copyright (C) 2021-2022, Ideas On Board * * agc.cpp - AGC/AEC mean-based control algorithm */ @@ -16,6 +16,8 @@ #include +#include "libipa/histogram.h" + /** * \file agc.h */ @@ -43,18 +45,22 @@ static constexpr utils::Duration kMaxShutterSpeed = 60ms; /* Number of frames to wait before calculating stats on minimum exposure */ static constexpr uint32_t kNumStartupFrames = 10; +/* Target value to reach for the top 2% of the histogram */ +static constexpr double kEvGainTarget = 0.5; + /* * Relative luminance target. * * It's a number that's chosen so that, when the camera points at a grey * target, the resulting image brightness is considered right. * - * \todo Why is the value different between IPU3 and RkISP1 ? + * \todo The value is not the same for IPU3 and RkIsp1 because we don't have + * sensor degamma yet. */ static constexpr double kRelativeLuminanceTarget = 0.4; Agc::Agc() - : frameCount_(0), numCells_(0), filteredExposure_(0s) + : frameCount_(0), numCells_(0), numHistBins_(0), filteredExposure_(0s) { } @@ -65,8 +71,7 @@ Agc::Agc() * * \return 0 */ -int Agc::configure(IPAContext &context, - [[maybe_unused]] const IPACameraSensorInfo &configInfo) +int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) { /* Configure the default exposure and gain. */ context.frameContext.agc.gain = std::max(context.configuration.agc.minAnalogueGain, kMinAnalogueGain); @@ -77,10 +82,22 @@ int Agc::configure(IPAContext &context, * - versions < V12 have RKISP1_CIF_ISP_AE_MEAN_MAX_V10 entries, * - versions >= V12 have RKISP1_CIF_ISP_AE_MEAN_MAX_V12 entries. */ - if (context.configuration.hw.revision < RKISP1_V12) + if (context.configuration.hw.revision < RKISP1_V12) { numCells_ = RKISP1_CIF_ISP_AE_MEAN_MAX_V10; - else + numHistBins_ = RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10; + } else { numCells_ = RKISP1_CIF_ISP_AE_MEAN_MAX_V12; + numHistBins_ = RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12; + } + + /* + * Define the measurement window for AGC as a centered rectangle + * covering 3/4 of the image width and height. + */ + context.configuration.agc.measureWindow.h_offs = configInfo.outputSize.width / 8; + context.configuration.agc.measureWindow.v_offs = configInfo.outputSize.height / 8; + context.configuration.agc.measureWindow.h_size = 3 * configInfo.outputSize.width / 4; + context.configuration.agc.measureWindow.v_size = 3 * configInfo.outputSize.height / 4; /* \todo Use actual frame index by populating it in the frameContext. */ frameCount_ = 0; @@ -126,8 +143,9 @@ utils::Duration Agc::filterExposure(utils::Duration exposureValue) * \brief Estimate the new exposure and gain values * \param[inout] frameContext The shared IPA frame Context * \param[in] yGain The gain calculated on the current brightness level + * \param[in] iqMeanGain The gain calculated based on the relative luminance target */ -void Agc::computeExposure(IPAContext &context, double yGain) +void Agc::computeExposure(IPAContext &context, double yGain, double iqMeanGain) { IPASessionConfiguration &configuration = context.configuration; IPAFrameContext &frameContext = context.frameContext; @@ -136,6 +154,9 @@ void Agc::computeExposure(IPAContext &context, double yGain) uint32_t exposure = frameContext.sensor.exposure; double analogueGain = frameContext.sensor.gain; + /* Use the highest of the two gain estimates. */ + double evGain = std::max(yGain, iqMeanGain); + utils::Duration minShutterSpeed = configuration.agc.minShutterSpeed; utils::Duration maxShutterSpeed = std::min(configuration.agc.maxShutterSpeed, kMaxShutterSpeed); @@ -146,7 +167,7 @@ void Agc::computeExposure(IPAContext &context, double yGain) kMaxAnalogueGain); /* Consider within 1% of the target as correctly exposed. */ - if (utils::abs_diff(yGain, 1.0) < 0.01) + if (utils::abs_diff(evGain, 1.0) < 0.01) return; /* extracted from Rpi::Agc::computeTargetExposure. */ @@ -163,13 +184,13 @@ void Agc::computeExposure(IPAContext &context, double yGain) LOG(RkISP1Agc, Debug) << "Actual total exposure " << currentShutter * analogueGain << " Shutter speed " << currentShutter << " Gain " << analogueGain - << " Needed ev gain " << yGain; + << " Needed ev gain " << evGain; /* * Calculate the current exposure value for the scene as the latest * exposure value applied multiplied by the new estimated gain. */ - utils::Duration exposureValue = effectiveExposureValue * yGain; + utils::Duration exposureValue = effectiveExposureValue * evGain; /* Clamp the exposure value to the min and max authorized. */ utils::Duration maxTotalExposure = maxShutterSpeed * maxAnalogueGain; @@ -240,6 +261,18 @@ double Agc::estimateLuminance(const rkisp1_cif_isp_ae_stat *ae, return ySum / numCells_ / 255; } +/** + * \brief Estimate the mean value of the top 2% of the histogram + * \param[in] hist The histogram statistics computed by the ImgU + * \return The mean value of the top 2% of the histogram + */ +double Agc::measureBrightness(const rkisp1_cif_isp_hist_stat *hist) const +{ + Histogram histogram{ Span(hist->hist_bins, numHistBins_) }; + /* Estimate the quantile mean of the top 2% of the histogram. */ + return histogram.interQuantileMean(0.98, 1.0); +} + /** * \brief Process RkISP1 statistics, and run AGC operations * \param[in] context The shared IPA context @@ -254,6 +287,10 @@ void Agc::process(IPAContext &context, const rkisp1_stat_buffer *stats) ASSERT(stats->meas_type & RKISP1_CIF_ISP_STAT_AUTOEXP); const rkisp1_cif_isp_ae_stat *ae = ¶ms->ae; + const rkisp1_cif_isp_hist_stat *hist = ¶ms->hist; + + double iqMean = measureBrightness(hist); + double iqMeanGain = kEvGainTarget * numHistBins_ / iqMean; /* * Estimate the gain needed to achieve a relative luminance target. To @@ -277,15 +314,44 @@ void Agc::process(IPAContext &context, const rkisp1_stat_buffer *stats) break; } - computeExposure(context, yGain); + computeExposure(context, yGain, iqMeanGain); frameCount_++; } -void Agc::prepare([[maybe_unused]] IPAContext &context, - rkisp1_params_cfg *params) +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Agc::prepare(IPAContext &context, rkisp1_params_cfg *params) { + if (context.frameContext.frameCount > 0) + return; + + /* Configure the measurement window. */ + params->meas.aec_config.meas_window = context.configuration.agc.measureWindow; + /* Use a continuous method for measure. */ + params->meas.aec_config.autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0; + /* Estimate Y as (R + G + B) x (85/256). */ + params->meas.aec_config.mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1; + + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AEC; params->module_ens |= RKISP1_CIF_ISP_MODULE_AEC; params->module_en_update |= RKISP1_CIF_ISP_MODULE_AEC; + + /* Configure histogram. */ + params->meas.hst_config.meas_window = context.configuration.agc.measureWindow; + /* Produce the luminance histogram. */ + params->meas.hst_config.mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM; + /* Set an average weighted histogram. */ + for (unsigned int histBin = 0; histBin < numHistBins_; histBin++) + params->meas.hst_config.hist_weight[histBin] = 1; + /* Step size can't be less than 3. */ + params->meas.hst_config.histogram_predivider = 4; + + /* Update the configuration for histogram. */ + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_HST; + /* Enable the histogram measure unit. */ + params->module_ens |= RKISP1_CIF_ISP_MODULE_HST; + params->module_en_update |= RKISP1_CIF_ISP_MODULE_HST; } } /* namespace ipa::rkisp1::algorithms */ diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h index 942c9d7a..ce1adf27 100644 --- a/src/ipa/rkisp1/algorithms/agc.h +++ b/src/ipa/rkisp1/algorithms/agc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2021, Ideas On Board + * Copyright (C) 2021-2022, Ideas On Board * * agc.h - RkISP1 AGC/AEC mean-based control algorithm */ @@ -32,13 +32,15 @@ public: void process(IPAContext &context, const rkisp1_stat_buffer *stats) override; private: - void computeExposure(IPAContext &Context, double yGain); + void computeExposure(IPAContext &Context, double yGain, double iqMeanGain); utils::Duration filterExposure(utils::Duration exposureValue); double estimateLuminance(const rkisp1_cif_isp_ae_stat *ae, double gain); + double measureBrightness(const rkisp1_cif_isp_hist_stat *hist) const; uint64_t frameCount_; uint32_t numCells_; + uint32_t numHistBins_; utils::Duration filteredExposure_; }; diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 664f572f..790e159b 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -71,6 +71,9 @@ namespace libcamera::ipa::rkisp1 { * \var IPASessionConfiguration::agc.maxAnalogueGain * \brief Maximum analogue gain supported with the configured sensor * + * \var IPASessionConfiguration::agc.measureWindow + * \brief AGC measure window + * * \var IPASessionConfiguration::hw * \brief RkISP1-specific hardware information * diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 212fa052..35e9b8e5 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -22,6 +22,7 @@ struct IPASessionConfiguration { utils::Duration maxShutterSpeed; double minAnalogueGain; double maxAnalogueGain; + struct rkisp1_cif_isp_window measureWindow; } agc; struct { From patchwork Thu Feb 24 11:33:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 15381 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 E4AA9BF415 for ; Thu, 24 Feb 2022 11:34:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AD6A261174; Thu, 24 Feb 2022 12:33:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="nSTfUB3o"; 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 BB6DC61159 for ; Thu, 24 Feb 2022 12:33:53 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:ce74:6df2:4b76:b230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 74FFB484; Thu, 24 Feb 2022 12:33:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1645702433; bh=HpEZjeyGDMf5kOyoPnvUJwMC9zVpxp37TiT3OTwMwgk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nSTfUB3odsPAdsVEcgqRnfgNAwcC2mix+oDMfWG7K4SwM24O7ylMH0uV23t7otlRp mnw/KvuaougZpoUpPyqmVDqhWXL1z7Sdh1v5NvQbQ5KV61ovZZlMeW+Ulwz2NuvOeI 36XbSWVZ3c6LsHbTqXM5JIjVDkzRfTdwrsbUPXEU= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 24 Feb 2022 12:33:47 +0100 Message-Id: <20220224113347.80001-6-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> References: <20220224113347.80001-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 5/5] ipa: rkisp1: Introduce AWB 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" The RkISP1 ISP calculates a mean value for Y, Cr and Cb at each frame. There is a RGB mode which could theoretically give us the values for R, G and B directly, but it seems to be failing right now. Convert those values into R, G and B and estimate the gain to apply in a grey world. Signed-off-by: Jean-Michel Hautbois Tested-by: Peter Griffin --- v3: - Change the date of the copyright - Fix the YCbCr to RGB formula --- src/ipa/rkisp1/algorithms/awb.cpp | 180 ++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/awb.h | 33 +++++ src/ipa/rkisp1/algorithms/meson.build | 1 + src/ipa/rkisp1/ipa_context.cpp | 28 ++++ src/ipa/rkisp1/ipa_context.h | 16 +++ src/ipa/rkisp1/rkisp1.cpp | 2 + 6 files changed, 260 insertions(+) create mode 100644 src/ipa/rkisp1/algorithms/awb.cpp create mode 100644 src/ipa/rkisp1/algorithms/awb.h diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp new file mode 100644 index 00000000..fce4c498 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * awb.cpp - AWB control algorithm + */ + +#include "awb.h" + +#include +#include + +#include + +#include + +/** + * \file awb.h + */ + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +/** + * \class Awb + * \brief A Grey world white balance correction algorithm + */ + +LOG_DEFINE_CATEGORY(RkISP1Awb) + +/** + * \copydoc libcamera::ipa::Algorithm::configure + */ +int Awb::configure(IPAContext &context, + const IPACameraSensorInfo &configInfo) +{ + context.frameContext.awb.gains.red = 1.0; + context.frameContext.awb.gains.blue = 1.0; + context.frameContext.awb.gains.green = 1.0; + + /* + * Define the measurement window for AWB as a centered rectangle + * covering 3/4 of the image width and height. + */ + context.configuration.awb.measureWindow.h_offs = configInfo.outputSize.width / 8; + context.configuration.awb.measureWindow.v_offs = configInfo.outputSize.height / 8; + context.configuration.awb.measureWindow.h_size = 3 * configInfo.outputSize.width / 4; + context.configuration.awb.measureWindow.v_size = 3 * configInfo.outputSize.height / 4; + + return 0; +} + +uint32_t Awb::estimateCCT(double red, double green, double blue) +{ + /* Convert the RGB values to CIE tristimulus values (XYZ) */ + double X = (-0.14282) * (red) + (1.54924) * (green) + (-0.95641) * (blue); + double Y = (-0.32466) * (red) + (1.57837) * (green) + (-0.73191) * (blue); + double Z = (-0.68202) * (red) + (0.77073) * (green) + (0.56332) * (blue); + + /* Calculate the normalized chromaticity values */ + double x = X / (X + Y + Z); + double y = Y / (X + Y + Z); + + /* Calculate CCT */ + double n = (x - 0.3320) / (0.1858 - y); + return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Awb::prepare(IPAContext &context, rkisp1_params_cfg *params) +{ + params->others.awb_gain_config.gain_green_b = 256 * context.frameContext.awb.gains.green; + params->others.awb_gain_config.gain_blue = 256 * context.frameContext.awb.gains.blue; + params->others.awb_gain_config.gain_red = 256 * context.frameContext.awb.gains.red; + params->others.awb_gain_config.gain_green_r = 256 * context.frameContext.awb.gains.green; + + /* Update the gains. */ + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN; + + /* If we already have configured the gains and window, return. */ + if (context.frameContext.frameCount > 0) + return; + + /* Configure the gains to apply. */ + params->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN; + /* Update the ISP to apply the gains configured. */ + params->module_ens |= RKISP1_CIF_ISP_MODULE_AWB_GAIN; + + /* Configure the measure window for AWB. */ + params->meas.awb_meas_config.awb_wnd = context.configuration.awb.measureWindow; + /* + * Measure Y, Cr and Cb means. + * \todo RGB is not working, the kernel seems to not configure it ? + */ + params->meas.awb_meas_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR; + /* Reference Cr and Cb. */ + params->meas.awb_meas_config.awb_ref_cb = 128; + params->meas.awb_meas_config.awb_ref_cr = 128; + /* Y values to include are between min_y and max_y only. */ + params->meas.awb_meas_config.min_y = 16; + params->meas.awb_meas_config.max_y = 250; + /* Maximum Cr+Cb value to take into account for awb. */ + params->meas.awb_meas_config.max_csum = 250; + /* Minimum Cr and Cb values to take into account. */ + params->meas.awb_meas_config.min_c = 16; + /* Number of frames to use to estimate the mean (0 means 1 frame). */ + params->meas.awb_meas_config.frames = 0; + + /* Update AWB measurement unit configuration. */ + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB; + /* Make sure the ISP is measuring the means for the next frame. */ + params->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB; + params->module_ens |= RKISP1_CIF_ISP_MODULE_AWB; +} + +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void Awb::process([[maybe_unused]] IPAContext &context, const rkisp1_stat_buffer *stats) +{ + const rkisp1_cif_isp_stat *params = &stats->params; + const rkisp1_cif_isp_awb_stat *awb = ¶ms->awb; + + /* Get the YCbCr mean values */ + double yMean = awb->awb_mean[0].mean_y_or_g; + double crMean = awb->awb_mean[0].mean_cr_or_r; + double cbMean = awb->awb_mean[0].mean_cb_or_b; + + /* + * Convert from YCbCr to RGB. + * The hardware uses the following formulas: + * Y = 16 + 0.2500 R + 0.5000 G + 0.1094 B + * Cb = 128 - 0.1406 R - 0.2969 G + 0.4375 B + * Cr = 128 + 0.4375 R - 0.3750 G - 0.0625 B + * + * The inverse matrix is thus: + * [[1,1636, -0,0623, 1,6008] + * [1,1636, -0,4045, -0,7949] + * [1,1636, 1,9912, -0,0250]] + */ + yMean -= 16; + cbMean -= 128; + crMean -= 128; + double redMean = 1.1636 * yMean - 0.0623 * cbMean + 1.6008 * crMean; + double blueMean = 1.1636 * yMean - 0.4045 * cbMean - 0.7949 * crMean; + double greenMean = 1.1636 * yMean + 1.9912 * cbMean - 0.0250 * crMean; + + /* + * Gain values are unsigned integer value, range 0 to 4 with 8 bit + * fractional part. + */ + redMean = std::clamp(redMean, 0.0, 1023.0 / 256); + blueMean = std::clamp(redMean, 0.0, 1023.0 / 256); + greenMean = std::clamp(redMean, 0.0, 1023.0 / 256); + + /* Estimate the red and blue gains to apply in a grey world. */ + double redGain = greenMean / (redMean + 1); + double blueGain = greenMean / (blueMean + 1); + + /* Filter the values to avoid oscillations. */ + IPAFrameContext &frameContext = context.frameContext; + + frameContext.awb.temperatureK = estimateCCT(redMean, greenMean, blueMean); + frameContext.awb.gains.red = 0.2 * redGain + + 0.8 * frameContext.awb.gains.red; + frameContext.awb.gains.blue = 0.2 * blueGain + + 0.8 * frameContext.awb.gains.blue; + /* Hardcode the green gain to 1.0. */ + frameContext.awb.gains.green = 1.0; + + LOG(RkISP1Awb, Debug) << "Gain found for red: " << context.frameContext.awb.gains.red + << " and for blue: " << context.frameContext.awb.gains.blue; +} + +} /* namespace ipa::rkisp1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h new file mode 100644 index 00000000..11946643 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/awb.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * awb.h - AWB control algorithm + */ + +#pragma once + +#include + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +class Awb : public Algorithm +{ +public: + Awb() = default; + ~Awb() = default; + + int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override; + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; + void process(IPAContext &context, const rkisp1_stat_buffer *stats) override; + +private: + uint32_t estimateCCT(double red, double green, double blue); +}; + +} /* namespace ipa::rkisp1::algorithms */ +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build index 27c97731..7ec53d89 100644 --- a/src/ipa/rkisp1/algorithms/meson.build +++ b/src/ipa/rkisp1/algorithms/meson.build @@ -2,5 +2,6 @@ rkisp1_ipa_algorithms = files([ 'agc.cpp', + 'awb.cpp', 'blc.cpp', ]) diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 790e159b..d6d8456c 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -81,6 +81,14 @@ namespace libcamera::ipa::rkisp1 { * \brief Hardware revision of the ISP */ +/** + * \var IPASessionConfiguration::awb + * \brief AWB parameters configuration of the IPA + * + * \var IPASessionConfiguration::awb.measureWindow + * \brief AWB measure window + */ + /** * \var IPASessionConfiguration::sensor * \brief Sensor-specific configuration of the IPA @@ -105,6 +113,26 @@ namespace libcamera::ipa::rkisp1 { * The gain should be adapted to the sensor specific gain code before applying. */ +/** + * \var IPAFrameContext::awb + * \brief Context for the Automatic White Balance algorithm + * + * \struct IPAFrameContext::awb.gains + * \brief White balance gains + * + * \var IPAFrameContext::awb.gains.red + * \brief White balance gain for R channel + * + * \var IPAFrameContext::awb.gains.green + * \brief White balance gain for G channel + * + * \var IPAFrameContext::awb.gains.blue + * \brief White balance gain for B channel + * + * \var IPAFrameContext::awb.temperatureK + * \brief Estimated color temperature + */ + /** * \var IPAFrameContext::sensor * \brief Effective sensor values diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 35e9b8e5..f387cace 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -12,6 +12,8 @@ #include +#include + namespace libcamera { namespace ipa::rkisp1 { @@ -25,6 +27,10 @@ struct IPASessionConfiguration { struct rkisp1_cif_isp_window measureWindow; } agc; + struct { + struct rkisp1_cif_isp_window measureWindow; + } awb; + struct { utils::Duration lineDuration; } sensor; @@ -40,6 +46,16 @@ struct IPAFrameContext { double gain; } agc; + struct { + struct { + double red; + double green; + double blue; + } gains; + + double temperatureK; + } awb; + struct { uint32_t exposure; double gain; diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index bb3deb93..f4db3a21 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -27,6 +27,7 @@ #include "algorithms/agc.h" #include "algorithms/algorithm.h" +#include "algorithms/awb.h" #include "algorithms/blc.h" #include "libipa/camera_sensor_helper.h" @@ -127,6 +128,7 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision) /* Construct our Algorithms */ algorithms_.push_back(std::make_unique()); + algorithms_.push_back(std::make_unique()); algorithms_.push_back(std::make_unique()); return 0;