From patchwork Sun Oct 26 23:30:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24826 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 513B5C32CE for ; Sun, 26 Oct 2025 23:31:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DF6AC60758; Mon, 27 Oct 2025 00:30:58 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="r/Jpw4Q2"; 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 4A5E5606CE for ; Mon, 27 Oct 2025 00:30:54 +0100 (CET) Received: from charm.hippo-penny.ts.net (unknown [209.38.108.23]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C644514A6; Mon, 27 Oct 2025 00:29:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761521346; bh=bycs83QWG4GQExYg5Tz8fnZpbW85jOhKNNeo9GT5w9Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r/Jpw4Q2LLOvrKI1kVqUcwAsLrIuGGAiNvbSimyjrf9aF8HnHTNqrm33pJKhV8KV2 IYWHSuEu9+Me0CsR9GkjOP2Ou1qwEdFFnnpkqz0GIDiWRKK/1dzU7JN9Urwls2C/7E 2hwIT+vDDuudivEcMydRbRz9KtOO3XsmqOJEY9xw= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH 3/6] ipa: rkisp1: cproc: Convert to use Quantized types Date: Sun, 26 Oct 2025 23:30:40 +0000 Message-ID: <20251026233048.175689-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251026233048.175689-1-kieran.bingham@ideasonboard.com> References: <20251026233048.175689-1-kieran.bingham@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" Convert the Contrast and Saturuation helper functions to a Quantizer type to support maintaining the data. Signed-off-by: Kieran Bingham --- src/ipa/rkisp1/algorithms/cproc.cpp | 67 +++++++++++++++++++++-------- src/ipa/rkisp1/ipa_context.h | 13 +++--- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp index d1fff6990d37..44c0fb8425de 100644 --- a/src/ipa/rkisp1/algorithms/cproc.cpp +++ b/src/ipa/rkisp1/algorithms/cproc.cpp @@ -14,6 +14,8 @@ #include +#include "libipa/quantized.h" + /** * \file cproc.h */ @@ -39,15 +41,44 @@ constexpr float kDefaultBrightness = 0.0f; constexpr float kDefaultContrast = 1.0f; constexpr float kDefaultSaturation = 1.0f; -int convertBrightness(const float v) +class BrightnessQ : public Quantizer { - return std::clamp(std::lround(v * 128), -128, 127); -} +public: + BrightnessQ(const float val) { set(val); } + BrightnessQ(const int8_t val) { set(val); } -int convertContrastOrSaturation(const float v) + int8_t fromFloat(float v) const override + { + int quantized = std::lround(v * 128.0f); + return static_cast(std::clamp(quantized, -128, 127)); + } + + float toFloat(int8_t v) const override + { + return static_cast(v) / 128.0f; + } +}; + +class ContrastSaturationQuantizer : public Quantizer { - return std::clamp(std::lround(v * 128), 0, 255); -} +public: + ContrastSaturationQuantizer(const float val) { set(val); } + ContrastSaturationQuantizer(const uint8_t val) { set(val); } + + uint8_t fromFloat(const float v) const override + { + int quantized = std::lround(v * 128.0f); + return static_cast(std::clamp(quantized, 0, 255)); + } + + float toFloat(const uint8_t v) const override + { + return static_cast(v) / 128.0f; + } +}; + +using ContrastQ = ContrastSaturationQuantizer; +using SaturationQ = ContrastSaturationQuantizer; } /* namespace */ @@ -74,9 +105,9 @@ int ColorProcessing::configure(IPAContext &context, { auto &cproc = context.activeState.cproc; - cproc.brightness = convertBrightness(kDefaultBrightness); - cproc.contrast = convertContrastOrSaturation(kDefaultContrast); - cproc.saturation = convertContrastOrSaturation(kDefaultSaturation); + cproc.brightness = BrightnessQ(kDefaultBrightness); + cproc.contrast = ContrastQ(kDefaultContrast); + cproc.saturation = SaturationQ(kDefaultSaturation); return 0; } @@ -97,35 +128,35 @@ void ColorProcessing::queueRequest(IPAContext &context, const auto &brightness = controls.get(controls::Brightness); if (brightness) { - int value = convertBrightness(*brightness); + BrightnessQ value = *brightness; if (cproc.brightness != value) { cproc.brightness = value; update = true; } - LOG(RkISP1CProc, Debug) << "Set brightness to " << value; + LOG(RkISP1CProc, Debug) << "Set brightness to " << value.value(); } const auto &contrast = controls.get(controls::Contrast); if (contrast) { - int value = convertContrastOrSaturation(*contrast); + ContrastQ value = *contrast; if (cproc.contrast != value) { cproc.contrast = value; update = true; } - LOG(RkISP1CProc, Debug) << "Set contrast to " << value; + LOG(RkISP1CProc, Debug) << "Set contrast to " << value.value(); } const auto saturation = controls.get(controls::Saturation); if (saturation) { - int value = convertContrastOrSaturation(*saturation); + SaturationQ value = *saturation; if (cproc.saturation != value) { cproc.saturation = value; update = true; } - LOG(RkISP1CProc, Debug) << "Set saturation to " << value; + LOG(RkISP1CProc, Debug) << "Set saturation to " << value.value(); } frameContext.cproc.brightness = cproc.brightness; @@ -148,9 +179,9 @@ void ColorProcessing::prepare([[maybe_unused]] IPAContext &context, auto config = params->block(); config.setEnabled(true); - config->brightness = frameContext.cproc.brightness; - config->contrast = frameContext.cproc.contrast; - config->sat = frameContext.cproc.saturation; + config->brightness = frameContext.cproc.brightness.quantized(); + config->contrast = frameContext.cproc.contrast.quantized(); + config->sat = frameContext.cproc.saturation.quantized(); } REGISTER_IPA_ALGORITHM(ColorProcessing, "ColorProcessing") diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index f85a130d9c23..b7cdfc36b275 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -27,6 +27,7 @@ #include #include #include "libipa/agc_mean_luminance.h" +#include "libipa/quantized.h" namespace libcamera { @@ -115,9 +116,9 @@ struct IPAActiveState { } ccm; struct { - int8_t brightness; - uint8_t contrast; - uint8_t saturation; + Quantized brightness; + Quantized contrast; + Quantized saturation; } cproc; struct { @@ -169,9 +170,9 @@ struct IPAFrameContext : public FrameContext { } awb; struct { - int8_t brightness; - uint8_t contrast; - uint8_t saturation; + Quantized brightness; + Quantized contrast; + Quantized saturation; bool update; } cproc;