From patchwork Wed May 6 21:46:28 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Javier Tia X-Patchwork-Id: 26649 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 4B35FC32F7 for ; Wed, 6 May 2026 22:19:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EEA1063021; Thu, 7 May 2026 00:19:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=jetm.me header.i=@jetm.me header.b="sCnzFFRr"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="DswLGRyn"; dkim-atps=neutral Received: from fhigh-a6-smtp.messagingengine.com (fhigh-a6-smtp.messagingengine.com [103.168.172.157]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C88C66301A for ; Thu, 7 May 2026 00:19:44 +0200 (CEST) Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailfhigh.phl.internal (Postfix) with ESMTP id 239EB1400104; Wed, 6 May 2026 18:19:44 -0400 (EDT) Received: from phl-imap-07 ([10.202.2.97]) by phl-compute-02.internal (MEProxy); Wed, 06 May 2026 18:19:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jetm.me; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm2; t=1778105984; x=1778192384; bh=5MB+QUJnQv7BuMZdc1sbTeJZxf3mGgcxn80Hy32zQLE=; b= sCnzFFRriEz+CHuS+K/Mh9dlP2X6xTDsORoVa4iu1oau7agLZ9wzP0OARV9lri+o JEWK0LP5payZCNUQTZlHoNpeSlK7XZTjb2yTD1Kx+X2AGrrnREKx0VzhWXQr0LJ6 38JDzpGT2sSMkKDThINdxATKPOByUhDmcZUc5vGsxnDRgdKa23KbMRBUTGGl94mA k89z9pTG0pRl+HL/wbIBy6b+fxNDClMeLWWeif7Ua1trsFVsE/S5ZVXMPLmSWxUq 2/cqCms2dWFAJHTfzSjSrpK7UC4APAhr9iyvx7t0V0weI4Cf1EMZ4DOijfzlgkSE e/B8ME0TKH18Hxk+pZOZ+Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1778105984; x= 1778192384; bh=5MB+QUJnQv7BuMZdc1sbTeJZxf3mGgcxn80Hy32zQLE=; b=D swLGRynmyG8uiiiH2WGrbXgXjUhUs6Ho4TgbmCOVZH0TLXqQ3omqpzFgNDTKxXlb JINmiLDzzfbQhOTQun2KrgV+kNbfWR0+nGMIf3Zo0Qz2iuaXY0w0etPTqBNGdhB3 +hkr+DlaYxWhcDVoHIdXGb1e0jHl5mFz8kNjxrERzCFSJ6RxvminYe8yIeGAjG6G fyNSJ3bOhwyM0JwFgBqTKpCUiJcmzBIfesvDLkBsESvnEHyA7KFAKnKEkWXGCJd6 sgl1x+xgIvpmdDGUAVy2nj6pI1hFB0qIVIMq4Fgm7ZEaydK9FDcI3NCXFDaX6FhU pD9dx/89A7EWC2MW0gV0w== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefhedrtddtgddutdehjeejucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucgopfhokfffucdluddtmdenucfjughrpefotggggffhvf ffufevjghfsehtkedttdertdejnecuhfhrohhmpeflrghvihgvrhcuvfhirgcuoehflhho shhssehjvghtmhdrmhgvqeenucggtffrrghtthgvrhhnpedtudejffejkeekteelueefvd ejvdeuhfefteehkeevtddvleduteekleetvdelhfenucevlhhushhtvghrufhiiigvpedt necurfgrrhgrmhepmhgrihhlfhhrohhmpehflhhoshhssehjvghtmhdrmhgvpdhnsggprh gtphhtthhopeegpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopegsrghrnhgrsggr shdrphhotgiivgesihguvggrshhonhgsohgrrhgurdgtohhmpdhrtghpthhtohepkhhivg hrrghnrdgsihhnghhhrghmsehiuggvrghsohhnsghorghrugdrtghomhdprhgtphhtthho pehlihgstggrmhgvrhgrqdguvghvvghlsehlihhsthhsrdhlihgstggrmhgvrhgrrdhorh hgpdhrtghpthhtohepmhiirghmrgiirghlsehrvgguhhgrthdrtghomh X-ME-Proxy: Feedback-ID: i9dde48b3:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 066FD1EA006B; Wed, 6 May 2026 18:19:44 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface MIME-Version: 1.0 From: Javier Tia To: libcamera-devel@lists.libcamera.org Date: Wed, 06 May 2026 15:46:28 -0600 Subject: [PATCH v5 2/3] libcamera: software_isp: Normalize statistics sums to 8-bit Cc: mzamazal@redhat.com, barnabas.pocze@ideasonboard.com, kieran.bingham@ideasonboard.com In-Reply-To: <177810597783.688418.1631246733707368646@jetm.me> References: <177810597783.688418.1631246733707368646@jetm.me> Message-Id: <20260506221944.066FD1EA006B@mailuser.phl.internal> 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 SWSTATS_ACCUMULATE_LINE_STATS() macro divides the luminance value for the histogram to normalize it to 8-bit range, but does not apply the same normalization to the RGB sums. For 10-bit and 12-bit unpacked Bayer formats this means the sums are accumulated at native bit depth (0-1023 or 0-4095 per pixel) while the AWB algorithm subtracts an 8-bit black level from them, under-correcting by 4x or 16x respectively. This mismatch between the AWB's gain calculation (using incorrectly BLC-subtracted sums) and the debayer's correct normalized BLC subtraction produces a visible color cast. For example, with the OV2740 sensor (10-bit, BLC=16), the under-subtraction skews R/G gain by ~9%. Fix this by right-shifting the RGB sums in finishFrame() to normalize them to 8-bit scale, matching the histogram and the 8-bit black level used by AWB. A per-format sumShift_ value is set in configure(): 0 for 8-bit and CSI-2 packed formats (already 8-bit), 2 for 10-bit, and 4 for 12-bit unpacked formats. Signed-off-by: Javier Tia Reviewed-by: Milan Zamazal Tested-by: Milan Zamazal Reviewed-by: Barnabás Pőcze Tested-by: Barnabás Pőcze --- include/libcamera/internal/software_isp/swstats_cpu.h | 1 + src/libcamera/software_isp/swstats_cpu.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h index 802370bd..2dac6945 100644 --- a/include/libcamera/internal/software_isp/swstats_cpu.h +++ b/include/libcamera/internal/software_isp/swstats_cpu.h @@ -116,6 +116,7 @@ private: unsigned int xShift_; unsigned int stride_; + unsigned int sumShift_; std::vector stats_; SharedMemObject sharedStats_; diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp index 5366e019..b40d3334 100644 --- a/src/libcamera/software_isp/swstats_cpu.cpp +++ b/src/libcamera/software_isp/swstats_cpu.cpp @@ -362,6 +362,11 @@ void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId) for (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++) sharedStats_->yHistogram[j] += s.yHistogram[j]; } + if (sumShift_) { + sharedStats_->sum_.r() >>= sumShift_; + sharedStats_->sum_.g() >>= sumShift_; + sharedStats_->sum_.b() >>= sumShift_; + } } sharedStats_->valid = valid; @@ -425,12 +430,15 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat switch (bayerFormat.bitDepth) { case 8: stats0_ = &SwStatsCpu::statsBGGR8Line0; + sumShift_ = 0; return 0; case 10: stats0_ = &SwStatsCpu::statsBGGR10Line0; + sumShift_ = 2; return 0; case 12: stats0_ = &SwStatsCpu::statsBGGR12Line0; + sumShift_ = 4; return 0; } } @@ -442,6 +450,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat /* Skip every 3th and 4th line, sample every other 2x2 block */ ySkipMask_ = 0x02; xShift_ = 0; + sumShift_ = 0; processFrame_ = &SwStatsCpu::processBayerFrame2; switch (bayerFormat.order) {