From patchwork Fri May 24 13:52:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 20098 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 A0FE2BD87C for ; Fri, 24 May 2024 13:53:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 28B9E634AC; Fri, 24 May 2024 15:53:06 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="qWrDM98J"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EFCB9634A8 for ; Fri, 24 May 2024 15:53:00 +0200 (CEST) Received: from Monstersaurus.local (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A6B4FD01; Fri, 24 May 2024 15:52:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1716558766; bh=7Z/SPyYH4evZP8X6lerq9wW+MNk5DuxVuhlmrGxCiHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qWrDM98J4C1vL18xk1pG7RO15cJ5RIax6gUEKvlSs+I9zl3stnpQXbYeC3MWCHUuB 13tTDb9nBOyh0aEshI9bb2zHKTZ4U7jMmg6VPdblCW+VFj2gOgQNWsHwW/MmUfROrq Gy9B+Z/+xfgFff1OH/oWAkToSISHPiNN+knVFi2Y= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH v2 1/2] test: ipa: libipa: Add CameraSensorHelper Gain Model tests Date: Fri, 24 May 2024 14:52:55 +0100 Message-Id: <20240524135256.649406-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240524135256.649406-1-kieran.bingham@ideasonboard.com> References: <20240524135256.649406-1-kieran.bingham@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" Introduce a test that validates conversion of the gain model in both Linear and Exponential models. It should be expected that if a gainCode produces a given gain value, then converting that gain back should produce the same result. The test is known to fail and is marked as such. The test will be updated with the corresponding fix. Signed-off-by: Kieran Bingham --- test/ipa/camera_sensor_helper.cpp | 101 ++++++++++++++++++++++++++++++ test/ipa/meson.build | 5 +- 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 test/ipa/camera_sensor_helper.cpp diff --git a/test/ipa/camera_sensor_helper.cpp b/test/ipa/camera_sensor_helper.cpp new file mode 100644 index 000000000000..d8a8c6850a04 --- /dev/null +++ b/test/ipa/camera_sensor_helper.cpp @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024, Ideas on Board Oy. + */ + +#include "libipa/camera_sensor_helper.h" + +#include +#include + +#include "test.h" + +using namespace std; +using namespace libcamera; +using namespace libcamera::ipa; + +/* + * Helper function to compute the m parameter of the exponential gain model + * when the gain code is expressed in dB. + */ +static constexpr double expGainDb(double step) +{ + constexpr double log2_10 = 3.321928094887362; + + /* + * The gain code is expressed in step * dB (e.g. in 0.1 dB steps): + * + * G_code = G_dB/step = 20/step*log10(G_linear) + * + * Inverting the formula, we get + * + * G_linear = 10^(step/20*G_code) = 2^(log2(10)*step/20*G_code) + */ + return log2_10 * step / 20; +} + +class CameraSensorHelperExponential : public CameraSensorHelper +{ +public: + CameraSensorHelperExponential() + { + gainType_ = AnalogueGainExponential; + gainConstants_.exp = { 1.0, expGainDb(0.3) }; + } +}; + +class CameraSensorHelperLinear : public CameraSensorHelper +{ +public: + CameraSensorHelperLinear() + { + gainType_ = AnalogueGainLinear; + gainConstants_.linear = { 0, 1024, -1, 1024 }; + } +}; + +class CameraSensorHelperTest : public Test +{ +protected: + int testGainModel(CameraSensorHelper &helper) + { + int ret = TestPass; + + /* + * Arbitrarily test 255 code positions assuming 8 bit fields + * are the normal maximum for a gain code register. + */ + for (unsigned int i = 0; i < 255; i++) { + float gain = helper.gain(i); + uint32_t gainCode = helper.gainCode(gain); + + if (i != gainCode) { + std::cout << "Gain conversions failed: " + << i << " : " << gain << " : " + << gainCode << std::endl; + + ret = TestFail; + } + }; + + return ret; + } + + int run() override + { + unsigned int failures = 0; + + CameraSensorHelperExponential exponential; + CameraSensorHelperLinear linear; + + if (testGainModel(exponential) == TestFail) + failures++; + + if (testGainModel(linear) == TestFail) + failures++; + + return failures ? TestFail : TestPass; + } +}; + +TEST_REGISTER(CameraSensorHelperTest) diff --git a/test/ipa/meson.build b/test/ipa/meson.build index 180b0da0a51a..abc2456fc341 100644 --- a/test/ipa/meson.build +++ b/test/ipa/meson.build @@ -1,6 +1,8 @@ # SPDX-License-Identifier: CC0-1.0 ipa_test = [ + {'name': 'camera_sensor_helper', 'sources': ['camera_sensor_helper.cpp'], + 'should_fail': true}, {'name': 'ipa_module_test', 'sources': ['ipa_module_test.cpp']}, {'name': 'ipa_interface_test', 'sources': ['ipa_interface_test.cpp']}, ] @@ -11,5 +13,6 @@ foreach test : ipa_test link_with : [libipa, test_libraries], include_directories : [libipa_includes, test_includes_internal]) - test(test['name'], exe, suite : 'ipa') + test(test['name'], exe, suite : 'ipa', + should_fail : test.get('should_fail', false)) endforeach From patchwork Fri May 24 13:52:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 20099 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 731CDBD87C for ; Fri, 24 May 2024 13:53:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 61BBB634B1; Fri, 24 May 2024 15:53:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Lcglayvb"; 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 22028634AA for ; Fri, 24 May 2024 15:53:01 +0200 (CEST) Received: from Monstersaurus.local (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DA5D1150E; Fri, 24 May 2024 15:52:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1716558767; bh=/3x9cfYUt/GOVWzCJbu4F/Y7UbYEi5cGg8i6XoXpTRE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Lcglayvb8xuw2vphV5rD/7LoNzIBG5SDsHFQSNLfLkCprGYiCV1VC64KpE5FF+9Ni WiP2cVxTtvNYB3XSPGLY4vu7LQoO2tFgBBsJc2XqCvTsB0bN7TaJDWuD122Z2TJUMF rrKypY6si72uhSwWHwIn4LivUos7bDgdoWZcLU5w= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH v2 2/2] libipa: camera_sensor_helper: Fix rounding of gainCode Date: Fri, 24 May 2024 14:52:56 +0100 Message-Id: <20240524135256.649406-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240524135256.649406-1-kieran.bingham@ideasonboard.com> References: <20240524135256.649406-1-kieran.bingham@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" The implementation of gainCode for both Exponential and Linear gain models does not generate a gainCode that matches the result of the reverse operation. This can be seen by converting sequential gainCodes to a gain and converting that back to the gainCode. The values do not translate back due to only rounding down, rather than to the closest integer. Correct the rounding error and ensure that gainCode translation produces accurate bi-directional conversions from the perspective of the gainCode. This fixes the IMX290, IMX296, IMX327 and IMX335 which use the Exponential gain model helpers, as well as IMX219, IMX258, IMX283, and IMX477 which use the Linear gain model helpers. This updates the corresponding test which was previously marked as expected to fail. Fixes: 8ad9249fb09d ("libipa: camera_sensor_helper: Implement exponential gain model") Signed-off-by: Kieran Bingham --- src/ipa/libipa/camera_sensor_helper.cpp | 6 +++--- test/ipa/meson.build | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp index 2cd61fccfbb9..4a92ead88b23 100644 --- a/src/ipa/libipa/camera_sensor_helper.cpp +++ b/src/ipa/libipa/camera_sensor_helper.cpp @@ -64,13 +64,13 @@ uint32_t CameraSensorHelper::gainCode(double gain) const case AnalogueGainLinear: ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0); - return (k.linear.c0 - k.linear.c1 * gain) / - (k.linear.m1 * gain - k.linear.m0); + return std::round((k.linear.c0 - k.linear.c1 * gain) / + (k.linear.m1 * gain - k.linear.m0)); case AnalogueGainExponential: ASSERT(k.exp.a != 0 && k.exp.m != 0); - return std::log2(gain / k.exp.a) / k.exp.m; + return std::round(std::log2(gain / k.exp.a) / k.exp.m); default: ASSERT(false); diff --git a/test/ipa/meson.build b/test/ipa/meson.build index abc2456fc341..0b22c7576e56 100644 --- a/test/ipa/meson.build +++ b/test/ipa/meson.build @@ -1,8 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 ipa_test = [ - {'name': 'camera_sensor_helper', 'sources': ['camera_sensor_helper.cpp'], - 'should_fail': true}, + {'name': 'camera_sensor_helper', 'sources': ['camera_sensor_helper.cpp']}, {'name': 'ipa_module_test', 'sources': ['ipa_module_test.cpp']}, {'name': 'ipa_interface_test', 'sources': ['ipa_interface_test.cpp']}, ]