{"id":26258,"url":"https://patchwork.libcamera.org/api/patches/26258/?format=json","web_url":"https://patchwork.libcamera.org/patch/26258/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260304232533.56D641EA006B@mailuser.phl.internal>","date":"2026-03-04T23:13:46","name":"[v2,2/4] libcamera: software_isp: Normalize statistics sums to 8-bit","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"f15aa23cf03fd5bcd192016a8f94eeb3e6edf6df","submitter":{"id":261,"url":"https://patchwork.libcamera.org/api/people/261/?format=json","name":"Javier Tia","email":"floss@jetm.me"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/26258/mbox/","series":[{"id":5821,"url":"https://patchwork.libcamera.org/api/series/5821/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5821","date":"2026-03-04T23:13:46","name":null,"version":2,"mbox":"https://patchwork.libcamera.org/series/5821/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/26258/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/26258/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 63803BE086\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  4 Mar 2026 23:25:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 297A8625E1;\n\tThu,  5 Mar 2026 00:25:36 +0100 (CET)","from fout-b7-smtp.messagingengine.com\n\t(fout-b7-smtp.messagingengine.com [202.12.124.150])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7396B623B5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  5 Mar 2026 00:25:34 +0100 (CET)","from phl-compute-02.internal (phl-compute-02.internal\n\t[10.202.2.42])\n\tby mailfout.stl.internal (Postfix) with ESMTP id 9E3361D0020E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  4 Mar 2026 18:25:33 -0500 (EST)","from phl-imap-07 ([10.202.2.97])\n\tby phl-compute-02.internal (MEProxy); Wed, 04 Mar 2026 18:25:33 -0500","by mailuser.phl.internal (Postfix, from userid 501)\n\tid 56D641EA006B; Wed,  4 Mar 2026 18:25:33 -0500 (EST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=jetm.me header.i=@jetm.me header.b=\"VoIQOM1T\";\n\tdkim=pass (2048-bit key;\n\tunprotected) header.d=messagingengine.com\n\theader.i=@messagingengine.com header.b=\"CLqTphPS\"; \n\tdkim-atps=neutral","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=jetm.me; h=cc\n\t:content-transfer-encoding:content-type:content-type:date:date\n\t:from:from:in-reply-to:in-reply-to:message-id:mime-version\n\t:references:reply-to:subject:subject:to:to; s=fm3; t=1772666733;\n\tx=1772753133; bh=vr23QiuLsfOcE/tj37mfrxI3IjI3XSG1oeye/ccoASc=; b=\n\tVoIQOM1Tfpm768edYjGdQ1Qd0fZ7jwrozodlp2JjKhsvwi+Ap5WmGuArNo3fI2ET\n\tHZzjRsN22H5XHj4ejTvslGxCvcXSRn+OY433kEMUiDOsuolYLV0by9rwGxhh5yyZ\n\tov5S/F8F9FcHH7z6Scl4VFX8dLqeJ4JppzXBGzcJIT6DUj8j2zWjSnLWm2qR8H4b\n\tjDaa5571XbMtvBbZg4Q5xEb469er5GbJ1SGKEXx2KphuuHDTOMo3i+C+KCyb/aAE\n\tPkHJQ8yfgy65h5UDnA87dGjeSOpFMgkV03lDYSMC3iyqg3VVQKcaRkxvt728jaTw\n\tIFpnRIsKNFAkWBmfGDwYlA==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=\n\tmessagingengine.com; h=cc:content-transfer-encoding:content-type\n\t:content-type:date:date:feedback-id:feedback-id:from:from\n\t:in-reply-to:in-reply-to:message-id:mime-version:references\n\t:reply-to:subject:subject:to:to:x-me-proxy:x-me-sender\n\t:x-me-sender:x-sasl-enc; s=fm1; t=1772666733; x=1772753133; bh=v\n\tr23QiuLsfOcE/tj37mfrxI3IjI3XSG1oeye/ccoASc=; b=CLqTphPSJL5Z2bral\n\tRMWCpiN0iYx4c2OzLJLWhSOL/51b0xDDWFmE8Bjx/XdJijrq3YLlijujaqWHzwE4\n\toYwF436IlJjUMGLULJbnDD8SBkCDJA7jr19Fmlun7VffSbLnTBn98eAHvITX1kkN\n\tIimfUYnjD3gpqcZDUbFNigTOD98jOZzgTWlYY01ozCCyicI4IN+iLml4AL4ZPhw5\n\thfH5c7G9MeoZeqUWoyVoOcXePklR85PaBd58Bvwe41J1kTWULTiwi+4hzUrEJ1Nc\n\tg1vEC8xQN5TLtiywBq3ZGdIAuxMWa1sKnfQ+3WtZBbMAGrWsSt/AUFHOLZ/LFcWP\n\trWZ1Q=="],"X-ME-Sender":"<xms:bb-oaSUNwGI8Ny9UFgJLAMrIFx5Ld56lAhV8Di-8dnFuGLuLZ5rhew>\n\t<xme:bb-oaZaqP6c9kAN5yeHGT0Vxt_MC-4ySoSsvLEF8S5X82a0jvAoq05Pex6ch_-J2P\n\tOm2ElJeL2ohq7gV8LTzR9BQh4_gcoP7iLkyrN550bcB3ZIlZz6v-A>","X-ME-Proxy-Cause":"gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddvieegkeduucetufdoteggodetrf\n\tdotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu\n\trghilhhouhhtmecufedttdenucgopfhokfffucdluddtmdenucfjughrpefotggggffhvf\n\tffufgjfhesthektddtredtjeenucfhrhhomheplfgrvhhivghrucfvihgruceofhhlohhs\n\tshesjhgvthhmrdhmvgeqnecuggftrfgrthhtvghrnhepteetvdeklefgledtjefhhfdtle\n\tdvhfffgfeuieelgeeigfekgffhleeghfefhfejnecuvehluhhsthgvrhfuihiivgepvden\n\tucfrrghrrghmpehmrghilhhfrhhomhepfhhlohhsshesjhgvthhmrdhmvgdpnhgspghrtg\n\thpthhtohepuddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheplhhisggtrghmvghr\n\trgdquggvvhgvlheslhhishhtshdrlhhisggtrghmvghrrgdrohhrgh","X-ME-Proxy":"<xmx:bb-oaaGvkCRLfLp_5WUkZ4xT9nolT82XTIlYs6QY4VMc0jyYOS52aw>\n\t<xmx:bb-oabTuRn4zTOHa65qwDn-pcmIjW8qNHWH59M6wkqwlmA3niBVl_w>\n\t<xmx:bb-oaRBQvkUoar2NBumw3aShZtwFcKMfmBT9L_NLkhnpcOpTX89WzQ>\n\t<xmx:bb-oab1jYR5ZgTHurpF-OpJJbAwUtP2B-0WnofMVunQx27QK6VPNqg>\n\t<xmx:bb-oaR6HNKlhYzHXM2o4tZ73gzZno1k1M_At806FJ_NG5RYDBvCt05Cv>","Feedback-ID":"i9dde48b3:Fastmail","X-Mailer":"MessagingEngine.com Webmail Interface","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","From":"Javier Tia <floss@jetm.me>","To":"libcamera-devel@lists.libcamera.org","Date":"Wed, 04 Mar 2026 17:13:46 -0600","Subject":"[PATCH v2 2/4] libcamera: software_isp: Normalize statistics sums to\n\t8-bit","In-Reply-To":"20260225221859.600869-1-floss@jetm.me","References":"20260225221859.600869-1-floss@jetm.me","Message-Id":"<20260304232533.56D641EA006B@mailuser.phl.internal>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"The SWSTATS_ACCUMULATE_LINE_STATS() macro divides the luminance value\nfor the histogram to normalize it to 8-bit range, but does not apply\nthe same normalization to the RGB sums. For 10-bit and 12-bit unpacked\nBayer formats this means the sums are accumulated at native bit depth\n(0-1023 or 0-4095 per pixel) while the AWB algorithm subtracts an\n8-bit black level from them, under-correcting by 4x or 16x\nrespectively.\n\nThis mismatch between the AWB's gain calculation (using incorrectly\nBLC-subtracted sums) and the debayer's correct normalized BLC\nsubtraction produces a visible color cast. For example, with the\nOV2740 sensor (10-bit, BLC=16), the under-subtraction skews R/G gain\nby ~9%.\n\nFix this by right-shifting the RGB sums in finishFrame() to normalize\nthem to 8-bit scale, matching the histogram and the 8-bit black level\nused by AWB. A per-format sumShift_ value is set in configure():\n0 for 8-bit and CSI-2 packed formats (already 8-bit), 2 for 10-bit,\nand 4 for 12-bit unpacked formats.\n\nSigned-off-by: Javier Tia <floss@jetm.me>\n---\n include/libcamera/internal/software_isp/swstats_cpu.h | 1 +\n src/libcamera/software_isp/swstats_cpu.cpp            | 9 +++++++++\n 2 files changed, 10 insertions(+)","diff":"diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\nindex 64b3e23f..37bfde53 100644\n--- a/include/libcamera/internal/software_isp/swstats_cpu.h\n+++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n@@ -115,6 +115,7 @@ private:\n \n \tunsigned int xShift_;\n \tunsigned int stride_;\n+\tunsigned int sumShift_;\n \n \tSharedMemObject<SwIspStats> sharedStats_;\n \tSwIspStats stats_;\ndiff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\nindex 5c3011a7..bf5e1960 100644\n--- a/src/libcamera/software_isp/swstats_cpu.cpp\n+++ b/src/libcamera/software_isp/swstats_cpu.cpp\n@@ -346,6 +346,11 @@ void SwStatsCpu::startFrame(uint32_t frame)\n void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId)\n {\n \tstats_.valid = frame % kStatPerNumFrames == 0;\n+\tif (stats_.valid && sumShift_) {\n+\t\tstats_.sum_.r() >>= sumShift_;\n+\t\tstats_.sum_.g() >>= sumShift_;\n+\t\tstats_.sum_.b() >>= sumShift_;\n+\t}\n \t*sharedStats_ = stats_;\n \tstatsReady.emit(frame, bufferId);\n }\n@@ -405,12 +410,15 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n \t\tswitch (bayerFormat.bitDepth) {\n \t\tcase 8:\n \t\t\tstats0_ = &SwStatsCpu::statsBGGR8Line0;\n+\t\t\tsumShift_ = 0;\n \t\t\treturn 0;\n \t\tcase 10:\n \t\t\tstats0_ = &SwStatsCpu::statsBGGR10Line0;\n+\t\t\tsumShift_ = 2;\n \t\t\treturn 0;\n \t\tcase 12:\n \t\t\tstats0_ = &SwStatsCpu::statsBGGR12Line0;\n+\t\t\tsumShift_ = 4;\n \t\t\treturn 0;\n \t\t}\n \t}\n@@ -422,6 +430,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n \t\t/* Skip every 3th and 4th line, sample every other 2x2 block */\n \t\tySkipMask_ = 0x02;\n \t\txShift_ = 0;\n+\t\tsumShift_ = 0;\n \t\tprocessFrame_ = &SwStatsCpu::processBayerFrame2;\n \n \t\tswitch (bayerFormat.order) {\n","prefixes":["v2","2/4"]}