[PATCH v2] libcamera: libipa: camera_sensor: Add onsemi AR0144 sensor properties
Kieran Bingham
kieran.bingham at ideasonboard.com
Tue Jul 23 17:41:31 CEST 2024
Quoting Laurent Pinchart (2024-07-04 00:11:36)
> Provide the onsemi AR0144 camera sensor properties and registration with
> libipa for the gain code helpers.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> Now that the kernel driver has been posted to the linux-media mailing
> list ([1]), it's time for a second version of this patch.
>
> [1] https://lore.kernel.org/r/20240603230301.26550-1-laurent.pinchart@ideasonboard.com
>
> Changes since RFC:
>
> - Add default case
> - Add black level
> ---
> src/ipa/libipa/camera_sensor_helper.cpp | 94 +++++++++++++++++++
> .../sensor/camera_sensor_properties.cpp | 9 ++
> 2 files changed, 103 insertions(+)
I think I'll be able to test this soon. Might as well be in by then ;-)
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
> index a1339c83c4cb..1cae0b3840af 100644
> --- a/src/ipa/libipa/camera_sensor_helper.cpp
> +++ b/src/ipa/libipa/camera_sensor_helper.cpp
> @@ -8,6 +8,7 @@
> #include "camera_sensor_helper.h"
>
> #include <cmath>
> +#include <limits>
>
> #include <libcamera/base/log.h>
>
> @@ -398,6 +399,99 @@ static constexpr double expGainDb(double step)
> return log2_10 * step / 20;
> }
>
> +class CameraSensorHelperAr0144 : public CameraSensorHelper
> +{
> +public:
> + CameraSensorHelperAr0144()
> + {
> + /* Power-on default value: 168 at 12bits. */
> + blackLevel_ = 2688;
> + }
> +
> + uint32_t gainCode(double gain) const override
> + {
> + /* The recommended minimum gain is 1.6842 to avoid artifacts. */
> + gain = std::clamp(gain, 1.0 / (1.0 - 13.0 / 32.0), 18.45);
> +
> + /*
> + * The analogue gain is made of a coarse exponential gain in
> + * the range [2^0, 2^4] and a fine inversely linear gain in the
> + * range [1.0, 2.0[. There is an additional fixed 1.153125
> + * multiplier when the coarse gain reaches 2^2.
> + */
> +
> + if (gain > 4.0)
> + gain /= 1.153125;
> +
> + unsigned int coarse = std::log2(gain);
> + unsigned int fine = (1 - (1 << coarse) / gain) * 32;
> +
> + /* The fine gain rounding depends on the coarse gain. */
> + if (coarse == 1 || coarse == 3)
> + fine &= ~1;
> + else if (coarse == 4)
> + fine &= ~3;
> +
> + return (coarse << 4) | (fine & 0xf);
> + }
> +
> + double gain(uint32_t gainCode) const override
> + {
> + unsigned int coarse = gainCode >> 4;
> + unsigned int fine = gainCode & 0xf;
> + unsigned int d1;
> + double d2, m;
> +
> + switch (coarse) {
> + default:
> + case 0:
> + d1 = 1;
> + d2 = 32.0;
> + m = 1.0;
> + break;
> + case 1:
> + d1 = 2;
> + d2 = 16.0;
> + m = 1.0;
> + break;
> + case 2:
> + d1 = 1;
> + d2 = 32.0;
> + m = 1.153125;
> + break;
> + case 3:
> + d1 = 2;
> + d2 = 16.0;
> + m = 1.153125;
> + break;
> + case 4:
> + d1 = 4;
> + d2 = 8.0;
> + m = 1.153125;
> + break;
> + }
> +
> + /*
> + * With infinite precision, the calculated gain would be exact,
> + * and the reverse conversion with gainCode() would produce the
> + * same gain code. In the real world, rounding errors may cause
> + * the calculated gain to be lower by an amount negligible for
> + * all purposes, except for the reverse conversion. Converting
> + * the gain to a gain code could then return the quantized value
> + * just lower than the original gain code. To avoid this, tests
> + * showed that adding the machine epsilon to the multiplier m is
> + * sufficient.
> + */
> + m += std::numeric_limits<decltype(m)>::epsilon();
> +
> + return m * (1 << coarse) / (1.0 - (fine / d1) / d2);
> + }
> +
> +private:
> + static constexpr double kStep_ = 16;
> +};
> +REGISTER_CAMERA_SENSOR_HELPER("ar0144", CameraSensorHelperAr0144)
> +
> class CameraSensorHelperAr0521 : public CameraSensorHelper
> {
> public:
> diff --git a/src/libcamera/sensor/camera_sensor_properties.cpp b/src/libcamera/sensor/camera_sensor_properties.cpp
> index b18524d85b37..4e5217ab51ef 100644
> --- a/src/libcamera/sensor/camera_sensor_properties.cpp
> +++ b/src/libcamera/sensor/camera_sensor_properties.cpp
> @@ -52,6 +52,15 @@ LOG_DEFINE_CATEGORY(CameraSensorProperties)
> const CameraSensorProperties *CameraSensorProperties::get(const std::string &sensor)
> {
> static const std::map<std::string, const CameraSensorProperties> sensorProps = {
> + { "ar0144", {
> + .unitCellSize = { 3000, 3000 },
> + .testPatternModes = {
> + { controls::draft::TestPatternModeOff, 0 },
> + { controls::draft::TestPatternModeSolidColor, 1 },
> + { controls::draft::TestPatternModeColorBars, 2 },
> + { controls::draft::TestPatternModeColorBarsFadeToGray, 3 },
> + },
> + } },
> { "ar0521", {
> .unitCellSize = { 2200, 2200 },
> .testPatternModes = {
>
> base-commit: 196abb8d1d6e0fe9d190315e72a85eb12d16a554
> --
> Regards,
>
> Laurent Pinchart
>
More information about the libcamera-devel
mailing list