Message ID | 20240319151121.561588-3-kieran.bingham@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi Will and Kieran, Thank you for the patch. On Tue, Mar 19, 2024 at 03:11:21PM +0000, Kieran Bingham wrote: > From: Will Whang <will@willwhang.com> > > Add tuning files and camera helpers for the Sony IMX283. > > Signed-off-by: Will Whang <will@willwhang.com> > [Kieran: Fix checkstyle formatting, extend commit message, remove pi5] > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > --- > This is a partial cherry-pick from > https://github.com/raspberrypi/libcamera/pull/118 > > The Pi5 support has not been included, as Pi5 is not yet upstream. > Once Pi5 is submitted, the remaining components from > https://github.com/raspberrypi/libcamera/pull/118 for the IMX283 should > be submitted on top. > > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > --- > src/ipa/rpi/cam_helper/cam_helper_imx283.cpp | 73 +++++ > src/ipa/rpi/cam_helper/meson.build | 1 + > src/ipa/rpi/vc4/data/imx283.json | 320 +++++++++++++++++++ > src/ipa/rpi/vc4/data/meson.build | 1 + > 4 files changed, 395 insertions(+) > create mode 100644 src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > create mode 100644 src/ipa/rpi/vc4/data/imx283.json > > diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > new file mode 100644 > index 000000000000..5674b75466b5 > --- /dev/null > +++ b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > @@ -0,0 +1,73 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > +/* > + * Copyright (C) 2021, Raspberry Pi Ltd > + * > + * cam_helper_imx283.cpp - camera information for imx283 sensor > + */ > + > +#include <assert.h> > + > +#include "cam_helper.h" > +#include "math.h" Missing blank line. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > +using namespace RPiController; > + > +class CamHelperImx283 : public CamHelper > +{ > +public: > + CamHelperImx283(); > + uint32_t gainCode(double gain) const override; > + double gain(uint32_t gainCode) const override; > + void getDelays(int &exposureDelay, int &gainDelay, > + int &vblankDelay, int &hblankDelay) const override; > + unsigned int hideFramesModeSwitch() const override; > + > +private: > + /* > + * Smallest difference between the frame length and integration time, > + * in units of lines. > + */ > + static constexpr int frameIntegrationDiff = 4; > +}; > + > +/* > + * Imx283 doesn't output metadata, so we have to use the "unicam parser" which > + * works by counting frames. > + */ > + > +CamHelperImx283::CamHelperImx283() > + : CamHelper({}, frameIntegrationDiff) > +{ > +} > + > +uint32_t CamHelperImx283::gainCode(double gain) const > +{ > + return static_cast<uint32_t>(2048.0 - 2048.0 / gain); > +} > + > +double CamHelperImx283::gain(uint32_t gainCode) const > +{ > + return static_cast<double>(2048.0 / (2048 - gainCode)); > +} > + > +void CamHelperImx283::getDelays(int &exposureDelay, int &gainDelay, > + int &vblankDelay, int &hblankDelay) const > +{ > + /* The driver appears to behave as follows: */ > + exposureDelay = 2; > + gainDelay = 2; > + vblankDelay = 2; > + hblankDelay = 2; > +} > + > +unsigned int CamHelperImx283::hideFramesModeSwitch() const > +{ > + /* After a mode switch, we seem to get 1 bad frame. */ > + return 1; > +} > + > +static CamHelper *create() > +{ > + return new CamHelperImx283(); > +} > + > +static RegisterCamHelper reg("imx283", &create); > diff --git a/src/ipa/rpi/cam_helper/meson.build b/src/ipa/rpi/cam_helper/meson.build > index 7262505742f3..1e43f1da29cd 100644 > --- a/src/ipa/rpi/cam_helper/meson.build > +++ b/src/ipa/rpi/cam_helper/meson.build > @@ -4,6 +4,7 @@ rpi_ipa_cam_helper_sources = files([ > 'cam_helper.cpp', > 'cam_helper_ov5647.cpp', > 'cam_helper_imx219.cpp', > + 'cam_helper_imx283.cpp', > 'cam_helper_imx290.cpp', > 'cam_helper_imx296.cpp', > 'cam_helper_imx477.cpp', > diff --git a/src/ipa/rpi/vc4/data/imx283.json b/src/ipa/rpi/vc4/data/imx283.json > new file mode 100644 > index 000000000000..20892de19299 > --- /dev/null > +++ b/src/ipa/rpi/vc4/data/imx283.json > @@ -0,0 +1,320 @@ > +{ > + "version": 2.0, > + "target": "bcm2835", > + "algorithms": [ > + { > + "rpi.black_level": > + { > + "black_level": 3200 > + } > + }, > + { > + "rpi.dpc": { } > + }, > + { > + "rpi.lux": > + { > + "reference_shutter_speed": 2461, > + "reference_gain": 1.0, > + "reference_aperture": 1.0, > + "reference_lux": 1148, > + "reference_Y": 13314 > + } > + }, > + { > + "rpi.noise": > + { > + "reference_constant": 0, > + "reference_slope": 2.204 > + } > + }, > + { > + "rpi.geq": > + { > + "offset": 199, > + "slope": 0.01947 > + } > + }, > + { > + "rpi.sdn": { } > + }, > + { > + "rpi.awb": > + { > + "priors": [ > + { > + "lux": 0, > + "prior": > + [ > + 2000, 1.0, > + 3000, 0.0, > + 13000, 0.0 > + ] > + }, > + { > + "lux": 800, > + "prior": > + [ > + 2000, 0.0, > + 6000, 2.0, > + 13000, 2.0 > + ] > + }, > + { > + "lux": 1500, > + "prior": > + [ > + 2000, 0.0, > + 4000, 1.0, > + 6000, 6.0, > + 6500, 7.0, > + 7000, 1.0, > + 13000, 1.0 > + ] > + } > + ], > + "modes": > + { > + "auto": > + { > + "lo": 2500, > + "hi": 8000 > + }, > + "incandescent": > + { > + "lo": 2500, > + "hi": 3000 > + }, > + "tungsten": > + { > + "lo": 3000, > + "hi": 3500 > + }, > + "fluorescent": > + { > + "lo": 4000, > + "hi": 4700 > + }, > + "indoor": > + { > + "lo": 3000, > + "hi": 5000 > + }, > + "daylight": > + { > + "lo": 5500, > + "hi": 6500 > + }, > + "cloudy": > + { > + "lo": 7000, > + "hi": 8600 > + } > + }, > + "bayes": 1, > + "ct_curve": > + [ > + 2213.0, 0.9607, 0.2593, > + 2255.0, 0.9309, 0.2521, > + 2259.0, 0.9257, 0.2508, > + 5313.0, 0.4822, 0.5909, > + 6237.0, 0.4726, 0.6376 > + ], > + "sensitivity_r": 1.0, > + "sensitivity_b": 1.0, > + "transverse_pos": 0.0144, > + "transverse_neg": 0.01 > + } > + }, > + { > + "rpi.agc": > + { > + "metering_modes": > + { > + "centre-weighted": > + { > + "weights": > + [ > + 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0 > + ] > + }, > + "spot": > + { > + "weights": > + [ > + 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 > + ] > + }, > + "matrix": > + { > + "weights": > + [ > + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 > + ] > + } > + }, > + "exposure_modes": > + { > + "normal": > + { > + "shutter": [ 100, 10000, 30000, 60000, 120000 ], > + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] > + }, > + "short": > + { > + "shutter": [ 100, 5000, 10000, 20000, 120000 ], > + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] > + } > + }, > + "constraint_modes": > + { > + "normal": [ > + { > + "bound": "LOWER", > + "q_lo": 0.98, > + "q_hi": 1.0, > + "y_target": > + [ > + 0, 0.5, > + 1000, 0.5 > + ] > + } > + ], > + "highlight": [ > + { > + "bound": "LOWER", > + "q_lo": 0.98, > + "q_hi": 1.0, > + "y_target": > + [ > + 0, 0.5, > + 1000, 0.5 > + ] > + }, > + { > + "bound": "UPPER", > + "q_lo": 0.98, > + "q_hi": 1.0, > + "y_target": > + [ > + 0, 0.8, > + 1000, 0.8 > + ] > + } > + ] > + }, > + "y_target": > + [ > + 0, 0.16, > + 1000, 0.165, > + 10000, 0.17 > + ] > + } > + }, > + { > + "rpi.alsc": > + { > + "omega": 1.3, > + "n_iter": 100, > + "luminance_strength": 0.7 > + } > + }, > + { > + "rpi.contrast": > + { > + "ce_enable": 1, > + "gamma_curve": > + [ > + 0, 0, > + 1024, 5040, > + 2048, 9338, > + 3072, 12356, > + 4096, 15312, > + 5120, 18051, > + 6144, 20790, > + 7168, 23193, > + 8192, 25744, > + 9216, 27942, > + 10240, 30035, > + 11264, 32005, > + 12288, 33975, > + 13312, 35815, > + 14336, 37600, > + 15360, 39168, > + 16384, 40642, > + 18432, 43379, > + 20480, 45749, > + 22528, 47753, > + 24576, 49621, > + 26624, 51253, > + 28672, 52698, > + 30720, 53796, > + 32768, 54876, > + 36864, 57012, > + 40960, 58656, > + 45056, 59954, > + 49152, 61183, > + 53248, 62355, > + 57344, 63419, > + 61440, 64476, > + 65535, 65535 > + ] > + } > + }, > + { > + "rpi.ccm": > + { > + "ccms": [ > + { > + "ct": 2213, > + "ccm": > + [ > + 1.91264, -0.27609, -0.63655, > + -0.65708, 2.11718, -0.46009, > + 0.03629, -1.38441, 2.34811 > + ] > + }, > + { > + "ct": 2255, > + "ccm": > + [ > + 1.90369, -0.29309, -0.61059, > + -0.64693, 2.08169, -0.43476, > + 0.04086, -1.29999, 2.25914 > + ] > + }, > + { > + "ct": 2259, > + "ccm": > + [ > + 1.92762, -0.35134, -0.57628, > + -0.63523, 2.08481, -0.44958, > + 0.06754, -1.32953, 2.26199 > + ] > + }, > + { > + "ct": 5313, > + "ccm": > + [ > + 1.75924, -0.54053, -0.21871, > + -0.38159, 1.88671, -0.50511, > + -0.00747, -0.53492, 1.54239 > + ] > + }, > + { > + "ct": 6237, > + "ccm": > + [ > + 2.19299, -0.74764, -0.44536, > + -0.51678, 2.27651, -0.75972, > + -0.06498, -0.74269, 1.80767 > + ] > + } > + ] > + } > + }, > + { > + "rpi.sharpen": { } > + } > + ] > +} > \ No newline at end of file > diff --git a/src/ipa/rpi/vc4/data/meson.build b/src/ipa/rpi/vc4/data/meson.build > index afbf875a113a..60477c112196 100644 > --- a/src/ipa/rpi/vc4/data/meson.build > +++ b/src/ipa/rpi/vc4/data/meson.build > @@ -3,6 +3,7 @@ > conf_files = files([ > 'imx219.json', > 'imx219_noir.json', > + 'imx283.json', > 'imx290.json', > 'imx296.json', > 'imx296_mono.json',
Hi Will, Thank you for this patch! On Tue, 19 Mar 2024 at 15:11, Kieran Bingham <kieran.bingham@ideasonboard.com> wrote: > > From: Will Whang <will@willwhang.com> > > Add tuning files and camera helpers for the Sony IMX283. > > Signed-off-by: Will Whang <will@willwhang.com> > [Kieran: Fix checkstyle formatting, extend commit message, remove pi5] > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > --- > This is a partial cherry-pick from > https://github.com/raspberrypi/libcamera/pull/118 > > The Pi5 support has not been included, as Pi5 is not yet upstream. > Once Pi5 is submitted, the remaining components from > https://github.com/raspberrypi/libcamera/pull/118 for the IMX283 should > be submitted on top. > > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > --- > src/ipa/rpi/cam_helper/cam_helper_imx283.cpp | 73 +++++ > src/ipa/rpi/cam_helper/meson.build | 1 + > src/ipa/rpi/vc4/data/imx283.json | 320 +++++++++++++++++++ > src/ipa/rpi/vc4/data/meson.build | 1 + > 4 files changed, 395 insertions(+) > create mode 100644 src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > create mode 100644 src/ipa/rpi/vc4/data/imx283.json > > diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > new file mode 100644 > index 000000000000..5674b75466b5 > --- /dev/null > +++ b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > @@ -0,0 +1,73 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > +/* > + * Copyright (C) 2021, Raspberry Pi Ltd > + * > + * cam_helper_imx283.cpp - camera information for imx283 sensor > + */ > + > +#include <assert.h> > + > +#include "cam_helper.h" > +#include "math.h" > +using namespace RPiController; > + > +class CamHelperImx283 : public CamHelper > +{ > +public: > + CamHelperImx283(); > + uint32_t gainCode(double gain) const override; > + double gain(uint32_t gainCode) const override; > + void getDelays(int &exposureDelay, int &gainDelay, > + int &vblankDelay, int &hblankDelay) const override; > + unsigned int hideFramesModeSwitch() const override; > + > +private: > + /* > + * Smallest difference between the frame length and integration time, > + * in units of lines. > + */ > + static constexpr int frameIntegrationDiff = 4; > +}; > + > +/* > + * Imx283 doesn't output metadata, so we have to use the "unicam parser" which > + * works by counting frames. > + */ > + > +CamHelperImx283::CamHelperImx283() > + : CamHelper({}, frameIntegrationDiff) > +{ > +} > + > +uint32_t CamHelperImx283::gainCode(double gain) const > +{ > + return static_cast<uint32_t>(2048.0 - 2048.0 / gain); > +} > + > +double CamHelperImx283::gain(uint32_t gainCode) const > +{ > + return static_cast<double>(2048.0 / (2048 - gainCode)); > +} > + > +void CamHelperImx283::getDelays(int &exposureDelay, int &gainDelay, > + int &vblankDelay, int &hblankDelay) const > +{ > + /* The driver appears to behave as follows: */ > + exposureDelay = 2; > + gainDelay = 2; > + vblankDelay = 2; > + hblankDelay = 2; > +} > + > +unsigned int CamHelperImx283::hideFramesModeSwitch() const > +{ > + /* After a mode switch, we seem to get 1 bad frame. */ > + return 1; > +} > + > +static CamHelper *create() > +{ > + return new CamHelperImx283(); > +} > + > +static RegisterCamHelper reg("imx283", &create); > diff --git a/src/ipa/rpi/cam_helper/meson.build b/src/ipa/rpi/cam_helper/meson.build > index 7262505742f3..1e43f1da29cd 100644 > --- a/src/ipa/rpi/cam_helper/meson.build > +++ b/src/ipa/rpi/cam_helper/meson.build > @@ -4,6 +4,7 @@ rpi_ipa_cam_helper_sources = files([ > 'cam_helper.cpp', > 'cam_helper_ov5647.cpp', > 'cam_helper_imx219.cpp', > + 'cam_helper_imx283.cpp', > 'cam_helper_imx290.cpp', > 'cam_helper_imx296.cpp', > 'cam_helper_imx477.cpp', > diff --git a/src/ipa/rpi/vc4/data/imx283.json b/src/ipa/rpi/vc4/data/imx283.json > new file mode 100644 > index 000000000000..20892de19299 > --- /dev/null > +++ b/src/ipa/rpi/vc4/data/imx283.json > @@ -0,0 +1,320 @@ > +{ > + "version": 2.0, > + "target": "bcm2835", > + "algorithms": [ > + { > + "rpi.black_level": > + { > + "black_level": 3200 > + } > + }, > + { > + "rpi.dpc": { } > + }, > + { > + "rpi.lux": > + { > + "reference_shutter_speed": 2461, > + "reference_gain": 1.0, > + "reference_aperture": 1.0, > + "reference_lux": 1148, > + "reference_Y": 13314 > + } > + }, > + { > + "rpi.noise": > + { > + "reference_constant": 0, > + "reference_slope": 2.204 > + } > + }, > + { > + "rpi.geq": > + { > + "offset": 199, > + "slope": 0.01947 > + } > + }, > + { > + "rpi.sdn": { } > + }, > + { > + "rpi.awb": > + { > + "priors": [ > + { > + "lux": 0, > + "prior": > + [ > + 2000, 1.0, > + 3000, 0.0, > + 13000, 0.0 > + ] > + }, > + { > + "lux": 800, > + "prior": > + [ > + 2000, 0.0, > + 6000, 2.0, > + 13000, 2.0 > + ] > + }, > + { > + "lux": 1500, > + "prior": > + [ > + 2000, 0.0, > + 4000, 1.0, > + 6000, 6.0, > + 6500, 7.0, > + 7000, 1.0, > + 13000, 1.0 > + ] > + } > + ], > + "modes": > + { > + "auto": > + { > + "lo": 2500, > + "hi": 8000 > + }, > + "incandescent": > + { > + "lo": 2500, > + "hi": 3000 > + }, > + "tungsten": > + { > + "lo": 3000, > + "hi": 3500 > + }, > + "fluorescent": > + { > + "lo": 4000, > + "hi": 4700 > + }, > + "indoor": > + { > + "lo": 3000, > + "hi": 5000 > + }, > + "daylight": > + { > + "lo": 5500, > + "hi": 6500 > + }, > + "cloudy": > + { > + "lo": 7000, > + "hi": 8600 > + } > + }, > + "bayes": 1, > + "ct_curve": > + [ > + 2213.0, 0.9607, 0.2593, > + 2255.0, 0.9309, 0.2521, > + 2259.0, 0.9257, 0.2508, > + 5313.0, 0.4822, 0.5909, > + 6237.0, 0.4726, 0.6376 > + ], This is a quirk of our tuning tool (and we should really fix it), but the CT curve has a range of approx. 2215K - 6235K. The AWB modes above should really be constrained to this range, or the search could jump to a bad target and give invalid results. This only impacts the "cloudy" awb mode. Perhaps it's best to leave that out? Naush > + "sensitivity_r": 1.0, > + "sensitivity_b": 1.0, > + "transverse_pos": 0.0144, > + "transverse_neg": 0.01 > + } > + }, > + { > + "rpi.agc": > + { > + "metering_modes": > + { > + "centre-weighted": > + { > + "weights": > + [ > + 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0 > + ] > + }, > + "spot": > + { > + "weights": > + [ > + 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 > + ] > + }, > + "matrix": > + { > + "weights": > + [ > + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 > + ] > + } > + }, > + "exposure_modes": > + { > + "normal": > + { > + "shutter": [ 100, 10000, 30000, 60000, 120000 ], > + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] > + }, > + "short": > + { > + "shutter": [ 100, 5000, 10000, 20000, 120000 ], > + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] > + } > + }, > + "constraint_modes": > + { > + "normal": [ > + { > + "bound": "LOWER", > + "q_lo": 0.98, > + "q_hi": 1.0, > + "y_target": > + [ > + 0, 0.5, > + 1000, 0.5 > + ] > + } > + ], > + "highlight": [ > + { > + "bound": "LOWER", > + "q_lo": 0.98, > + "q_hi": 1.0, > + "y_target": > + [ > + 0, 0.5, > + 1000, 0.5 > + ] > + }, > + { > + "bound": "UPPER", > + "q_lo": 0.98, > + "q_hi": 1.0, > + "y_target": > + [ > + 0, 0.8, > + 1000, 0.8 > + ] > + } > + ] > + }, > + "y_target": > + [ > + 0, 0.16, > + 1000, 0.165, > + 10000, 0.17 > + ] > + } > + }, > + { > + "rpi.alsc": > + { > + "omega": 1.3, > + "n_iter": 100, > + "luminance_strength": 0.7 > + } > + }, > + { > + "rpi.contrast": > + { > + "ce_enable": 1, > + "gamma_curve": > + [ > + 0, 0, > + 1024, 5040, > + 2048, 9338, > + 3072, 12356, > + 4096, 15312, > + 5120, 18051, > + 6144, 20790, > + 7168, 23193, > + 8192, 25744, > + 9216, 27942, > + 10240, 30035, > + 11264, 32005, > + 12288, 33975, > + 13312, 35815, > + 14336, 37600, > + 15360, 39168, > + 16384, 40642, > + 18432, 43379, > + 20480, 45749, > + 22528, 47753, > + 24576, 49621, > + 26624, 51253, > + 28672, 52698, > + 30720, 53796, > + 32768, 54876, > + 36864, 57012, > + 40960, 58656, > + 45056, 59954, > + 49152, 61183, > + 53248, 62355, > + 57344, 63419, > + 61440, 64476, > + 65535, 65535 > + ] > + } > + }, > + { > + "rpi.ccm": > + { > + "ccms": [ > + { > + "ct": 2213, > + "ccm": > + [ > + 1.91264, -0.27609, -0.63655, > + -0.65708, 2.11718, -0.46009, > + 0.03629, -1.38441, 2.34811 > + ] > + }, > + { > + "ct": 2255, > + "ccm": > + [ > + 1.90369, -0.29309, -0.61059, > + -0.64693, 2.08169, -0.43476, > + 0.04086, -1.29999, 2.25914 > + ] > + }, > + { > + "ct": 2259, > + "ccm": > + [ > + 1.92762, -0.35134, -0.57628, > + -0.63523, 2.08481, -0.44958, > + 0.06754, -1.32953, 2.26199 > + ] > + }, > + { > + "ct": 5313, > + "ccm": > + [ > + 1.75924, -0.54053, -0.21871, > + -0.38159, 1.88671, -0.50511, > + -0.00747, -0.53492, 1.54239 > + ] > + }, > + { > + "ct": 6237, > + "ccm": > + [ > + 2.19299, -0.74764, -0.44536, > + -0.51678, 2.27651, -0.75972, > + -0.06498, -0.74269, 1.80767 > + ] > + } > + ] > + } > + }, > + { > + "rpi.sharpen": { } > + } > + ] > +} > \ No newline at end of file > diff --git a/src/ipa/rpi/vc4/data/meson.build b/src/ipa/rpi/vc4/data/meson.build > index afbf875a113a..60477c112196 100644 > --- a/src/ipa/rpi/vc4/data/meson.build > +++ b/src/ipa/rpi/vc4/data/meson.build > @@ -3,6 +3,7 @@ > conf_files = files([ > 'imx219.json', > 'imx219_noir.json', > + 'imx283.json', > 'imx290.json', > 'imx296.json', > 'imx296_mono.json', > -- > 2.34.1 >
Hi Naushir, I can update the calibration file later this week with the cloudy weather coming up : D. I thought the CT curve can extrapolate over the existing range, but if not I can try to covers it. Thanks, Wei-Chun Naushir Patuck <naush@raspberrypi.com> 於 2024年3月20日 週三 上午2:22寫道: > Hi Will, > > Thank you for this patch! > > On Tue, 19 Mar 2024 at 15:11, Kieran Bingham > <kieran.bingham@ideasonboard.com> wrote: > > > > From: Will Whang <will@willwhang.com> > > > > Add tuning files and camera helpers for the Sony IMX283. > > > > Signed-off-by: Will Whang <will@willwhang.com> > > [Kieran: Fix checkstyle formatting, extend commit message, remove pi5] > > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > > > --- > > This is a partial cherry-pick from > > https://github.com/raspberrypi/libcamera/pull/118 > > > > The Pi5 support has not been included, as Pi5 is not yet upstream. > > Once Pi5 is submitted, the remaining components from > > https://github.com/raspberrypi/libcamera/pull/118 for the IMX283 should > > be submitted on top. > > > > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > --- > > src/ipa/rpi/cam_helper/cam_helper_imx283.cpp | 73 +++++ > > src/ipa/rpi/cam_helper/meson.build | 1 + > > src/ipa/rpi/vc4/data/imx283.json | 320 +++++++++++++++++++ > > src/ipa/rpi/vc4/data/meson.build | 1 + > > 4 files changed, 395 insertions(+) > > create mode 100644 src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > > create mode 100644 src/ipa/rpi/vc4/data/imx283.json > > > > diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > > new file mode 100644 > > index 000000000000..5674b75466b5 > > --- /dev/null > > +++ b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp > > @@ -0,0 +1,73 @@ > > +/* SPDX-License-Identifier: BSD-2-Clause */ > > +/* > > + * Copyright (C) 2021, Raspberry Pi Ltd > > + * > > + * cam_helper_imx283.cpp - camera information for imx283 sensor > > + */ > > + > > +#include <assert.h> > > + > > +#include "cam_helper.h" > > +#include "math.h" > > +using namespace RPiController; > > + > > +class CamHelperImx283 : public CamHelper > > +{ > > +public: > > + CamHelperImx283(); > > + uint32_t gainCode(double gain) const override; > > + double gain(uint32_t gainCode) const override; > > + void getDelays(int &exposureDelay, int &gainDelay, > > + int &vblankDelay, int &hblankDelay) const > override; > > + unsigned int hideFramesModeSwitch() const override; > > + > > +private: > > + /* > > + * Smallest difference between the frame length and integration > time, > > + * in units of lines. > > + */ > > + static constexpr int frameIntegrationDiff = 4; > > +}; > > + > > +/* > > + * Imx283 doesn't output metadata, so we have to use the "unicam > parser" which > > + * works by counting frames. > > + */ > > + > > +CamHelperImx283::CamHelperImx283() > > + : CamHelper({}, frameIntegrationDiff) > > +{ > > +} > > + > > +uint32_t CamHelperImx283::gainCode(double gain) const > > +{ > > + return static_cast<uint32_t>(2048.0 - 2048.0 / gain); > > +} > > + > > +double CamHelperImx283::gain(uint32_t gainCode) const > > +{ > > + return static_cast<double>(2048.0 / (2048 - gainCode)); > > +} > > + > > +void CamHelperImx283::getDelays(int &exposureDelay, int &gainDelay, > > + int &vblankDelay, int &hblankDelay) const > > +{ > > + /* The driver appears to behave as follows: */ > > + exposureDelay = 2; > > + gainDelay = 2; > > + vblankDelay = 2; > > + hblankDelay = 2; > > +} > > + > > +unsigned int CamHelperImx283::hideFramesModeSwitch() const > > +{ > > + /* After a mode switch, we seem to get 1 bad frame. */ > > + return 1; > > +} > > + > > +static CamHelper *create() > > +{ > > + return new CamHelperImx283(); > > +} > > + > > +static RegisterCamHelper reg("imx283", &create); > > diff --git a/src/ipa/rpi/cam_helper/meson.build > b/src/ipa/rpi/cam_helper/meson.build > > index 7262505742f3..1e43f1da29cd 100644 > > --- a/src/ipa/rpi/cam_helper/meson.build > > +++ b/src/ipa/rpi/cam_helper/meson.build > > @@ -4,6 +4,7 @@ rpi_ipa_cam_helper_sources = files([ > > 'cam_helper.cpp', > > 'cam_helper_ov5647.cpp', > > 'cam_helper_imx219.cpp', > > + 'cam_helper_imx283.cpp', > > 'cam_helper_imx290.cpp', > > 'cam_helper_imx296.cpp', > > 'cam_helper_imx477.cpp', > > diff --git a/src/ipa/rpi/vc4/data/imx283.json > b/src/ipa/rpi/vc4/data/imx283.json > > new file mode 100644 > > index 000000000000..20892de19299 > > --- /dev/null > > +++ b/src/ipa/rpi/vc4/data/imx283.json > > @@ -0,0 +1,320 @@ > > +{ > > + "version": 2.0, > > + "target": "bcm2835", > > + "algorithms": [ > > + { > > + "rpi.black_level": > > + { > > + "black_level": 3200 > > + } > > + }, > > + { > > + "rpi.dpc": { } > > + }, > > + { > > + "rpi.lux": > > + { > > + "reference_shutter_speed": 2461, > > + "reference_gain": 1.0, > > + "reference_aperture": 1.0, > > + "reference_lux": 1148, > > + "reference_Y": 13314 > > + } > > + }, > > + { > > + "rpi.noise": > > + { > > + "reference_constant": 0, > > + "reference_slope": 2.204 > > + } > > + }, > > + { > > + "rpi.geq": > > + { > > + "offset": 199, > > + "slope": 0.01947 > > + } > > + }, > > + { > > + "rpi.sdn": { } > > + }, > > + { > > + "rpi.awb": > > + { > > + "priors": [ > > + { > > + "lux": 0, > > + "prior": > > + [ > > + 2000, 1.0, > > + 3000, 0.0, > > + 13000, 0.0 > > + ] > > + }, > > + { > > + "lux": 800, > > + "prior": > > + [ > > + 2000, 0.0, > > + 6000, 2.0, > > + 13000, 2.0 > > + ] > > + }, > > + { > > + "lux": 1500, > > + "prior": > > + [ > > + 2000, 0.0, > > + 4000, 1.0, > > + 6000, 6.0, > > + 6500, 7.0, > > + 7000, 1.0, > > + 13000, 1.0 > > + ] > > + } > > + ], > > + "modes": > > + { > > + "auto": > > + { > > + "lo": 2500, > > + "hi": 8000 > > + }, > > + "incandescent": > > + { > > + "lo": 2500, > > + "hi": 3000 > > + }, > > + "tungsten": > > + { > > + "lo": 3000, > > + "hi": 3500 > > + }, > > + "fluorescent": > > + { > > + "lo": 4000, > > + "hi": 4700 > > + }, > > + "indoor": > > + { > > + "lo": 3000, > > + "hi": 5000 > > + }, > > + "daylight": > > + { > > + "lo": 5500, > > + "hi": 6500 > > + }, > > + "cloudy": > > + { > > + "lo": 7000, > > + "hi": 8600 > > + } > > + }, > > + "bayes": 1, > > + "ct_curve": > > + [ > > + 2213.0, 0.9607, 0.2593, > > + 2255.0, 0.9309, 0.2521, > > + 2259.0, 0.9257, 0.2508, > > + 5313.0, 0.4822, 0.5909, > > + 6237.0, 0.4726, 0.6376 > > + ], > > This is a quirk of our tuning tool (and we should really fix it), but > the CT curve has a range of approx. 2215K - 6235K. The AWB modes > above should really be constrained to this range, or the search could > jump to a bad target and give invalid results. This only impacts the > "cloudy" awb mode. Perhaps it's best to leave that out? > > Naush > > > > + "sensitivity_r": 1.0, > > + "sensitivity_b": 1.0, > > + "transverse_pos": 0.0144, > > + "transverse_neg": 0.01 > > + } > > + }, > > + { > > + "rpi.agc": > > + { > > + "metering_modes": > > + { > > + "centre-weighted": > > + { > > + "weights": > > + [ > > + 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0 > > + ] > > + }, > > + "spot": > > + { > > + "weights": > > + [ > > + 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 > > + ] > > + }, > > + "matrix": > > + { > > + "weights": > > + [ > > + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 > > + ] > > + } > > + }, > > + "exposure_modes": > > + { > > + "normal": > > + { > > + "shutter": [ 100, 10000, 30000, 60000, 120000 ], > > + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] > > + }, > > + "short": > > + { > > + "shutter": [ 100, 5000, 10000, 20000, 120000 ], > > + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] > > + } > > + }, > > + "constraint_modes": > > + { > > + "normal": [ > > + { > > + "bound": "LOWER", > > + "q_lo": 0.98, > > + "q_hi": 1.0, > > + "y_target": > > + [ > > + 0, 0.5, > > + 1000, 0.5 > > + ] > > + } > > + ], > > + "highlight": [ > > + { > > + "bound": "LOWER", > > + "q_lo": 0.98, > > + "q_hi": 1.0, > > + "y_target": > > + [ > > + 0, 0.5, > > + 1000, 0.5 > > + ] > > + }, > > + { > > + "bound": "UPPER", > > + "q_lo": 0.98, > > + "q_hi": 1.0, > > + "y_target": > > + [ > > + 0, 0.8, > > + 1000, 0.8 > > + ] > > + } > > + ] > > + }, > > + "y_target": > > + [ > > + 0, 0.16, > > + 1000, 0.165, > > + 10000, 0.17 > > + ] > > + } > > + }, > > + { > > + "rpi.alsc": > > + { > > + "omega": 1.3, > > + "n_iter": 100, > > + "luminance_strength": 0.7 > > + } > > + }, > > + { > > + "rpi.contrast": > > + { > > + "ce_enable": 1, > > + "gamma_curve": > > + [ > > + 0, 0, > > + 1024, 5040, > > + 2048, 9338, > > + 3072, 12356, > > + 4096, 15312, > > + 5120, 18051, > > + 6144, 20790, > > + 7168, 23193, > > + 8192, 25744, > > + 9216, 27942, > > + 10240, 30035, > > + 11264, 32005, > > + 12288, 33975, > > + 13312, 35815, > > + 14336, 37600, > > + 15360, 39168, > > + 16384, 40642, > > + 18432, 43379, > > + 20480, 45749, > > + 22528, 47753, > > + 24576, 49621, > > + 26624, 51253, > > + 28672, 52698, > > + 30720, 53796, > > + 32768, 54876, > > + 36864, 57012, > > + 40960, 58656, > > + 45056, 59954, > > + 49152, 61183, > > + 53248, 62355, > > + 57344, 63419, > > + 61440, 64476, > > + 65535, 65535 > > + ] > > + } > > + }, > > + { > > + "rpi.ccm": > > + { > > + "ccms": [ > > + { > > + "ct": 2213, > > + "ccm": > > + [ > > + 1.91264, -0.27609, -0.63655, > > + -0.65708, 2.11718, -0.46009, > > + 0.03629, -1.38441, 2.34811 > > + ] > > + }, > > + { > > + "ct": 2255, > > + "ccm": > > + [ > > + 1.90369, -0.29309, -0.61059, > > + -0.64693, 2.08169, -0.43476, > > + 0.04086, -1.29999, 2.25914 > > + ] > > + }, > > + { > > + "ct": 2259, > > + "ccm": > > + [ > > + 1.92762, -0.35134, -0.57628, > > + -0.63523, 2.08481, -0.44958, > > + 0.06754, -1.32953, 2.26199 > > + ] > > + }, > > + { > > + "ct": 5313, > > + "ccm": > > + [ > > + 1.75924, -0.54053, -0.21871, > > + -0.38159, 1.88671, -0.50511, > > + -0.00747, -0.53492, 1.54239 > > + ] > > + }, > > + { > > + "ct": 6237, > > + "ccm": > > + [ > > + 2.19299, -0.74764, -0.44536, > > + -0.51678, 2.27651, -0.75972, > > + -0.06498, -0.74269, 1.80767 > > + ] > > + } > > + ] > > + } > > + }, > > + { > > + "rpi.sharpen": { } > > + } > > + ] > > +} > > \ No newline at end of file > > diff --git a/src/ipa/rpi/vc4/data/meson.build > b/src/ipa/rpi/vc4/data/meson.build > > index afbf875a113a..60477c112196 100644 > > --- a/src/ipa/rpi/vc4/data/meson.build > > +++ b/src/ipa/rpi/vc4/data/meson.build > > @@ -3,6 +3,7 @@ > > conf_files = files([ > > 'imx219.json', > > 'imx219_noir.json', > > + 'imx283.json', > > 'imx290.json', > > 'imx296.json', > > 'imx296_mono.json', > > -- > > 2.34.1 > > >
diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp new file mode 100644 index 000000000000..5674b75466b5 --- /dev/null +++ b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2021, Raspberry Pi Ltd + * + * cam_helper_imx283.cpp - camera information for imx283 sensor + */ + +#include <assert.h> + +#include "cam_helper.h" +#include "math.h" +using namespace RPiController; + +class CamHelperImx283 : public CamHelper +{ +public: + CamHelperImx283(); + uint32_t gainCode(double gain) const override; + double gain(uint32_t gainCode) const override; + void getDelays(int &exposureDelay, int &gainDelay, + int &vblankDelay, int &hblankDelay) const override; + unsigned int hideFramesModeSwitch() const override; + +private: + /* + * Smallest difference between the frame length and integration time, + * in units of lines. + */ + static constexpr int frameIntegrationDiff = 4; +}; + +/* + * Imx283 doesn't output metadata, so we have to use the "unicam parser" which + * works by counting frames. + */ + +CamHelperImx283::CamHelperImx283() + : CamHelper({}, frameIntegrationDiff) +{ +} + +uint32_t CamHelperImx283::gainCode(double gain) const +{ + return static_cast<uint32_t>(2048.0 - 2048.0 / gain); +} + +double CamHelperImx283::gain(uint32_t gainCode) const +{ + return static_cast<double>(2048.0 / (2048 - gainCode)); +} + +void CamHelperImx283::getDelays(int &exposureDelay, int &gainDelay, + int &vblankDelay, int &hblankDelay) const +{ + /* The driver appears to behave as follows: */ + exposureDelay = 2; + gainDelay = 2; + vblankDelay = 2; + hblankDelay = 2; +} + +unsigned int CamHelperImx283::hideFramesModeSwitch() const +{ + /* After a mode switch, we seem to get 1 bad frame. */ + return 1; +} + +static CamHelper *create() +{ + return new CamHelperImx283(); +} + +static RegisterCamHelper reg("imx283", &create); diff --git a/src/ipa/rpi/cam_helper/meson.build b/src/ipa/rpi/cam_helper/meson.build index 7262505742f3..1e43f1da29cd 100644 --- a/src/ipa/rpi/cam_helper/meson.build +++ b/src/ipa/rpi/cam_helper/meson.build @@ -4,6 +4,7 @@ rpi_ipa_cam_helper_sources = files([ 'cam_helper.cpp', 'cam_helper_ov5647.cpp', 'cam_helper_imx219.cpp', + 'cam_helper_imx283.cpp', 'cam_helper_imx290.cpp', 'cam_helper_imx296.cpp', 'cam_helper_imx477.cpp', diff --git a/src/ipa/rpi/vc4/data/imx283.json b/src/ipa/rpi/vc4/data/imx283.json new file mode 100644 index 000000000000..20892de19299 --- /dev/null +++ b/src/ipa/rpi/vc4/data/imx283.json @@ -0,0 +1,320 @@ +{ + "version": 2.0, + "target": "bcm2835", + "algorithms": [ + { + "rpi.black_level": + { + "black_level": 3200 + } + }, + { + "rpi.dpc": { } + }, + { + "rpi.lux": + { + "reference_shutter_speed": 2461, + "reference_gain": 1.0, + "reference_aperture": 1.0, + "reference_lux": 1148, + "reference_Y": 13314 + } + }, + { + "rpi.noise": + { + "reference_constant": 0, + "reference_slope": 2.204 + } + }, + { + "rpi.geq": + { + "offset": 199, + "slope": 0.01947 + } + }, + { + "rpi.sdn": { } + }, + { + "rpi.awb": + { + "priors": [ + { + "lux": 0, + "prior": + [ + 2000, 1.0, + 3000, 0.0, + 13000, 0.0 + ] + }, + { + "lux": 800, + "prior": + [ + 2000, 0.0, + 6000, 2.0, + 13000, 2.0 + ] + }, + { + "lux": 1500, + "prior": + [ + 2000, 0.0, + 4000, 1.0, + 6000, 6.0, + 6500, 7.0, + 7000, 1.0, + 13000, 1.0 + ] + } + ], + "modes": + { + "auto": + { + "lo": 2500, + "hi": 8000 + }, + "incandescent": + { + "lo": 2500, + "hi": 3000 + }, + "tungsten": + { + "lo": 3000, + "hi": 3500 + }, + "fluorescent": + { + "lo": 4000, + "hi": 4700 + }, + "indoor": + { + "lo": 3000, + "hi": 5000 + }, + "daylight": + { + "lo": 5500, + "hi": 6500 + }, + "cloudy": + { + "lo": 7000, + "hi": 8600 + } + }, + "bayes": 1, + "ct_curve": + [ + 2213.0, 0.9607, 0.2593, + 2255.0, 0.9309, 0.2521, + 2259.0, 0.9257, 0.2508, + 5313.0, 0.4822, 0.5909, + 6237.0, 0.4726, 0.6376 + ], + "sensitivity_r": 1.0, + "sensitivity_b": 1.0, + "transverse_pos": 0.0144, + "transverse_neg": 0.01 + } + }, + { + "rpi.agc": + { + "metering_modes": + { + "centre-weighted": + { + "weights": + [ + 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0 + ] + }, + "spot": + { + "weights": + [ + 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ] + }, + "matrix": + { + "weights": + [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ] + } + }, + "exposure_modes": + { + "normal": + { + "shutter": [ 100, 10000, 30000, 60000, 120000 ], + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] + }, + "short": + { + "shutter": [ 100, 5000, 10000, 20000, 120000 ], + "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ] + } + }, + "constraint_modes": + { + "normal": [ + { + "bound": "LOWER", + "q_lo": 0.98, + "q_hi": 1.0, + "y_target": + [ + 0, 0.5, + 1000, 0.5 + ] + } + ], + "highlight": [ + { + "bound": "LOWER", + "q_lo": 0.98, + "q_hi": 1.0, + "y_target": + [ + 0, 0.5, + 1000, 0.5 + ] + }, + { + "bound": "UPPER", + "q_lo": 0.98, + "q_hi": 1.0, + "y_target": + [ + 0, 0.8, + 1000, 0.8 + ] + } + ] + }, + "y_target": + [ + 0, 0.16, + 1000, 0.165, + 10000, 0.17 + ] + } + }, + { + "rpi.alsc": + { + "omega": 1.3, + "n_iter": 100, + "luminance_strength": 0.7 + } + }, + { + "rpi.contrast": + { + "ce_enable": 1, + "gamma_curve": + [ + 0, 0, + 1024, 5040, + 2048, 9338, + 3072, 12356, + 4096, 15312, + 5120, 18051, + 6144, 20790, + 7168, 23193, + 8192, 25744, + 9216, 27942, + 10240, 30035, + 11264, 32005, + 12288, 33975, + 13312, 35815, + 14336, 37600, + 15360, 39168, + 16384, 40642, + 18432, 43379, + 20480, 45749, + 22528, 47753, + 24576, 49621, + 26624, 51253, + 28672, 52698, + 30720, 53796, + 32768, 54876, + 36864, 57012, + 40960, 58656, + 45056, 59954, + 49152, 61183, + 53248, 62355, + 57344, 63419, + 61440, 64476, + 65535, 65535 + ] + } + }, + { + "rpi.ccm": + { + "ccms": [ + { + "ct": 2213, + "ccm": + [ + 1.91264, -0.27609, -0.63655, + -0.65708, 2.11718, -0.46009, + 0.03629, -1.38441, 2.34811 + ] + }, + { + "ct": 2255, + "ccm": + [ + 1.90369, -0.29309, -0.61059, + -0.64693, 2.08169, -0.43476, + 0.04086, -1.29999, 2.25914 + ] + }, + { + "ct": 2259, + "ccm": + [ + 1.92762, -0.35134, -0.57628, + -0.63523, 2.08481, -0.44958, + 0.06754, -1.32953, 2.26199 + ] + }, + { + "ct": 5313, + "ccm": + [ + 1.75924, -0.54053, -0.21871, + -0.38159, 1.88671, -0.50511, + -0.00747, -0.53492, 1.54239 + ] + }, + { + "ct": 6237, + "ccm": + [ + 2.19299, -0.74764, -0.44536, + -0.51678, 2.27651, -0.75972, + -0.06498, -0.74269, 1.80767 + ] + } + ] + } + }, + { + "rpi.sharpen": { } + } + ] +} \ No newline at end of file diff --git a/src/ipa/rpi/vc4/data/meson.build b/src/ipa/rpi/vc4/data/meson.build index afbf875a113a..60477c112196 100644 --- a/src/ipa/rpi/vc4/data/meson.build +++ b/src/ipa/rpi/vc4/data/meson.build @@ -3,6 +3,7 @@ conf_files = files([ 'imx219.json', 'imx219_noir.json', + 'imx283.json', 'imx290.json', 'imx296.json', 'imx296_mono.json',