From patchwork Wed May 22 14:54:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 20086 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 69AA2BD87C for ; Wed, 22 May 2024 14:55:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D57AF6349D; Wed, 22 May 2024 16:55:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tQBjLyA4"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 54BDF6349B for ; Wed, 22 May 2024 16:55:06 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:9beb:c30d:4413:8c99]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9A3B1C67; Wed, 22 May 2024 16:54:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1716389693; bh=l5fwIaw1q7mA3XvKAgkgqaFQ8wKVZWbfA1pzzivnB0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tQBjLyA44PN/Nk8NXrjj4nPJkOwiKBugSutcnNbNereCCnxgH1xQbyprxF9TKx3Uo pWG5hym81NuRJ5DcbQPps2cJX5fzviJjA7Q31fy5HrDU4gjx6DHfBatPWlaJM7G2JO 8a1uzEIYWtcla/KdQgRSMtG8Z6FhyfkC0pttSJuE= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v2 4/4] pipeline: rkisp1: Implement gamma control Date: Wed, 22 May 2024 16:54:38 +0200 Message-Id: <20240522145438.436688-5-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240522145438.436688-1-stefan.klug@ideasonboard.com> References: <20240522145438.436688-1-stefan.klug@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" Add support for the gamma control on the rkisp1. This was tested on an imx8mp. Signed-off-by: Stefan Klug --- src/ipa/rkisp1/algorithms/goc.cpp | 77 +++++++++++++++++++++++++++---- src/ipa/rkisp1/algorithms/goc.h | 11 ++++- src/ipa/rkisp1/ipa_context.h | 4 ++ 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp index 6f313820..0b312e7a 100644 --- a/src/ipa/rkisp1/algorithms/goc.cpp +++ b/src/ipa/rkisp1/algorithms/goc.cpp @@ -11,6 +11,8 @@ #include #include +#include + #include "libcamera/internal/yaml_parser.h" #include "linux/rkisp1-config.h" @@ -41,6 +43,7 @@ namespace ipa::rkisp1::algorithms { LOG_DEFINE_CATEGORY(RkISP1Gamma) Gamma::Gamma() + : gamma_(0) { } @@ -50,6 +53,8 @@ Gamma::Gamma() int Gamma::init([[maybe_unused]] IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) { + context.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, 2.2f); + if (context.hw->numGammaOutSamples != RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10) { LOG(RkISP1Gamma, Error) @@ -60,6 +65,41 @@ int Gamma::init([[maybe_unused]] IPAContext &context, return 0; } +/** + * \brief Configure the Gamma given a configInfo + * \param[in] context The shared IPA context + * \param[in] configInfo The IPA configuration data + * + * \return 0 + */ +int Gamma::configure(IPAContext &context, + [[maybe_unused]] const IPACameraSensorInfo &configInfo) +{ + context.activeState.gamma = 2.2; + return 0; +} + +/** + * \copydoc libcamera::ipa::Algorithm::queueRequest + */ +void Gamma::queueRequest([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) +{ + const auto &gamma = controls.get(controls::Gamma); + if (gamma) { + /* \todo This is not correct as it updates the current state with a + * future value. But it does no harm at the moment an allows us to + * track the last active gamma + */ + context.activeState.gamma = *gamma; + LOG(RkISP1Gamma, Debug) << "Set gamma to " << *gamma; + } + + frameContext.gamma = context.activeState.gamma; +} + /** * \copydoc libcamera::ipa::Algorithm::prepare */ @@ -78,19 +118,36 @@ void Gamma::prepare([[maybe_unused]] IPAContext &context, ASSERT(context.hw->numGammaOutSamples == RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10); - if (frame > 0) - return; + if (frame == 0 || std::fabs(frameContext.gamma - gamma_) > 0.001) { + gamma_ = frameContext.gamma; + + int x = 0; + for (unsigned i = 0; i < context.hw->numGammaOutSamples; i++) { + gamma_y[i] = std::pow(x / 4096.0, 1.0 / gamma_) * 1023.0; + x += segments[i]; + } - int x = 0; - for (unsigned i = 0; i < context.hw->numGammaOutSamples; i++) { - gamma_y[i] = std::pow(x / 4096.0, 1.0 / gamma_) * 1023.0; - x += segments[i]; + params->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC; + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC; + + /* It is unclear why these bits need to be set more than once. + * Setting them only on frame 0 didn't apply gamma. + */ + params->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC; + params->module_ens |= RKISP1_CIF_ISP_MODULE_GOC; } +} - params->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC; - params->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC; - params->module_ens |= RKISP1_CIF_ISP_MODULE_GOC; - params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC; +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void Gamma::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] const rkisp1_stat_buffer *stats, + ControlList &metadata) +{ + metadata.set(controls::Gamma, frameContext.gamma); } REGISTER_IPA_ALGORITHM(Gamma, "Gamma") diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h index fe7caba3..f2142b55 100644 --- a/src/ipa/rkisp1/algorithms/goc.h +++ b/src/ipa/rkisp1/algorithms/goc.h @@ -20,12 +20,21 @@ public: ~Gamma() = default; int init(IPAContext &context, const YamlObject &tuningData) override; + int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override; + void queueRequest(IPAContext &context, + const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, rkisp1_params_cfg *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const rkisp1_stat_buffer *stats, + ControlList &metadata) override; private: - float gamma_ = 2.2; + float gamma_; }; } /* namespace ipa::rkisp1::algorithms */ diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index bd02a7a2..5252e222 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -104,6 +104,8 @@ struct IPAActiveState { uint8_t denoise; uint8_t sharpness; } filter; + + double gamma; }; struct IPAFrameContext : public FrameContext { @@ -146,6 +148,8 @@ struct IPAFrameContext : public FrameContext { uint32_t exposure; double gain; } sensor; + + double gamma; }; struct IPAContext {