From patchwork Wed May 6 23:06:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: devve X-Patchwork-Id: 26654 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 7D25DC32F8 for ; Wed, 6 May 2026 23:07:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DA8A16302F; Thu, 7 May 2026 01:06:58 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="XCZHGpuv"; dkim-atps=neutral Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3600B6271A for ; Thu, 7 May 2026 01:06:52 +0200 (CEST) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-4891e5b9c1fso1803655e9.2 for ; Wed, 06 May 2026 16:06:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778108811; x=1778713611; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=TdmC3s5OWUslsg0CaqrHDC/ToejoU6twUaRb3QtsRVI=; b=XCZHGpuvcMBcdW4Yoql9ekeSYBmnFTUoNm6zeL0pA3+bdIB69tDHWcOOmUTxjcVGvF 4qDRzJ4CiRzIVJj6xVRmiDhTnuf93Ca3Smy5xNPWpr4sfnYzZOT6IGsO4F52cJf+55ot RZqHq0p2TVK7/xWzZBM1q1ZWY3gK2an36hy/O37fWLT9o6UbYTJjahO6dnuqtP1fmgrg zr5oouRasTELckG8nMHsqfHP8nh3k3N+v5aDAp1XwAdQtSaeqgaGv0UWO6EXzHUX1T+9 fLw2mph+EFKAa4CxfoXRm9VACM4JTMAgZ3igK2WnygZO9cgzAyM+JDTIJ+B0tY7SZgzm WMAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778108811; x=1778713611; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=TdmC3s5OWUslsg0CaqrHDC/ToejoU6twUaRb3QtsRVI=; b=UsoNyc6dEZ0MW6SgHWj8ovVgJcGFE24FKyPHC0gC+aiSMuIZifvP9RDDT6S+IsdTFF bCsAnHsw7fuVIaRrjnh9+lwcPAzdmCFFETCoybZjsao7ahWrI6XW9nlP0l9jMQIhcAU8 w4jHVyYMsS9QJTIv+qByoTqdkFvRgIKFqWUy9nxqpClWD6A0d/DDS5vraDmVa1DPXJHh 4Lytyvt82KtZTMXv1804FpPOYegp4QLeNBaV7Y7uEVFkofRsCAplGnRWL+Bgt/z/DU/j m94DRlZzq1ylt/7qY2VqPngcmV1f6GTSEimRXfeFXaiLR0WZ7u3c/ixzECIY8TFmMH9Z XuFw== X-Gm-Message-State: AOJu0YznV3d72mmH5fz99cvAnZ/zLTMcXBiyj+wzruhIC/Ha7388aOoW bv8ZKuToxFjOX3Ik9Lg9isUel+R6Cb7ms6hRjkGlwQuduUGcyp3KhJ2p6sHAsw== X-Gm-Gg: AeBDieu+As6Ejo/DKLo9J5xKHNI4tVOtougQ6zgVeWKqsrWTH3sOEOnAfPAV0prQPkZ oRVTw9nExJKY73kaNz6nt73QxIEI92a71k4n7AAAV89dLmkqmbCiUPTYz9pmOV/thekmL2fGilX Z9vsltC9I3zTemsEYPVI9EtvPax83MvPWbtwpjNH9KORdh2A113QmAd2wTY/WWc1TsgmEdSICch ZmD3TlJVuiZzd+boTI7UkLWnmLcQge92Kj30whq3nEb2BY1Cgg+D0gX3vqs336AjeEtMPkdxsqf TOmdmNarhkcFTAAh6bZcgpgbGfKObUud4tPu81cc9MEgcOohlIDQ094sGCDSiOSxxH43/uRh3NV GB9RXntuyVUV6YxhzpxaAGm1h8rufGaZpGZmVwaSVXvibiM6VWplY8q+467vzuUvnlIWRqGuA8T mLqa/Dr4OuT0MMUcoQ+RFOU6DiZhEnLroA9d9TXXMe7qdUDfI6CLy669V1oef8ivtqNFCbE2blK EtovvQfE3Nwa3yDf71P+KG9lNBgTT7q X-Received: by 2002:a05:600c:45c6:b0:48a:93f8:dd02 with SMTP id 5b1f17b1804b1-48e521e6090mr85110545e9.14.1778108811386; Wed, 06 May 2026 16:06:51 -0700 (PDT) Received: from dexps.speedport.ip (p200300eda74453cf3cf3f7929e513b94.dip0.t-ipconnect.de. [2003:ed:a744:53cf:3cf3:f792:9e51:3b94]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e538a547bsm85951935e9.5.2026.05.06.16.06.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 May 2026 16:06:51 -0700 (PDT) From: d3vv3 To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 03/10] ipa: simple: adjust: Support gamma, contrast, saturation defaults from YAML Date: Thu, 7 May 2026 01:06:42 +0200 Message-ID: <20260506230649.1040794-4-devve.3@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260506230649.1040794-1-devve.3@gmail.com> References: <20260506230649.1040794-1-devve.3@gmail.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" Read default values for gamma, contrast, and saturation from the tuning file so sensors can specify different image processing defaults without code changes. Falls back to prior defaults (gamma 2.2, contrast 1.0, saturation 1.0) when not specified in YAML. Signed-off-by: d3vv3 --- src/ipa/simple/algorithms/adjust.cpp | 48 +++++++++++++--------------- src/ipa/simple/algorithms/adjust.h | 4 +++ src/ipa/simple/ipa_context.h | 8 ++--- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp index 8bf39c4c..a03a6f1f 100644 --- a/src/ipa/simple/algorithms/adjust.cpp +++ b/src/ipa/simple/algorithms/adjust.cpp @@ -14,34 +14,37 @@ #include #include "libcamera/internal/matrix.h" +#include "libcamera/internal/yaml_parser.h" namespace libcamera { namespace ipa::soft::algorithms { -constexpr float kDefaultContrast = 1.0f; -constexpr float kDefaultSaturation = 1.0f; - LOG_DEFINE_CATEGORY(IPASoftAdjust) -int Adjust::init(IPAContext &context, [[maybe_unused]] const ValueNode &tuningData) +int Adjust::init(IPAContext &context, const ValueNode &tuningData) { + defaultGamma_ = tuningData["gamma"].get().value_or(kDefaultGamma); + defaultContrast_ = tuningData["contrast"].get().value_or(1.0f); + defaultSaturation_ = tuningData["saturation"].get().value_or(1.0f); + context.ctrlMap[&controls::Gamma] = - ControlInfo(0.1f, 10.0f, kDefaultGamma); + ControlInfo(0.1f, 10.0f, defaultGamma_); context.ctrlMap[&controls::Contrast] = - ControlInfo(0.0f, 2.0f, kDefaultContrast); + ControlInfo(0.0f, 2.0f, defaultContrast_); if (context.ccmEnabled) context.ctrlMap[&controls::Saturation] = - ControlInfo(0.0f, 2.0f, kDefaultSaturation); + ControlInfo(0.0f, 2.0f, defaultSaturation_); + return 0; } int Adjust::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { - context.activeState.knobs.gamma = kDefaultGamma; - context.activeState.knobs.contrast = std::optional(); - context.activeState.knobs.saturation = std::optional(); + context.activeState.knobs.gamma = defaultGamma_; + context.activeState.knobs.contrast = defaultContrast_; + context.activeState.knobs.saturation = defaultSaturation_; return 0; } @@ -59,13 +62,13 @@ void Adjust::queueRequest(typename Module::Context &context, const auto &contrast = controls.get(controls::Contrast); if (contrast.has_value()) { - context.activeState.knobs.contrast = contrast; + context.activeState.knobs.contrast = contrast.value(); LOG(IPASoftAdjust, Debug) << "Setting contrast to " << contrast.value(); } const auto &saturation = controls.get(controls::Saturation); if (saturation.has_value()) { - context.activeState.knobs.saturation = saturation; + context.activeState.knobs.saturation = saturation.value(); LOG(IPASoftAdjust, Debug) << "Setting saturation to " << saturation.value(); } } @@ -100,15 +103,15 @@ void Adjust::prepare(IPAContext &context, frameContext.gamma = context.activeState.knobs.gamma; frameContext.contrast = context.activeState.knobs.contrast; - auto &saturation = context.activeState.knobs.saturation; - if (context.ccmEnabled && saturation) { - applySaturation(context.activeState.combinedMatrix, saturation.value()); + const float saturation = context.activeState.knobs.saturation; + if (context.ccmEnabled) { + applySaturation(context.activeState.combinedMatrix, saturation); frameContext.saturation = saturation; } params->gamma = 1.0 / context.activeState.knobs.gamma; - const float contrast = context.activeState.knobs.contrast.value_or(kDefaultContrast); - params->contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); + params->contrastExp = tan(std::clamp(context.activeState.knobs.contrast * M_PI_4, + 0.0, M_PI_2 - 0.00001)); } void Adjust::process([[maybe_unused]] IPAContext &context, @@ -117,14 +120,9 @@ void Adjust::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const SwIspStats *stats, ControlList &metadata) { - const auto &gamma = frameContext.gamma; - metadata.set(controls::Gamma, gamma); - - const auto &contrast = frameContext.contrast; - metadata.set(controls::Contrast, contrast.value_or(kDefaultContrast)); - - const auto &saturation = frameContext.saturation; - metadata.set(controls::Saturation, saturation.value_or(kDefaultSaturation)); + metadata.set(controls::Gamma, frameContext.gamma); + metadata.set(controls::Contrast, frameContext.contrast); + metadata.set(controls::Saturation, frameContext.saturation); } REGISTER_IPA_ALGORITHM(Adjust, "Adjust") diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h index 49c1f26c..a836b51b 100644 --- a/src/ipa/simple/algorithms/adjust.h +++ b/src/ipa/simple/algorithms/adjust.h @@ -43,6 +43,10 @@ public: private: void applySaturation(Matrix &ccm, float saturation); + + float defaultGamma_; + float defaultContrast_; + float defaultSaturation_; }; } /* namespace ipa::soft::algorithms */ diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index 34f7403a..cd9a8eda 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -58,8 +58,8 @@ struct IPAActiveState { struct { float gamma; /* 0..2 range, 1.0 = normal */ - std::optional contrast; - std::optional saturation; + float contrast; + float saturation; } knobs; }; @@ -77,8 +77,8 @@ struct IPAFrameContext : public FrameContext { } gains; float gamma; - std::optional contrast; - std::optional saturation; + float contrast; + float saturation; }; struct IPAContext {