From patchwork Thu Oct 2 13:26:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24549 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 6438CC328C for ; Thu, 2 Oct 2025 13:35:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B6B1E6B5F3; Thu, 2 Oct 2025 15:35:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="RRoSG21L"; dkim-atps=neutral Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1559D6B5A2 for ; Thu, 2 Oct 2025 15:35:31 +0200 (CEST) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-46e509368caso1392925e9.1 for ; Thu, 02 Oct 2025 06:35:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759412130; x=1760016930; 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=IVoMSQ9NqKSYjvVxbeL+oHW0AnGWWAyEI8GVF0//jK4=; b=RRoSG21LX0whvvVzC1mDANWqmxen6YnFVx2cIL2dkZYV9o/h5/YvAz4Xu9ko9rvKVW rVtjxcd4gkl4TqKx2nIM/MNrXqrXjitwvOEf4cs8QKom142vXF2SApF78JC35Nj/fEYz N2L8VZNXT+11Qk6SC80C+3O5XK9o5DZru6pc9b4wV9RNjyA67dw+5O7IKpBTWvrOorsW PUGCycZGujEWMQSlIUz/gujYokCLy/f4nHXZp4f92FTqB6X1aqkgui/re9rHSxAqbG+8 ryMkdwhSkkioJXGQs53/AniTpXRyFe4Q8QOMUeR/NIdmyJUYEHUEhRLCyLoGGIJHisr4 xCxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759412130; x=1760016930; 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=IVoMSQ9NqKSYjvVxbeL+oHW0AnGWWAyEI8GVF0//jK4=; b=i4J+mHfn+ftxgWk5F0IR8B++pbVJQmQZsQwoHkzDrJ4Ofnsg/gSUrzcGhxvti/2xq8 2po/+yLfTGKJSBbE+48ElFXlBwJveE+1DLwvXV0njWSJGaRW9wBIsjwrKy9yI68K28S4 kyAokL+auQrDusOrMaCgidsKBkbVr3aP5s4Simr+AMBv9CUy+MdhZwJW5pFO9hIIZ633 6QpXquYKgVNxzF64tJ4bJ5FqKnCbp9/FVpSaA/zFzrUnmdtSDDfCeJiXoDqWQUhuMOUP vwVe+myWBjpVNYq4PQuOqSgy0NXAc7SL4HbcvFcRSYRJee1+pnYK+RsY8MMYJ4Xkr1yP QlHA== X-Gm-Message-State: AOJu0YzvSEfFu/LvUKLxqSrWeOgyn3IrgFeAxiZgqpk7e2Ucj/dCNJso 3VzUvKJG+kzzq1TyFUoOtI6wP4JycswRP/O8nMzdISR4ygk7GOMPuI554bObRNQJZ30osXVJgmh g1HiD X-Gm-Gg: ASbGnctQKuTqMDweSpPH8zr6yrSG6FDL9WUjGOxJC4PR49uq6HZovBaA4VVrOetRFVI u2VmbjxrhYY0vY9MvBw/dakpcFMrLd4AXE02m6jXuy0M+mh2LLYTXVHwaYL9zhwAbubF+swiuKm YLxHU+Nf32NReyFRbxHLLmJECiZGTnxHu1toSpyJgT0CYpB7japgkW0sfhkNLF+fAg4vt8Jfb/8 CqSS3/zRtAADS5FJIuZoDKJSOE3m7nyCCErrNERLom0avbxFJXAZ5WNDYTd+U1VYAHF0qvIio4T nhWmEpJElaTXo28C/quUaAjOi8nyghv+WmI5UZ6szTl5FOHaZWvuKcOVk3CjNHLJ/n1DhnixPGb sftbp2yb/rWbPbyEDALJJmmoMa6p5r45JO7+LtKL4R5q8ygqUwPWYZ6v9JcIQMzoe/g== X-Google-Smtp-Source: AGHT+IEirLTYWf1LNe1EuyRVEnD7RJ/VXbyO11sbdUCcv7VOTLLa7bfZDk1dQsoah1YWoWMHQOxd1g== X-Received: by 2002:a05:600c:1d19:b0:46e:3c73:2f9d with SMTP id 5b1f17b1804b1-46e612c9809mr32447265e9.6.1759412130276; Thu, 02 Oct 2025 06:35:30 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-46e6918bdebsm40396015e9.9.2025.10.02.06.35.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 06:35:29 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Sena Asotani , Naushir Patuck Subject: [PATCH v1 1/4] ipa: rpi: pisp: Add decompand support using PiSP hardware block Date: Thu, 2 Oct 2025 14:26:04 +0100 Message-ID: <20251002133523.293413-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002133523.293413-1-naush@raspberrypi.com> References: <20251002133523.293413-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 --- 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 | 40 ++++++++++++++++ 5 files changed, 138 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..911b04bc0da0 --- /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([[maybe_unused]] 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 (Algorithm *)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..5ef35946efa5 --- /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 = NULL); + 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..e75c87df1924 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, uint16_t *lut, std::size_t lutSize = 65) +{ + if (pwl.empty()) + return -EINVAL; + + constexpr int step = 1024; + for (std::size_t i = 0; i < lutSize; ++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,20 @@ 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 = {}; + + fe_->GetGlobal(feGlobal); + + if (!generateDecompandLut(decompandStatus->decompandCurve, decompand.lut, PISP_FE_DECOMPAND_LUT_SIZE)) { + 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 Thu Oct 2 13:26:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24550 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 3B544C328C for ; Thu, 2 Oct 2025 13:35:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 95C246B5AA; Thu, 2 Oct 2025 15:35:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="lbGrknTJ"; dkim-atps=neutral Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A59D06B5F8 for ; Thu, 2 Oct 2025 15:35:31 +0200 (CEST) Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-46e310e64f4so1319185e9.3 for ; Thu, 02 Oct 2025 06:35:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759412131; x=1760016931; 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=2FLUPxtStom9sPnXBOfr3PHqylq/XtMY5MS9+dCgLKk=; b=lbGrknTJ3fhbwOkirRJUn7fnB3MbAxLn1JK8CxzfRjb+txvR4+QfJ7Vnk3vvPSu+qg n+QDqE9YHdL734YRdBN/+b8WWmBGopiOzLCF5bQwIywFGlbDInUzopXI9KkwTjNAOHtK HjToB38CoAMRO9wWwCAfJo+Ef7tyJiS9F9Je257kXNdkWfMiEQ281Ba3nzgpN3Hfruyj vPKV4YWT1UpKHyUhn4R4qIpN7ApuUhTwFtK+hzFXFXwb4yEQD97xGKBCOEao8Vg2K68g g5x4gLGQdqIio8ppf/mpcTG++YtLtEUxwE3CA94/esFUnBYbzenpAc4KtVTRlVT2zyqP /mOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759412131; x=1760016931; 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=2FLUPxtStom9sPnXBOfr3PHqylq/XtMY5MS9+dCgLKk=; b=bjoUfn90ScblH56gMekuSI30uxNoAeCf6x/K3wRYLY0w5jwcT56pHLNu4bl+AlddQY XmgZreWCfK8FTWx9WdyTNeBJvf6EFjw8o6RyVMFfGdAWRkkwuIVgQoIpvhJoFyc0WgvN c7j+kMnLou54JhGaSZ/2h8Ub/94pvEgyxgL+mul1dGD6ZVCG7SuWTOzNdPq/5D0u6iDU tzE1AguJzFy26bPSkef5ChaAWopL+wlSnrW/P8TAxv02rvnTsb2nCIk1vlF8KZ3Jpm0H WtKokZgcAnwcClSrv+vaN3yhasub2TdNYjyiHd8JFQkyc7POlaWC/TvN1qIGtUjXgwa7 EIzQ== X-Gm-Message-State: AOJu0YzMNJs8IKxAKXMLD4QlIoBRzfUxbad7dk5qF4orwr0Hh7jPjqbT 6990wtpZij2LmJOCEOtuUWJCEAY185eULv1A43MlFOE2aNHk/iWK4gXShTcdRJaZOGhLvNrDzUU kuXUD X-Gm-Gg: ASbGnctgEIteECbsL/hjnAaYVIT/d/vHdyxBcfvX1Gv0VgQstsbALW48FWs1f1hyuH5 o+Av1C9DOlJ8HPX2UiV0CdWLrQm90GrP5nBt52gpx8KmQ5z8QDEvMAPzdwOhzgdGkY/wrUijHD1 73eEtwtoZWq9jpoU+gxgXstdxVW/2DzfBmslWC0TBdx5nluO7flm9T8A8oI8l2Y+S2/VE8o7teB 7USR3lop6sj6m1H8HVDCYHyuhRfOeRM6vmZICAfHudhpiAuSbq8t2yGNIa0wWGkn5s8sXSecfi3 OG9zjb0qDUGlVrC61k9bwXNt4ktQsX9D3+sUoNOxWqaBZG1DQQkHo134nWhegHEfZwUl9uZw8SQ DGKE/KJg22VBiTNgrapPs01icXITm6VUDa8xnMPiPpfzxACkOTOIZRLcuDljTcNpU6ggDfjdr3M uf X-Google-Smtp-Source: AGHT+IHtHbD2B8EKUQGTyXSdgExtDHZWw/bMZlNXKu7ag58MoRm94aZ5+XQYFWndEzacHwYJ6JWRPA== X-Received: by 2002:a05:600c:4511:b0:46e:3d3d:ea92 with SMTP id 5b1f17b1804b1-46e61294dc2mr32208605e9.5.1759412130938; Thu, 02 Oct 2025 06:35:30 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-46e6918bdebsm40396015e9.9.2025.10.02.06.35.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 06:35:30 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Naushir Patuck Subject: [PATCH v1 2/4] ipa: rpi: Add FE globals as a parameter to applyDecompand() Date: Thu, 2 Oct 2025 14:26:05 +0100 Message-ID: <20251002133523.293413-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002133523.293413-1-naush@raspberrypi.com> References: <20251002133523.293413-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 --- src/ipa/rpi/pisp/pisp.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ipa/rpi/pisp/pisp.cpp b/src/ipa/rpi/pisp/pisp.cpp index e75c87df1924..03c6c47c1bd9 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,18 +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 = {}; - fe_->GetGlobal(feGlobal); - if (!generateDecompandLut(decompandStatus->decompandCurve, decompand.lut, PISP_FE_DECOMPAND_LUT_SIZE)) { 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 Thu Oct 2 13:26:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24551 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 7EB87C3310 for ; Thu, 2 Oct 2025 13:35:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8ACC96B5F9; Thu, 2 Oct 2025 15:35:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="XZBC5onu"; 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 3148C6B5F8 for ; Thu, 2 Oct 2025 15:35:32 +0200 (CEST) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-46e310e64f4so1319195e9.3 for ; Thu, 02 Oct 2025 06:35:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759412131; x=1760016931; 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=i8zkLLTT4paFP9gI8ujDezDawHht0wHhmVNglan8uqo=; b=XZBC5onuj2f6DaoShFJxZ9hkY1XtwxEec8mrNi8zSjU1M5mZchTsDGtKkTLZ3TpKi4 mDzQ5/7JuaMZkPK8zhSkfUB/Kjin2tHbAB13TPeCuI0EEhgKfkZsqA6u22tV5M/YNWQT C2RSyZsao0q+yFEVGwh7ptUWR+PF6QhUmrVFtit19u5d+pdA3AyEZQXhzTayX/fGzCwf 313jueEQswCvC93NPgfy5mU7qGg8QkTYmC+ED4RUpZaEZT/Qz3/ejk+/9MNUc7z55rx4 KndCbXESWakSP4ePHSaSSHqNFuYLbhujlv39lM4SADTfRodzx5UFG2Sw3NzpkJeLGugU 1eLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759412131; x=1760016931; 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=i8zkLLTT4paFP9gI8ujDezDawHht0wHhmVNglan8uqo=; b=fc1qgH07CDVD9XsrixXW2IH5P1i7brqHCq0tKX2KMEBT+iJHn4ssZbruURIJHf/cI3 xNqdK+i4ams2QVPhB+wlY5RMDhTcyJElK1siZXNjMWhrO51HMSnqX9lsV9+0y2btbxMO 7XtGqHV+WyZSUGsp5YRKakBAyRBlOp49Yrv1W4g8BL+bEZb968Ey5mq/tKwNPhZb5XGI Yy7iTZYjl6JitGAnkiRKN7rJACTdj5u1SoQnrT3GrIGAE836R68NP+C3FJn5plvM3Krp K9cyU5CGmNwgYVKvyoY6+S4ygomgMmuOaRup5455G8Lrua5Xt5gokvGE1G9f6/VxImoQ leXA== X-Gm-Message-State: AOJu0YzxwHwOyr8/3aR7XvV1LViOftP8CfYTuJdW6GOx7133yCrlrEOK VXkea+SqxCqW3I3+AG/d+JgpTGla9ZO1ftkaJ0AiEwvJAxmeQ6rLXM/EvNZWks5w4Yryy+GsDXS r+ool X-Gm-Gg: ASbGncuQPFpJV6YNDkSz7fsDs9Kbhhkf175Teg7hG8npkQ6M2YwJdZuwQGRHhMCrpyn r4l52tf9Amg3hw/Dh1p1hOLB0ZMU+gC1Urbpvk4mSwo2Io2VeG+Yu6NtIQksnGRRc7ZbQTIFxm5 uUgeoPL7X/VnrDtepytqZ4BjX+WdhQ92z4S1XvdmCTucpISQk9BJe5Xnz/KLwCxu+OLF8eZBkjF PIg9iYAaK5JXln1GIY6qJcczB8YqRb1QrEhUlbJkMBXZC7u1u8HKquDhjsijLiTEboqsLRgGLoj KQfvUW5DiLmy3KGIlchm2+AdztoD125EjR8A3/oIlubpmB55kZFlpnFpD+O0z3d9+bOlw53btQ5 snojvqRgwy1JB2OanTxz/qgFXODfU+OnalSsXBz58iXybs90JTEwcX3cCAl/wcd6C/O6trI8CRo xv X-Google-Smtp-Source: AGHT+IEfkaTkpx3vw745W8zu4nzidFM4Ihg33zZZ4gLntUHsF0WEiQCdrQ/TAtGskmYgJqFN9s9jjw== X-Received: by 2002:a05:600c:4ec6:b0:46e:354d:d1b1 with SMTP id 5b1f17b1804b1-46e612862c8mr30189545e9.3.1759412131508; Thu, 02 Oct 2025 06:35:31 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-46e6918bdebsm40396015e9.9.2025.10.02.06.35.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 06:35:31 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Naushir Patuck Subject: [PATCH v1 3/4] ipa: rpi: pisp: Add a DecompandAlgorithm class Date: Thu, 2 Oct 2025 14:26:06 +0100 Message-ID: <20251002133523.293413-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002133523.293413-1-naush@raspberrypi.com> References: <20251002133523.293413-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 --- 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 911b04bc0da0..b450436806e1 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 5ef35946efa5..321a561ab141 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 = NULL); From patchwork Thu Oct 2 13:26:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 24552 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 42017C328C for ; Thu, 2 Oct 2025 13:35:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 985506B615; Thu, 2 Oct 2025 15:35:39 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="ESd4XYu/"; dkim-atps=neutral Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1FF326B5F9 for ; Thu, 2 Oct 2025 15:35:33 +0200 (CEST) Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-45a1b0ce15fso690175e9.3 for ; Thu, 02 Oct 2025 06:35:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1759412132; x=1760016932; 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=Xh7vT5smofoDWv6eoWK8ZtPETUG17hmhKYV54w92rXI=; b=ESd4XYu/ae9+XlIMsUGyvWLWi3HEsQZkywbiYMFpp2ID/RTMPKjof3WLJ5MbIgU78N fFhP0oq4emY/t4ao0JUyjFw+FjFax42OLmIJwIzw/gzcwmAVYxDAGqiiBlDzPELlgi2K x0jG46h04bdeN3KsGBXjFr71Qjh9BBq+iGZB28aE4DWGbg7x7nfgJXOYslFACuHCzgOo oNPFZUswgYPO4UXDDHcdUkjSOAwNgaPJXssLqIsoLXH1/Es9bUTzxPEsZ2Ff2bc6Yblo mQMzzW5ptZkotHJCEMfJf5VaOENr/zIUESGevFknZ7Q8bvMQ6nj1tH04vCkRKzwuXAWO /cnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759412132; x=1760016932; 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=Xh7vT5smofoDWv6eoWK8ZtPETUG17hmhKYV54w92rXI=; b=FTCgGHwEX7dKM5TkkroT+U3pRVvmPn+PKFacHdzFIk4WgH3fnl845QXgkTil0ipNrp BWrKYS8VksiHKli6Axd3X+X7MxQ0h4uE/UOH6GjiEBPm7hY45auDAsVe8X1OBE0kE7qV OdVFXjb/fL4pqBWEDJfqt+bl/cYYY5rjERMCBirwATufszXp0A9AGpm4hu4fnWnfMPqO lc7I3roJ+WKmhaG8xy1zoEGHbyxH9JOT7ykuFHSw7JLeh4dTMAMaL4kSESNQhC16ztui ps6E75AVx6sYMJgFgarvwKNBvOJ7ReXgP40t/HLzT8TSI11/5hiNlLAR4egiIk9ArnN1 /KxA== X-Gm-Message-State: AOJu0YwQPiZgQw4aM3QEuS9MY0Ead6zM2eeF6FxiYZk3xzgkcoG6kwRK 9+xn7atu6QnUe4MCe5dtKRbE8QmegKsrYUpOLkRVKxKvRXlH44vgmPzuJBFcda0XynSeU6GRJml X0JDU X-Gm-Gg: ASbGncupirG1jAA+Mhh+bgcr8d79kvpEFJiWzarJcQjZ4BXbJTa4b2//OXq8ZvINIWt Th5WqcWmMA+hcD0xLz8AbLY1zEXZgwlyy2PL7YTWXze5ZP6JYMZZKVLFtGJEZTu7kZw8Vefkp8R SYKOi5By0udTG6ONky7KCYuNNav8cXybGsWUQGn7IKpd9pYHEIqU0fYElCg37KyIJ9dfie0rWWl /fP+y4AXoEbeAyEgLjQUFA9mAJiMA+NF826/nkBCa2sngpenFRmvY52hMp92/bienw0fiNEmR5P BWtAIX2ZwyYJpKKhyDUotBvciM60lcg8T7Xca5Q6doeHi0+H9gNaFIsScuHnM3c2MMzksSz8SiJ OjgQXOQBiqYFA7zYbdAc9VIz1k9Fj6G0DlQjpowwalfhpcfvuQYmz2gMbVFh6XfKX4Q== X-Google-Smtp-Source: AGHT+IESYDyvTST5yH8XdBP+8u4JtabcdFNz3aKpmfK9U+lSFwxjKnlC1CuX1lTzBc4c8WecqC1Bzw== X-Received: by 2002:a05:600c:4fd4:b0:468:7a5a:14cc with SMTP id 5b1f17b1804b1-46e61263eb4mr29697955e9.3.1759412132294; Thu, 02 Oct 2025 06:35:32 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-46e6918bdebsm40396015e9.9.2025.10.02.06.35.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 06:35:31 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Nick Hollinghurst , Naushir Patuck Subject: [PATCH v1 4/4] ipa: rpi: pisp: Allow an initial decompand curve to be set on the FE Date: Thu, 2 Oct 2025 14:26:07 +0100 Message-ID: <20251002133523.293413-5-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002133523.293413-1-naush@raspberrypi.com> References: <20251002133523.293413-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 --- 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 b450436806e1..2c3bf7ee4d11 100644 --- a/src/ipa/rpi/controller/rpi/decompand.cpp +++ b/src/ipa/rpi/controller/rpi/decompand.cpp @@ -39,6 +39,14 @@ void Decompand::switchMode([[maybe_unused]] 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 321a561ab141..2c44b09e4192 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 03c6c47c1bd9..134fc5aab12d 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; }