[{"id":38774,"web_url":"https://patchwork.libcamera.org/comment/38774/","msgid":"<5db355fe-2ed5-490a-9b3b-e92df7c215c9@oss.qualcomm.com>","date":"2026-05-07T13:16:13","subject":"Re: [PATCH v5 2/3] libcamera: software_isp: Normalize statistics\n\tsums to 8-bit","submitter":{"id":242,"url":"https://patchwork.libcamera.org/api/people/242/","name":"Hans de Goede","email":"johannes.goede@oss.qualcomm.com"},"content":"Hi,\n\nOn 6-May-26 23:46, Javier Tia wrote:\n> The SWSTATS_ACCUMULATE_LINE_STATS() macro divides the luminance value\n> for the histogram to normalize it to 8-bit range, but does not apply\n> the same normalization to the RGB sums. For 10-bit and 12-bit unpacked\n> Bayer 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\n> 8-bit black level from them, under-correcting by 4x or 16x\n> respectively.\n> \n> This mismatch between the AWB's gain calculation (using incorrectly\n> BLC-subtracted sums) and the debayer's correct normalized BLC\n> subtraction produces a visible color cast. For example, with the\n> OV2740 sensor (10-bit, BLC=16), the under-subtraction skews R/G gain\n> by ~9%.\n> \n> Fix this by right-shifting the RGB sums in finishFrame() to normalize\n> them to 8-bit scale, matching the histogram and the 8-bit black level\n> used by AWB. A per-format sumShift_ value is set in configure():\n> 0 for 8-bit and CSI-2 packed formats (already 8-bit), 2 for 10-bit,\n> and 4 for 12-bit unpacked formats.\n> \n> Signed-off-by: Javier Tia <floss@jetm.me>\n> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>\n> Tested-by: Milan Zamazal <mzamazal@redhat.com>\n> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n\nThanks, patch looks good to me:\n\nReviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n\nRegards,\n\nHans\n\n\n\n\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(+)\n> \n> diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\n> index 802370bd..2dac6945 100644\n> --- a/include/libcamera/internal/software_isp/swstats_cpu.h\n> +++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n> @@ -116,6 +116,7 @@ private:\n>  \n>  \tunsigned int xShift_;\n>  \tunsigned int stride_;\n> +\tunsigned int sumShift_;\n>  \n>  \tstd::vector<SwIspStats> stats_;\n>  \tSharedMemObject<SwIspStats> sharedStats_;\n> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n> index 5366e019..b40d3334 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n> @@ -362,6 +362,11 @@ void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId)\n>  \t\t\tfor (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++)\n>  \t\t\t\tsharedStats_->yHistogram[j] += s.yHistogram[j];\n>  \t\t}\n> +\t\tif (sumShift_) {\n> +\t\t\tsharedStats_->sum_.r() >>= sumShift_;\n> +\t\t\tsharedStats_->sum_.g() >>= sumShift_;\n> +\t\t\tsharedStats_->sum_.b() >>= sumShift_;\n> +\t\t}\n>  \t}\n>  \n>  \tsharedStats_->valid = valid;\n> @@ -425,12 +430,15 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\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> @@ -442,6 +450,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\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) {","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 5DDBEBDCB5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  7 May 2026 13:16:22 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0F4AD6301E;\n\tThu,  7 May 2026 15:16:22 +0200 (CEST)","from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com\n\t[205.220.180.131])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id AE56A62FEC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  7 May 2026 15:16:20 +0200 (CEST)","from pps.filterd (m0279868.ppops.net [127.0.0.1])\n\tby mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n\t647AISP2879630 for <libcamera-devel@lists.libcamera.org>;\n\tThu, 7 May 2026 13:16:19 GMT","from mail-oi1-f199.google.com (mail-oi1-f199.google.com\n\t[209.85.167.199])\n\tby mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e0kdq1x3k-1\n\t(version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 07 May 2026 13:16:19 +0000 (GMT)","by mail-oi1-f199.google.com with SMTP id\n\t5614622812f47-47bcb08890aso916084b6e.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 07 May 2026 06:16:19 -0700 (PDT)","from ?IPV6:2001:1c00:c32:7800:5bfa:a036:83f0:f9ec?\n\t(2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl.\n\t[2001:1c00:c32:7800:5bfa:a036:83f0:f9ec])\n\tby smtp.gmail.com with ESMTPSA id\n\t4fb4d7f45d1cf-67cd91bc5b0sm2299979a12.23.2026.05.07.06.16.14\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tThu, 07 May 2026 06:16:15 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=qualcomm.com header.i=@qualcomm.com\n\theader.b=\"AfQvS6aE\"; dkim=pass (2048-bit key;\n\tunprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n\theader.b=\"hwMMO3Zm\"; dkim-atps=neutral","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n\tcc:content-transfer-encoding:content-type:date:from:in-reply-to\n\t:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=\n\tA2g0w0eDvq0Zm6ldbZ2s9DZT/oi+ZIyu8K8xjTwlchI=; b=AfQvS6aE9jH6qbEy\n\tzZuxfwAXDECAJ8fcF9fCYEq6Zx8YDvmTNPxWealeVkFU61rTcH7/EFceQ5Jz+iJA\n\tfgkhoOu9xBxpEtliNTVxDumFjYIzuY6dZiMofrcviu/UkehNksiMeyFajmKOIm6V\n\tt1lztw3evmh2TFBa/32vd73693LZxlQlmk3mE9WVT8OMM7UIDV7/9uNKhY/78S3i\n\tx1c9HfI4Qw7Tl48VD08Qc27ObaiNd5wiDjk06EwoLt61j4oynaCSopZhe3ZHghVI\n\tQ1ljroLaqQKUEOitlnToJJcb32r1UsrLnrDjRB6j/HSHu6yE461BQgeffn6fqmfc\n\t9gpLFw==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=oss.qualcomm.com; s=google; t=1778159779; x=1778764579;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:in-reply-to:content-language:references\n\t:cc:to:subject:from:user-agent:mime-version:date:message-id:from:to\n\t:cc:subject:date:message-id:reply-to;\n\tbh=A2g0w0eDvq0Zm6ldbZ2s9DZT/oi+ZIyu8K8xjTwlchI=;\n\tb=hwMMO3Zm6s/bPSLoXEVIjPCSdslvBfo4vILpCpJ3w92kD3HgNav2JBZW5ZHOMBvcY6\n\t/D4R37/FtsMtdlc7eWV1amdF4s2TcwpKsLR9JQSbQ5KjzVZVPcFR2+GALRHTkZs8MNSp\n\tRuwCk0uo1hWOOC40d4uOKqSMTRwvhAX4h1xzpkf2hzbH1rNu5ttwhyA4sQJu/69dc5Gp\n\tD7Nskd69o7NM+zbxH8gPy5gm8HhmLCgXxtU3HIED4x1GRWcviBhsH7cItCvi+4EUHvsw\n\tUAIdax6f/C+qMiKxkYuisRZVeEpJfEPzxLJIdIq1YSHGXvrsNG17ma0lDl7X0l8sdqZU\n\toYHg=="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1778159779; x=1778764579;\n\th=content-transfer-encoding:in-reply-to:content-language:references\n\t:cc:to:subject:from:user-agent:mime-version:date:message-id:x-gm-gg\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=A2g0w0eDvq0Zm6ldbZ2s9DZT/oi+ZIyu8K8xjTwlchI=;\n\tb=aLMAKc01pt0CuJNxzSfo33EZ5aiUIlRdz9kFw911mugkcly1LNpcX2XR+K3yitntn3\n\tOJUE6ZYjfO8DtonsbwEKrYFWHgTB2f95xAgMmKNXfrtDU6HOT8266Gu3kM+diF0OiC0L\n\t7+6nQQbHF7fzI99OeWjLUKIhBhL4neppHvSFWcwOOb2ENf8v0j+i10GjGXBvgPHlWoIC\n\tMfdp8rOjsJsDlCBJlG8t6tAg/gy/BY/cDnn/hgHcQpq3lisRSXGJCmHYyx/l6ptplIZA\n\tPIPgGgDJbtLs0MO39uIHuEnB+PzrPA5DtQchmBJsK9afaVPSfIRoa2cjBk/wKbbHYrxA\n\t5czA==","X-Forwarded-Encrypted":"i=1;\n\tAFNElJ96Z6smIeZgp/5wPb40dTRzdEwA3/gWg6XDxt21GujH4LyElhvtW4iyMnPg71gWMIz2EXZ3ZDkcd428kkzJ4xM=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YwLC5hog+BYpq6g2eTQcIiBEZG57RqAjVoPuDue73F1Nd1aNMzA\n\tE8DIzRcJ6BnbmhYvSlDq4DEumNJF3DYRiX/EC0qSy8agu+Ih6CawWY+wR1byGekcNlAt7lyKBNu\n\t5EW/acV0J/+W7rfnaib6xhAbvFO38dB2wYhnJ5eoMrXS42WfV5e4Pi1RdGJzPqFe605F7R/4nP8\n\t1e","X-Gm-Gg":"AeBDieteUJzVxLLgfBo2l1VfVHFELtaghHNZXSLh1euiM3ZR7QNKqUZ35gTFyNUzEkx\n\t2tAVRL9wAHgl15JId3DsMLQX6eKMOC0iBLEsG/uS4vWCr5LOXCuOJ8ACM95kme+8nMzQznHo+zz\n\tgqYDBqAmy9PPGCYblEyV/VW1JyJu4qQ5yFzEGlKe9m2m2FwpqBxD+ZQ0KKCSWErmi5IQT7tOJfd\n\tuQLsGcxT5NsEPCZipaIJIsJXJ63gDsIfMAdj/25ZLVhzX5miZdUL93+JjS6QsxaRuY8AFNSPFoo\n\te3VeVJnYfOVXRllqeaqyXo2O2KpNKRy/m556mse7XyYxZ7oFYGes2MKWZ78JvCPcTXDmpfHHADR\n\tiaT/KViXkM15TBa7Gd833N24Su/E+LB1pMi380JBVWi1v81ma5p/36F8zrt3dryfBQ8Kav07EyN\n\ti/MbNVcHODN+yCiPRKj1EO4wc52LrWXyuFgJR7v16+pQctm0viX5yAYnopBZXAzfl2Hxy72k7xY\n\tua3hXIupIdvxD88wBD+Sk/ACBo=","X-Received":["by 2002:a05:6808:1a21:b0:479:ac7d:6d94 with SMTP id\n\t5614622812f47-4804247a9e7mr4577089b6e.24.1778159778466; \n\tThu, 07 May 2026 06:16:18 -0700 (PDT)","by 2002:a05:6808:1a21:b0:479:ac7d:6d94 with SMTP id\n\t5614622812f47-4804247a9e7mr4577051b6e.24.1778159777815; \n\tThu, 07 May 2026 06:16:17 -0700 (PDT)"],"Message-ID":"<5db355fe-2ed5-490a-9b3b-e92df7c215c9@oss.qualcomm.com>","Date":"Thu, 7 May 2026 15:16:13 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","From":"johannes.goede@oss.qualcomm.com","Subject":"Re: [PATCH v5 2/3] libcamera: software_isp: Normalize statistics\n\tsums to 8-bit","To":"Javier Tia <floss@jetm.me>, libcamera-devel@lists.libcamera.org","Cc":"mzamazal@redhat.com, barnabas.pocze@ideasonboard.com,\n\tkieran.bingham@ideasonboard.com","References":"<177810597783.688418.1631246733707368646@jetm.me>\n\t<20260506221944.066FD1EA006B@mailuser.phl.internal>","Content-Language":"en-US, nl","In-Reply-To":"<20260506221944.066FD1EA006B@mailuser.phl.internal>","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","X-Authority-Analysis":"v=2.4 cv=P6IKQCAu c=1 sm=1 tr=0 ts=69fc90a3 cx=c_pps\n\ta=yymyAM/LQ7lj/HqAiIiKTw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10\n\ta=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22\n\ta=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=20KFwNOVAAAA:8\n\ta=P1BnusSwAAAA:8 a=EUspDBNiAAAA:8 a=CsBOSgtXeETop8OZ4LEA:9\n\ta=3ZKOabzyN94A:10\n\ta=QEXdDO2ut3YA:10 a=efpaJB4zofY2dbm2aIRb:22 a=D0XLA9XvdZm18NrgonBM:22","X-Proofpoint-ORIG-GUID":"vheUiQg8zyWOusN6KcpLNOWpB3gOuxOG","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwNTA3MDEzMiBTYWx0ZWRfX8/vES8/r0B+X\n\tQi0LfgrFW+VJ30P2ANWAeyCsU5kJTg9g+hH/x8Iu58WJDmDgsCtKmoC+0E2NiTNdokTk2RaSV9L\n\tPTzi/xfYCiyxKTd/XbiOch5Wg6x5wQX8bL38ZqXK1dzf5ii78JvV9LEeZrRRFbsge5j6JdniDUY\n\tIbFSpspnO6nNtPW6DBPLooSruF02qHsfM3cx8ZYTsTtdeVptiNsJXpXfjk3BfKgR0B+fl/GfJka\n\ttX59CRKvhwyyx+e1pjMxcS/j0nh+mWo7sMAs0q1uSSX2HgcnOnM0X0p0+gzJWV9f2JCbWT2A01n\n\tafBwa9aRlvw8+JxgF8AuqnvBYz90RrxECB7FbDY7SpTr9UpcW3tmkWL9JhO7I2oZCFUtlS8hGKj\n\tL1njAZaWJaFaBS6NjWbMGR2G31xiqmm74cEIAzdU80L0GTPR2OWMK55S1p+JtqAP1Lmf3h/Qhbx\n\tK9iCiTfdkvsy6nwbUyg==","X-Proofpoint-GUID":"vheUiQg8zyWOusN6KcpLNOWpB3gOuxOG","X-Proofpoint-Virus-Version":"vendor=baseguard\n\tengine=ICAP:2.0.293, Aquarius:18.0.1143, Hydra:6.1.51,\n\tFMLib:17.12.100.49\n\tdefinitions=2026-05-07_01,2026-05-06_01,2025-10-01_01","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n\tphishscore=0 suspectscore=0 clxscore=1015 bulkscore=0 spamscore=0\n\tlowpriorityscore=0 malwarescore=0 adultscore=0 priorityscore=1501\n\timpostorscore=0 classifier=typeunknown authscore=0 authtc= authcc=\n\troute=outbound adjust=0 reason=mlx scancount=1\n\tengine=8.22.0-2604200000\n\tdefinitions=main-2605070132","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>"}},{"id":38779,"web_url":"https://patchwork.libcamera.org/comment/38779/","msgid":"<20260507142159.GM1547435@killaraus.ideasonboard.com>","date":"2026-05-07T14:21:59","subject":"Re: [PATCH v5 2/3] libcamera: software_isp: Normalize statistics\n\tsums to 8-bit","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Wed, May 06, 2026 at 03:46:28PM -0600, Javier Tia wrote:\n> The SWSTATS_ACCUMULATE_LINE_STATS() macro divides the luminance value\n> for the histogram to normalize it to 8-bit range, but does not apply\n> the same normalization to the RGB sums. For 10-bit and 12-bit unpacked\n> Bayer 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\n> 8-bit black level from them, under-correcting by 4x or 16x\n> respectively.\n> \n> This mismatch between the AWB's gain calculation (using incorrectly\n> BLC-subtracted sums) and the debayer's correct normalized BLC\n> subtraction produces a visible color cast. For example, with the\n> OV2740 sensor (10-bit, BLC=16), the under-subtraction skews R/G gain\n> by ~9%.\n> \n> Fix this by right-shifting the RGB sums in finishFrame() to normalize\n> them to 8-bit scale, matching the histogram and the 8-bit black level\n> used by AWB. A per-format sumShift_ value is set in configure():\n> 0 for 8-bit and CSI-2 packed formats (already 8-bit), 2 for 10-bit,\n> and 4 for 12-bit unpacked formats.\n> \n> Signed-off-by: Javier Tia <floss@jetm.me>\n> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>\n> Tested-by: Milan Zamazal <mzamazal@redhat.com>\n> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\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(+)\n> \n> diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\n> index 802370bd..2dac6945 100644\n> --- a/include/libcamera/internal/software_isp/swstats_cpu.h\n> +++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n> @@ -116,6 +116,7 @@ private:\n>  \n>  \tunsigned int xShift_;\n>  \tunsigned int stride_;\n> +\tunsigned int sumShift_;\n>  \n>  \tstd::vector<SwIspStats> stats_;\n>  \tSharedMemObject<SwIspStats> sharedStats_;\n> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n> index 5366e019..b40d3334 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n> @@ -362,6 +362,11 @@ void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId)\n>  \t\t\tfor (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++)\n>  \t\t\t\tsharedStats_->yHistogram[j] += s.yHistogram[j];\n>  \t\t}\n> +\t\tif (sumShift_) {\n> +\t\t\tsharedStats_->sum_.r() >>= sumShift_;\n> +\t\t\tsharedStats_->sum_.g() >>= sumShift_;\n> +\t\t\tsharedStats_->sum_.b() >>= sumShift_;\n> +\t\t}\n\nShould we do this unconditionally ? Shifting right by 0 is a no-op.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n>  \t}\n>  \n>  \tsharedStats_->valid = valid;\n> @@ -425,12 +430,15 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\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> @@ -442,6 +450,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\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) {","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 798F2BDCB5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  7 May 2026 14:22:03 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 978DA6301E;\n\tThu,  7 May 2026 16:22:02 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8506C62010\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  7 May 2026 16:22:01 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-70f3-e800--a06.rev.dnainternet.fi\n\t[IPv6:2001:14ba:70f3:e800::a06])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 13F26664;\n\tThu,  7 May 2026 16:21:57 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"PU3/6Mcx\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778163717;\n\tbh=Jiw2APhiSDfNs7NHi175+MPN0K6dO1oHL5q0+ZI9gLE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=PU3/6McxcQoi6PZhjsnpl2GRgDF+AY4jXlkFUqPXUKoz75s/sGXm7fQkJm6+DyF7/\n\tTZccIo1a9huOA52UaNllVtLAAbMP+/DE/sgbYBs0kUBM67NZEd14mFOXsXGNvCAWSz\n\tDMlIIxbLVxNwNu4dOwxMIsV+5asBJffq8Do/xBAw=","Date":"Thu, 7 May 2026 17:21:59 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Javier Tia <floss@jetm.me>","Cc":"libcamera-devel@lists.libcamera.org, mzamazal@redhat.com,\n\tbarnabas.pocze@ideasonboard.com, kieran.bingham@ideasonboard.com","Subject":"Re: [PATCH v5 2/3] libcamera: software_isp: Normalize statistics\n\tsums to 8-bit","Message-ID":"<20260507142159.GM1547435@killaraus.ideasonboard.com>","References":"<177810597783.688418.1631246733707368646@jetm.me>\n\t<20260506221944.066FD1EA006B@mailuser.phl.internal>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20260506221944.066FD1EA006B@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>"}},{"id":38780,"web_url":"https://patchwork.libcamera.org/comment/38780/","msgid":"<7815ee23-e8ac-4199-baab-6129b378f20c@ideasonboard.com>","date":"2026-05-07T14:23:27","subject":"Re: [PATCH v5 2/3] libcamera: software_isp: Normalize statistics\n\tsums to 8-bit","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 05. 07. 16:21 keltezéssel, Laurent Pinchart írta:\n> On Wed, May 06, 2026 at 03:46:28PM -0600, Javier Tia wrote:\n>> The SWSTATS_ACCUMULATE_LINE_STATS() macro divides the luminance value\n>> for the histogram to normalize it to 8-bit range, but does not apply\n>> the same normalization to the RGB sums. For 10-bit and 12-bit unpacked\n>> Bayer 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\n>> 8-bit black level from them, under-correcting by 4x or 16x\n>> respectively.\n>>\n>> This mismatch between the AWB's gain calculation (using incorrectly\n>> BLC-subtracted sums) and the debayer's correct normalized BLC\n>> subtraction produces a visible color cast. For example, with the\n>> OV2740 sensor (10-bit, BLC=16), the under-subtraction skews R/G gain\n>> by ~9%.\n>>\n>> Fix this by right-shifting the RGB sums in finishFrame() to normalize\n>> them to 8-bit scale, matching the histogram and the 8-bit black level\n>> used by AWB. A per-format sumShift_ value is set in configure():\n>> 0 for 8-bit and CSI-2 packed formats (already 8-bit), 2 for 10-bit,\n>> and 4 for 12-bit unpacked formats.\n>>\n>> Signed-off-by: Javier Tia <floss@jetm.me>\n>> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>\n>> Tested-by: Milan Zamazal <mzamazal@redhat.com>\n>> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\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(+)\n>>\n>> diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\n>> index 802370bd..2dac6945 100644\n>> --- a/include/libcamera/internal/software_isp/swstats_cpu.h\n>> +++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n>> @@ -116,6 +116,7 @@ private:\n>>   \n>>   \tunsigned int xShift_;\n>>   \tunsigned int stride_;\n>> +\tunsigned int sumShift_;\n>>   \n>>   \tstd::vector<SwIspStats> stats_;\n>>   \tSharedMemObject<SwIspStats> sharedStats_;\n>> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n>> index 5366e019..b40d3334 100644\n>> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n>> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n>> @@ -362,6 +362,11 @@ void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId)\n>>   \t\t\tfor (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++)\n>>   \t\t\t\tsharedStats_->yHistogram[j] += s.yHistogram[j];\n>>   \t\t}\n>> +\t\tif (sumShift_) {\n>> +\t\t\tsharedStats_->sum_.r() >>= sumShift_;\n>> +\t\t\tsharedStats_->sum_.g() >>= sumShift_;\n>> +\t\t\tsharedStats_->sum_.b() >>= sumShift_;\n>> +\t\t}\n> \n> Should we do this unconditionally ? Shifting right by 0 is a no-op.\n\nI second that!\n\n\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n>>   \t}\n>>   \n>>   \tsharedStats_->valid = valid;\n>> @@ -425,12 +430,15 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\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>> @@ -442,6 +450,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\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>","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 9CD70BDCB5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  7 May 2026 14:23:33 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4316D63026;\n\tThu,  7 May 2026 16:23:33 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 84F2962FE1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  7 May 2026 16:23:31 +0200 (CEST)","from [192.168.33.83] (185.221.140.217.nat.pool.zt.hu\n\t[185.221.140.217])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E9D9A664;\n\tThu,  7 May 2026 16:23:26 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ewMLytfi\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778163807;\n\tbh=VGdVthjkpqtDYTozpLU7YaO0X33h+JGqtLZ37NIQZDE=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=ewMLytfibfHybgAoY+G24CLwHpmCvGvSo+JGAXUfD7+5aYukjAXC1lbluySLctMug\n\tSsXlWQCCX8C3/GQTUI3tvgrkR25IGkN+zlAuIdP8tEPakdEa+k1i3y3J2eJfpoYk99\n\tFWNt3W+ooZs258GkoMkwvSueAmTwuRxhvcR304B8=","Message-ID":"<7815ee23-e8ac-4199-baab-6129b378f20c@ideasonboard.com>","Date":"Thu, 7 May 2026 16:23:27 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v5 2/3] libcamera: software_isp: Normalize statistics\n\tsums to 8-bit","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tJavier Tia <floss@jetm.me>","Cc":"libcamera-devel@lists.libcamera.org, mzamazal@redhat.com,\n\tkieran.bingham@ideasonboard.com","References":"<177810597783.688418.1631246733707368646@jetm.me>\n\t<20260506221944.066FD1EA006B@mailuser.phl.internal>\n\t<20260507142159.GM1547435@killaraus.ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260507142159.GM1547435@killaraus.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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>"}}]