From patchwork Fri Oct 3 12:15:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24558 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 5480AC324C for ; Fri, 3 Oct 2025 12:18:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 297666B5F3; Fri, 3 Oct 2025 14:18:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="BAbJ8hZz"; dkim-atps=neutral Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8322169318 for ; Fri, 3 Oct 2025 14:18:31 +0200 (CEST) Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-3ee0fd0c5c4so198816f8f.3 for ; Fri, 03 Oct 2025 05:18:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759493911; x=1760098711; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UbalvF77R6m7kRGcNwpXf4C99U24C/faJvy6AO/sdII=; b=BAbJ8hZzCnAkgLeNUgtnIuR3HF1angcdN0dnj0I1kcWPaXfevphwRWZD1P2LyaezZG 6pnfMhbE51LxOm9rOuEytw37PKqzTXzSkf8AG5bx6c0r1UYBt/8ZDACXylAIDebCBCKB hjaBNWwuOArKqG1SXWA+o7XKtUs94RzNLJbw785oMUW9GwwFbtzAvMspvlVyjsdvD/FI lVTuBSV5F7D99MtkJxJRKxy4sAtRElajj/vlRDoQ/N1thogC43mc8ef7AXv5klPUw9KI gsKG6+5e2spNwOaT47sYxqjMQsezV/xwLPLP2NY2bKXk3hZAOSXTI5kdnE2QoNFFPV1K 7OSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759493911; x=1760098711; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UbalvF77R6m7kRGcNwpXf4C99U24C/faJvy6AO/sdII=; b=RxFAvWvyzvz4aG7wfvNu93Bu26nadEjWo2mK1miAgAy1uQUR3eCI0EcVGkMJY4Ac0g 4cZgPGqotMj1cHaidJgZeXtmjVv1wFtKLk21I3fqsztzmYoWDNQKdJvcGnHyZfApVSHp C3kYTHtXjG0M+HPG4BYwFik4lZ75zQ6yQPSK8YqoMMrJFPv9WIYNHGUSe3XDq5AoR3Nk 54XKwFP8KtZG0Q7+WE8FT7US7CEmi8KZI4GpYpXN+pVvF14T4diESapFGwe3kAZqWKkR P0ne+bsAragGaqUvPlXhxCeAc6ZHm+quBoxYEuTTUi+486kcwj+5MK5yXd54q0IMy35h rRJQ== X-Gm-Message-State: AOJu0YyBGXLEg073jP/N/yFAz+82O7ZHJGeyC5za/Ikr4tB7Zo9mM/cg Z0q9due1gZ7H3MvPoY8m1YbOOsRCQYuhXZSgB5iyd8EzC2YlSwKJ3zI34DiyNZ5wriAeJ7OGXiP WgWxF X-Gm-Gg: ASbGncvmGg2HhjWpfa9BT8FLwPdATvB+Svb8E7QANjDcdYkjK1leVxlhv4fzC/o+f3M MZDGLDj/1SjBudbeuN/OREdzANuaOu78In6c/Bo6PjOKgYOs0oq72ZTC/DcnGWTMZYUajFqmyoe qYzi/CQAoerg9FCgac3zfUPgzk261dJstkrIH/eWXbAP/PYLg7pCkFbCrqDCP6AJIBNyiiXLUov FkRXYpPyfUZ3bAOGSvTAR+NLNytHzn0Jyz/q3q9c4uCXhnT02+ZqyrSyR5kEOWCz4X5xdau19Sa reCaTCZmkeAhCCQOq2N0q6nBnVpWncPn35vDnAdgxiOzyYcBNP8T0c4p+fET9ClIcE1xQ9FvBbe 9hcGSXZYgC7nL56VavLuB1VZQ4LxFK24rgc3mbu+0RemSvkbNK7zdwpTy1dZp8HGl4N1VZA6+ok Gm X-Google-Smtp-Source: AGHT+IH2yG60LIZeoGDumTCkWBhQExH1DkuBbUGJMMhylzEyaHO+s+8XJCUN6IlUXmwKz7ldzfRJYg== X-Received: by 2002:a05:6000:2282:b0:3f3:1be5:ecbf with SMTP id ffacd0b85a97d-425671a06aemr903770f8f.7.1759493910694; Fri, 03 Oct 2025 05:18:30 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4255d8f02a8sm7812529f8f.39.2025.10.03.05.18.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 05:18:30 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Sena Asotani , Naushir Patuck Subject: [PATCH v2 1/4] ipa: rpi: pisp: Add decompand support using PiSP hardware block Date: Fri, 3 Oct 2025 13:15:52 +0100 Message-ID: <20251003121821.659081-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003121821.659081-1-naush@raspberrypi.com> References: <20251003121821.659081-1-naush@raspberrypi.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: Sena Asotani This patch integrates a new decompand algorithm that utilizes the PiSP FE hardware block available on Raspberry Pi 5. The implementation enables conversion of companded sensor data into linear format prior to ISP processing. Changes include: - Implementation of decompand logic for controller and pipe interfaces - Enabling decompand block by "rpi.decompand" in tuning.json Signed-off-by: Sena Asotani Signed-off-by: Naushir Patuck Tested-by: Nick Hollinghurst Reviewed-by: David Plowman --- src/ipa/rpi/controller/decompand_status.h | 8 ++++ src/ipa/rpi/controller/meson.build | 1 + src/ipa/rpi/controller/rpi/decompand.cpp | 58 +++++++++++++++++++++++ src/ipa/rpi/controller/rpi/decompand.h | 31 ++++++++++++ src/ipa/rpi/pisp/pisp.cpp | 38 +++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 src/ipa/rpi/controller/decompand_status.h create mode 100644 src/ipa/rpi/controller/rpi/decompand.cpp create mode 100644 src/ipa/rpi/controller/rpi/decompand.h diff --git a/src/ipa/rpi/controller/decompand_status.h b/src/ipa/rpi/controller/decompand_status.h new file mode 100644 index 000000000000..2d9888dca4f3 --- /dev/null +++ b/src/ipa/rpi/controller/decompand_status.h @@ -0,0 +1,8 @@ +#pragma once + +#include "libipa/pwl.h" + +struct DecompandStatus { + uint32_t bitdepth; + libcamera::ipa::Pwl decompandCurve; +}; diff --git a/src/ipa/rpi/controller/meson.build b/src/ipa/rpi/controller/meson.build index 74b74888bbff..c13c48539d10 100644 --- a/src/ipa/rpi/controller/meson.build +++ b/src/ipa/rpi/controller/meson.build @@ -14,6 +14,7 @@ rpi_ipa_controller_sources = files([ 'rpi/cac.cpp', 'rpi/ccm.cpp', 'rpi/contrast.cpp', + 'rpi/decompand.cpp', 'rpi/denoise.cpp', 'rpi/dpc.cpp', 'rpi/geq.cpp', diff --git a/src/ipa/rpi/controller/rpi/decompand.cpp b/src/ipa/rpi/controller/rpi/decompand.cpp new file mode 100644 index 000000000000..2036750f82f4 --- /dev/null +++ b/src/ipa/rpi/controller/rpi/decompand.cpp @@ -0,0 +1,58 @@ +#include "decompand.h" + +#include + +#include "../decompand_status.h" +#include "../histogram.h" + +using namespace RPiController; +using namespace libcamera; + +LOG_DEFINE_CATEGORY(RPiDecompand) + +#define NAME "rpi.decompand" + +Decompand::Decompand(Controller *controller) + : Algorithm(controller) +{ +} + +char const *Decompand::name() const +{ + return NAME; +} + +int Decompand::read(const libcamera::YamlObject ¶ms) +{ + config_.bitdepth = params["bitdepth"].get(0); + config_.decompandCurve = params["decompand_curve"].get(ipa::Pwl{}); + return config_.decompandCurve.empty() ? -EINVAL : 0; +} + +void Decompand::initialise() +{ +} + +void Decompand::switchMode(CameraMode const &cameraMode, + [[maybe_unused]] Metadata *metadata) +{ + mode_ = cameraMode; +} + +void Decompand::prepare(Metadata *imageMetadata) +{ + DecompandStatus decompandStatus; + + if (config_.bitdepth == 0 || mode_.bitdepth == config_.bitdepth) { + decompandStatus.decompandCurve = config_.decompandCurve; + imageMetadata->set("decompand.status", decompandStatus); + } +} + +/* Register algorithm with the system. */ +static Algorithm *create(Controller *controller) +{ + return new Decompand(controller); +} + +static RegisterAlgorithm reg(NAME, &create); diff --git a/src/ipa/rpi/controller/rpi/decompand.h b/src/ipa/rpi/controller/rpi/decompand.h new file mode 100644 index 000000000000..38b26a21e6d5 --- /dev/null +++ b/src/ipa/rpi/controller/rpi/decompand.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#include "../decompand_status.h" + +#include "algorithm.h" + +namespace RPiController { + +struct DecompandConfig { + uint32_t bitdepth; + libcamera::ipa::Pwl decompandCurve; +}; + +class Decompand : public Algorithm +{ +public: + Decompand(Controller *controller = nullptr); + char const *name() const override; + int read(const libcamera::YamlObject ¶ms) override; + void initialise() override; + void switchMode(CameraMode const &cameraMode, Metadata *metadata) override; + void prepare(Metadata *imageMetadata) override; + +private: + CameraMode mode_; + DecompandConfig config_; +}; + +} /* namespace RPiController */ diff --git a/src/ipa/rpi/pisp/pisp.cpp b/src/ipa/rpi/pisp/pisp.cpp index 829b91258522..14ece12b0895 100644 --- a/src/ipa/rpi/pisp/pisp.cpp +++ b/src/ipa/rpi/pisp/pisp.cpp @@ -32,6 +32,7 @@ #include "controller/cac_status.h" #include "controller/ccm_status.h" #include "controller/contrast_status.h" +#include "controller/decompand_status.h" #include "controller/denoise_algorithm.h" #include "controller/denoise_status.h" #include "controller/dpc_status.h" @@ -113,6 +114,25 @@ int generateLut(const ipa::Pwl &pwl, uint32_t *lut, std::size_t lutSize, return 0; } +int generateDecompandLut(const ipa::Pwl &pwl, Span lut) +{ + if (pwl.empty()) + return -EINVAL; + + constexpr int step = 1024; + for (std::size_t i = 0; i < lut.size(); ++i) { + int x = i * step; + + int y = pwl.eval(x); + if (y < 0) + return -1; + + lut[i] = static_cast(std::min(y, 65535)); + } + + return 0; +} + void packLscLut(uint32_t packed[NumLscVertexes][NumLscVertexes], double const rgb[3][NumLscVertexes][NumLscVertexes]) { @@ -236,6 +256,7 @@ private: void applyLensShading(const AlscStatus *alscStatus, pisp_be_global_config &global); void applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global); + void applyDecompand(const DecompandStatus *decompandStatus); void applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global); void applyTdn(const TdnStatus *tdnStatus, const DeviceStatus *deviceStatus, pisp_be_global_config &global); @@ -351,6 +372,11 @@ void IpaPiSP::platformPrepareIsp([[maybe_unused]] const PrepareParams ¶ms, if (noiseStatus) applyFocusStats(noiseStatus); + DecompandStatus *decompandStatus = + rpiMetadata.getLocked("decompand.status"); + if (decompandStatus) + applyDecompand(decompandStatus); + BlackLevelStatus *blackLevelStatus = rpiMetadata.getLocked("black_level.status"); if (blackLevelStatus) @@ -702,6 +728,18 @@ void IpaPiSP::applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global be_->SetDpc(dpc); } +void IpaPiSP::applyDecompand(const DecompandStatus *decompandStatus) +{ + pisp_fe_global_config feGlobal; + pisp_fe_decompand_config decompand = {}; + + if (!generateDecompandLut(decompandStatus->decompandCurve, decompand.lut)) { + fe_->SetDecompand(decompand); + feGlobal.enables |= PISP_FE_ENABLE_DECOMPAND; + fe_->SetGlobal(feGlobal); + } +} + void IpaPiSP::applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global) { pisp_be_sdn_config sdn = {}; From patchwork Fri Oct 3 12:15:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24559 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 7F286C324C for ; Fri, 3 Oct 2025 12:18:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 24E1C69318; Fri, 3 Oct 2025 14:18:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="b+TKvhOq"; dkim-atps=neutral Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7E66769318 for ; Fri, 3 Oct 2025 14:18:32 +0200 (CEST) Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-46e38c21fafso4055465e9.2 for ; Fri, 03 Oct 2025 05:18:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759493911; x=1760098711; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Nq0/DZ49evXH+3DtXg1iN+pSyMK/YaIlLQA5DCjVQTc=; b=b+TKvhOqhLHPbWh08GweF6ffedFh41wryOpEGJU33/FANE5g0w10JpSKwYzzKhM+tv JXDm9F6UarrzW/kFg3k/FHcjIyW/oj2n5tYfO7ni1fsUvT+oUBj34cWd0ukl90gpm2we daYJ7cEfJQZdlSOJqBRZ3RS+wu1NfgJUt2wC0zVzXoNcsSq92U67J0033BcG/+SoScum +DgGgZWO9awabAcgVfbDeWphHn2yokwZr1FM30r68hQuy5Dq/9ZBfl8HAwLBWnvjt1VW 64bWQN9WlfHTHs3SmVWkTAu2Pa1R8hNTI5/xPaxbR9C1X5r2klkaliTdJiVoXEjNnNUF jBAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759493911; x=1760098711; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Nq0/DZ49evXH+3DtXg1iN+pSyMK/YaIlLQA5DCjVQTc=; b=oH7Oxh14iJ+I5GaAH6Ex/8EzQxKquN9tlHqgVHefFyPICvfO8Efid0W0kfTByUXzr2 ryG8n+i4S9FukXtYglQsCoKJCQkIepvxb/IGb+Eh+MfbH9jBGMgeLkjbh2NF0KeYMp3U AWX8tF7mCj6fbIJDbDh7yIRTc5MrheJESbsMn39/vRLp4O/xcHybAezcAc3u8DadfVmk JAqfkaBH0Xgw6io2dKOXvTMNnrEsXrRIWECX8t3AdKf38GXL0cpQAeJkoRli94NqR8WU RsQIp6lRsDfT2nVlXN+TCrHFy5tb23L5ACiToRNODEu19B0KUxicY7gqSRuMIxcMseMD J9fQ== X-Gm-Message-State: AOJu0YwB9YpQOIGhBXzea+oSkOcoPRMXLOcVDIbmwU3gS1hOoDuAYhrE yFfqToPFcMXAoFnCh/HYASckVEOBwZENU6ymHicr8sTr1/BB6gTHfmZ52jflgruIsJu5BL87/zg 9yp05 X-Gm-Gg: ASbGncskBFqF3TEqp4+vg9YpikOuprRsNvp7VE8mSbD8mgqxhASXLvr5js6m2cxVPAR VU55KesVwMX/5DZD0W4KXuMqNn719tKen6irJSD2HNX2mqWl4I5+sxGPzYF7+EOksKhDrIJzN59 LUjyBqiZd28SfUE46BJF7MlV8wBIsu6DBtYirp0t9w0ydchXmoFxVF30/4w2Ddp0cDWinafv7Wm PzIH/Ig7AEWqyrBjmwwAOggzl94Wb+mPZeLPEeY9kgztcpo0Y+UiguHseqqPZAyvj2HA0g2iAMf +B5SAT6HvpBhamGRl8Mu4ijpi8YJbUy8W4BTXNfg9sMpmiQtXzKEl2lB22kqtZtZmJQB3Jdx9No u+Of5BUCH9chXse0O28JjHji99J2ISlg4q1sQRICwQXLgP4vPof53oIshs1+k/Y1/2Q== X-Google-Smtp-Source: AGHT+IG/MRuO3c/3vs7C782o/jvFkkWLvIp5sE+Mes9wlaUMCtjILYhtUzCB5macOHoLbynRk85uew== X-Received: by 2002:a5d:5d13:0:b0:3f4:52d3:7a6a with SMTP id ffacd0b85a97d-425671d3e41mr812206f8f.10.1759493911336; Fri, 03 Oct 2025 05:18:31 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4255d8f02a8sm7812529f8f.39.2025.10.03.05.18.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 05:18:31 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Naushir Patuck Subject: [PATCH v2 2/4] ipa: rpi: Add FE globals as a parameter to applyDecompand() Date: Fri, 3 Oct 2025 13:15:53 +0100 Message-ID: <20251003121821.659081-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003121821.659081-1-naush@raspberrypi.com> References: <20251003121821.659081-1-naush@raspberrypi.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" Don't let applyDecompand() directly change the FE global enables. Instead pass the global mask into the function and set it in the caller. This will be needed when a future commit will add setting the decompand initial values. Signed-off-by: Naushir Patuck Tested-by: Nick Hollinghurst Reviewed-by: David Plowman --- src/ipa/rpi/pisp/pisp.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/ipa/rpi/pisp/pisp.cpp b/src/ipa/rpi/pisp/pisp.cpp index 14ece12b0895..f5be39aca5ee 100644 --- a/src/ipa/rpi/pisp/pisp.cpp +++ b/src/ipa/rpi/pisp/pisp.cpp @@ -256,7 +256,7 @@ private: void applyLensShading(const AlscStatus *alscStatus, pisp_be_global_config &global); void applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global); - void applyDecompand(const DecompandStatus *decompandStatus); + void applyDecompand(const DecompandStatus *decompandStatus, pisp_fe_global_config &feGlobal); void applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global); void applyTdn(const TdnStatus *tdnStatus, const DeviceStatus *deviceStatus, pisp_be_global_config &global); @@ -368,6 +368,9 @@ void IpaPiSP::platformPrepareIsp([[maybe_unused]] const PrepareParams ¶ms, { /* All Frontend config goes first, we do not want to hold the FE lock for long! */ std::scoped_lock lf(*fe_); + pisp_fe_global_config feGlobal; + + fe_->GetGlobal(feGlobal); if (noiseStatus) applyFocusStats(noiseStatus); @@ -375,13 +378,14 @@ void IpaPiSP::platformPrepareIsp([[maybe_unused]] const PrepareParams ¶ms, DecompandStatus *decompandStatus = rpiMetadata.getLocked("decompand.status"); if (decompandStatus) - applyDecompand(decompandStatus); + applyDecompand(decompandStatus, feGlobal); BlackLevelStatus *blackLevelStatus = rpiMetadata.getLocked("black_level.status"); if (blackLevelStatus) applyBlackLevel(blackLevelStatus, global); + fe_->SetGlobal(feGlobal); } CacStatus *cacStatus = rpiMetadata.getLocked("cac.status"); @@ -728,16 +732,15 @@ void IpaPiSP::applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global be_->SetDpc(dpc); } -void IpaPiSP::applyDecompand(const DecompandStatus *decompandStatus) +void IpaPiSP::applyDecompand(const DecompandStatus *decompandStatus, pisp_fe_global_config &feGlobal) { - pisp_fe_global_config feGlobal; pisp_fe_decompand_config decompand = {}; if (!generateDecompandLut(decompandStatus->decompandCurve, decompand.lut)) { fe_->SetDecompand(decompand); feGlobal.enables |= PISP_FE_ENABLE_DECOMPAND; - fe_->SetGlobal(feGlobal); - } + } else + feGlobal.enables &= ~PISP_FE_ENABLE_DECOMPAND; } void IpaPiSP::applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global) From patchwork Fri Oct 3 12:15:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24560 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 BB531C3261 for ; Fri, 3 Oct 2025 12:18:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A42F56B614; Fri, 3 Oct 2025 14:18:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="adHMWele"; dkim-atps=neutral Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C847A6B5FF for ; Fri, 3 Oct 2025 14:18:32 +0200 (CEST) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-401ce0cae36so85143f8f.2 for ; Fri, 03 Oct 2025 05:18:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759493912; x=1760098712; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/MXPwOONyQGMGD5pq4Uaj2ICO0nNlOgDyk5ZR9DdQiM=; b=adHMWelewUBRt+w7tmXO+h03ERAkvGSPOu29LMYOK7FIN2GQcraHs2ssnc+YtYJ0pS R7kbTnHbi5kPEqr0iGDjnVkMQVgPUvGDPvDfJRy/5Q2RoKSpCWjOPLSzZWlRd/3o2A+k hFyYGt6pYq0OEM5eEW1U3gr6MYwi0TZ5NLs1t+uI8SB+/vR7pYAAzbzno+yDMa+fKJr9 iZ+z7Y7wfyy5C/1uxvxzwHfb2w07ZzF9V3TEQJ74RE7BUvxEFTaEu7C3wX/ZomzujTdq wn+U8KQYOSduTT7rE86qf2S5bvX5PXtyhq1wdqeGsiguRiXJiur5EgavdriNIFSobugF aFZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759493912; x=1760098712; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/MXPwOONyQGMGD5pq4Uaj2ICO0nNlOgDyk5ZR9DdQiM=; b=NZ4xRL4ydbdYsbd8p4nc0mwkO6VvffPO0fIJNe105weWIJ6yvnc8j4P3QLWbBGU/SN PQ36j+KzWobdRPW90hi8rV49JWojyeX+2YCzWZgp8MH6GTKNsGwS0tUE5brXVBg0S7RA 6U2fWZaA0NoEb+gHGD92W3iA3WD2+ifmoqhljDdJNC43u7pKnMwVUpEvtl8djFYU4aYz BIXMKebINEADDrJUiTAV9xhfLWBX+fR9OgBAeGzdU93tENEPH6cQUQnM/uj97Rv0uSfd ts2z2TI8HYkimxu4x1/ctu8i0/Bb0INgo/lJNmN34emHCaht6wEqg4KdPLd2BoI8VRzA pisg== X-Gm-Message-State: AOJu0YxNM0OF4B6rUKTDiKzQ4SSbh31YU24ptgrv6fKd3kz+FVFKO6Er +SunHudzBoq2lmwnfAc4JhBu4m1QR6iLmeWBih6tMGtYMLGBKIcd/J2SKwe8AbIovKzWPnyqf89 dYmYm X-Gm-Gg: ASbGncvaFvk3Y4spND0cOGRngfXEcdj0KnSzP8swMe8f94VUbEbZBkleR6kl9WVxtth WR0uArRtTrwQ+6TwKe4T3MwBaxUwcYATeec3Bk1LvtO7buGZHXEUOGErr2b/8NXxdePEEoZLspA kkfc2nKvT3cLPre4i+bsX5lwPM+Tet62lmNXdOMaqjsFlz95RQroZDBTObn5p6YDCwRocN/R5Wk 4auir9j6zK3N0LDoq2SjpqUxhAQXNdswAoST6KuwgJUof92eFBM100YbcqUl5BxVsEdYqhZKiwK 2pUJbrzsu4OWqI86UgZadpXAYdmlZBEnRGVXUJITHfxvpGirasAWyu55f8KEI0oaB6vbDTCUuFZ CAOTe0H9gY+psBdVisNzMGDi7MMzCMFkRgnuIcBjvXk+v2PxjBpQX3/gdabx8gkaRwA== X-Google-Smtp-Source: AGHT+IFxeYXsi9FsnoldHMUOsk6OgHe1YdgXE4ZYQF0N5Zps/YyAT9Bv22th5JAkOpBbzGLWNcWypQ== X-Received: by 2002:a05:6000:1861:b0:3f7:f02b:d7a with SMTP id ffacd0b85a97d-42567171f1bmr859654f8f.5.1759493912013; Fri, 03 Oct 2025 05:18:32 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4255d8f02a8sm7812529f8f.39.2025.10.03.05.18.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 05:18:31 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Naushir Patuck Subject: [PATCH v2 3/4] ipa: rpi: pisp: Add a DecompandAlgorithm class Date: Fri, 3 Oct 2025 13:15:54 +0100 Message-ID: <20251003121821.659081-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003121821.659081-1-naush@raspberrypi.com> References: <20251003121821.659081-1-naush@raspberrypi.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" The decompand algorithm implementation will subclass the DecompandAlgorithm class. This will be needed for setting the initial decompand values in a future commit. Signed-off-by: Naushir Patuck Tested-by: Nick Hollinghurst Reviewed-by: David Plowman --- src/ipa/rpi/controller/decompand_algorithm.h | 24 ++++++++++++++++++++ src/ipa/rpi/controller/rpi/decompand.cpp | 2 +- src/ipa/rpi/controller/rpi/decompand.h | 5 ++-- 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 src/ipa/rpi/controller/decompand_algorithm.h diff --git a/src/ipa/rpi/controller/decompand_algorithm.h b/src/ipa/rpi/controller/decompand_algorithm.h new file mode 100644 index 000000000000..f19f8c109323 --- /dev/null +++ b/src/ipa/rpi/controller/decompand_algorithm.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2025, Raspberry Pi Ltd + * + * Decompand control algorithm interface + */ +#pragma once + +#include "libipa/pwl.h" + +#include "algorithm.h" + +namespace RPiController { + +class DecompandAlgorithm : public Algorithm +{ +public: + DecompandAlgorithm(Controller *controller = NULL) + : Algorithm(controller) + { + } +}; + +} /* namespace RPiController */ diff --git a/src/ipa/rpi/controller/rpi/decompand.cpp b/src/ipa/rpi/controller/rpi/decompand.cpp index 2036750f82f4..5b4c2e5524af 100644 --- a/src/ipa/rpi/controller/rpi/decompand.cpp +++ b/src/ipa/rpi/controller/rpi/decompand.cpp @@ -13,7 +13,7 @@ LOG_DEFINE_CATEGORY(RPiDecompand) #define NAME "rpi.decompand" Decompand::Decompand(Controller *controller) - : Algorithm(controller) + : DecompandAlgorithm(controller) { } diff --git a/src/ipa/rpi/controller/rpi/decompand.h b/src/ipa/rpi/controller/rpi/decompand.h index 38b26a21e6d5..0f2a9b3bbdc4 100644 --- a/src/ipa/rpi/controller/rpi/decompand.h +++ b/src/ipa/rpi/controller/rpi/decompand.h @@ -2,10 +2,9 @@ #include +#include "../decompand_algorithm.h" #include "../decompand_status.h" -#include "algorithm.h" - namespace RPiController { struct DecompandConfig { @@ -13,7 +12,7 @@ struct DecompandConfig { libcamera::ipa::Pwl decompandCurve; }; -class Decompand : public Algorithm +class Decompand : public DecompandAlgorithm { public: Decompand(Controller *controller = nullptr); From patchwork Fri Oct 3 12:15:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24561 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 B4EFDC324C for ; Fri, 3 Oct 2025 12:18:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1EEBB6B5AA; Fri, 3 Oct 2025 14:18:39 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="QJEDlvE7"; 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 89F9B6B605 for ; Fri, 3 Oct 2025 14:18:33 +0200 (CEST) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-46e38c21fafso4055545e9.2 for ; Fri, 03 Oct 2025 05:18:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759493913; x=1760098713; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=I7DihWxCBk0ycoGsfleZNkucjNC5ge4C2YuX1MZttNY=; b=QJEDlvE7jOKo7IZz96Rybb8xNtDIJ+SzkhsFuDabTDe5aCsZYJjqbnjgiuMG8/l1rf zAq6kJ3+SutCQ5a28AZJm9BI43cWoxxzK9QnWfTUo5U5NXrpB44IFWLOl9wMoZNiaCMc qsd+gEtWSKVzOceYbJflPSlBlStnXMuN1yWnXzkSw66pJYYTJPViowBn6ElCxx59Pvrx 2SF5JI5VMuN03O2BzqPhPb0HMvp3FO26Wc9mrMx00ub5dekcgNsrNsQ6Hp71Dzi1MTH8 PLvG7kVh3XzFbbO/kf3ZI0Z0j+6bLTUzAtPTWRjLWwEUZ8vwptLnx5yxjI+TiMqGs8Ub xNKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759493913; x=1760098713; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=I7DihWxCBk0ycoGsfleZNkucjNC5ge4C2YuX1MZttNY=; b=oWkKGrX8497kGcw/+b9WSuwaJQ0p2FpHMmfmFTUU36ctOIihfwLWFr1PVv1zQrbexk LDMfc22gbvIlohSh641F/NzYbV62DWUfzDjV4ZMOC1PbIAfTNy8oWnTjCEp2Z+ggU3bd +AFKUKAwUq99FCBWQbCkCzOOVslfduEj3tsD5ZSP5kXbUCw15u4JdapVqUWRVA/A9fDn tdstG/nJ/wOHXy6cWBKduvjPv4C7BzuV3wbXzh78UgbWOnLx2YgjYLdfUivbcvcQ2JyZ DsVXzP/jaXmSuDcAVH2wVuFfButWgyhlramLERihhdNJf5k7z0a/gG6w+npgasB1LPF/ kxug== X-Gm-Message-State: AOJu0YwEi7WVE16sRBWn5fe1//lYSHTCrT2hHExiC3zb5dxug29Ojdsb LWSGr7N18TKwbJFzx3nhmjoI7tYLy9oizqWumAb9coiluuoqDU6TLzOSIfUE46qlf0TNljkv18x /epFc X-Gm-Gg: ASbGnctkq056eqRuIU4Os6zKJ6HZdkBeUhdV6OJcJla87PJsw68zXXk3hWIJ4ysTjvD Hdb4ZcYoW4sAcAfBXrqvnm+Wzx9HVJouNr3VBhOGH8OqfUeNiygl78n6Jv7+Fr7r/pO2MvPgQSq F9EEx/9K+1CYdun7skadMNerJ7GOrXppPxZQhWzQNbZb4NN+6dxGVlvCKE5eQ/GmQF9wgnI28UE bK1OAjMTsOjXs1Y4Y11jhxTsznQY4MbSnl2GoKvTGSvEcjZm8H+xuz92+GsaZh59a2Le1a6bfgU ou5yVudVvuF59piYNMyWXmCAzJRcJI9f1LgAk14MyfD9Pj0Eqq/Sohd1OP5ajqWTDkJ3t6X9Saf yfCOJ5Ui6NYaujqRYNb40pUTnF0U7M7abgeUCgxsf8Kx/fALo6omhjMMq30qNTSarQw== X-Google-Smtp-Source: AGHT+IHpQKvzmqrsiedJfORZYzWOTQuFiX20v6FQir53p0Dn0Gro1xjnak3/xHWTcjL463wE6Vl+eg== X-Received: by 2002:a05:600c:3510:b0:45d:f7df:270b with SMTP id 5b1f17b1804b1-46e710b22c1mr11106185e9.0.1759493912657; Fri, 03 Oct 2025 05:18:32 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4255d8f02a8sm7812529f8f.39.2025.10.03.05.18.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 05:18:32 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Naushir Patuck Subject: [PATCH v2 4/4] ipa: rpi: pisp: Allow an initial decompand curve to be set on the FE Date: Fri, 3 Oct 2025 13:15:55 +0100 Message-ID: <20251003121821.659081-5-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003121821.659081-1-naush@raspberrypi.com> References: <20251003121821.659081-1-naush@raspberrypi.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" In the current code, decompand will only set a curve in the prepare phase, which will only run after 1-2 frames pass through the FE. This is fixed by adding an initialValues() member function to the decompand algorithm, which will be called in the IPA before we start the hardware streaming. Signed-off-by: Naushir Patuck Tested-by: Nick Hollinghurst Reviewed-by: David Plowman --- src/ipa/rpi/controller/decompand_algorithm.h | 2 ++ src/ipa/rpi/controller/rpi/decompand.cpp | 8 ++++++++ src/ipa/rpi/controller/rpi/decompand.h | 1 + src/ipa/rpi/pisp/pisp.cpp | 15 +++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/src/ipa/rpi/controller/decompand_algorithm.h b/src/ipa/rpi/controller/decompand_algorithm.h index f19f8c109323..6d2467490106 100644 --- a/src/ipa/rpi/controller/decompand_algorithm.h +++ b/src/ipa/rpi/controller/decompand_algorithm.h @@ -19,6 +19,8 @@ public: : Algorithm(controller) { } + /* A decompand algorithm must provide the following: */ + virtual void initialValues(libcamera::ipa::Pwl &decompandCurve) = 0; }; } /* namespace RPiController */ diff --git a/src/ipa/rpi/controller/rpi/decompand.cpp b/src/ipa/rpi/controller/rpi/decompand.cpp index 5b4c2e5524af..2d457926c060 100644 --- a/src/ipa/rpi/controller/rpi/decompand.cpp +++ b/src/ipa/rpi/controller/rpi/decompand.cpp @@ -39,6 +39,14 @@ void Decompand::switchMode(CameraMode const &cameraMode, mode_ = cameraMode; } +void Decompand::initialValues(libcamera::ipa::Pwl &decompandCurve) +{ + if (config_.bitdepth == 0 || mode_.bitdepth == config_.bitdepth) { + decompandCurve = config_.decompandCurve; + } else + decompandCurve = {}; +} + void Decompand::prepare(Metadata *imageMetadata) { DecompandStatus decompandStatus; diff --git a/src/ipa/rpi/controller/rpi/decompand.h b/src/ipa/rpi/controller/rpi/decompand.h index 0f2a9b3bbdc4..6db779c359a8 100644 --- a/src/ipa/rpi/controller/rpi/decompand.h +++ b/src/ipa/rpi/controller/rpi/decompand.h @@ -20,6 +20,7 @@ public: int read(const libcamera::YamlObject ¶ms) override; void initialise() override; void switchMode(CameraMode const &cameraMode, Metadata *metadata) override; + void initialValues(libcamera::ipa::Pwl &decompandCurve) override; void prepare(Metadata *imageMetadata) override; private: diff --git a/src/ipa/rpi/pisp/pisp.cpp b/src/ipa/rpi/pisp/pisp.cpp index f5be39aca5ee..01baebcd2bb6 100644 --- a/src/ipa/rpi/pisp/pisp.cpp +++ b/src/ipa/rpi/pisp/pisp.cpp @@ -32,6 +32,7 @@ #include "controller/cac_status.h" #include "controller/ccm_status.h" #include "controller/contrast_status.h" +#include "controller/decompand_algorithm.h" #include "controller/decompand_status.h" #include "controller/denoise_algorithm.h" #include "controller/denoise_status.h" @@ -335,6 +336,20 @@ int32_t IpaPiSP::platformStart([[maybe_unused]] const ControlList &controls, /* Cause the stitch block to be reset correctly. */ lastStitchHdrStatus_ = HdrStatus(); + /* Setup a default decompand curve on startup if needed. */ + RPiController::DecompandAlgorithm *decompand = dynamic_cast( + controller_.getAlgorithm("decompand")); + if (decompand) { + std::scoped_lock l(*fe_); + pisp_fe_global_config feGlobal; + DecompandStatus decompandStatus; + + fe_->GetGlobal(feGlobal); + decompand->initialValues(decompandStatus.decompandCurve); + applyDecompand(&decompandStatus, feGlobal); + fe_->SetGlobal(feGlobal); + } + return 0; }