From patchwork Tue Sep 8 16:37:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "D. Manresa" X-Patchwork-Id: 28209 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 84957BD160 for ; Tue, 8 Sep 2026 16:37:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 344FF68637; Tue, 8 Sep 2026 18:37:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="DRuzmv+3"; dkim-atps=neutral Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6CB3D68625 for ; Tue, 8 Sep 2026 18:37:03 +0200 (CEST) Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-485843aeab8so5396880f8f.1 for ; Tue, 08 Sep 2026 09:37:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788885423; x=1789490223; 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:content-type; bh=se6BENrywLu0mAUaUSqbrUeQSArODb2U+yBezrMFg+M=; b=DRuzmv+3XSlEQw+mKytijLsw8quHYfnciIqq1wwr8b2I3g7TUkxJIgFE9caIDqJjMu mlDRodEh1g5s3ZkUVh6deiUmmwrUP+6V0BUYC7qVT2KrOjN9uXA0tIq6LGYbNge1E5Mm LSetkfOX9C2RQ7B7RQE6kRg0Y1a2IuwRCb3MGw1GENM7tpWnT1k1VoO4fzyee0srZ0fi u1XjB5B0s0ynNBpQfKgPMsr/T//NMN1R+fU9F2tCeH5uwT8UU6zq/r6J41xrc0Eiwj5/ k2o5fljh6o8B71+A/fbv7EqBqeV9KRyMi5WkphnuW2y1WMozwkow4QuRox6oXMdZzx+1 L56A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788885423; x=1789490223; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=se6BENrywLu0mAUaUSqbrUeQSArODb2U+yBezrMFg+M=; b=TK5qiJVDkI1yLOWxTX4Jf9IBixrapvUi+kzl4hPytlj9bwmoRuH2lHase3PtDXSW+A Fr+5U+V/SbzGAgoxsLg6Mr6AI/oKqjeCu0n6H6CkqmI3x36Belc2H49EHLF0Onk0TeU3 Vf8mED+6EhgibL4/+f4InD/tp6z6Mok6d/JkWO08k2HauZlRR8Fva5kFil6n6Y4fpeqD 4KOBn/MlOS5LhiDHSL5Qid6HZ1cav6GpfgFOOXhkxtvlM0z9lguLRiuRNG5+cS1Ioh0r WvwhsYsJJCJo4uvDn7wps1aeNel9qtZyhG06RTapXz6g/RO7FteG0rB1qaOICuivgHZ8 moIg== X-Gm-Message-State: AFuF++nM3S9kuuyuuSAiOI/CzXHhgigABwx6jRkB1H64RbP9ja2wSINC q2AyifYUYr5oXa6y98tb+4bTOIdysDDM1qB6pk8fLM5OsIDqCs2zyChndo2+gFBGcA== X-Gm-Gg: AYBFou1qm627IsMd7IkqeO4oT9TlUPmiezWR2edVbr9rzig7f+C7lYNReFPIAmfCfO8 208tpKadD+OwrSACaqCSBlI7TT2fPEQx4uLnfmnISGX+e+lnokB3bnqQHUvheMhNNdjJt/jKg4V 4tXrCU4y6kcDVLbjlkvokv+F2ma63xaqGN42kpTAdScmP/RTBx8K/SQ4uHJZKmbRHsJiKX9/ceV 8L8fIje8S+FppqzvXLq5PdaMppn2sx7UsAhFkpWUOgRg+K9YCxeDzqqy/gTMv1edpgAHteVkQWP SwiNeocrTpvIv4O7UsuJK1XCUXDTW3dZBE13wUsPEy9NJxtCjouLCpHVSxvf+B2bFRymqDIHvhU K3lNEeC0R32BSJu7nklzU06vu/NcMMFZ3vcChRy2DAm3RTYN0VNhw/aiqLq15JLdqlpxbTAYmdl T4r47sg00w2YPBNKVDEqJXCXHGiDwDm5xZdCCriRwZUf292uTkvLlqYCVhj+DsKpB3NFECFWTj0 OfZE0A5o2+9n+MsogcfVgf97B2Afjtc8qVIvX2TZI70e+ya X-Received: by 2002:a05:6000:70b:b0:485:8be1:378d with SMTP id ffacd0b85a97d-4858be14b94mr59649659f8f.12.1788885422354; Tue, 08 Sep 2026 09:37:02 -0700 (PDT) Received: from latitude7275 (84.124.213.91.dyn.user.ono.com. [84.124.213.91]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48588394fa1sm35268362f8f.8.2026.09.08.09.37.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2026 09:37:01 -0700 (PDT) From: "D. Manresa" To: libcamera-devel@lists.libcamera.org Cc: Daniel Scally Subject: [PATCH v2 1/2] ipa: libipa: camera_sensor_helper: Add OV5670 black level Date: Tue, 8 Sep 2026 18:37:07 +0200 Message-ID: <20260908163708.341308-2-dmanresa@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260908163708.341308-1-dmanresa@gmail.com> References: <20260904062840.46739-3-dmanresa@gmail.com> <20260908163708.341308-1-dmanresa@gmail.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 OV5670 has a black level of 64 at 10 bits, the sensor's default BLC target. This was confirmed on a Dell Latitude 7275 by reading the ImgU statistics and dark frames with different black level corrections. Provide it in the camera sensor helper so that IPAs can use it instead of hard-coded or tuning-file values. Signed-off-by: D. Manresa --- src/ipa/libipa/camera_sensor_helper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp index 82bf255..eeb3277 100644 --- a/src/ipa/libipa/camera_sensor_helper.cpp +++ b/src/ipa/libipa/camera_sensor_helper.cpp @@ -802,6 +802,8 @@ class CameraSensorHelperOv5670 : public CameraSensorHelper public: CameraSensorHelperOv5670() { + /* Default BLC target of 64 at 10bits, confirmed by measurement. */ + blackLevel_ = 4096; gain_ = AnalogueGainLinear{ 1, 0, 0, 128 }; } }; From patchwork Tue Sep 8 16:37:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "D. Manresa" X-Patchwork-Id: 28210 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 0B2EDBDCC0 for ; Tue, 8 Sep 2026 16:37:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CB2F768639; Tue, 8 Sep 2026 18:37:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Z81g+b+z"; dkim-atps=neutral Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CBD4568632 for ; Tue, 8 Sep 2026 18:37:03 +0200 (CEST) Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-482f9309813so4527093f8f.1 for ; Tue, 08 Sep 2026 09:37:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788885423; x=1789490223; 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:content-type; bh=PqP5HL02LEAi5XIwSuHOUVN+emle9xozs8+rqIsalFw=; b=Z81g+b+zmvC5YT50C46LIvihCoCnhWJjJSeHN1nYgbupqy1nWzvXwFWpEHFTqre4IA WO7fZm4IvQstBuxRapvDVXhTJ67342MHm5alDgrQu8A7U0apSbAZwN9PBqSsG2lOdNwf ZNUlCNYkC32fQFpkcC/aykkYYwY1FqUoqqwk4Ktc7q37XzQkCH5rw39ovauknviEpmWQ nQpKrhGZFjfOJTQagTvHG6L8itIVwolk6ddjrNu4iUkoH7k97EmmIUY+PZDwUXdrrvt3 SiAgJpq50n1QQhwWsOXohvRz7y//PNxj2MPVswvR2xmiGbAa2NbPv3RWSigEzoHvXS8A xujg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788885423; x=1789490223; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=PqP5HL02LEAi5XIwSuHOUVN+emle9xozs8+rqIsalFw=; b=I4ma7pdN4valugB+/VNmFTaqdmsA4cWSEUpUFgk9YFAPPAtAij2svH3tN5JT268Ekk g/ytuHf2i+5J1Trcagf5rBYAiHQ6SIoZSjPgDQNqbsrAVVIsB8HSgAJRxe5UhvonLCeF xHU8b78I4ppK5fkzk2TCaoT83RXIrF2SnyXsM5OqH6lInwLYui+LzcMTRi8EEnL3Ymr1 yyioh2+oy8k1P1MbFk/Psjv/6E6T80ckrp7INvi4/2IdObnhGmT8XRvhuMAo/A5B/T46 skW1Y+zl1TEX6bRbssCINiNzDZpAbD+yBpSxdRmMIgfYMrqxwum3JQjievi+BuT9SV4N /NjA== X-Gm-Message-State: AFuF++kbx9pmdsmjz0CWeW68upkbd0GCgujjECNP/gCzjJdGE/6VV8AY 4wfItGJnipnwK7vTfbBD8biom3aCq7ugGrM0j7Mlryp/5xa3K9Xhw3AB8SQ2o09btQ== X-Gm-Gg: AYBFou2caKYviSR/ssz1XwgMNPGpCJy3GHN9vvcsO6x/OyU2mN0x3z9SZMybNM1qvE1 8GrQ8FRbcvzvsRHjDaZJnP8aRTDvEWu625qC0c//Bp+qRcpeh3CqR72SgnfHHi2QSg8FjmmnKuS dh728xZqqKqOgECh1lNQYjB7WHEmNepHJuxWoyrqAKzIb68pDSwg/M00FtmiZdKMVX52zvexwff QlkHVTmomEpgBG+N7qgMlkC2ZVeM/k9MWbdpUEXEVE0YVIYB0X1Wc17j0Vcf7Gy3aXFSb2xIPoR I3WY1sSnDYC8nBf5IBRHDA3bI37lKwSmYvciPjHPCuguhKlygTpV3qCT1BxrCMeL6dUYg6LXpT2 YV26eCwiox0ZddoIQgYcJQ/x54vJIT042Gw4cl+jlbvIfeVnN7YiulP4YxF408nCOfD03wEo/Vd KZmotzzG9tOAbhW68AJVoaLPH+pCc4JPzm68pUWLc5aiqxMHQBw3LAiLJCcX9LxQ+v87grpMPOu ef3XT+fWfHtngo4Jn3iPTsduFO2SGEd6IaOadqPaost7ECUaX14qPN0jaE= X-Received: by 2002:a05:6000:4304:b0:484:3313:fd86 with SMTP id ffacd0b85a97d-485872d6572mr35632914f8f.27.1788885423228; Tue, 08 Sep 2026 09:37:03 -0700 (PDT) Received: from latitude7275 (84.124.213.91.dyn.user.ono.com. [84.124.213.91]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48588394fa1sm35268362f8f.8.2026.09.08.09.37.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2026 09:37:02 -0700 (PDT) From: "D. Manresa" To: libcamera-devel@lists.libcamera.org Cc: Daniel Scally Subject: [PATCH v2 2/2] ipa: ipu3: blc: Use the black level from the camera sensor helper Date: Tue, 8 Sep 2026 18:37:08 +0200 Message-ID: <20260908163708.341308-3-dmanresa@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260908163708.341308-1-dmanresa@gmail.com> References: <20260904062840.46739-3-dmanresa@gmail.com> <20260908163708.341308-1-dmanresa@gmail.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 black level correction algorithm hard-codes an optical black level of 64 for the four Bayer channels. Take it from the camera sensor helper instead, like the RkISP1 IPA does, falling back to the historical value with a warning when the helper does not provide one. The helper reports the level as a 16-bit value, while the ImgU OB grid expects units of half a 10-bit LSB: on a Dell Latitude 7275 (OV5670, black level 64 at 10 bits) a correction of 64 leaves a residual pedestal in the AWB statistics and in the image, which the colour gains then amplify into a blue or cyan cast; 128 removes the pedestal and 192 clips dark areas to zero. The 16-bit value is therefore shifted right by 5, giving 128 for the OV5670. Measured on the same indoor scene with the uncalibrated tuning file (NV12, limited range, black = 16): with 64 the darkest percentile of Y is 32 and its mean chroma is U/V = 132/131; with 128 they are 15 and 128/128. Signed-off-by: D. Manresa --- src/ipa/ipu3/algorithms/blc.cpp | 56 +++++++++++++++++++++++++++------ src/ipa/ipu3/algorithms/blc.h | 5 +++ 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/ipa/ipu3/algorithms/blc.cpp b/src/ipa/ipu3/algorithms/blc.cpp index 35748fb..1cd2c6b 100644 --- a/src/ipa/ipu3/algorithms/blc.cpp +++ b/src/ipa/ipu3/algorithms/blc.cpp @@ -7,6 +7,10 @@ #include "blc.h" +#include + +#include "libipa/camera_sensor_helper.h" + /** * \file blc.h * \brief IPU3 Black Level Correction control @@ -30,8 +34,46 @@ namespace ipa::ipu3::algorithms { * isn't currently supported. */ +LOG_DEFINE_CATEGORY(IPU3Blc) + +/* + * Black level used when the camera sensor helper does not provide one, + * expressed in ImgU units (see init()). This is the historical value that + * was hard-coded before the level came from the helper. + */ +static constexpr int16_t kDefaultBlackLevel = 64; + BlackLevelCorrection::BlackLevelCorrection() + : blackLevel_(kDefaultBlackLevel) +{ +} + +/** + * \copydoc libcamera::ipa::Algorithm::init + * + * Get the sensor black level from the camera sensor helper. The helper + * reports it as a 16-bit value, while the ImgU OB grid expects it in units + * of half a 10-bit LSB: on an OV5670 (black level 64 at 10 bits) a + * correction of 64 leaves a residual pedestal of about 9/255 in the AWB + * statistics and in the image, 128 removes it, and 192 clips dark areas to + * zero. The 16-bit value is therefore shifted right by 5. + */ +int BlackLevelCorrection::init(IPAContext &context, + [[maybe_unused]] const ValueNode &tuningData) { + std::optional blackLevel = context.camHelper->blackLevel(); + if (!blackLevel) { + LOG(IPU3Blc, Warning) + << "No black level provided by camera sensor helper" + << ", please fix"; + blackLevel_ = kDefaultBlackLevel; + } else { + blackLevel_ = *blackLevel >> 5; + } + + LOG(IPU3Blc, Debug) << "Black level " << blackLevel_; + + return 0; } /** @@ -49,15 +91,11 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] IPAFrameContext &frameContext, ipu3_uapi_params *params) { - /* - * The Optical Black Level correction values - * \todo The correction values should come from sensor specific - * tuning processes. This is a first rough approximation. - */ - params->obgrid_param.gr = 64; - params->obgrid_param.r = 64; - params->obgrid_param.b = 64; - params->obgrid_param.gb = 64; + /* The Optical Black Level correction values */ + params->obgrid_param.gr = blackLevel_; + params->obgrid_param.r = blackLevel_; + params->obgrid_param.b = blackLevel_; + params->obgrid_param.gb = blackLevel_; /* Enable the custom black level correction processing */ params->use.obgrid = 1; diff --git a/src/ipa/ipu3/algorithms/blc.h b/src/ipa/ipu3/algorithms/blc.h index 6274804..58cdd92 100644 --- a/src/ipa/ipu3/algorithms/blc.h +++ b/src/ipa/ipu3/algorithms/blc.h @@ -18,9 +18,14 @@ class BlackLevelCorrection : public Algorithm public: BlackLevelCorrection(); + int init(IPAContext &context, const ValueNode &tuningData) override; + void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, ipu3_uapi_params *params) override; + +private: + int16_t blackLevel_; }; } /* namespace ipa::ipu3::algorithms */