Message ID | 20211020132334.2199-2-david.plowman@raspberrypi.com |
---|---|
State | Accepted |
Commit | 5004d8a969330c52449e6840bbef6552cfa8ee1a |
Headers | show |
Series |
|
Related | show |
Hi Lee and David, Thank you for your work. On Wed, 20 Oct 2021 at 14:23, David Plowman <david.plowman@raspberrypi.com> wrote: > From: Arducam info <info@arducam.com> > > The necessary tuning file and CamHelper is added for the imx519 sensor. > > The imx519 is a 16MP rolling shutter sensor. To enable > it, please add > > dtoverlay=imx519 > > to the /boot/config.txt file and reboot the Pi. > > Signed-off-by: Lee Jackson <info@arducam.com> > Reviewed-by: David Plowman <david.plowman@raspberrypi.com> > Reviewed-by: Naushir Patuck <naush@raspberrypi.com> > > --- > src/ipa/raspberrypi/cam_helper_imx519.cpp | 185 ++++++++++++ > src/ipa/raspberrypi/data/imx519.json | 338 ++++++++++++++++++++++ > src/ipa/raspberrypi/data/meson.build | 1 + > src/ipa/raspberrypi/meson.build | 1 + > 4 files changed, 525 insertions(+) > create mode 100644 src/ipa/raspberrypi/cam_helper_imx519.cpp > create mode 100644 src/ipa/raspberrypi/data/imx519.json > > diff --git a/src/ipa/raspberrypi/cam_helper_imx519.cpp > b/src/ipa/raspberrypi/cam_helper_imx519.cpp > new file mode 100644 > index 00000000..eaf24982 > --- /dev/null > +++ b/src/ipa/raspberrypi/cam_helper_imx519.cpp > @@ -0,0 +1,185 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > +/* > + * Based on cam_helper_imx477.cpp > + * Copyright (C) 2020, Raspberry Pi (Trading) Limited > + * > + * cam_helper_imx519.cpp - camera helper for imx519 sensor > + * Copyright (C) 2021, Arducam Technology co., Ltd. > + */ > + > +#include <assert.h> > +#include <cmath> > +#include <stddef.h> > +#include <stdio.h> > +#include <stdlib.h> > + > +#include <libcamera/base/log.h> > + > +#include "cam_helper.hpp" > +#include "md_parser.hpp" > + > +using namespace RPiController; > +using namespace libcamera; > +using libcamera::utils::Duration; > + > +namespace libcamera { > +LOG_DECLARE_CATEGORY(IPARPI) > +} > + > +/* > + * We care about two gain registers and a pair of exposure registers. > Their > + * I2C addresses from the Sony IMX519 datasheet: > + */ > +constexpr uint32_t expHiReg = 0x0202; > +constexpr uint32_t expLoReg = 0x0203; > +constexpr uint32_t gainHiReg = 0x0204; > +constexpr uint32_t gainLoReg = 0x0205; > +constexpr uint32_t frameLengthHiReg = 0x0340; > +constexpr uint32_t frameLengthLoReg = 0x0341; > +constexpr std::initializer_list<uint32_t> registerList = > + { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, > frameLengthLoReg }; > + > +class CamHelperImx519 : public CamHelper > +{ > +public: > + CamHelperImx519(); > + uint32_t GainCode(double gain) const override; > + double Gain(uint32_t gain_code) const override; > + void Prepare(libcamera::Span<const uint8_t> buffer, Metadata > &metadata) override; > + uint32_t GetVBlanking(Duration &exposure, Duration > minFrameDuration, > + Duration maxFrameDuration) const override; > + void GetDelays(int &exposure_delay, int &gain_delay, > + int &vblank_delay) const override; > + bool SensorEmbeddedDataPresent() const override; > + > +private: > + /* > + * Smallest difference between the frame length and integration > time, > + * in units of lines. > + */ > + static constexpr int frameIntegrationDiff = 32; > + /* Maximum frame length allowable for long exposure calculations. > */ > + static constexpr int frameLengthMax = 0xffdc; > + /* Largest long exposure scale factor given as a left shift on the > frame length. */ > + static constexpr int longExposureShiftMax = 7; > + > + void PopulateMetadata(const MdParser::RegisterMap ®isters, > + Metadata &metadata) const override; > +}; > + > +CamHelperImx519::CamHelperImx519() > + : CamHelper(std::make_unique<MdParserSmia>(registerList), > frameIntegrationDiff) > +{ > +} > + > +uint32_t CamHelperImx519::GainCode(double gain) const > +{ > + return static_cast<uint32_t>(1024 - 1024 / gain); > +} > + > +double CamHelperImx519::Gain(uint32_t gain_code) const > +{ > + return 1024.0 / (1024 - gain_code); > +} > + > +void CamHelperImx519::Prepare(libcamera::Span<const uint8_t> buffer, > Metadata &metadata) > +{ > + MdParser::RegisterMap registers; > + DeviceStatus deviceStatus; > + > + if (metadata.Get("device.status", deviceStatus)) { > + LOG(IPARPI, Error) << "DeviceStatus not found from > DelayedControls"; > + return; > + } > + > + parseEmbeddedData(buffer, metadata); > + > + /* > + * The DeviceStatus struct is first populated with values obtained > from > + * DelayedControls. If this reports frame length is > > frameLengthMax, > + * it means we are using a long exposure mode. Since the long > exposure > + * scale factor is not returned back through embedded data, we > must rely > + * on the existing exposure lines and frame length values returned > by > + * DelayedControls. > + * > + * Otherwise, all values are updated with what is reported in the > + * embedded data. > + */ > + if (deviceStatus.frame_length > frameLengthMax) { > + DeviceStatus parsedDeviceStatus; > + > + metadata.Get("device.status", parsedDeviceStatus); > + parsedDeviceStatus.shutter_speed = > deviceStatus.shutter_speed; > + parsedDeviceStatus.frame_length = > deviceStatus.frame_length; > + metadata.Set("device.status", parsedDeviceStatus); > + > + LOG(IPARPI, Debug) << "Metadata updated for long exposure: > " > + << parsedDeviceStatus; > + } > +} > + > +uint32_t CamHelperImx519::GetVBlanking(Duration &exposure, > + Duration minFrameDuration, > + Duration maxFrameDuration) const > +{ > + uint32_t frameLength, exposureLines; > + unsigned int shift = 0; > + > + frameLength = mode_.height + CamHelper::GetVBlanking(exposure, > minFrameDuration, > + > maxFrameDuration); > + /* > + * Check if the frame length calculated needs to be setup for long > + * exposure mode. This will require us to use a long exposure scale > + * factor provided by a shift operation in the sensor. > + */ > + while (frameLength > frameLengthMax) { > + if (++shift > longExposureShiftMax) { > + shift = longExposureShiftMax; > + frameLength = frameLengthMax; > + break; > + } > + frameLength >>= 1; > + } > + > + if (shift) { > + /* Account for any rounding in the scaled frame length > value. */ > + frameLength <<= shift; > + exposureLines = ExposureLines(exposure); > + exposureLines = std::min(exposureLines, frameLength - > frameIntegrationDiff); > + exposure = Exposure(exposureLines); > + } > + > + return frameLength - mode_.height; > +} > + > +void CamHelperImx519::GetDelays(int &exposure_delay, int &gain_delay, > + int &vblank_delay) const > +{ > + exposure_delay = 2; > + gain_delay = 2; > + vblank_delay = 3; > +} > + > +bool CamHelperImx519::SensorEmbeddedDataPresent() const > +{ > + return true; > +} > + > +void CamHelperImx519::PopulateMetadata(const MdParser::RegisterMap > ®isters, > + Metadata &metadata) const > +{ > + DeviceStatus deviceStatus; > + > + deviceStatus.shutter_speed = Exposure(registers.at(expHiReg) * > 256 + registers.at(expLoReg)); > + deviceStatus.analogue_gain = Gain(registers.at(gainHiReg) * 256 + > registers.at(gainLoReg)); > + deviceStatus.frame_length = registers.at(frameLengthHiReg) * 256 > + registers.at(frameLengthLoReg); > + > + metadata.Set("device.status", deviceStatus); > +} > + > +static CamHelper *Create() > +{ > + return new CamHelperImx519(); > +} > + > +static RegisterCamHelper reg("imx519", &Create); > diff --git a/src/ipa/raspberrypi/data/imx519.json > b/src/ipa/raspberrypi/data/imx519.json > new file mode 100644 > index 00000000..164d0d9d > --- /dev/null > +++ b/src/ipa/raspberrypi/data/imx519.json > @@ -0,0 +1,338 @@ > +{ > + "rpi.black_level": > + { > + "black_level": 4096 > + }, > + "rpi.dpc": > + { > + }, > + "rpi.lux": > + { > + "reference_shutter_speed": 13841, > + "reference_gain": 2.0, > + "reference_aperture": 1.0, > + "reference_lux": 900, > + "reference_Y": 12064 > + }, > + "rpi.noise": > + { > + "reference_constant": 0, > + "reference_slope": 2.776 > + }, > + "rpi.geq": > + { > + "offset": 189, > + "slope": 0.01495 > + }, > + "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": 7900 > + }, > + "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": 8000 > + } > + }, > + "bayes": 1, > + "ct_curve": > + [ > + 2890.0, 0.7328, 0.3734, 3550.0, 0.6228, 0.4763, 4500.0, > 0.5208, 0.5825, 5700.0, 0.4467, 0.6671, 7900.0, 0.3858, 0.7411 > + ], > + "sensitivity_r": 1.0, > + "sensitivity_b": 1.0, > + "transverse_pos": 0.02027, > + "transverse_neg": 0.01935 > + }, > + "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.5, > + "calibrations_Cr": > + [ > + { > + "ct": 3000, "table": > + [ > + 1.527, 1.521, 1.508, 1.493, 1.476, 1.455, 1.442, > 1.441, 1.441, 1.441, 1.448, 1.467, 1.483, 1.494, 1.503, 1.504, > + 1.525, 1.513, 1.496, 1.477, 1.461, 1.434, 1.418, > 1.409, 1.409, 1.416, 1.429, 1.449, 1.469, 1.485, 1.495, 1.503, > + 1.517, 1.506, 1.485, 1.461, 1.434, 1.412, 1.388, > 1.376, 1.376, 1.386, 1.405, 1.429, 1.449, 1.471, 1.488, 1.495, > + 1.512, 1.496, 1.471, 1.442, 1.412, 1.388, 1.361, > 1.344, 1.344, 1.358, 1.384, 1.405, 1.431, 1.456, 1.479, 1.489, > + 1.508, 1.488, 1.458, 1.425, 1.393, 1.361, 1.343, > 1.322, 1.321, 1.342, 1.358, 1.385, 1.416, 1.445, 1.471, 1.484, > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, > 1.318, 1.318, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, > 1.313, 1.313, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > + 1.507, 1.485, 1.455, 1.422, 1.387, 1.355, 1.333, > 1.319, 1.321, 1.333, 1.351, 1.381, 1.411, 1.441, 1.467, 1.483, > + 1.508, 1.489, 1.463, 1.432, 1.401, 1.372, 1.355, > 1.333, 1.333, 1.351, 1.369, 1.393, 1.422, 1.448, 1.471, 1.484, > + 1.511, 1.494, 1.472, 1.444, 1.416, 1.398, 1.372, > 1.361, 1.361, 1.369, 1.393, 1.411, 1.436, 1.458, 1.477, 1.487, > + 1.511, 1.496, 1.478, 1.455, 1.436, 1.416, 1.399, > 1.391, 1.391, 1.397, 1.411, 1.429, 1.451, 1.466, 1.479, 1.487, > + 1.511, 1.495, 1.478, 1.462, 1.448, 1.432, 1.419, > 1.419, 1.419, 1.419, 1.429, 1.445, 1.459, 1.471, 1.482, 1.487 > + ] > + }, > + { > + "ct": 6000, "table": > + [ > + 2.581, 2.573, 2.558, 2.539, 2.514, 2.487, 2.473, > 2.471, 2.471, 2.471, 2.479, 2.499, 2.517, 2.532, 2.543, 2.544, > + 2.575, 2.559, 2.539, 2.521, 2.491, 2.458, 2.435, > 2.421, 2.421, 2.429, 2.449, 2.477, 2.499, 2.519, 2.534, 2.543, > + 2.561, 2.549, 2.521, 2.491, 2.457, 2.423, 2.393, > 2.375, 2.375, 2.387, 2.412, 2.444, 2.475, 2.499, 2.519, 2.532, > + 2.552, 2.531, 2.498, 2.459, 2.423, 2.391, 2.349, > 2.325, 2.325, 2.344, 2.374, 2.412, 2.444, 2.476, 2.505, 2.519, > + 2.543, 2.518, 2.479, 2.435, 2.392, 2.349, 2.324, > 2.285, 2.283, 2.313, 2.344, 2.374, 2.417, 2.457, 2.489, 2.506, > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, > 2.277, 2.279, 2.283, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, > 2.267, 2.267, 2.281, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > + 2.541, 2.512, 2.472, 2.425, 2.381, 2.338, 2.302, > 2.278, 2.279, 2.301, 2.324, 2.364, 2.407, 2.447, 2.481, 2.504, > + 2.544, 2.519, 2.483, 2.441, 2.401, 2.363, 2.338, > 2.302, 2.302, 2.324, 2.355, 2.385, 2.423, 2.459, 2.488, 2.506, > + 2.549, 2.527, 2.497, 2.463, 2.427, 2.401, 2.363, > 2.345, 2.345, 2.355, 2.385, 2.412, 2.444, 2.473, 2.497, 2.509, > + 2.552, 2.532, 2.507, 2.481, 2.459, 2.427, 2.402, > 2.389, 2.389, 2.394, 2.412, 2.444, 2.465, 2.481, 2.499, 2.511, > + 2.553, 2.533, 2.508, 2.489, 2.475, 2.454, 2.429, > 2.429, 2.429, 2.429, 2.439, 2.463, 2.481, 2.492, 2.504, 2.511 > + ] > + } > + ], > + "calibrations_Cb": > + [ > + { > + "ct": 3000, "table": > + [ > + 3.132, 3.126, 3.116, 3.103, 3.097, 3.091, 3.087, > 3.086, 3.088, 3.091, 3.092, 3.102, 3.113, 3.121, 3.141, 3.144, > + 3.149, 3.132, 3.123, 3.108, 3.101, 3.096, 3.091, > 3.089, 3.091, 3.092, 3.101, 3.107, 3.116, 3.129, 3.144, 3.153, > + 3.161, 3.149, 3.129, 3.121, 3.108, 3.103, 3.101, > 3.101, 3.101, 3.103, 3.107, 3.116, 3.125, 3.134, 3.153, 3.159, > + 3.176, 3.161, 3.144, 3.129, 3.124, 3.121, 3.117, > 3.118, 3.118, 3.119, 3.122, 3.125, 3.134, 3.146, 3.159, 3.171, > + 3.183, 3.176, 3.157, 3.144, 3.143, 3.143, 3.139, > 3.141, 3.141, 3.141, 3.141, 3.141, 3.146, 3.161, 3.171, 3.179, > + 3.189, 3.183, 3.165, 3.157, 3.156, 3.157, 3.159, > 3.163, 3.163, 3.163, 3.163, 3.161, 3.163, 3.169, 3.179, 3.187, > + 3.199, 3.189, 3.171, 3.165, 3.164, 3.167, 3.171, > 3.173, 3.173, 3.172, 3.171, 3.169, 3.169, 3.175, 3.187, 3.189, > + 3.206, 3.196, 3.177, 3.171, 3.165, 3.167, 3.171, > 3.173, 3.173, 3.172, 3.171, 3.171, 3.173, 3.177, 3.192, 3.194, > + 3.209, 3.197, 3.178, 3.171, 3.164, 3.161, 3.159, > 3.161, 3.162, 3.164, 3.167, 3.171, 3.173, 3.181, 3.193, 3.198, > + 3.204, 3.194, 3.176, 3.165, 3.161, 3.156, 3.154, > 3.154, 3.159, 3.161, 3.164, 3.168, 3.173, 3.182, 3.198, 3.199, > + 3.199, 3.191, 3.176, 3.169, 3.161, 3.157, 3.153, > 3.153, 3.156, 3.161, 3.164, 3.168, 3.173, 3.186, 3.196, 3.199, > + 3.199, 3.188, 3.179, 3.173, 3.165, 3.157, 3.153, > 3.154, 3.156, 3.159, 3.167, 3.171, 3.176, 3.185, 3.193, 3.198 > + ] > + }, > + { > + "ct": 6000, "table": > + [ > + 1.579, 1.579, 1.577, 1.574, 1.573, 1.571, 1.571, > 1.571, 1.571, 1.569, 1.569, 1.571, 1.572, 1.574, 1.577, 1.578, > + 1.584, 1.579, 1.578, 1.575, 1.573, 1.572, 1.571, > 1.572, 1.572, 1.571, 1.571, 1.572, 1.573, 1.576, 1.578, 1.579, > + 1.587, 1.584, 1.579, 1.578, 1.575, 1.573, 1.573, > 1.575, 1.575, 1.574, 1.573, 1.574, 1.576, 1.578, 1.581, 1.581, > + 1.591, 1.587, 1.584, 1.579, 1.578, 1.579, 1.579, > 1.581, 1.581, 1.581, 1.578, 1.577, 1.578, 1.581, 1.585, 1.586, > + 1.595, 1.591, 1.587, 1.585, 1.585, 1.586, 1.587, > 1.587, 1.588, 1.588, 1.585, 1.584, 1.584, 1.586, 1.589, 1.589, > + 1.597, 1.595, 1.591, 1.589, 1.591, 1.593, 1.595, > 1.596, 1.597, 1.597, 1.595, 1.594, 1.592, 1.592, 1.593, 1.593, > + 1.601, 1.597, 1.593, 1.592, 1.593, 1.595, 1.598, > 1.599, 1.602, 1.601, 1.598, 1.596, 1.595, 1.596, 1.595, 1.595, > + 1.601, 1.599, 1.594, 1.593, 1.593, 1.595, 1.598, > 1.599, 1.602, 1.601, 1.598, 1.597, 1.597, 1.597, 1.597, 1.597, > + 1.602, 1.599, 1.594, 1.593, 1.592, 1.593, 1.595, > 1.597, 1.597, 1.598, 1.598, 1.597, 1.597, 1.597, 1.598, 1.598, > + 1.599, 1.598, 1.594, 1.592, 1.591, 1.591, 1.592, > 1.595, 1.596, 1.597, 1.597, 1.597, 1.597, 1.599, 1.599, 1.599, > + 1.598, 1.596, 1.594, 1.593, 1.592, 1.592, 1.592, > 1.594, 1.595, 1.597, 1.597, 1.597, 1.598, 1.599, 1.599, 1.599, > + 1.597, 1.595, 1.594, 1.594, 1.593, 1.592, 1.593, > 1.595, 1.595, 1.597, 1.598, 1.598, 1.598, 1.599, 1.599, 1.599 > + ] > + } > + ], > + "luminance_lut": > + [ > + 2.887, 2.754, 2.381, 2.105, 1.859, 1.678, 1.625, 1.623, > 1.623, 1.624, 1.669, 1.849, 2.092, 2.362, 2.723, 2.838, > + 2.754, 2.443, 2.111, 1.905, 1.678, 1.542, 1.455, 1.412, > 1.412, 1.452, 1.535, 1.665, 1.893, 2.096, 2.413, 2.723, > + 2.443, 2.216, 1.911, 1.678, 1.537, 1.372, 1.288, 1.245, > 1.245, 1.283, 1.363, 1.527, 1.665, 1.895, 2.193, 2.413, > + 2.318, 2.057, 1.764, 1.541, 1.372, 1.282, 1.159, 1.113, > 1.113, 1.151, 1.269, 1.363, 1.527, 1.749, 2.034, 2.278, > + 2.259, 1.953, 1.671, 1.452, 1.283, 1.159, 1.107, 1.018, > 1.017, 1.097, 1.151, 1.269, 1.437, 1.655, 1.931, 2.222, > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.019, 1.011, > 1.005, 1.014, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.016, 1.001, > 1.001, 1.007, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > + 2.257, 1.946, 1.666, 1.448, 1.281, 1.153, 1.093, 1.013, > 1.008, 1.089, 1.143, 1.269, 1.437, 1.654, 1.934, 2.226, > + 2.309, 2.044, 1.756, 1.532, 1.363, 1.259, 1.153, 1.093, > 1.093, 1.143, 1.264, 1.354, 1.524, 1.746, 2.035, 2.284, > + 2.425, 2.201, 1.896, 1.662, 1.519, 1.363, 1.259, 1.214, > 1.214, 1.264, 1.354, 1.519, 1.655, 1.888, 2.191, 2.413, > + 2.724, 2.417, 2.091, 1.888, 1.662, 1.519, 1.419, 1.373, > 1.373, 1.425, 1.521, 1.655, 1.885, 2.089, 2.409, 2.722, > + 2.858, 2.724, 2.356, 2.085, 1.842, 1.658, 1.581, 1.577, > 1.577, 1.579, 1.653, 1.838, 2.084, 2.359, 2.722, 2.842 > + ], > + "sigma": 0.00372, > + "sigma_Cb": 0.00244 > + }, > + "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": 2890, "ccm": > + [ > + 1.36754, -0.18448, -0.18306, -0.32356, 1.44826, > -0.12471, -0.00412, -0.69936, 1.70348 > + ] > + }, > + { > + "ct": 2920, "ccm": > + [ > + 1.26704, 0.01624, -0.28328, -0.28516, 1.38934, > -0.10419, -0.04854, -0.82211, 1.87066 > + ] > + }, > + { > + "ct": 3550, "ccm": > + [ > + 1.42836, -0.27235, -0.15601, -0.28751, 1.41075, > -0.12325, -0.01812, -0.54849, 1.56661 > + ] > + }, > + { > + "ct": 4500, "ccm": > + [ > + 1.36328, -0.19569, -0.16759, -0.25254, 1.52248, > -0.26994, -0.01575, -0.53155, 1.54729 > + ] > + }, > + { > + "ct": 5700, "ccm": > + [ > + 1.49207, -0.37245, -0.11963, -0.21493, 1.40005, > -0.18512, -0.03781, -0.38779, 1.42561 > + ] > + }, > + { > + "ct": 7900, "ccm": > + [ > + 1.34849, -0.05425, -0.29424, -0.22182, 1.77684, > -0.55502, -0.07403, -0.55336, 1.62739 > + ] > + } > + ] > + }, > + "rpi.sharpen": > + { > + } > +} > diff --git a/src/ipa/raspberrypi/data/meson.build > b/src/ipa/raspberrypi/data/meson.build > index 2def75cb..e84cd099 100644 > --- a/src/ipa/raspberrypi/data/meson.build > +++ b/src/ipa/raspberrypi/data/meson.build > @@ -7,6 +7,7 @@ conf_files = files([ > 'imx378.json', > 'imx477.json', > 'imx477_noir.json', > + 'imx519.json', > 'ov5647.json', > 'ov5647_noir.json', > 'ov9281.json', > diff --git a/src/ipa/raspberrypi/meson.build > b/src/ipa/raspberrypi/meson.build > index 1af31e4a..176055f4 100644 > --- a/src/ipa/raspberrypi/meson.build > +++ b/src/ipa/raspberrypi/meson.build > @@ -22,6 +22,7 @@ rpi_ipa_sources = files([ > 'cam_helper_imx219.cpp', > 'cam_helper_imx290.cpp', > 'cam_helper_imx477.cpp', > + 'cam_helper_imx519.cpp', > 'cam_helper_ov9281.cpp', > 'controller/controller.cpp', > 'controller/histogram.cpp', > -- > 2.20.1 > >
Hi Lee, David, Quoting David Plowman (2021-10-20 14:23:34) > From: Arducam info <info@arducam.com> > > The necessary tuning file and CamHelper is added for the imx519 sensor. > > The imx519 is a 16MP rolling shutter sensor. To enable > it, please add > > dtoverlay=imx519 > Great, I'm glad to see new sensor support progressing. For this patch: Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> I see the imx519 is integrated into the Raspberry Pi kernel, who will take this forward and post to the linux-media to get it intgrated into the kernel directly? -- Kieran > to the /boot/config.txt file and reboot the Pi. > > Signed-off-by: Lee Jackson <info@arducam.com> > Reviewed-by: David Plowman <david.plowman@raspberrypi.com> > > --- > src/ipa/raspberrypi/cam_helper_imx519.cpp | 185 ++++++++++++ > src/ipa/raspberrypi/data/imx519.json | 338 ++++++++++++++++++++++ > src/ipa/raspberrypi/data/meson.build | 1 + > src/ipa/raspberrypi/meson.build | 1 + > 4 files changed, 525 insertions(+) > create mode 100644 src/ipa/raspberrypi/cam_helper_imx519.cpp > create mode 100644 src/ipa/raspberrypi/data/imx519.json > > diff --git a/src/ipa/raspberrypi/cam_helper_imx519.cpp b/src/ipa/raspberrypi/cam_helper_imx519.cpp > new file mode 100644 > index 00000000..eaf24982 > --- /dev/null > +++ b/src/ipa/raspberrypi/cam_helper_imx519.cpp > @@ -0,0 +1,185 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > +/* > + * Based on cam_helper_imx477.cpp > + * Copyright (C) 2020, Raspberry Pi (Trading) Limited > + * > + * cam_helper_imx519.cpp - camera helper for imx519 sensor > + * Copyright (C) 2021, Arducam Technology co., Ltd. > + */ > + > +#include <assert.h> > +#include <cmath> > +#include <stddef.h> > +#include <stdio.h> > +#include <stdlib.h> > + > +#include <libcamera/base/log.h> > + > +#include "cam_helper.hpp" > +#include "md_parser.hpp" > + > +using namespace RPiController; > +using namespace libcamera; > +using libcamera::utils::Duration; > + > +namespace libcamera { > +LOG_DECLARE_CATEGORY(IPARPI) > +} > + > +/* > + * We care about two gain registers and a pair of exposure registers. Their > + * I2C addresses from the Sony IMX519 datasheet: > + */ > +constexpr uint32_t expHiReg = 0x0202; > +constexpr uint32_t expLoReg = 0x0203; > +constexpr uint32_t gainHiReg = 0x0204; > +constexpr uint32_t gainLoReg = 0x0205; > +constexpr uint32_t frameLengthHiReg = 0x0340; > +constexpr uint32_t frameLengthLoReg = 0x0341; > +constexpr std::initializer_list<uint32_t> registerList = > + { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, frameLengthLoReg }; > + > +class CamHelperImx519 : public CamHelper > +{ > +public: > + CamHelperImx519(); > + uint32_t GainCode(double gain) const override; > + double Gain(uint32_t gain_code) const override; > + void Prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) override; > + uint32_t GetVBlanking(Duration &exposure, Duration minFrameDuration, > + Duration maxFrameDuration) const override; > + void GetDelays(int &exposure_delay, int &gain_delay, > + int &vblank_delay) const override; > + bool SensorEmbeddedDataPresent() const override; > + > +private: > + /* > + * Smallest difference between the frame length and integration time, > + * in units of lines. > + */ > + static constexpr int frameIntegrationDiff = 32; > + /* Maximum frame length allowable for long exposure calculations. */ > + static constexpr int frameLengthMax = 0xffdc; > + /* Largest long exposure scale factor given as a left shift on the frame length. */ > + static constexpr int longExposureShiftMax = 7; > + > + void PopulateMetadata(const MdParser::RegisterMap ®isters, > + Metadata &metadata) const override; > +}; > + > +CamHelperImx519::CamHelperImx519() > + : CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff) > +{ > +} > + > +uint32_t CamHelperImx519::GainCode(double gain) const > +{ > + return static_cast<uint32_t>(1024 - 1024 / gain); > +} > + > +double CamHelperImx519::Gain(uint32_t gain_code) const > +{ > + return 1024.0 / (1024 - gain_code); > +} > + > +void CamHelperImx519::Prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) > +{ > + MdParser::RegisterMap registers; > + DeviceStatus deviceStatus; > + > + if (metadata.Get("device.status", deviceStatus)) { > + LOG(IPARPI, Error) << "DeviceStatus not found from DelayedControls"; > + return; > + } > + > + parseEmbeddedData(buffer, metadata); > + > + /* > + * The DeviceStatus struct is first populated with values obtained from > + * DelayedControls. If this reports frame length is > frameLengthMax, > + * it means we are using a long exposure mode. Since the long exposure > + * scale factor is not returned back through embedded data, we must rely > + * on the existing exposure lines and frame length values returned by > + * DelayedControls. > + * > + * Otherwise, all values are updated with what is reported in the > + * embedded data. > + */ > + if (deviceStatus.frame_length > frameLengthMax) { > + DeviceStatus parsedDeviceStatus; > + > + metadata.Get("device.status", parsedDeviceStatus); > + parsedDeviceStatus.shutter_speed = deviceStatus.shutter_speed; > + parsedDeviceStatus.frame_length = deviceStatus.frame_length; > + metadata.Set("device.status", parsedDeviceStatus); > + > + LOG(IPARPI, Debug) << "Metadata updated for long exposure: " > + << parsedDeviceStatus; > + } > +} > + > +uint32_t CamHelperImx519::GetVBlanking(Duration &exposure, > + Duration minFrameDuration, > + Duration maxFrameDuration) const > +{ > + uint32_t frameLength, exposureLines; > + unsigned int shift = 0; > + > + frameLength = mode_.height + CamHelper::GetVBlanking(exposure, minFrameDuration, > + maxFrameDuration); > + /* > + * Check if the frame length calculated needs to be setup for long > + * exposure mode. This will require us to use a long exposure scale > + * factor provided by a shift operation in the sensor. > + */ > + while (frameLength > frameLengthMax) { > + if (++shift > longExposureShiftMax) { > + shift = longExposureShiftMax; > + frameLength = frameLengthMax; > + break; > + } > + frameLength >>= 1; > + } > + > + if (shift) { > + /* Account for any rounding in the scaled frame length value. */ > + frameLength <<= shift; > + exposureLines = ExposureLines(exposure); > + exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff); > + exposure = Exposure(exposureLines); > + } > + > + return frameLength - mode_.height; > +} > + > +void CamHelperImx519::GetDelays(int &exposure_delay, int &gain_delay, > + int &vblank_delay) const > +{ > + exposure_delay = 2; > + gain_delay = 2; > + vblank_delay = 3; > +} > + > +bool CamHelperImx519::SensorEmbeddedDataPresent() const > +{ > + return true; > +} > + > +void CamHelperImx519::PopulateMetadata(const MdParser::RegisterMap ®isters, > + Metadata &metadata) const > +{ > + DeviceStatus deviceStatus; > + > + deviceStatus.shutter_speed = Exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg)); > + deviceStatus.analogue_gain = Gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg)); > + deviceStatus.frame_length = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg); > + > + metadata.Set("device.status", deviceStatus); > +} > + > +static CamHelper *Create() > +{ > + return new CamHelperImx519(); > +} > + > +static RegisterCamHelper reg("imx519", &Create); > diff --git a/src/ipa/raspberrypi/data/imx519.json b/src/ipa/raspberrypi/data/imx519.json > new file mode 100644 > index 00000000..164d0d9d > --- /dev/null > +++ b/src/ipa/raspberrypi/data/imx519.json > @@ -0,0 +1,338 @@ > +{ > + "rpi.black_level": > + { > + "black_level": 4096 > + }, > + "rpi.dpc": > + { > + }, > + "rpi.lux": > + { > + "reference_shutter_speed": 13841, > + "reference_gain": 2.0, > + "reference_aperture": 1.0, > + "reference_lux": 900, > + "reference_Y": 12064 > + }, > + "rpi.noise": > + { > + "reference_constant": 0, > + "reference_slope": 2.776 > + }, > + "rpi.geq": > + { > + "offset": 189, > + "slope": 0.01495 > + }, > + "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": 7900 > + }, > + "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": 8000 > + } > + }, > + "bayes": 1, > + "ct_curve": > + [ > + 2890.0, 0.7328, 0.3734, 3550.0, 0.6228, 0.4763, 4500.0, 0.5208, 0.5825, 5700.0, 0.4467, 0.6671, 7900.0, 0.3858, 0.7411 > + ], > + "sensitivity_r": 1.0, > + "sensitivity_b": 1.0, > + "transverse_pos": 0.02027, > + "transverse_neg": 0.01935 > + }, > + "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.5, > + "calibrations_Cr": > + [ > + { > + "ct": 3000, "table": > + [ > + 1.527, 1.521, 1.508, 1.493, 1.476, 1.455, 1.442, 1.441, 1.441, 1.441, 1.448, 1.467, 1.483, 1.494, 1.503, 1.504, > + 1.525, 1.513, 1.496, 1.477, 1.461, 1.434, 1.418, 1.409, 1.409, 1.416, 1.429, 1.449, 1.469, 1.485, 1.495, 1.503, > + 1.517, 1.506, 1.485, 1.461, 1.434, 1.412, 1.388, 1.376, 1.376, 1.386, 1.405, 1.429, 1.449, 1.471, 1.488, 1.495, > + 1.512, 1.496, 1.471, 1.442, 1.412, 1.388, 1.361, 1.344, 1.344, 1.358, 1.384, 1.405, 1.431, 1.456, 1.479, 1.489, > + 1.508, 1.488, 1.458, 1.425, 1.393, 1.361, 1.343, 1.322, 1.321, 1.342, 1.358, 1.385, 1.416, 1.445, 1.471, 1.484, > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, 1.318, 1.318, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, 1.313, 1.313, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > + 1.507, 1.485, 1.455, 1.422, 1.387, 1.355, 1.333, 1.319, 1.321, 1.333, 1.351, 1.381, 1.411, 1.441, 1.467, 1.483, > + 1.508, 1.489, 1.463, 1.432, 1.401, 1.372, 1.355, 1.333, 1.333, 1.351, 1.369, 1.393, 1.422, 1.448, 1.471, 1.484, > + 1.511, 1.494, 1.472, 1.444, 1.416, 1.398, 1.372, 1.361, 1.361, 1.369, 1.393, 1.411, 1.436, 1.458, 1.477, 1.487, > + 1.511, 1.496, 1.478, 1.455, 1.436, 1.416, 1.399, 1.391, 1.391, 1.397, 1.411, 1.429, 1.451, 1.466, 1.479, 1.487, > + 1.511, 1.495, 1.478, 1.462, 1.448, 1.432, 1.419, 1.419, 1.419, 1.419, 1.429, 1.445, 1.459, 1.471, 1.482, 1.487 > + ] > + }, > + { > + "ct": 6000, "table": > + [ > + 2.581, 2.573, 2.558, 2.539, 2.514, 2.487, 2.473, 2.471, 2.471, 2.471, 2.479, 2.499, 2.517, 2.532, 2.543, 2.544, > + 2.575, 2.559, 2.539, 2.521, 2.491, 2.458, 2.435, 2.421, 2.421, 2.429, 2.449, 2.477, 2.499, 2.519, 2.534, 2.543, > + 2.561, 2.549, 2.521, 2.491, 2.457, 2.423, 2.393, 2.375, 2.375, 2.387, 2.412, 2.444, 2.475, 2.499, 2.519, 2.532, > + 2.552, 2.531, 2.498, 2.459, 2.423, 2.391, 2.349, 2.325, 2.325, 2.344, 2.374, 2.412, 2.444, 2.476, 2.505, 2.519, > + 2.543, 2.518, 2.479, 2.435, 2.392, 2.349, 2.324, 2.285, 2.283, 2.313, 2.344, 2.374, 2.417, 2.457, 2.489, 2.506, > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, 2.277, 2.279, 2.283, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, 2.267, 2.267, 2.281, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > + 2.541, 2.512, 2.472, 2.425, 2.381, 2.338, 2.302, 2.278, 2.279, 2.301, 2.324, 2.364, 2.407, 2.447, 2.481, 2.504, > + 2.544, 2.519, 2.483, 2.441, 2.401, 2.363, 2.338, 2.302, 2.302, 2.324, 2.355, 2.385, 2.423, 2.459, 2.488, 2.506, > + 2.549, 2.527, 2.497, 2.463, 2.427, 2.401, 2.363, 2.345, 2.345, 2.355, 2.385, 2.412, 2.444, 2.473, 2.497, 2.509, > + 2.552, 2.532, 2.507, 2.481, 2.459, 2.427, 2.402, 2.389, 2.389, 2.394, 2.412, 2.444, 2.465, 2.481, 2.499, 2.511, > + 2.553, 2.533, 2.508, 2.489, 2.475, 2.454, 2.429, 2.429, 2.429, 2.429, 2.439, 2.463, 2.481, 2.492, 2.504, 2.511 > + ] > + } > + ], > + "calibrations_Cb": > + [ > + { > + "ct": 3000, "table": > + [ > + 3.132, 3.126, 3.116, 3.103, 3.097, 3.091, 3.087, 3.086, 3.088, 3.091, 3.092, 3.102, 3.113, 3.121, 3.141, 3.144, > + 3.149, 3.132, 3.123, 3.108, 3.101, 3.096, 3.091, 3.089, 3.091, 3.092, 3.101, 3.107, 3.116, 3.129, 3.144, 3.153, > + 3.161, 3.149, 3.129, 3.121, 3.108, 3.103, 3.101, 3.101, 3.101, 3.103, 3.107, 3.116, 3.125, 3.134, 3.153, 3.159, > + 3.176, 3.161, 3.144, 3.129, 3.124, 3.121, 3.117, 3.118, 3.118, 3.119, 3.122, 3.125, 3.134, 3.146, 3.159, 3.171, > + 3.183, 3.176, 3.157, 3.144, 3.143, 3.143, 3.139, 3.141, 3.141, 3.141, 3.141, 3.141, 3.146, 3.161, 3.171, 3.179, > + 3.189, 3.183, 3.165, 3.157, 3.156, 3.157, 3.159, 3.163, 3.163, 3.163, 3.163, 3.161, 3.163, 3.169, 3.179, 3.187, > + 3.199, 3.189, 3.171, 3.165, 3.164, 3.167, 3.171, 3.173, 3.173, 3.172, 3.171, 3.169, 3.169, 3.175, 3.187, 3.189, > + 3.206, 3.196, 3.177, 3.171, 3.165, 3.167, 3.171, 3.173, 3.173, 3.172, 3.171, 3.171, 3.173, 3.177, 3.192, 3.194, > + 3.209, 3.197, 3.178, 3.171, 3.164, 3.161, 3.159, 3.161, 3.162, 3.164, 3.167, 3.171, 3.173, 3.181, 3.193, 3.198, > + 3.204, 3.194, 3.176, 3.165, 3.161, 3.156, 3.154, 3.154, 3.159, 3.161, 3.164, 3.168, 3.173, 3.182, 3.198, 3.199, > + 3.199, 3.191, 3.176, 3.169, 3.161, 3.157, 3.153, 3.153, 3.156, 3.161, 3.164, 3.168, 3.173, 3.186, 3.196, 3.199, > + 3.199, 3.188, 3.179, 3.173, 3.165, 3.157, 3.153, 3.154, 3.156, 3.159, 3.167, 3.171, 3.176, 3.185, 3.193, 3.198 > + ] > + }, > + { > + "ct": 6000, "table": > + [ > + 1.579, 1.579, 1.577, 1.574, 1.573, 1.571, 1.571, 1.571, 1.571, 1.569, 1.569, 1.571, 1.572, 1.574, 1.577, 1.578, > + 1.584, 1.579, 1.578, 1.575, 1.573, 1.572, 1.571, 1.572, 1.572, 1.571, 1.571, 1.572, 1.573, 1.576, 1.578, 1.579, > + 1.587, 1.584, 1.579, 1.578, 1.575, 1.573, 1.573, 1.575, 1.575, 1.574, 1.573, 1.574, 1.576, 1.578, 1.581, 1.581, > + 1.591, 1.587, 1.584, 1.579, 1.578, 1.579, 1.579, 1.581, 1.581, 1.581, 1.578, 1.577, 1.578, 1.581, 1.585, 1.586, > + 1.595, 1.591, 1.587, 1.585, 1.585, 1.586, 1.587, 1.587, 1.588, 1.588, 1.585, 1.584, 1.584, 1.586, 1.589, 1.589, > + 1.597, 1.595, 1.591, 1.589, 1.591, 1.593, 1.595, 1.596, 1.597, 1.597, 1.595, 1.594, 1.592, 1.592, 1.593, 1.593, > + 1.601, 1.597, 1.593, 1.592, 1.593, 1.595, 1.598, 1.599, 1.602, 1.601, 1.598, 1.596, 1.595, 1.596, 1.595, 1.595, > + 1.601, 1.599, 1.594, 1.593, 1.593, 1.595, 1.598, 1.599, 1.602, 1.601, 1.598, 1.597, 1.597, 1.597, 1.597, 1.597, > + 1.602, 1.599, 1.594, 1.593, 1.592, 1.593, 1.595, 1.597, 1.597, 1.598, 1.598, 1.597, 1.597, 1.597, 1.598, 1.598, > + 1.599, 1.598, 1.594, 1.592, 1.591, 1.591, 1.592, 1.595, 1.596, 1.597, 1.597, 1.597, 1.597, 1.599, 1.599, 1.599, > + 1.598, 1.596, 1.594, 1.593, 1.592, 1.592, 1.592, 1.594, 1.595, 1.597, 1.597, 1.597, 1.598, 1.599, 1.599, 1.599, > + 1.597, 1.595, 1.594, 1.594, 1.593, 1.592, 1.593, 1.595, 1.595, 1.597, 1.598, 1.598, 1.598, 1.599, 1.599, 1.599 > + ] > + } > + ], > + "luminance_lut": > + [ > + 2.887, 2.754, 2.381, 2.105, 1.859, 1.678, 1.625, 1.623, 1.623, 1.624, 1.669, 1.849, 2.092, 2.362, 2.723, 2.838, > + 2.754, 2.443, 2.111, 1.905, 1.678, 1.542, 1.455, 1.412, 1.412, 1.452, 1.535, 1.665, 1.893, 2.096, 2.413, 2.723, > + 2.443, 2.216, 1.911, 1.678, 1.537, 1.372, 1.288, 1.245, 1.245, 1.283, 1.363, 1.527, 1.665, 1.895, 2.193, 2.413, > + 2.318, 2.057, 1.764, 1.541, 1.372, 1.282, 1.159, 1.113, 1.113, 1.151, 1.269, 1.363, 1.527, 1.749, 2.034, 2.278, > + 2.259, 1.953, 1.671, 1.452, 1.283, 1.159, 1.107, 1.018, 1.017, 1.097, 1.151, 1.269, 1.437, 1.655, 1.931, 2.222, > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.019, 1.011, 1.005, 1.014, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.016, 1.001, 1.001, 1.007, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > + 2.257, 1.946, 1.666, 1.448, 1.281, 1.153, 1.093, 1.013, 1.008, 1.089, 1.143, 1.269, 1.437, 1.654, 1.934, 2.226, > + 2.309, 2.044, 1.756, 1.532, 1.363, 1.259, 1.153, 1.093, 1.093, 1.143, 1.264, 1.354, 1.524, 1.746, 2.035, 2.284, > + 2.425, 2.201, 1.896, 1.662, 1.519, 1.363, 1.259, 1.214, 1.214, 1.264, 1.354, 1.519, 1.655, 1.888, 2.191, 2.413, > + 2.724, 2.417, 2.091, 1.888, 1.662, 1.519, 1.419, 1.373, 1.373, 1.425, 1.521, 1.655, 1.885, 2.089, 2.409, 2.722, > + 2.858, 2.724, 2.356, 2.085, 1.842, 1.658, 1.581, 1.577, 1.577, 1.579, 1.653, 1.838, 2.084, 2.359, 2.722, 2.842 > + ], > + "sigma": 0.00372, > + "sigma_Cb": 0.00244 > + }, > + "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": 2890, "ccm": > + [ > + 1.36754, -0.18448, -0.18306, -0.32356, 1.44826, -0.12471, -0.00412, -0.69936, 1.70348 > + ] > + }, > + { > + "ct": 2920, "ccm": > + [ > + 1.26704, 0.01624, -0.28328, -0.28516, 1.38934, -0.10419, -0.04854, -0.82211, 1.87066 > + ] > + }, > + { > + "ct": 3550, "ccm": > + [ > + 1.42836, -0.27235, -0.15601, -0.28751, 1.41075, -0.12325, -0.01812, -0.54849, 1.56661 > + ] > + }, > + { > + "ct": 4500, "ccm": > + [ > + 1.36328, -0.19569, -0.16759, -0.25254, 1.52248, -0.26994, -0.01575, -0.53155, 1.54729 > + ] > + }, > + { > + "ct": 5700, "ccm": > + [ > + 1.49207, -0.37245, -0.11963, -0.21493, 1.40005, -0.18512, -0.03781, -0.38779, 1.42561 > + ] > + }, > + { > + "ct": 7900, "ccm": > + [ > + 1.34849, -0.05425, -0.29424, -0.22182, 1.77684, -0.55502, -0.07403, -0.55336, 1.62739 > + ] > + } > + ] > + }, > + "rpi.sharpen": > + { > + } > +} > diff --git a/src/ipa/raspberrypi/data/meson.build b/src/ipa/raspberrypi/data/meson.build > index 2def75cb..e84cd099 100644 > --- a/src/ipa/raspberrypi/data/meson.build > +++ b/src/ipa/raspberrypi/data/meson.build > @@ -7,6 +7,7 @@ conf_files = files([ > 'imx378.json', > 'imx477.json', > 'imx477_noir.json', > + 'imx519.json', > 'ov5647.json', > 'ov5647_noir.json', > 'ov9281.json', > diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build > index 1af31e4a..176055f4 100644 > --- a/src/ipa/raspberrypi/meson.build > +++ b/src/ipa/raspberrypi/meson.build > @@ -22,6 +22,7 @@ rpi_ipa_sources = files([ > 'cam_helper_imx219.cpp', > 'cam_helper_imx290.cpp', > 'cam_helper_imx477.cpp', > + 'cam_helper_imx519.cpp', > 'cam_helper_ov9281.cpp', > 'controller/controller.cpp', > 'controller/histogram.cpp', > -- > 2.20.1 >
Quoting Kieran Bingham (2021-10-21 10:38:20) > Hi Lee, David, > > Quoting David Plowman (2021-10-20 14:23:34) > > From: Arducam info <info@arducam.com> > > > > The necessary tuning file and CamHelper is added for the imx519 sensor. > > > > The imx519 is a 16MP rolling shutter sensor. To enable > > it, please add > > > > dtoverlay=imx519 > > > > Great, I'm glad to see new sensor support progressing. > > For this patch: > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > I see the imx519 is integrated into the Raspberry Pi kernel, who will > take this forward and post to the linux-media to get it intgrated into > the kernel directly? Excellent, with [PATCH 1/2] dt-bindings: media: i2c: Add IMX519 CMOS sensor binding https://lore.kernel.org/linux-media/38FCC5C9-9D03-4C8B-9ADF-896AE2BD90DE@arducam.com/T/#u and [PATCH 2/2] media: i2c: Add driver for IMX519 sensor https://lore.kernel.org/linux-media/DBFF7F52-B763-4D54-8DC9-10508ECC7BD2@arducam.com/T/#u posted, I think we should get this integrated into libcamera now. David/Naush - I'm not able to test this. Is this fine to go in as it is? Any impacts on the recent MC series, or anything else? -- Kieran > > -- > Kieran > > > to the /boot/config.txt file and reboot the Pi. > > > > Signed-off-by: Lee Jackson <info@arducam.com> > > Reviewed-by: David Plowman <david.plowman@raspberrypi.com> > > > > --- > > src/ipa/raspberrypi/cam_helper_imx519.cpp | 185 ++++++++++++ > > src/ipa/raspberrypi/data/imx519.json | 338 ++++++++++++++++++++++ > > src/ipa/raspberrypi/data/meson.build | 1 + > > src/ipa/raspberrypi/meson.build | 1 + > > 4 files changed, 525 insertions(+) > > create mode 100644 src/ipa/raspberrypi/cam_helper_imx519.cpp > > create mode 100644 src/ipa/raspberrypi/data/imx519.json > > > > diff --git a/src/ipa/raspberrypi/cam_helper_imx519.cpp b/src/ipa/raspberrypi/cam_helper_imx519.cpp > > new file mode 100644 > > index 00000000..eaf24982 > > --- /dev/null > > +++ b/src/ipa/raspberrypi/cam_helper_imx519.cpp > > @@ -0,0 +1,185 @@ > > +/* SPDX-License-Identifier: BSD-2-Clause */ > > +/* > > + * Based on cam_helper_imx477.cpp > > + * Copyright (C) 2020, Raspberry Pi (Trading) Limited > > + * > > + * cam_helper_imx519.cpp - camera helper for imx519 sensor > > + * Copyright (C) 2021, Arducam Technology co., Ltd. > > + */ > > + > > +#include <assert.h> > > +#include <cmath> > > +#include <stddef.h> > > +#include <stdio.h> > > +#include <stdlib.h> > > + > > +#include <libcamera/base/log.h> > > + > > +#include "cam_helper.hpp" > > +#include "md_parser.hpp" > > + > > +using namespace RPiController; > > +using namespace libcamera; > > +using libcamera::utils::Duration; > > + > > +namespace libcamera { > > +LOG_DECLARE_CATEGORY(IPARPI) > > +} > > + > > +/* > > + * We care about two gain registers and a pair of exposure registers. Their > > + * I2C addresses from the Sony IMX519 datasheet: > > + */ > > +constexpr uint32_t expHiReg = 0x0202; > > +constexpr uint32_t expLoReg = 0x0203; > > +constexpr uint32_t gainHiReg = 0x0204; > > +constexpr uint32_t gainLoReg = 0x0205; > > +constexpr uint32_t frameLengthHiReg = 0x0340; > > +constexpr uint32_t frameLengthLoReg = 0x0341; > > +constexpr std::initializer_list<uint32_t> registerList = > > + { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, frameLengthLoReg }; > > + > > +class CamHelperImx519 : public CamHelper > > +{ > > +public: > > + CamHelperImx519(); > > + uint32_t GainCode(double gain) const override; > > + double Gain(uint32_t gain_code) const override; > > + void Prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) override; > > + uint32_t GetVBlanking(Duration &exposure, Duration minFrameDuration, > > + Duration maxFrameDuration) const override; > > + void GetDelays(int &exposure_delay, int &gain_delay, > > + int &vblank_delay) const override; > > + bool SensorEmbeddedDataPresent() const override; > > + > > +private: > > + /* > > + * Smallest difference between the frame length and integration time, > > + * in units of lines. > > + */ > > + static constexpr int frameIntegrationDiff = 32; > > + /* Maximum frame length allowable for long exposure calculations. */ > > + static constexpr int frameLengthMax = 0xffdc; > > + /* Largest long exposure scale factor given as a left shift on the frame length. */ > > + static constexpr int longExposureShiftMax = 7; > > + > > + void PopulateMetadata(const MdParser::RegisterMap ®isters, > > + Metadata &metadata) const override; > > +}; > > + > > +CamHelperImx519::CamHelperImx519() > > + : CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff) > > +{ > > +} > > + > > +uint32_t CamHelperImx519::GainCode(double gain) const > > +{ > > + return static_cast<uint32_t>(1024 - 1024 / gain); > > +} > > + > > +double CamHelperImx519::Gain(uint32_t gain_code) const > > +{ > > + return 1024.0 / (1024 - gain_code); > > +} > > + > > +void CamHelperImx519::Prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) > > +{ > > + MdParser::RegisterMap registers; > > + DeviceStatus deviceStatus; > > + > > + if (metadata.Get("device.status", deviceStatus)) { > > + LOG(IPARPI, Error) << "DeviceStatus not found from DelayedControls"; > > + return; > > + } > > + > > + parseEmbeddedData(buffer, metadata); > > + > > + /* > > + * The DeviceStatus struct is first populated with values obtained from > > + * DelayedControls. If this reports frame length is > frameLengthMax, > > + * it means we are using a long exposure mode. Since the long exposure > > + * scale factor is not returned back through embedded data, we must rely > > + * on the existing exposure lines and frame length values returned by > > + * DelayedControls. > > + * > > + * Otherwise, all values are updated with what is reported in the > > + * embedded data. > > + */ > > + if (deviceStatus.frame_length > frameLengthMax) { > > + DeviceStatus parsedDeviceStatus; > > + > > + metadata.Get("device.status", parsedDeviceStatus); > > + parsedDeviceStatus.shutter_speed = deviceStatus.shutter_speed; > > + parsedDeviceStatus.frame_length = deviceStatus.frame_length; > > + metadata.Set("device.status", parsedDeviceStatus); > > + > > + LOG(IPARPI, Debug) << "Metadata updated for long exposure: " > > + << parsedDeviceStatus; > > + } > > +} > > + > > +uint32_t CamHelperImx519::GetVBlanking(Duration &exposure, > > + Duration minFrameDuration, > > + Duration maxFrameDuration) const > > +{ > > + uint32_t frameLength, exposureLines; > > + unsigned int shift = 0; > > + > > + frameLength = mode_.height + CamHelper::GetVBlanking(exposure, minFrameDuration, > > + maxFrameDuration); > > + /* > > + * Check if the frame length calculated needs to be setup for long > > + * exposure mode. This will require us to use a long exposure scale > > + * factor provided by a shift operation in the sensor. > > + */ > > + while (frameLength > frameLengthMax) { > > + if (++shift > longExposureShiftMax) { > > + shift = longExposureShiftMax; > > + frameLength = frameLengthMax; > > + break; > > + } > > + frameLength >>= 1; > > + } > > + > > + if (shift) { > > + /* Account for any rounding in the scaled frame length value. */ > > + frameLength <<= shift; > > + exposureLines = ExposureLines(exposure); > > + exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff); > > + exposure = Exposure(exposureLines); > > + } > > + > > + return frameLength - mode_.height; > > +} > > + > > +void CamHelperImx519::GetDelays(int &exposure_delay, int &gain_delay, > > + int &vblank_delay) const > > +{ > > + exposure_delay = 2; > > + gain_delay = 2; > > + vblank_delay = 3; > > +} > > + > > +bool CamHelperImx519::SensorEmbeddedDataPresent() const > > +{ > > + return true; > > +} > > + > > +void CamHelperImx519::PopulateMetadata(const MdParser::RegisterMap ®isters, > > + Metadata &metadata) const > > +{ > > + DeviceStatus deviceStatus; > > + > > + deviceStatus.shutter_speed = Exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg)); > > + deviceStatus.analogue_gain = Gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg)); > > + deviceStatus.frame_length = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg); > > + > > + metadata.Set("device.status", deviceStatus); > > +} > > + > > +static CamHelper *Create() > > +{ > > + return new CamHelperImx519(); > > +} > > + > > +static RegisterCamHelper reg("imx519", &Create); > > diff --git a/src/ipa/raspberrypi/data/imx519.json b/src/ipa/raspberrypi/data/imx519.json > > new file mode 100644 > > index 00000000..164d0d9d > > --- /dev/null > > +++ b/src/ipa/raspberrypi/data/imx519.json > > @@ -0,0 +1,338 @@ > > +{ > > + "rpi.black_level": > > + { > > + "black_level": 4096 > > + }, > > + "rpi.dpc": > > + { > > + }, > > + "rpi.lux": > > + { > > + "reference_shutter_speed": 13841, > > + "reference_gain": 2.0, > > + "reference_aperture": 1.0, > > + "reference_lux": 900, > > + "reference_Y": 12064 > > + }, > > + "rpi.noise": > > + { > > + "reference_constant": 0, > > + "reference_slope": 2.776 > > + }, > > + "rpi.geq": > > + { > > + "offset": 189, > > + "slope": 0.01495 > > + }, > > + "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": 7900 > > + }, > > + "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": 8000 > > + } > > + }, > > + "bayes": 1, > > + "ct_curve": > > + [ > > + 2890.0, 0.7328, 0.3734, 3550.0, 0.6228, 0.4763, 4500.0, 0.5208, 0.5825, 5700.0, 0.4467, 0.6671, 7900.0, 0.3858, 0.7411 > > + ], > > + "sensitivity_r": 1.0, > > + "sensitivity_b": 1.0, > > + "transverse_pos": 0.02027, > > + "transverse_neg": 0.01935 > > + }, > > + "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.5, > > + "calibrations_Cr": > > + [ > > + { > > + "ct": 3000, "table": > > + [ > > + 1.527, 1.521, 1.508, 1.493, 1.476, 1.455, 1.442, 1.441, 1.441, 1.441, 1.448, 1.467, 1.483, 1.494, 1.503, 1.504, > > + 1.525, 1.513, 1.496, 1.477, 1.461, 1.434, 1.418, 1.409, 1.409, 1.416, 1.429, 1.449, 1.469, 1.485, 1.495, 1.503, > > + 1.517, 1.506, 1.485, 1.461, 1.434, 1.412, 1.388, 1.376, 1.376, 1.386, 1.405, 1.429, 1.449, 1.471, 1.488, 1.495, > > + 1.512, 1.496, 1.471, 1.442, 1.412, 1.388, 1.361, 1.344, 1.344, 1.358, 1.384, 1.405, 1.431, 1.456, 1.479, 1.489, > > + 1.508, 1.488, 1.458, 1.425, 1.393, 1.361, 1.343, 1.322, 1.321, 1.342, 1.358, 1.385, 1.416, 1.445, 1.471, 1.484, > > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, 1.318, 1.318, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, 1.313, 1.313, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > > + 1.507, 1.485, 1.455, 1.422, 1.387, 1.355, 1.333, 1.319, 1.321, 1.333, 1.351, 1.381, 1.411, 1.441, 1.467, 1.483, > > + 1.508, 1.489, 1.463, 1.432, 1.401, 1.372, 1.355, 1.333, 1.333, 1.351, 1.369, 1.393, 1.422, 1.448, 1.471, 1.484, > > + 1.511, 1.494, 1.472, 1.444, 1.416, 1.398, 1.372, 1.361, 1.361, 1.369, 1.393, 1.411, 1.436, 1.458, 1.477, 1.487, > > + 1.511, 1.496, 1.478, 1.455, 1.436, 1.416, 1.399, 1.391, 1.391, 1.397, 1.411, 1.429, 1.451, 1.466, 1.479, 1.487, > > + 1.511, 1.495, 1.478, 1.462, 1.448, 1.432, 1.419, 1.419, 1.419, 1.419, 1.429, 1.445, 1.459, 1.471, 1.482, 1.487 > > + ] > > + }, > > + { > > + "ct": 6000, "table": > > + [ > > + 2.581, 2.573, 2.558, 2.539, 2.514, 2.487, 2.473, 2.471, 2.471, 2.471, 2.479, 2.499, 2.517, 2.532, 2.543, 2.544, > > + 2.575, 2.559, 2.539, 2.521, 2.491, 2.458, 2.435, 2.421, 2.421, 2.429, 2.449, 2.477, 2.499, 2.519, 2.534, 2.543, > > + 2.561, 2.549, 2.521, 2.491, 2.457, 2.423, 2.393, 2.375, 2.375, 2.387, 2.412, 2.444, 2.475, 2.499, 2.519, 2.532, > > + 2.552, 2.531, 2.498, 2.459, 2.423, 2.391, 2.349, 2.325, 2.325, 2.344, 2.374, 2.412, 2.444, 2.476, 2.505, 2.519, > > + 2.543, 2.518, 2.479, 2.435, 2.392, 2.349, 2.324, 2.285, 2.283, 2.313, 2.344, 2.374, 2.417, 2.457, 2.489, 2.506, > > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, 2.277, 2.279, 2.283, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, 2.267, 2.267, 2.281, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > > + 2.541, 2.512, 2.472, 2.425, 2.381, 2.338, 2.302, 2.278, 2.279, 2.301, 2.324, 2.364, 2.407, 2.447, 2.481, 2.504, > > + 2.544, 2.519, 2.483, 2.441, 2.401, 2.363, 2.338, 2.302, 2.302, 2.324, 2.355, 2.385, 2.423, 2.459, 2.488, 2.506, > > + 2.549, 2.527, 2.497, 2.463, 2.427, 2.401, 2.363, 2.345, 2.345, 2.355, 2.385, 2.412, 2.444, 2.473, 2.497, 2.509, > > + 2.552, 2.532, 2.507, 2.481, 2.459, 2.427, 2.402, 2.389, 2.389, 2.394, 2.412, 2.444, 2.465, 2.481, 2.499, 2.511, > > + 2.553, 2.533, 2.508, 2.489, 2.475, 2.454, 2.429, 2.429, 2.429, 2.429, 2.439, 2.463, 2.481, 2.492, 2.504, 2.511 > > + ] > > + } > > + ], > > + "calibrations_Cb": > > + [ > > + { > > + "ct": 3000, "table": > > + [ > > + 3.132, 3.126, 3.116, 3.103, 3.097, 3.091, 3.087, 3.086, 3.088, 3.091, 3.092, 3.102, 3.113, 3.121, 3.141, 3.144, > > + 3.149, 3.132, 3.123, 3.108, 3.101, 3.096, 3.091, 3.089, 3.091, 3.092, 3.101, 3.107, 3.116, 3.129, 3.144, 3.153, > > + 3.161, 3.149, 3.129, 3.121, 3.108, 3.103, 3.101, 3.101, 3.101, 3.103, 3.107, 3.116, 3.125, 3.134, 3.153, 3.159, > > + 3.176, 3.161, 3.144, 3.129, 3.124, 3.121, 3.117, 3.118, 3.118, 3.119, 3.122, 3.125, 3.134, 3.146, 3.159, 3.171, > > + 3.183, 3.176, 3.157, 3.144, 3.143, 3.143, 3.139, 3.141, 3.141, 3.141, 3.141, 3.141, 3.146, 3.161, 3.171, 3.179, > > + 3.189, 3.183, 3.165, 3.157, 3.156, 3.157, 3.159, 3.163, 3.163, 3.163, 3.163, 3.161, 3.163, 3.169, 3.179, 3.187, > > + 3.199, 3.189, 3.171, 3.165, 3.164, 3.167, 3.171, 3.173, 3.173, 3.172, 3.171, 3.169, 3.169, 3.175, 3.187, 3.189, > > + 3.206, 3.196, 3.177, 3.171, 3.165, 3.167, 3.171, 3.173, 3.173, 3.172, 3.171, 3.171, 3.173, 3.177, 3.192, 3.194, > > + 3.209, 3.197, 3.178, 3.171, 3.164, 3.161, 3.159, 3.161, 3.162, 3.164, 3.167, 3.171, 3.173, 3.181, 3.193, 3.198, > > + 3.204, 3.194, 3.176, 3.165, 3.161, 3.156, 3.154, 3.154, 3.159, 3.161, 3.164, 3.168, 3.173, 3.182, 3.198, 3.199, > > + 3.199, 3.191, 3.176, 3.169, 3.161, 3.157, 3.153, 3.153, 3.156, 3.161, 3.164, 3.168, 3.173, 3.186, 3.196, 3.199, > > + 3.199, 3.188, 3.179, 3.173, 3.165, 3.157, 3.153, 3.154, 3.156, 3.159, 3.167, 3.171, 3.176, 3.185, 3.193, 3.198 > > + ] > > + }, > > + { > > + "ct": 6000, "table": > > + [ > > + 1.579, 1.579, 1.577, 1.574, 1.573, 1.571, 1.571, 1.571, 1.571, 1.569, 1.569, 1.571, 1.572, 1.574, 1.577, 1.578, > > + 1.584, 1.579, 1.578, 1.575, 1.573, 1.572, 1.571, 1.572, 1.572, 1.571, 1.571, 1.572, 1.573, 1.576, 1.578, 1.579, > > + 1.587, 1.584, 1.579, 1.578, 1.575, 1.573, 1.573, 1.575, 1.575, 1.574, 1.573, 1.574, 1.576, 1.578, 1.581, 1.581, > > + 1.591, 1.587, 1.584, 1.579, 1.578, 1.579, 1.579, 1.581, 1.581, 1.581, 1.578, 1.577, 1.578, 1.581, 1.585, 1.586, > > + 1.595, 1.591, 1.587, 1.585, 1.585, 1.586, 1.587, 1.587, 1.588, 1.588, 1.585, 1.584, 1.584, 1.586, 1.589, 1.589, > > + 1.597, 1.595, 1.591, 1.589, 1.591, 1.593, 1.595, 1.596, 1.597, 1.597, 1.595, 1.594, 1.592, 1.592, 1.593, 1.593, > > + 1.601, 1.597, 1.593, 1.592, 1.593, 1.595, 1.598, 1.599, 1.602, 1.601, 1.598, 1.596, 1.595, 1.596, 1.595, 1.595, > > + 1.601, 1.599, 1.594, 1.593, 1.593, 1.595, 1.598, 1.599, 1.602, 1.601, 1.598, 1.597, 1.597, 1.597, 1.597, 1.597, > > + 1.602, 1.599, 1.594, 1.593, 1.592, 1.593, 1.595, 1.597, 1.597, 1.598, 1.598, 1.597, 1.597, 1.597, 1.598, 1.598, > > + 1.599, 1.598, 1.594, 1.592, 1.591, 1.591, 1.592, 1.595, 1.596, 1.597, 1.597, 1.597, 1.597, 1.599, 1.599, 1.599, > > + 1.598, 1.596, 1.594, 1.593, 1.592, 1.592, 1.592, 1.594, 1.595, 1.597, 1.597, 1.597, 1.598, 1.599, 1.599, 1.599, > > + 1.597, 1.595, 1.594, 1.594, 1.593, 1.592, 1.593, 1.595, 1.595, 1.597, 1.598, 1.598, 1.598, 1.599, 1.599, 1.599 > > + ] > > + } > > + ], > > + "luminance_lut": > > + [ > > + 2.887, 2.754, 2.381, 2.105, 1.859, 1.678, 1.625, 1.623, 1.623, 1.624, 1.669, 1.849, 2.092, 2.362, 2.723, 2.838, > > + 2.754, 2.443, 2.111, 1.905, 1.678, 1.542, 1.455, 1.412, 1.412, 1.452, 1.535, 1.665, 1.893, 2.096, 2.413, 2.723, > > + 2.443, 2.216, 1.911, 1.678, 1.537, 1.372, 1.288, 1.245, 1.245, 1.283, 1.363, 1.527, 1.665, 1.895, 2.193, 2.413, > > + 2.318, 2.057, 1.764, 1.541, 1.372, 1.282, 1.159, 1.113, 1.113, 1.151, 1.269, 1.363, 1.527, 1.749, 2.034, 2.278, > > + 2.259, 1.953, 1.671, 1.452, 1.283, 1.159, 1.107, 1.018, 1.017, 1.097, 1.151, 1.269, 1.437, 1.655, 1.931, 2.222, > > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.019, 1.011, 1.005, 1.014, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.016, 1.001, 1.001, 1.007, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > > + 2.257, 1.946, 1.666, 1.448, 1.281, 1.153, 1.093, 1.013, 1.008, 1.089, 1.143, 1.269, 1.437, 1.654, 1.934, 2.226, > > + 2.309, 2.044, 1.756, 1.532, 1.363, 1.259, 1.153, 1.093, 1.093, 1.143, 1.264, 1.354, 1.524, 1.746, 2.035, 2.284, > > + 2.425, 2.201, 1.896, 1.662, 1.519, 1.363, 1.259, 1.214, 1.214, 1.264, 1.354, 1.519, 1.655, 1.888, 2.191, 2.413, > > + 2.724, 2.417, 2.091, 1.888, 1.662, 1.519, 1.419, 1.373, 1.373, 1.425, 1.521, 1.655, 1.885, 2.089, 2.409, 2.722, > > + 2.858, 2.724, 2.356, 2.085, 1.842, 1.658, 1.581, 1.577, 1.577, 1.579, 1.653, 1.838, 2.084, 2.359, 2.722, 2.842 > > + ], > > + "sigma": 0.00372, > > + "sigma_Cb": 0.00244 > > + }, > > + "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": 2890, "ccm": > > + [ > > + 1.36754, -0.18448, -0.18306, -0.32356, 1.44826, -0.12471, -0.00412, -0.69936, 1.70348 > > + ] > > + }, > > + { > > + "ct": 2920, "ccm": > > + [ > > + 1.26704, 0.01624, -0.28328, -0.28516, 1.38934, -0.10419, -0.04854, -0.82211, 1.87066 > > + ] > > + }, > > + { > > + "ct": 3550, "ccm": > > + [ > > + 1.42836, -0.27235, -0.15601, -0.28751, 1.41075, -0.12325, -0.01812, -0.54849, 1.56661 > > + ] > > + }, > > + { > > + "ct": 4500, "ccm": > > + [ > > + 1.36328, -0.19569, -0.16759, -0.25254, 1.52248, -0.26994, -0.01575, -0.53155, 1.54729 > > + ] > > + }, > > + { > > + "ct": 5700, "ccm": > > + [ > > + 1.49207, -0.37245, -0.11963, -0.21493, 1.40005, -0.18512, -0.03781, -0.38779, 1.42561 > > + ] > > + }, > > + { > > + "ct": 7900, "ccm": > > + [ > > + 1.34849, -0.05425, -0.29424, -0.22182, 1.77684, -0.55502, -0.07403, -0.55336, 1.62739 > > + ] > > + } > > + ] > > + }, > > + "rpi.sharpen": > > + { > > + } > > +} > > diff --git a/src/ipa/raspberrypi/data/meson.build b/src/ipa/raspberrypi/data/meson.build > > index 2def75cb..e84cd099 100644 > > --- a/src/ipa/raspberrypi/data/meson.build > > +++ b/src/ipa/raspberrypi/data/meson.build > > @@ -7,6 +7,7 @@ conf_files = files([ > > 'imx378.json', > > 'imx477.json', > > 'imx477_noir.json', > > + 'imx519.json', > > 'ov5647.json', > > 'ov5647_noir.json', > > 'ov9281.json', > > diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build > > index 1af31e4a..176055f4 100644 > > --- a/src/ipa/raspberrypi/meson.build > > +++ b/src/ipa/raspberrypi/meson.build > > @@ -22,6 +22,7 @@ rpi_ipa_sources = files([ > > 'cam_helper_imx219.cpp', > > 'cam_helper_imx290.cpp', > > 'cam_helper_imx477.cpp', > > + 'cam_helper_imx519.cpp', > > 'cam_helper_ov9281.cpp', > > 'controller/controller.cpp', > > 'controller/histogram.cpp', > > -- > > 2.20.1 > >
Hi Kieran, On Tue, 2 Nov 2021 at 11:19, Kieran Bingham <kieran.bingham@ideasonboard.com> wrote: > Quoting Kieran Bingham (2021-10-21 10:38:20) > > Hi Lee, David, > > > > Quoting David Plowman (2021-10-20 14:23:34) > > > From: Arducam info <info@arducam.com> > > > > > > The necessary tuning file and CamHelper is added for the imx519 sensor. > > > > > > The imx519 is a 16MP rolling shutter sensor. To enable > > > it, please add > > > > > > dtoverlay=imx519 > > > > > > > Great, I'm glad to see new sensor support progressing. > > > > For this patch: > > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > > > I see the imx519 is integrated into the Raspberry Pi kernel, who will > > take this forward and post to the linux-media to get it intgrated into > > the kernel directly? > > Excellent, with > [PATCH 1/2] dt-bindings: media: i2c: Add IMX519 CMOS sensor binding > > https://lore.kernel.org/linux-media/38FCC5C9-9D03-4C8B-9ADF-896AE2BD90DE@arducam.com/T/#u > and > [PATCH 2/2] media: i2c: Add driver for IMX519 sensor > > https://lore.kernel.org/linux-media/DBFF7F52-B763-4D54-8DC9-10508ECC7BD2@arducam.com/T/#u > > posted, I think we should get this integrated into libcamera now. > > David/Naush - I'm not able to test this. Is this fine to go in as it is? > Yup, happy to have this merged now. > Any impacts on the recent MC series, or anything else? > There should not be any conflicts/impact with the MC series, which incidentally is good to go as well :-) Regards, Naush > > -- > Kieran > > > > > > -- > > Kieran > > > > > to the /boot/config.txt file and reboot the Pi. > > > > > > Signed-off-by: Lee Jackson <info@arducam.com> > > > Reviewed-by: David Plowman <david.plowman@raspberrypi.com> > > > > > > --- > > > src/ipa/raspberrypi/cam_helper_imx519.cpp | 185 ++++++++++++ > > > src/ipa/raspberrypi/data/imx519.json | 338 ++++++++++++++++++++++ > > > src/ipa/raspberrypi/data/meson.build | 1 + > > > src/ipa/raspberrypi/meson.build | 1 + > > > 4 files changed, 525 insertions(+) > > > create mode 100644 src/ipa/raspberrypi/cam_helper_imx519.cpp > > > create mode 100644 src/ipa/raspberrypi/data/imx519.json > > > > > > diff --git a/src/ipa/raspberrypi/cam_helper_imx519.cpp > b/src/ipa/raspberrypi/cam_helper_imx519.cpp > > > new file mode 100644 > > > index 00000000..eaf24982 > > > --- /dev/null > > > +++ b/src/ipa/raspberrypi/cam_helper_imx519.cpp > > > @@ -0,0 +1,185 @@ > > > +/* SPDX-License-Identifier: BSD-2-Clause */ > > > +/* > > > + * Based on cam_helper_imx477.cpp > > > + * Copyright (C) 2020, Raspberry Pi (Trading) Limited > > > + * > > > + * cam_helper_imx519.cpp - camera helper for imx519 sensor > > > + * Copyright (C) 2021, Arducam Technology co., Ltd. > > > + */ > > > + > > > +#include <assert.h> > > > +#include <cmath> > > > +#include <stddef.h> > > > +#include <stdio.h> > > > +#include <stdlib.h> > > > + > > > +#include <libcamera/base/log.h> > > > + > > > +#include "cam_helper.hpp" > > > +#include "md_parser.hpp" > > > + > > > +using namespace RPiController; > > > +using namespace libcamera; > > > +using libcamera::utils::Duration; > > > + > > > +namespace libcamera { > > > +LOG_DECLARE_CATEGORY(IPARPI) > > > +} > > > + > > > +/* > > > + * We care about two gain registers and a pair of exposure registers. > Their > > > + * I2C addresses from the Sony IMX519 datasheet: > > > + */ > > > +constexpr uint32_t expHiReg = 0x0202; > > > +constexpr uint32_t expLoReg = 0x0203; > > > +constexpr uint32_t gainHiReg = 0x0204; > > > +constexpr uint32_t gainLoReg = 0x0205; > > > +constexpr uint32_t frameLengthHiReg = 0x0340; > > > +constexpr uint32_t frameLengthLoReg = 0x0341; > > > +constexpr std::initializer_list<uint32_t> registerList = > > > + { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, > frameLengthLoReg }; > > > + > > > +class CamHelperImx519 : public CamHelper > > > +{ > > > +public: > > > + CamHelperImx519(); > > > + uint32_t GainCode(double gain) const override; > > > + double Gain(uint32_t gain_code) const override; > > > + void Prepare(libcamera::Span<const uint8_t> buffer, Metadata > &metadata) override; > > > + uint32_t GetVBlanking(Duration &exposure, Duration > minFrameDuration, > > > + Duration maxFrameDuration) const > override; > > > + void GetDelays(int &exposure_delay, int &gain_delay, > > > + int &vblank_delay) const override; > > > + bool SensorEmbeddedDataPresent() const override; > > > + > > > +private: > > > + /* > > > + * Smallest difference between the frame length and > integration time, > > > + * in units of lines. > > > + */ > > > + static constexpr int frameIntegrationDiff = 32; > > > + /* Maximum frame length allowable for long exposure > calculations. */ > > > + static constexpr int frameLengthMax = 0xffdc; > > > + /* Largest long exposure scale factor given as a left shift on > the frame length. */ > > > + static constexpr int longExposureShiftMax = 7; > > > + > > > + void PopulateMetadata(const MdParser::RegisterMap ®isters, > > > + Metadata &metadata) const override; > > > +}; > > > + > > > +CamHelperImx519::CamHelperImx519() > > > + : CamHelper(std::make_unique<MdParserSmia>(registerList), > frameIntegrationDiff) > > > +{ > > > +} > > > + > > > +uint32_t CamHelperImx519::GainCode(double gain) const > > > +{ > > > + return static_cast<uint32_t>(1024 - 1024 / gain); > > > +} > > > + > > > +double CamHelperImx519::Gain(uint32_t gain_code) const > > > +{ > > > + return 1024.0 / (1024 - gain_code); > > > +} > > > + > > > +void CamHelperImx519::Prepare(libcamera::Span<const uint8_t> buffer, > Metadata &metadata) > > > +{ > > > + MdParser::RegisterMap registers; > > > + DeviceStatus deviceStatus; > > > + > > > + if (metadata.Get("device.status", deviceStatus)) { > > > + LOG(IPARPI, Error) << "DeviceStatus not found from > DelayedControls"; > > > + return; > > > + } > > > + > > > + parseEmbeddedData(buffer, metadata); > > > + > > > + /* > > > + * The DeviceStatus struct is first populated with values > obtained from > > > + * DelayedControls. If this reports frame length is > > frameLengthMax, > > > + * it means we are using a long exposure mode. Since the long > exposure > > > + * scale factor is not returned back through embedded data, we > must rely > > > + * on the existing exposure lines and frame length values > returned by > > > + * DelayedControls. > > > + * > > > + * Otherwise, all values are updated with what is reported in > the > > > + * embedded data. > > > + */ > > > + if (deviceStatus.frame_length > frameLengthMax) { > > > + DeviceStatus parsedDeviceStatus; > > > + > > > + metadata.Get("device.status", parsedDeviceStatus); > > > + parsedDeviceStatus.shutter_speed = > deviceStatus.shutter_speed; > > > + parsedDeviceStatus.frame_length = > deviceStatus.frame_length; > > > + metadata.Set("device.status", parsedDeviceStatus); > > > + > > > + LOG(IPARPI, Debug) << "Metadata updated for long > exposure: " > > > + << parsedDeviceStatus; > > > + } > > > +} > > > + > > > +uint32_t CamHelperImx519::GetVBlanking(Duration &exposure, > > > + Duration minFrameDuration, > > > + Duration maxFrameDuration) const > > > +{ > > > + uint32_t frameLength, exposureLines; > > > + unsigned int shift = 0; > > > + > > > + frameLength = mode_.height + CamHelper::GetVBlanking(exposure, > minFrameDuration, > > > + > maxFrameDuration); > > > + /* > > > + * Check if the frame length calculated needs to be setup for > long > > > + * exposure mode. This will require us to use a long exposure > scale > > > + * factor provided by a shift operation in the sensor. > > > + */ > > > + while (frameLength > frameLengthMax) { > > > + if (++shift > longExposureShiftMax) { > > > + shift = longExposureShiftMax; > > > + frameLength = frameLengthMax; > > > + break; > > > + } > > > + frameLength >>= 1; > > > + } > > > + > > > + if (shift) { > > > + /* Account for any rounding in the scaled frame length > value. */ > > > + frameLength <<= shift; > > > + exposureLines = ExposureLines(exposure); > > > + exposureLines = std::min(exposureLines, frameLength - > frameIntegrationDiff); > > > + exposure = Exposure(exposureLines); > > > + } > > > + > > > + return frameLength - mode_.height; > > > +} > > > + > > > +void CamHelperImx519::GetDelays(int &exposure_delay, int &gain_delay, > > > + int &vblank_delay) const > > > +{ > > > + exposure_delay = 2; > > > + gain_delay = 2; > > > + vblank_delay = 3; > > > +} > > > + > > > +bool CamHelperImx519::SensorEmbeddedDataPresent() const > > > +{ > > > + return true; > > > +} > > > + > > > +void CamHelperImx519::PopulateMetadata(const MdParser::RegisterMap > ®isters, > > > + Metadata &metadata) const > > > +{ > > > + DeviceStatus deviceStatus; > > > + > > > + deviceStatus.shutter_speed = Exposure(registers.at(expHiReg) > * 256 + registers.at(expLoReg)); > > > + deviceStatus.analogue_gain = Gain(registers.at(gainHiReg) * > 256 + registers.at(gainLoReg)); > > > + deviceStatus.frame_length = registers.at(frameLengthHiReg) * > 256 + registers.at(frameLengthLoReg); > > > + > > > + metadata.Set("device.status", deviceStatus); > > > +} > > > + > > > +static CamHelper *Create() > > > +{ > > > + return new CamHelperImx519(); > > > +} > > > + > > > +static RegisterCamHelper reg("imx519", &Create); > > > diff --git a/src/ipa/raspberrypi/data/imx519.json > b/src/ipa/raspberrypi/data/imx519.json > > > new file mode 100644 > > > index 00000000..164d0d9d > > > --- /dev/null > > > +++ b/src/ipa/raspberrypi/data/imx519.json > > > @@ -0,0 +1,338 @@ > > > +{ > > > + "rpi.black_level": > > > + { > > > + "black_level": 4096 > > > + }, > > > + "rpi.dpc": > > > + { > > > + }, > > > + "rpi.lux": > > > + { > > > + "reference_shutter_speed": 13841, > > > + "reference_gain": 2.0, > > > + "reference_aperture": 1.0, > > > + "reference_lux": 900, > > > + "reference_Y": 12064 > > > + }, > > > + "rpi.noise": > > > + { > > > + "reference_constant": 0, > > > + "reference_slope": 2.776 > > > + }, > > > + "rpi.geq": > > > + { > > > + "offset": 189, > > > + "slope": 0.01495 > > > + }, > > > + "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": 7900 > > > + }, > > > + "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": 8000 > > > + } > > > + }, > > > + "bayes": 1, > > > + "ct_curve": > > > + [ > > > + 2890.0, 0.7328, 0.3734, 3550.0, 0.6228, 0.4763, 4500.0, > 0.5208, 0.5825, 5700.0, 0.4467, 0.6671, 7900.0, 0.3858, 0.7411 > > > + ], > > > + "sensitivity_r": 1.0, > > > + "sensitivity_b": 1.0, > > > + "transverse_pos": 0.02027, > > > + "transverse_neg": 0.01935 > > > + }, > > > + "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.5, > > > + "calibrations_Cr": > > > + [ > > > + { > > > + "ct": 3000, "table": > > > + [ > > > + 1.527, 1.521, 1.508, 1.493, 1.476, 1.455, 1.442, > 1.441, 1.441, 1.441, 1.448, 1.467, 1.483, 1.494, 1.503, 1.504, > > > + 1.525, 1.513, 1.496, 1.477, 1.461, 1.434, 1.418, > 1.409, 1.409, 1.416, 1.429, 1.449, 1.469, 1.485, 1.495, 1.503, > > > + 1.517, 1.506, 1.485, 1.461, 1.434, 1.412, 1.388, > 1.376, 1.376, 1.386, 1.405, 1.429, 1.449, 1.471, 1.488, 1.495, > > > + 1.512, 1.496, 1.471, 1.442, 1.412, 1.388, 1.361, > 1.344, 1.344, 1.358, 1.384, 1.405, 1.431, 1.456, 1.479, 1.489, > > > + 1.508, 1.488, 1.458, 1.425, 1.393, 1.361, 1.343, > 1.322, 1.321, 1.342, 1.358, 1.385, 1.416, 1.445, 1.471, 1.484, > > > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, > 1.318, 1.318, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > > > + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, > 1.313, 1.313, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, > > > + 1.507, 1.485, 1.455, 1.422, 1.387, 1.355, 1.333, > 1.319, 1.321, 1.333, 1.351, 1.381, 1.411, 1.441, 1.467, 1.483, > > > + 1.508, 1.489, 1.463, 1.432, 1.401, 1.372, 1.355, > 1.333, 1.333, 1.351, 1.369, 1.393, 1.422, 1.448, 1.471, 1.484, > > > + 1.511, 1.494, 1.472, 1.444, 1.416, 1.398, 1.372, > 1.361, 1.361, 1.369, 1.393, 1.411, 1.436, 1.458, 1.477, 1.487, > > > + 1.511, 1.496, 1.478, 1.455, 1.436, 1.416, 1.399, > 1.391, 1.391, 1.397, 1.411, 1.429, 1.451, 1.466, 1.479, 1.487, > > > + 1.511, 1.495, 1.478, 1.462, 1.448, 1.432, 1.419, > 1.419, 1.419, 1.419, 1.429, 1.445, 1.459, 1.471, 1.482, 1.487 > > > + ] > > > + }, > > > + { > > > + "ct": 6000, "table": > > > + [ > > > + 2.581, 2.573, 2.558, 2.539, 2.514, 2.487, 2.473, > 2.471, 2.471, 2.471, 2.479, 2.499, 2.517, 2.532, 2.543, 2.544, > > > + 2.575, 2.559, 2.539, 2.521, 2.491, 2.458, 2.435, > 2.421, 2.421, 2.429, 2.449, 2.477, 2.499, 2.519, 2.534, 2.543, > > > + 2.561, 2.549, 2.521, 2.491, 2.457, 2.423, 2.393, > 2.375, 2.375, 2.387, 2.412, 2.444, 2.475, 2.499, 2.519, 2.532, > > > + 2.552, 2.531, 2.498, 2.459, 2.423, 2.391, 2.349, > 2.325, 2.325, 2.344, 2.374, 2.412, 2.444, 2.476, 2.505, 2.519, > > > + 2.543, 2.518, 2.479, 2.435, 2.392, 2.349, 2.324, > 2.285, 2.283, 2.313, 2.344, 2.374, 2.417, 2.457, 2.489, 2.506, > > > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, > 2.277, 2.279, 2.283, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > > > + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, > 2.267, 2.267, 2.281, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, > > > + 2.541, 2.512, 2.472, 2.425, 2.381, 2.338, 2.302, > 2.278, 2.279, 2.301, 2.324, 2.364, 2.407, 2.447, 2.481, 2.504, > > > + 2.544, 2.519, 2.483, 2.441, 2.401, 2.363, 2.338, > 2.302, 2.302, 2.324, 2.355, 2.385, 2.423, 2.459, 2.488, 2.506, > > > + 2.549, 2.527, 2.497, 2.463, 2.427, 2.401, 2.363, > 2.345, 2.345, 2.355, 2.385, 2.412, 2.444, 2.473, 2.497, 2.509, > > > + 2.552, 2.532, 2.507, 2.481, 2.459, 2.427, 2.402, > 2.389, 2.389, 2.394, 2.412, 2.444, 2.465, 2.481, 2.499, 2.511, > > > + 2.553, 2.533, 2.508, 2.489, 2.475, 2.454, 2.429, > 2.429, 2.429, 2.429, 2.439, 2.463, 2.481, 2.492, 2.504, 2.511 > > > + ] > > > + } > > > + ], > > > + "calibrations_Cb": > > > + [ > > > + { > > > + "ct": 3000, "table": > > > + [ > > > + 3.132, 3.126, 3.116, 3.103, 3.097, 3.091, 3.087, > 3.086, 3.088, 3.091, 3.092, 3.102, 3.113, 3.121, 3.141, 3.144, > > > + 3.149, 3.132, 3.123, 3.108, 3.101, 3.096, 3.091, > 3.089, 3.091, 3.092, 3.101, 3.107, 3.116, 3.129, 3.144, 3.153, > > > + 3.161, 3.149, 3.129, 3.121, 3.108, 3.103, 3.101, > 3.101, 3.101, 3.103, 3.107, 3.116, 3.125, 3.134, 3.153, 3.159, > > > + 3.176, 3.161, 3.144, 3.129, 3.124, 3.121, 3.117, > 3.118, 3.118, 3.119, 3.122, 3.125, 3.134, 3.146, 3.159, 3.171, > > > + 3.183, 3.176, 3.157, 3.144, 3.143, 3.143, 3.139, > 3.141, 3.141, 3.141, 3.141, 3.141, 3.146, 3.161, 3.171, 3.179, > > > + 3.189, 3.183, 3.165, 3.157, 3.156, 3.157, 3.159, > 3.163, 3.163, 3.163, 3.163, 3.161, 3.163, 3.169, 3.179, 3.187, > > > + 3.199, 3.189, 3.171, 3.165, 3.164, 3.167, 3.171, > 3.173, 3.173, 3.172, 3.171, 3.169, 3.169, 3.175, 3.187, 3.189, > > > + 3.206, 3.196, 3.177, 3.171, 3.165, 3.167, 3.171, > 3.173, 3.173, 3.172, 3.171, 3.171, 3.173, 3.177, 3.192, 3.194, > > > + 3.209, 3.197, 3.178, 3.171, 3.164, 3.161, 3.159, > 3.161, 3.162, 3.164, 3.167, 3.171, 3.173, 3.181, 3.193, 3.198, > > > + 3.204, 3.194, 3.176, 3.165, 3.161, 3.156, 3.154, > 3.154, 3.159, 3.161, 3.164, 3.168, 3.173, 3.182, 3.198, 3.199, > > > + 3.199, 3.191, 3.176, 3.169, 3.161, 3.157, 3.153, > 3.153, 3.156, 3.161, 3.164, 3.168, 3.173, 3.186, 3.196, 3.199, > > > + 3.199, 3.188, 3.179, 3.173, 3.165, 3.157, 3.153, > 3.154, 3.156, 3.159, 3.167, 3.171, 3.176, 3.185, 3.193, 3.198 > > > + ] > > > + }, > > > + { > > > + "ct": 6000, "table": > > > + [ > > > + 1.579, 1.579, 1.577, 1.574, 1.573, 1.571, 1.571, > 1.571, 1.571, 1.569, 1.569, 1.571, 1.572, 1.574, 1.577, 1.578, > > > + 1.584, 1.579, 1.578, 1.575, 1.573, 1.572, 1.571, > 1.572, 1.572, 1.571, 1.571, 1.572, 1.573, 1.576, 1.578, 1.579, > > > + 1.587, 1.584, 1.579, 1.578, 1.575, 1.573, 1.573, > 1.575, 1.575, 1.574, 1.573, 1.574, 1.576, 1.578, 1.581, 1.581, > > > + 1.591, 1.587, 1.584, 1.579, 1.578, 1.579, 1.579, > 1.581, 1.581, 1.581, 1.578, 1.577, 1.578, 1.581, 1.585, 1.586, > > > + 1.595, 1.591, 1.587, 1.585, 1.585, 1.586, 1.587, > 1.587, 1.588, 1.588, 1.585, 1.584, 1.584, 1.586, 1.589, 1.589, > > > + 1.597, 1.595, 1.591, 1.589, 1.591, 1.593, 1.595, > 1.596, 1.597, 1.597, 1.595, 1.594, 1.592, 1.592, 1.593, 1.593, > > > + 1.601, 1.597, 1.593, 1.592, 1.593, 1.595, 1.598, > 1.599, 1.602, 1.601, 1.598, 1.596, 1.595, 1.596, 1.595, 1.595, > > > + 1.601, 1.599, 1.594, 1.593, 1.593, 1.595, 1.598, > 1.599, 1.602, 1.601, 1.598, 1.597, 1.597, 1.597, 1.597, 1.597, > > > + 1.602, 1.599, 1.594, 1.593, 1.592, 1.593, 1.595, > 1.597, 1.597, 1.598, 1.598, 1.597, 1.597, 1.597, 1.598, 1.598, > > > + 1.599, 1.598, 1.594, 1.592, 1.591, 1.591, 1.592, > 1.595, 1.596, 1.597, 1.597, 1.597, 1.597, 1.599, 1.599, 1.599, > > > + 1.598, 1.596, 1.594, 1.593, 1.592, 1.592, 1.592, > 1.594, 1.595, 1.597, 1.597, 1.597, 1.598, 1.599, 1.599, 1.599, > > > + 1.597, 1.595, 1.594, 1.594, 1.593, 1.592, 1.593, > 1.595, 1.595, 1.597, 1.598, 1.598, 1.598, 1.599, 1.599, 1.599 > > > + ] > > > + } > > > + ], > > > + "luminance_lut": > > > + [ > > > + 2.887, 2.754, 2.381, 2.105, 1.859, 1.678, 1.625, 1.623, > 1.623, 1.624, 1.669, 1.849, 2.092, 2.362, 2.723, 2.838, > > > + 2.754, 2.443, 2.111, 1.905, 1.678, 1.542, 1.455, 1.412, > 1.412, 1.452, 1.535, 1.665, 1.893, 2.096, 2.413, 2.723, > > > + 2.443, 2.216, 1.911, 1.678, 1.537, 1.372, 1.288, 1.245, > 1.245, 1.283, 1.363, 1.527, 1.665, 1.895, 2.193, 2.413, > > > + 2.318, 2.057, 1.764, 1.541, 1.372, 1.282, 1.159, 1.113, > 1.113, 1.151, 1.269, 1.363, 1.527, 1.749, 2.034, 2.278, > > > + 2.259, 1.953, 1.671, 1.452, 1.283, 1.159, 1.107, 1.018, > 1.017, 1.097, 1.151, 1.269, 1.437, 1.655, 1.931, 2.222, > > > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.019, 1.011, > 1.005, 1.014, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > > > + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.016, 1.001, > 1.001, 1.007, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, > > > + 2.257, 1.946, 1.666, 1.448, 1.281, 1.153, 1.093, 1.013, > 1.008, 1.089, 1.143, 1.269, 1.437, 1.654, 1.934, 2.226, > > > + 2.309, 2.044, 1.756, 1.532, 1.363, 1.259, 1.153, 1.093, > 1.093, 1.143, 1.264, 1.354, 1.524, 1.746, 2.035, 2.284, > > > + 2.425, 2.201, 1.896, 1.662, 1.519, 1.363, 1.259, 1.214, > 1.214, 1.264, 1.354, 1.519, 1.655, 1.888, 2.191, 2.413, > > > + 2.724, 2.417, 2.091, 1.888, 1.662, 1.519, 1.419, 1.373, > 1.373, 1.425, 1.521, 1.655, 1.885, 2.089, 2.409, 2.722, > > > + 2.858, 2.724, 2.356, 2.085, 1.842, 1.658, 1.581, 1.577, > 1.577, 1.579, 1.653, 1.838, 2.084, 2.359, 2.722, 2.842 > > > + ], > > > + "sigma": 0.00372, > > > + "sigma_Cb": 0.00244 > > > + }, > > > + "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": 2890, "ccm": > > > + [ > > > + 1.36754, -0.18448, -0.18306, -0.32356, 1.44826, > -0.12471, -0.00412, -0.69936, 1.70348 > > > + ] > > > + }, > > > + { > > > + "ct": 2920, "ccm": > > > + [ > > > + 1.26704, 0.01624, -0.28328, -0.28516, 1.38934, > -0.10419, -0.04854, -0.82211, 1.87066 > > > + ] > > > + }, > > > + { > > > + "ct": 3550, "ccm": > > > + [ > > > + 1.42836, -0.27235, -0.15601, -0.28751, 1.41075, > -0.12325, -0.01812, -0.54849, 1.56661 > > > + ] > > > + }, > > > + { > > > + "ct": 4500, "ccm": > > > + [ > > > + 1.36328, -0.19569, -0.16759, -0.25254, 1.52248, > -0.26994, -0.01575, -0.53155, 1.54729 > > > + ] > > > + }, > > > + { > > > + "ct": 5700, "ccm": > > > + [ > > > + 1.49207, -0.37245, -0.11963, -0.21493, 1.40005, > -0.18512, -0.03781, -0.38779, 1.42561 > > > + ] > > > + }, > > > + { > > > + "ct": 7900, "ccm": > > > + [ > > > + 1.34849, -0.05425, -0.29424, -0.22182, 1.77684, > -0.55502, -0.07403, -0.55336, 1.62739 > > > + ] > > > + } > > > + ] > > > + }, > > > + "rpi.sharpen": > > > + { > > > + } > > > +} > > > diff --git a/src/ipa/raspberrypi/data/meson.build > b/src/ipa/raspberrypi/data/meson.build > > > index 2def75cb..e84cd099 100644 > > > --- a/src/ipa/raspberrypi/data/meson.build > > > +++ b/src/ipa/raspberrypi/data/meson.build > > > @@ -7,6 +7,7 @@ conf_files = files([ > > > 'imx378.json', > > > 'imx477.json', > > > 'imx477_noir.json', > > > + 'imx519.json', > > > 'ov5647.json', > > > 'ov5647_noir.json', > > > 'ov9281.json', > > > diff --git a/src/ipa/raspberrypi/meson.build > b/src/ipa/raspberrypi/meson.build > > > index 1af31e4a..176055f4 100644 > > > --- a/src/ipa/raspberrypi/meson.build > > > +++ b/src/ipa/raspberrypi/meson.build > > > @@ -22,6 +22,7 @@ rpi_ipa_sources = files([ > > > 'cam_helper_imx219.cpp', > > > 'cam_helper_imx290.cpp', > > > 'cam_helper_imx477.cpp', > > > + 'cam_helper_imx519.cpp', > > > 'cam_helper_ov9281.cpp', > > > 'controller/controller.cpp', > > > 'controller/histogram.cpp', > > > -- > > > 2.20.1 > > > >
diff --git a/src/ipa/raspberrypi/cam_helper_imx519.cpp b/src/ipa/raspberrypi/cam_helper_imx519.cpp new file mode 100644 index 00000000..eaf24982 --- /dev/null +++ b/src/ipa/raspberrypi/cam_helper_imx519.cpp @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Based on cam_helper_imx477.cpp + * Copyright (C) 2020, Raspberry Pi (Trading) Limited + * + * cam_helper_imx519.cpp - camera helper for imx519 sensor + * Copyright (C) 2021, Arducam Technology co., Ltd. + */ + +#include <assert.h> +#include <cmath> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> + +#include <libcamera/base/log.h> + +#include "cam_helper.hpp" +#include "md_parser.hpp" + +using namespace RPiController; +using namespace libcamera; +using libcamera::utils::Duration; + +namespace libcamera { +LOG_DECLARE_CATEGORY(IPARPI) +} + +/* + * We care about two gain registers and a pair of exposure registers. Their + * I2C addresses from the Sony IMX519 datasheet: + */ +constexpr uint32_t expHiReg = 0x0202; +constexpr uint32_t expLoReg = 0x0203; +constexpr uint32_t gainHiReg = 0x0204; +constexpr uint32_t gainLoReg = 0x0205; +constexpr uint32_t frameLengthHiReg = 0x0340; +constexpr uint32_t frameLengthLoReg = 0x0341; +constexpr std::initializer_list<uint32_t> registerList = + { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, frameLengthLoReg }; + +class CamHelperImx519 : public CamHelper +{ +public: + CamHelperImx519(); + uint32_t GainCode(double gain) const override; + double Gain(uint32_t gain_code) const override; + void Prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) override; + uint32_t GetVBlanking(Duration &exposure, Duration minFrameDuration, + Duration maxFrameDuration) const override; + void GetDelays(int &exposure_delay, int &gain_delay, + int &vblank_delay) const override; + bool SensorEmbeddedDataPresent() const override; + +private: + /* + * Smallest difference between the frame length and integration time, + * in units of lines. + */ + static constexpr int frameIntegrationDiff = 32; + /* Maximum frame length allowable for long exposure calculations. */ + static constexpr int frameLengthMax = 0xffdc; + /* Largest long exposure scale factor given as a left shift on the frame length. */ + static constexpr int longExposureShiftMax = 7; + + void PopulateMetadata(const MdParser::RegisterMap ®isters, + Metadata &metadata) const override; +}; + +CamHelperImx519::CamHelperImx519() + : CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff) +{ +} + +uint32_t CamHelperImx519::GainCode(double gain) const +{ + return static_cast<uint32_t>(1024 - 1024 / gain); +} + +double CamHelperImx519::Gain(uint32_t gain_code) const +{ + return 1024.0 / (1024 - gain_code); +} + +void CamHelperImx519::Prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) +{ + MdParser::RegisterMap registers; + DeviceStatus deviceStatus; + + if (metadata.Get("device.status", deviceStatus)) { + LOG(IPARPI, Error) << "DeviceStatus not found from DelayedControls"; + return; + } + + parseEmbeddedData(buffer, metadata); + + /* + * The DeviceStatus struct is first populated with values obtained from + * DelayedControls. If this reports frame length is > frameLengthMax, + * it means we are using a long exposure mode. Since the long exposure + * scale factor is not returned back through embedded data, we must rely + * on the existing exposure lines and frame length values returned by + * DelayedControls. + * + * Otherwise, all values are updated with what is reported in the + * embedded data. + */ + if (deviceStatus.frame_length > frameLengthMax) { + DeviceStatus parsedDeviceStatus; + + metadata.Get("device.status", parsedDeviceStatus); + parsedDeviceStatus.shutter_speed = deviceStatus.shutter_speed; + parsedDeviceStatus.frame_length = deviceStatus.frame_length; + metadata.Set("device.status", parsedDeviceStatus); + + LOG(IPARPI, Debug) << "Metadata updated for long exposure: " + << parsedDeviceStatus; + } +} + +uint32_t CamHelperImx519::GetVBlanking(Duration &exposure, + Duration minFrameDuration, + Duration maxFrameDuration) const +{ + uint32_t frameLength, exposureLines; + unsigned int shift = 0; + + frameLength = mode_.height + CamHelper::GetVBlanking(exposure, minFrameDuration, + maxFrameDuration); + /* + * Check if the frame length calculated needs to be setup for long + * exposure mode. This will require us to use a long exposure scale + * factor provided by a shift operation in the sensor. + */ + while (frameLength > frameLengthMax) { + if (++shift > longExposureShiftMax) { + shift = longExposureShiftMax; + frameLength = frameLengthMax; + break; + } + frameLength >>= 1; + } + + if (shift) { + /* Account for any rounding in the scaled frame length value. */ + frameLength <<= shift; + exposureLines = ExposureLines(exposure); + exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff); + exposure = Exposure(exposureLines); + } + + return frameLength - mode_.height; +} + +void CamHelperImx519::GetDelays(int &exposure_delay, int &gain_delay, + int &vblank_delay) const +{ + exposure_delay = 2; + gain_delay = 2; + vblank_delay = 3; +} + +bool CamHelperImx519::SensorEmbeddedDataPresent() const +{ + return true; +} + +void CamHelperImx519::PopulateMetadata(const MdParser::RegisterMap ®isters, + Metadata &metadata) const +{ + DeviceStatus deviceStatus; + + deviceStatus.shutter_speed = Exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg)); + deviceStatus.analogue_gain = Gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg)); + deviceStatus.frame_length = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg); + + metadata.Set("device.status", deviceStatus); +} + +static CamHelper *Create() +{ + return new CamHelperImx519(); +} + +static RegisterCamHelper reg("imx519", &Create); diff --git a/src/ipa/raspberrypi/data/imx519.json b/src/ipa/raspberrypi/data/imx519.json new file mode 100644 index 00000000..164d0d9d --- /dev/null +++ b/src/ipa/raspberrypi/data/imx519.json @@ -0,0 +1,338 @@ +{ + "rpi.black_level": + { + "black_level": 4096 + }, + "rpi.dpc": + { + }, + "rpi.lux": + { + "reference_shutter_speed": 13841, + "reference_gain": 2.0, + "reference_aperture": 1.0, + "reference_lux": 900, + "reference_Y": 12064 + }, + "rpi.noise": + { + "reference_constant": 0, + "reference_slope": 2.776 + }, + "rpi.geq": + { + "offset": 189, + "slope": 0.01495 + }, + "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": 7900 + }, + "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": 8000 + } + }, + "bayes": 1, + "ct_curve": + [ + 2890.0, 0.7328, 0.3734, 3550.0, 0.6228, 0.4763, 4500.0, 0.5208, 0.5825, 5700.0, 0.4467, 0.6671, 7900.0, 0.3858, 0.7411 + ], + "sensitivity_r": 1.0, + "sensitivity_b": 1.0, + "transverse_pos": 0.02027, + "transverse_neg": 0.01935 + }, + "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.5, + "calibrations_Cr": + [ + { + "ct": 3000, "table": + [ + 1.527, 1.521, 1.508, 1.493, 1.476, 1.455, 1.442, 1.441, 1.441, 1.441, 1.448, 1.467, 1.483, 1.494, 1.503, 1.504, + 1.525, 1.513, 1.496, 1.477, 1.461, 1.434, 1.418, 1.409, 1.409, 1.416, 1.429, 1.449, 1.469, 1.485, 1.495, 1.503, + 1.517, 1.506, 1.485, 1.461, 1.434, 1.412, 1.388, 1.376, 1.376, 1.386, 1.405, 1.429, 1.449, 1.471, 1.488, 1.495, + 1.512, 1.496, 1.471, 1.442, 1.412, 1.388, 1.361, 1.344, 1.344, 1.358, 1.384, 1.405, 1.431, 1.456, 1.479, 1.489, + 1.508, 1.488, 1.458, 1.425, 1.393, 1.361, 1.343, 1.322, 1.321, 1.342, 1.358, 1.385, 1.416, 1.445, 1.471, 1.484, + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, 1.318, 1.318, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, + 1.507, 1.482, 1.453, 1.418, 1.382, 1.349, 1.322, 1.313, 1.313, 1.321, 1.345, 1.373, 1.405, 1.437, 1.465, 1.483, + 1.507, 1.485, 1.455, 1.422, 1.387, 1.355, 1.333, 1.319, 1.321, 1.333, 1.351, 1.381, 1.411, 1.441, 1.467, 1.483, + 1.508, 1.489, 1.463, 1.432, 1.401, 1.372, 1.355, 1.333, 1.333, 1.351, 1.369, 1.393, 1.422, 1.448, 1.471, 1.484, + 1.511, 1.494, 1.472, 1.444, 1.416, 1.398, 1.372, 1.361, 1.361, 1.369, 1.393, 1.411, 1.436, 1.458, 1.477, 1.487, + 1.511, 1.496, 1.478, 1.455, 1.436, 1.416, 1.399, 1.391, 1.391, 1.397, 1.411, 1.429, 1.451, 1.466, 1.479, 1.487, + 1.511, 1.495, 1.478, 1.462, 1.448, 1.432, 1.419, 1.419, 1.419, 1.419, 1.429, 1.445, 1.459, 1.471, 1.482, 1.487 + ] + }, + { + "ct": 6000, "table": + [ + 2.581, 2.573, 2.558, 2.539, 2.514, 2.487, 2.473, 2.471, 2.471, 2.471, 2.479, 2.499, 2.517, 2.532, 2.543, 2.544, + 2.575, 2.559, 2.539, 2.521, 2.491, 2.458, 2.435, 2.421, 2.421, 2.429, 2.449, 2.477, 2.499, 2.519, 2.534, 2.543, + 2.561, 2.549, 2.521, 2.491, 2.457, 2.423, 2.393, 2.375, 2.375, 2.387, 2.412, 2.444, 2.475, 2.499, 2.519, 2.532, + 2.552, 2.531, 2.498, 2.459, 2.423, 2.391, 2.349, 2.325, 2.325, 2.344, 2.374, 2.412, 2.444, 2.476, 2.505, 2.519, + 2.543, 2.518, 2.479, 2.435, 2.392, 2.349, 2.324, 2.285, 2.283, 2.313, 2.344, 2.374, 2.417, 2.457, 2.489, 2.506, + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, 2.277, 2.279, 2.283, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, + 2.541, 2.511, 2.469, 2.421, 2.372, 2.326, 2.284, 2.267, 2.267, 2.281, 2.313, 2.357, 2.401, 2.443, 2.479, 2.504, + 2.541, 2.512, 2.472, 2.425, 2.381, 2.338, 2.302, 2.278, 2.279, 2.301, 2.324, 2.364, 2.407, 2.447, 2.481, 2.504, + 2.544, 2.519, 2.483, 2.441, 2.401, 2.363, 2.338, 2.302, 2.302, 2.324, 2.355, 2.385, 2.423, 2.459, 2.488, 2.506, + 2.549, 2.527, 2.497, 2.463, 2.427, 2.401, 2.363, 2.345, 2.345, 2.355, 2.385, 2.412, 2.444, 2.473, 2.497, 2.509, + 2.552, 2.532, 2.507, 2.481, 2.459, 2.427, 2.402, 2.389, 2.389, 2.394, 2.412, 2.444, 2.465, 2.481, 2.499, 2.511, + 2.553, 2.533, 2.508, 2.489, 2.475, 2.454, 2.429, 2.429, 2.429, 2.429, 2.439, 2.463, 2.481, 2.492, 2.504, 2.511 + ] + } + ], + "calibrations_Cb": + [ + { + "ct": 3000, "table": + [ + 3.132, 3.126, 3.116, 3.103, 3.097, 3.091, 3.087, 3.086, 3.088, 3.091, 3.092, 3.102, 3.113, 3.121, 3.141, 3.144, + 3.149, 3.132, 3.123, 3.108, 3.101, 3.096, 3.091, 3.089, 3.091, 3.092, 3.101, 3.107, 3.116, 3.129, 3.144, 3.153, + 3.161, 3.149, 3.129, 3.121, 3.108, 3.103, 3.101, 3.101, 3.101, 3.103, 3.107, 3.116, 3.125, 3.134, 3.153, 3.159, + 3.176, 3.161, 3.144, 3.129, 3.124, 3.121, 3.117, 3.118, 3.118, 3.119, 3.122, 3.125, 3.134, 3.146, 3.159, 3.171, + 3.183, 3.176, 3.157, 3.144, 3.143, 3.143, 3.139, 3.141, 3.141, 3.141, 3.141, 3.141, 3.146, 3.161, 3.171, 3.179, + 3.189, 3.183, 3.165, 3.157, 3.156, 3.157, 3.159, 3.163, 3.163, 3.163, 3.163, 3.161, 3.163, 3.169, 3.179, 3.187, + 3.199, 3.189, 3.171, 3.165, 3.164, 3.167, 3.171, 3.173, 3.173, 3.172, 3.171, 3.169, 3.169, 3.175, 3.187, 3.189, + 3.206, 3.196, 3.177, 3.171, 3.165, 3.167, 3.171, 3.173, 3.173, 3.172, 3.171, 3.171, 3.173, 3.177, 3.192, 3.194, + 3.209, 3.197, 3.178, 3.171, 3.164, 3.161, 3.159, 3.161, 3.162, 3.164, 3.167, 3.171, 3.173, 3.181, 3.193, 3.198, + 3.204, 3.194, 3.176, 3.165, 3.161, 3.156, 3.154, 3.154, 3.159, 3.161, 3.164, 3.168, 3.173, 3.182, 3.198, 3.199, + 3.199, 3.191, 3.176, 3.169, 3.161, 3.157, 3.153, 3.153, 3.156, 3.161, 3.164, 3.168, 3.173, 3.186, 3.196, 3.199, + 3.199, 3.188, 3.179, 3.173, 3.165, 3.157, 3.153, 3.154, 3.156, 3.159, 3.167, 3.171, 3.176, 3.185, 3.193, 3.198 + ] + }, + { + "ct": 6000, "table": + [ + 1.579, 1.579, 1.577, 1.574, 1.573, 1.571, 1.571, 1.571, 1.571, 1.569, 1.569, 1.571, 1.572, 1.574, 1.577, 1.578, + 1.584, 1.579, 1.578, 1.575, 1.573, 1.572, 1.571, 1.572, 1.572, 1.571, 1.571, 1.572, 1.573, 1.576, 1.578, 1.579, + 1.587, 1.584, 1.579, 1.578, 1.575, 1.573, 1.573, 1.575, 1.575, 1.574, 1.573, 1.574, 1.576, 1.578, 1.581, 1.581, + 1.591, 1.587, 1.584, 1.579, 1.578, 1.579, 1.579, 1.581, 1.581, 1.581, 1.578, 1.577, 1.578, 1.581, 1.585, 1.586, + 1.595, 1.591, 1.587, 1.585, 1.585, 1.586, 1.587, 1.587, 1.588, 1.588, 1.585, 1.584, 1.584, 1.586, 1.589, 1.589, + 1.597, 1.595, 1.591, 1.589, 1.591, 1.593, 1.595, 1.596, 1.597, 1.597, 1.595, 1.594, 1.592, 1.592, 1.593, 1.593, + 1.601, 1.597, 1.593, 1.592, 1.593, 1.595, 1.598, 1.599, 1.602, 1.601, 1.598, 1.596, 1.595, 1.596, 1.595, 1.595, + 1.601, 1.599, 1.594, 1.593, 1.593, 1.595, 1.598, 1.599, 1.602, 1.601, 1.598, 1.597, 1.597, 1.597, 1.597, 1.597, + 1.602, 1.599, 1.594, 1.593, 1.592, 1.593, 1.595, 1.597, 1.597, 1.598, 1.598, 1.597, 1.597, 1.597, 1.598, 1.598, + 1.599, 1.598, 1.594, 1.592, 1.591, 1.591, 1.592, 1.595, 1.596, 1.597, 1.597, 1.597, 1.597, 1.599, 1.599, 1.599, + 1.598, 1.596, 1.594, 1.593, 1.592, 1.592, 1.592, 1.594, 1.595, 1.597, 1.597, 1.597, 1.598, 1.599, 1.599, 1.599, + 1.597, 1.595, 1.594, 1.594, 1.593, 1.592, 1.593, 1.595, 1.595, 1.597, 1.598, 1.598, 1.598, 1.599, 1.599, 1.599 + ] + } + ], + "luminance_lut": + [ + 2.887, 2.754, 2.381, 2.105, 1.859, 1.678, 1.625, 1.623, 1.623, 1.624, 1.669, 1.849, 2.092, 2.362, 2.723, 2.838, + 2.754, 2.443, 2.111, 1.905, 1.678, 1.542, 1.455, 1.412, 1.412, 1.452, 1.535, 1.665, 1.893, 2.096, 2.413, 2.723, + 2.443, 2.216, 1.911, 1.678, 1.537, 1.372, 1.288, 1.245, 1.245, 1.283, 1.363, 1.527, 1.665, 1.895, 2.193, 2.413, + 2.318, 2.057, 1.764, 1.541, 1.372, 1.282, 1.159, 1.113, 1.113, 1.151, 1.269, 1.363, 1.527, 1.749, 2.034, 2.278, + 2.259, 1.953, 1.671, 1.452, 1.283, 1.159, 1.107, 1.018, 1.017, 1.097, 1.151, 1.269, 1.437, 1.655, 1.931, 2.222, + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.019, 1.011, 1.005, 1.014, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, + 2.257, 1.902, 1.624, 1.408, 1.239, 1.111, 1.016, 1.001, 1.001, 1.007, 1.098, 1.227, 1.395, 1.608, 1.883, 2.222, + 2.257, 1.946, 1.666, 1.448, 1.281, 1.153, 1.093, 1.013, 1.008, 1.089, 1.143, 1.269, 1.437, 1.654, 1.934, 2.226, + 2.309, 2.044, 1.756, 1.532, 1.363, 1.259, 1.153, 1.093, 1.093, 1.143, 1.264, 1.354, 1.524, 1.746, 2.035, 2.284, + 2.425, 2.201, 1.896, 1.662, 1.519, 1.363, 1.259, 1.214, 1.214, 1.264, 1.354, 1.519, 1.655, 1.888, 2.191, 2.413, + 2.724, 2.417, 2.091, 1.888, 1.662, 1.519, 1.419, 1.373, 1.373, 1.425, 1.521, 1.655, 1.885, 2.089, 2.409, 2.722, + 2.858, 2.724, 2.356, 2.085, 1.842, 1.658, 1.581, 1.577, 1.577, 1.579, 1.653, 1.838, 2.084, 2.359, 2.722, 2.842 + ], + "sigma": 0.00372, + "sigma_Cb": 0.00244 + }, + "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": 2890, "ccm": + [ + 1.36754, -0.18448, -0.18306, -0.32356, 1.44826, -0.12471, -0.00412, -0.69936, 1.70348 + ] + }, + { + "ct": 2920, "ccm": + [ + 1.26704, 0.01624, -0.28328, -0.28516, 1.38934, -0.10419, -0.04854, -0.82211, 1.87066 + ] + }, + { + "ct": 3550, "ccm": + [ + 1.42836, -0.27235, -0.15601, -0.28751, 1.41075, -0.12325, -0.01812, -0.54849, 1.56661 + ] + }, + { + "ct": 4500, "ccm": + [ + 1.36328, -0.19569, -0.16759, -0.25254, 1.52248, -0.26994, -0.01575, -0.53155, 1.54729 + ] + }, + { + "ct": 5700, "ccm": + [ + 1.49207, -0.37245, -0.11963, -0.21493, 1.40005, -0.18512, -0.03781, -0.38779, 1.42561 + ] + }, + { + "ct": 7900, "ccm": + [ + 1.34849, -0.05425, -0.29424, -0.22182, 1.77684, -0.55502, -0.07403, -0.55336, 1.62739 + ] + } + ] + }, + "rpi.sharpen": + { + } +} diff --git a/src/ipa/raspberrypi/data/meson.build b/src/ipa/raspberrypi/data/meson.build index 2def75cb..e84cd099 100644 --- a/src/ipa/raspberrypi/data/meson.build +++ b/src/ipa/raspberrypi/data/meson.build @@ -7,6 +7,7 @@ conf_files = files([ 'imx378.json', 'imx477.json', 'imx477_noir.json', + 'imx519.json', 'ov5647.json', 'ov5647_noir.json', 'ov9281.json', diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build index 1af31e4a..176055f4 100644 --- a/src/ipa/raspberrypi/meson.build +++ b/src/ipa/raspberrypi/meson.build @@ -22,6 +22,7 @@ rpi_ipa_sources = files([ 'cam_helper_imx219.cpp', 'cam_helper_imx290.cpp', 'cam_helper_imx477.cpp', + 'cam_helper_imx519.cpp', 'cam_helper_ov9281.cpp', 'controller/controller.cpp', 'controller/histogram.cpp',