From patchwork Wed Jul 3 13:49:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 20508 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 8C0EEBD87C for ; Wed, 3 Jul 2024 13:50:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0319362E25; Wed, 3 Jul 2024 15:50:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="D38LDlSF"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D98EE62C95 for ; Wed, 3 Jul 2024 15:50:08 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:9263:c199:9587:576]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BFE713D6; Wed, 3 Jul 2024 15:49:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1720014580; bh=HX3uAUPRMm66rx8wnqck16xTrciPzeJCvjFVfNnc+Ls=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D38LDlSF970FKEbn5zqrMmGQYaytb8NOD0+vRAJCGb+WD/Z/3Qte2dowxbVeqjaiW aFlp7ZTjLTtCw/ytDqUObN23Sel9CoGkRfK+Jon2i9nG61xl7mP322fDaJPrQdxJfR Q9KhxhPRh5dqaE59X3ZmLbKt8YJ+A/uv4OADpk1A= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Paul Elder , Kieran Bingham , Laurent Pinchart Subject: [PATCH v3 1/6] ipa: libipa: Add black levels to camera sensor helper Date: Wed, 3 Jul 2024 15:49:49 +0200 Message-ID: <20240703135000.242227-2-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240703135000.242227-1-stefan.klug@ideasonboard.com> References: <20240703135000.242227-1-stefan.klug@ideasonboard.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" For a proper tuning process we need to know the sensor black levels. In most cases these are fixed and not reported by the kernel driver. Store them inside the sensor helpers for later retrieval by the algorithms. Add black level value corresponding to the data pedestal for three initial sensors as documented in the datasheets. More should be added, eventually filling the gaps for all supported sensors. Signed-off-by: Stefan Klug Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/libipa/camera_sensor_helper.cpp | 38 +++++++++++++++++++++++++ src/ipa/libipa/camera_sensor_helper.h | 3 ++ 2 files changed, 41 insertions(+) diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp index 782ff9904e81..82c795eac71b 100644 --- a/src/ipa/libipa/camera_sensor_helper.cpp +++ b/src/ipa/libipa/camera_sensor_helper.cpp @@ -47,6 +47,33 @@ namespace ipa { * function. */ +/** + * \fn CameraSensorHelper::blackLevel() + * \brief Fetch the black level of the sensor + * + * This function returns the black level of the sensor scaled to a 16bit pixel + * width. If it is unknown an empty optional is returned. + * + * \todo Fill the blanks and add pedestal values for all supported sensors. Once + * done, drop the std::optional<>. + * + * Black levels are typically the result of the following phenomena: + * - Pedestal added by the sensor to pixel values. They are typically fixed, + * sometimes programmable and should be reported in datasheets (but + * documentation is not always available). + * - Dark currents and other physical effects that add charge to pixels in the + * absence of light. Those can depend on the integration time and the sensor + * die temperature, and their contribution to pixel values depend on the + * sensor gains. + * + * The pedestal is usually the value with the biggest contribution to the + * overall black level. In most cases it is either known before or in rare cases + * (there is not a single driver with such a control in the linux kernel) can be + * queried from the sensor. This function provides that fixed, known value. + * + * \return The black level of the sensor, or std::nullopt if not known + */ + /** * \brief Compute gain code from the analogue gain absolute value * \param[in] gain The real gain to pass @@ -204,6 +231,11 @@ double CameraSensorHelper::gain(uint32_t gainCode) const * \brief Constants for the exponential gain model */ +/** + * \var CameraSensorHelper::blackLevel_ + * \brief The black level of the sensor + */ + /** * \var CameraSensorHelper::gainType_ * \brief The analogue gain model type @@ -396,6 +428,8 @@ class CameraSensorHelperImx219 : public CameraSensorHelper public: CameraSensorHelperImx219() { + /* From datasheet: 64 at 10bits. */ + blackLevel_ = 4096; gainType_ = AnalogueGainLinear; gainConstants_.linear = { 0, 256, -1, 256 }; } @@ -407,6 +441,8 @@ class CameraSensorHelperImx258 : public CameraSensorHelper public: CameraSensorHelperImx258() { + /* From datasheet: 0x40 at 10bits. */ + blackLevel_ = 4096; gainType_ = AnalogueGainLinear; gainConstants_.linear = { 0, 512, -1, 512 }; } @@ -456,6 +492,8 @@ class CameraSensorHelperImx335 : public CameraSensorHelper public: CameraSensorHelperImx335() { + /* From datasheet: 0x32 at 10bits. */ + blackLevel_ = 3200; gainType_ = AnalogueGainExponential; gainConstants_.exp = { 1.0, expGainDb(0.3) }; } diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h index 0d99073bea82..ac276e27f523 100644 --- a/src/ipa/libipa/camera_sensor_helper.h +++ b/src/ipa/libipa/camera_sensor_helper.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -25,6 +26,7 @@ public: CameraSensorHelper() = default; virtual ~CameraSensorHelper() = default; + std::optional blackLevel() const { return blackLevel_; } virtual uint32_t gainCode(double gain) const; virtual double gain(uint32_t gainCode) const; @@ -51,6 +53,7 @@ protected: AnalogueGainExpConstants exp; }; + std::optional blackLevel_; AnalogueGainType gainType_; AnalogueGainConstants gainConstants_;