summaryrefslogtreecommitdiff
path: root/src/ipa/raspberrypi
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa/raspberrypi')
-rw-r--r--src/ipa/raspberrypi/README.md25
-rw-r--r--src/ipa/raspberrypi/cam_helper.cpp219
-rw-r--r--src/ipa/raspberrypi/cam_helper.hpp123
-rw-r--r--src/ipa/raspberrypi/cam_helper_imx219.cpp109
-rw-r--r--src/ipa/raspberrypi/cam_helper_imx290.cpp67
-rw-r--r--src/ipa/raspberrypi/cam_helper_imx296.cpp69
-rw-r--r--src/ipa/raspberrypi/cam_helper_imx477.cpp186
-rw-r--r--src/ipa/raspberrypi/cam_helper_imx519.cpp185
-rw-r--r--src/ipa/raspberrypi/cam_helper_ov5647.cpp108
-rw-r--r--src/ipa/raspberrypi/cam_helper_ov9281.cpp65
-rw-r--r--src/ipa/raspberrypi/controller/agc_algorithm.hpp32
-rw-r--r--src/ipa/raspberrypi/controller/agc_status.h41
-rw-r--r--src/ipa/raspberrypi/controller/algorithm.cpp44
-rw-r--r--src/ipa/raspberrypi/controller/algorithm.hpp60
-rw-r--r--src/ipa/raspberrypi/controller/alsc_status.h27
-rw-r--r--src/ipa/raspberrypi/controller/awb_algorithm.hpp23
-rw-r--r--src/ipa/raspberrypi/controller/awb_status.h26
-rw-r--r--src/ipa/raspberrypi/controller/black_level_status.h23
-rw-r--r--src/ipa/raspberrypi/controller/camera_mode.h50
-rw-r--r--src/ipa/raspberrypi/controller/ccm_algorithm.hpp21
-rw-r--r--src/ipa/raspberrypi/controller/ccm_status.h22
-rw-r--r--src/ipa/raspberrypi/controller/contrast_algorithm.hpp22
-rw-r--r--src/ipa/raspberrypi/controller/contrast_status.h31
-rw-r--r--src/ipa/raspberrypi/controller/controller.cpp104
-rw-r--r--src/ipa/raspberrypi/controller/controller.hpp54
-rw-r--r--src/ipa/raspberrypi/controller/denoise_algorithm.hpp23
-rw-r--r--src/ipa/raspberrypi/controller/denoise_status.h24
-rw-r--r--src/ipa/raspberrypi/controller/device_status.cpp30
-rw-r--r--src/ipa/raspberrypi/controller/device_status.h41
-rw-r--r--src/ipa/raspberrypi/controller/dpc_status.h21
-rw-r--r--src/ipa/raspberrypi/controller/focus_status.h26
-rw-r--r--src/ipa/raspberrypi/controller/geq_status.h22
-rw-r--r--src/ipa/raspberrypi/controller/histogram.cpp64
-rw-r--r--src/ipa/raspberrypi/controller/histogram.hpp44
-rw-r--r--src/ipa/raspberrypi/controller/lux_status.h29
-rw-r--r--src/ipa/raspberrypi/controller/metadata.hpp110
-rw-r--r--src/ipa/raspberrypi/controller/noise_status.h22
-rw-r--r--src/ipa/raspberrypi/controller/pwl.cpp246
-rw-r--r--src/ipa/raspberrypi/controller/pwl.hpp112
-rw-r--r--src/ipa/raspberrypi/controller/rpi/agc.cpp797
-rw-r--r--src/ipa/raspberrypi/controller/rpi/agc.hpp139
-rw-r--r--src/ipa/raspberrypi/controller/rpi/alsc.cpp787
-rw-r--r--src/ipa/raspberrypi/controller/rpi/alsc.hpp106
-rw-r--r--src/ipa/raspberrypi/controller/rpi/awb.cpp667
-rw-r--r--src/ipa/raspberrypi/controller/rpi/awb.hpp179
-rw-r--r--src/ipa/raspberrypi/controller/rpi/black_level.cpp63
-rw-r--r--src/ipa/raspberrypi/controller/rpi/black_level.hpp30
-rw-r--r--src/ipa/raspberrypi/controller/rpi/ccm.cpp169
-rw-r--r--src/ipa/raspberrypi/controller/rpi/ccm.hpp75
-rw-r--r--src/ipa/raspberrypi/controller/rpi/contrast.cpp185
-rw-r--r--src/ipa/raspberrypi/controller/rpi/contrast.hpp50
-rw-r--r--src/ipa/raspberrypi/controller/rpi/dpc.cpp53
-rw-r--r--src/ipa/raspberrypi/controller/rpi/dpc.hpp32
-rw-r--r--src/ipa/raspberrypi/controller/rpi/focus.cpp50
-rw-r--r--src/ipa/raspberrypi/controller/rpi/focus.hpp28
-rw-r--r--src/ipa/raspberrypi/controller/rpi/geq.cpp81
-rw-r--r--src/ipa/raspberrypi/controller/rpi/geq.hpp34
-rw-r--r--src/ipa/raspberrypi/controller/rpi/lux.cpp104
-rw-r--r--src/ipa/raspberrypi/controller/rpi/lux.hpp43
-rw-r--r--src/ipa/raspberrypi/controller/rpi/noise.cpp76
-rw-r--r--src/ipa/raspberrypi/controller/rpi/noise.hpp32
-rw-r--r--src/ipa/raspberrypi/controller/rpi/sdn.cpp75
-rw-r--r--src/ipa/raspberrypi/controller/rpi/sdn.hpp32
-rw-r--r--src/ipa/raspberrypi/controller/rpi/sharpen.cpp85
-rw-r--r--src/ipa/raspberrypi/controller/rpi/sharpen.hpp34
-rw-r--r--src/ipa/raspberrypi/controller/sharpen_algorithm.hpp21
-rw-r--r--src/ipa/raspberrypi/controller/sharpen_status.h28
-rw-r--r--src/ipa/raspberrypi/data/imx219.json412
-rw-r--r--src/ipa/raspberrypi/data/imx219_noir.json344
-rw-r--r--src/ipa/raspberrypi/data/imx290.json165
-rw-r--r--src/ipa/raspberrypi/data/imx296.json191
-rw-r--r--src/ipa/raspberrypi/data/imx378.json338
-rw-r--r--src/ipa/raspberrypi/data/imx477.json430
-rw-r--r--src/ipa/raspberrypi/data/imx477_noir.json362
-rw-r--r--src/ipa/raspberrypi/data/imx519.json338
-rw-r--r--src/ipa/raspberrypi/data/meson.build20
-rw-r--r--src/ipa/raspberrypi/data/ov5647.json409
-rw-r--r--src/ipa/raspberrypi/data/ov5647_noir.json341
-rw-r--r--src/ipa/raspberrypi/data/ov9281.json92
-rw-r--r--src/ipa/raspberrypi/data/se327m12.json341
-rw-r--r--src/ipa/raspberrypi/data/uncalibrated.json82
-rw-r--r--src/ipa/raspberrypi/md_parser.hpp155
-rw-r--r--src/ipa/raspberrypi/md_parser_smia.cpp149
-rw-r--r--src/ipa/raspberrypi/meson.build66
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp1460
85 files changed, 0 insertions, 12300 deletions
diff --git a/src/ipa/raspberrypi/README.md b/src/ipa/raspberrypi/README.md
deleted file mode 100644
index 94a8ccc8..00000000
--- a/src/ipa/raspberrypi/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-.. SPDX-License-Identifier: BSD-2-Clause
-
-# _libcamera_ for the Raspberry Pi
-
-Raspberry Pi provides a fully featured pipeline handler and control algorithms
-(IPAs, or "Image Processing Algorithms") to work with _libcamera_. Support is
-included for all existing Raspberry Pi camera modules.
-
-_libcamera_ for the Raspberry Pi allows users to:
-
-1. Use their existing Raspberry Pi cameras.
-1. Change the tuning of the image processing for their Raspberry Pi cameras.
-1. Alter or amend the control algorithms (such as AGC/AEC, AWB or any others)
- that control the sensor and ISP.
-1. Implement their own custom control algorithms.
-1. Supply new tunings and/or algorithms for completely new sensors.
-
-## How to install and run _libcamera_ on the Raspberry Pi
-
-Please follow the instructions [here](https://www.raspberrypi.com/documentation/accessories/camera.html).
-
-## Documentation
-
-Full documentation for the _Raspberry Pi Camera Algorithm and Tuning Guide_ can
-be found [here](https://datasheets.raspberrypi.com/camera/raspberry-pi-camera-guide.pdf).
diff --git a/src/ipa/raspberrypi/cam_helper.cpp b/src/ipa/raspberrypi/cam_helper.cpp
deleted file mode 100644
index 3f81d418..00000000
--- a/src/ipa/raspberrypi/cam_helper.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * cam_helper.cpp - helper information for different sensors
- */
-
-#include <linux/videodev2.h>
-
-#include <assert.h>
-#include <map>
-#include <string.h>
-
-#include "libcamera/internal/v4l2_videodevice.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)
-}
-
-static std::map<std::string, CamHelperCreateFunc> cam_helpers;
-
-CamHelper *CamHelper::Create(std::string const &cam_name)
-{
- /*
- * CamHelpers get registered by static RegisterCamHelper
- * initialisers.
- */
- for (auto &p : cam_helpers) {
- if (cam_name.find(p.first) != std::string::npos)
- return p.second();
- }
-
- return nullptr;
-}
-
-CamHelper::CamHelper(std::unique_ptr<MdParser> parser, unsigned int frameIntegrationDiff)
- : parser_(std::move(parser)), initialized_(false),
- frameIntegrationDiff_(frameIntegrationDiff)
-{
-}
-
-CamHelper::~CamHelper()
-{
-}
-
-void CamHelper::Prepare(Span<const uint8_t> buffer,
- Metadata &metadata)
-{
- parseEmbeddedData(buffer, metadata);
-}
-
-void CamHelper::Process([[maybe_unused]] StatisticsPtr &stats,
- [[maybe_unused]] Metadata &metadata)
-{
-}
-
-uint32_t CamHelper::ExposureLines(const Duration exposure) const
-{
- assert(initialized_);
- return exposure / mode_.line_length;
-}
-
-Duration CamHelper::Exposure(uint32_t exposure_lines) const
-{
- assert(initialized_);
- return exposure_lines * mode_.line_length;
-}
-
-uint32_t CamHelper::GetVBlanking(Duration &exposure,
- Duration minFrameDuration,
- Duration maxFrameDuration) const
-{
- uint32_t frameLengthMin, frameLengthMax, vblank;
- uint32_t exposureLines = ExposureLines(exposure);
-
- assert(initialized_);
-
- /*
- * minFrameDuration and maxFrameDuration are clamped by the caller
- * based on the limits for the active sensor mode.
- */
- frameLengthMin = minFrameDuration / mode_.line_length;
- frameLengthMax = maxFrameDuration / mode_.line_length;
-
- /*
- * Limit the exposure to the maximum frame duration requested, and
- * re-calculate if it has been clipped.
- */
- exposureLines = std::min(frameLengthMax - frameIntegrationDiff_, exposureLines);
- exposure = Exposure(exposureLines);
-
- /* Limit the vblank to the range allowed by the frame length limits. */
- vblank = std::clamp(exposureLines + frameIntegrationDiff_,
- frameLengthMin, frameLengthMax) - mode_.height;
- return vblank;
-}
-
-void CamHelper::SetCameraMode(const CameraMode &mode)
-{
- mode_ = mode;
- if (parser_) {
- parser_->SetBitsPerPixel(mode.bitdepth);
- parser_->SetLineLengthBytes(0); /* We use SetBufferSize. */
- }
- initialized_ = true;
-}
-
-void CamHelper::GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const
-{
- /*
- * These values are correct for many sensors. Other sensors will
- * need to over-ride this function.
- */
- exposure_delay = 2;
- gain_delay = 1;
- vblank_delay = 2;
-}
-
-bool CamHelper::SensorEmbeddedDataPresent() const
-{
- return false;
-}
-
-double CamHelper::GetModeSensitivity([[maybe_unused]] const CameraMode &mode) const
-{
- /*
- * Most sensors have the same sensitivity in every mode, but this
- * function can be overridden for those that do not. Note that it is
- * called before mode_ is set, so it must return the sensitivity
- * of the mode that is passed in.
- */
- return 1.0;
-}
-
-unsigned int CamHelper::HideFramesStartup() const
-{
- /*
- * The number of frames when a camera first starts that shouldn't be
- * displayed as they are invalid in some way.
- */
- return 0;
-}
-
-unsigned int CamHelper::HideFramesModeSwitch() const
-{
- /* After a mode switch, many sensors return valid frames immediately. */
- return 0;
-}
-
-unsigned int CamHelper::MistrustFramesStartup() const
-{
- /* Many sensors return a single bad frame on start-up. */
- return 1;
-}
-
-unsigned int CamHelper::MistrustFramesModeSwitch() const
-{
- /* Many sensors return valid metadata immediately. */
- return 0;
-}
-
-void CamHelper::parseEmbeddedData(Span<const uint8_t> buffer,
- Metadata &metadata)
-{
- MdParser::RegisterMap registers;
- Metadata parsedMetadata;
-
- if (buffer.empty())
- return;
-
- if (parser_->Parse(buffer, registers) != MdParser::Status::OK) {
- LOG(IPARPI, Error) << "Embedded data buffer parsing failed";
- return;
- }
-
- PopulateMetadata(registers, parsedMetadata);
- metadata.Merge(parsedMetadata);
-
- /*
- * Overwrite the exposure/gain, frame length and sensor temperature values
- * in the existing DeviceStatus with values from the parsed embedded buffer.
- * Fetch it first in case any other fields were set meaningfully.
- */
- DeviceStatus deviceStatus, parsedDeviceStatus;
- if (metadata.Get("device.status", deviceStatus) ||
- parsedMetadata.Get("device.status", parsedDeviceStatus)) {
- LOG(IPARPI, Error) << "DeviceStatus not found";
- return;
- }
-
- deviceStatus.shutter_speed = parsedDeviceStatus.shutter_speed;
- deviceStatus.analogue_gain = parsedDeviceStatus.analogue_gain;
- deviceStatus.frame_length = parsedDeviceStatus.frame_length;
- if (parsedDeviceStatus.sensor_temperature)
- deviceStatus.sensor_temperature = parsedDeviceStatus.sensor_temperature;
-
- LOG(IPARPI, Debug) << "Metadata updated - " << deviceStatus;
-
- metadata.Set("device.status", deviceStatus);
-}
-
-void CamHelper::PopulateMetadata([[maybe_unused]] const MdParser::RegisterMap &registers,
- [[maybe_unused]] Metadata &metadata) const
-{
-}
-
-RegisterCamHelper::RegisterCamHelper(char const *cam_name,
- CamHelperCreateFunc create_func)
-{
- cam_helpers[std::string(cam_name)] = create_func;
-}
diff --git a/src/ipa/raspberrypi/cam_helper.hpp b/src/ipa/raspberrypi/cam_helper.hpp
deleted file mode 100644
index 300f8f8a..00000000
--- a/src/ipa/raspberrypi/cam_helper.hpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * cam_helper.hpp - helper class providing camera information
- */
-#pragma once
-
-#include <memory>
-#include <string>
-
-#include <libcamera/base/span.h>
-#include <libcamera/base/utils.h>
-
-#include "camera_mode.h"
-#include "controller/controller.hpp"
-#include "controller/metadata.hpp"
-#include "md_parser.hpp"
-
-#include "libcamera/internal/v4l2_videodevice.h"
-
-namespace RPiController {
-
-// The CamHelper class provides a number of facilities that anyone trying
-// to drive a camera will need to know, but which are not provided by the
-// standard driver framework. Specifically, it provides:
-//
-// A "CameraMode" structure to describe extra information about the chosen
-// mode of the driver. For example, how it is cropped from the full sensor
-// area, how it is scaled, whether pixels are averaged compared to the full
-// resolution.
-//
-// The ability to convert between number of lines of exposure and actual
-// exposure time, and to convert between the sensor's gain codes and actual
-// gains.
-//
-// A function to return the number of frames of delay between updating exposure,
-// analogue gain and vblanking, and for the changes to take effect. For many
-// sensors these take the values 2, 1 and 2 respectively, but sensors that are
-// different will need to over-ride the default function provided.
-//
-// A function to query if the sensor outputs embedded data that can be parsed.
-//
-// A function to return the sensitivity of a given camera mode.
-//
-// A parser to parse the embedded data buffers provided by some sensors (for
-// example, the imx219 does; the ov5647 doesn't). This allows us to know for
-// sure the exposure and gain of the frame we're looking at. CamHelper
-// provides functions for converting analogue gains to and from the sensor's
-// native gain codes.
-//
-// Finally, a set of functions that determine how to handle the vagaries of
-// different camera modules on start-up or when switching modes. Some
-// modules may produce one or more frames that are not yet correctly exposed,
-// or where the metadata may be suspect. We have the following functions:
-// HideFramesStartup(): Tell the pipeline handler not to return this many
-// frames at start-up. This can also be used to hide initial frames
-// while the AGC and other algorithms are sorting themselves out.
-// HideFramesModeSwitch(): Tell the pipeline handler not to return this
-// many frames after a mode switch (other than start-up). Some sensors
-// may produce innvalid frames after a mode switch; others may not.
-// MistrustFramesStartup(): At start-up a sensor may return frames for
-// which we should not run any control algorithms (for example, metadata
-// may be invalid).
-// MistrustFramesModeSwitch(): The number of frames, after a mode switch
-// (other than start-up), for which control algorithms should not run
-// (for example, metadata may be unreliable).
-
-class CamHelper
-{
-public:
- static CamHelper *Create(std::string const &cam_name);
- CamHelper(std::unique_ptr<MdParser> parser, unsigned int frameIntegrationDiff);
- virtual ~CamHelper();
- void SetCameraMode(const CameraMode &mode);
- virtual void Prepare(libcamera::Span<const uint8_t> buffer,
- Metadata &metadata);
- virtual void Process(StatisticsPtr &stats, Metadata &metadata);
- virtual uint32_t ExposureLines(libcamera::utils::Duration exposure) const;
- virtual libcamera::utils::Duration Exposure(uint32_t exposure_lines) const;
- virtual uint32_t GetVBlanking(libcamera::utils::Duration &exposure,
- libcamera::utils::Duration minFrameDuration,
- libcamera::utils::Duration maxFrameDuration) const;
- virtual uint32_t GainCode(double gain) const = 0;
- virtual double Gain(uint32_t gain_code) const = 0;
- virtual void GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const;
- virtual bool SensorEmbeddedDataPresent() const;
- virtual double GetModeSensitivity(const CameraMode &mode) const;
- virtual unsigned int HideFramesStartup() const;
- virtual unsigned int HideFramesModeSwitch() const;
- virtual unsigned int MistrustFramesStartup() const;
- virtual unsigned int MistrustFramesModeSwitch() const;
-
-protected:
- void parseEmbeddedData(libcamera::Span<const uint8_t> buffer,
- Metadata &metadata);
- virtual void PopulateMetadata(const MdParser::RegisterMap &registers,
- Metadata &metadata) const;
-
- std::unique_ptr<MdParser> parser_;
- CameraMode mode_;
-
-private:
- bool initialized_;
- /*
- * Smallest difference between the frame length and integration time,
- * in units of lines.
- */
- unsigned int frameIntegrationDiff_;
-};
-
-// This is for registering camera helpers with the system, so that the
-// CamHelper::Create function picks them up automatically.
-
-typedef CamHelper *(*CamHelperCreateFunc)();
-struct RegisterCamHelper
-{
- RegisterCamHelper(char const *cam_name,
- CamHelperCreateFunc create_func);
-};
-
-} // namespace RPi
diff --git a/src/ipa/raspberrypi/cam_helper_imx219.cpp b/src/ipa/raspberrypi/cam_helper_imx219.cpp
deleted file mode 100644
index a3caab71..00000000
--- a/src/ipa/raspberrypi/cam_helper_imx219.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * cam_helper_imx219.cpp - camera helper for imx219 sensor
- */
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/*
- * We have observed that the imx219 embedded data stream randomly returns junk
- * register values. Do not rely on embedded data until this has been resolved.
- */
-#define ENABLE_EMBEDDED_DATA 0
-
-#include "cam_helper.hpp"
-#if ENABLE_EMBEDDED_DATA
-#include "md_parser.hpp"
-#endif
-
-using namespace RPiController;
-
-/*
- * We care about one gain register and a pair of exposure registers. Their I2C
- * addresses from the Sony IMX219 datasheet:
- */
-constexpr uint32_t gainReg = 0x157;
-constexpr uint32_t expHiReg = 0x15a;
-constexpr uint32_t expLoReg = 0x15b;
-constexpr uint32_t frameLengthHiReg = 0x160;
-constexpr uint32_t frameLengthLoReg = 0x161;
-constexpr std::initializer_list<uint32_t> registerList [[maybe_unused]]
- = { expHiReg, expLoReg, gainReg, frameLengthHiReg, frameLengthLoReg };
-
-class CamHelperImx219 : public CamHelper
-{
-public:
- CamHelperImx219();
- uint32_t GainCode(double gain) const override;
- double Gain(uint32_t gain_code) const override;
- unsigned int MistrustFramesModeSwitch() const override;
- bool SensorEmbeddedDataPresent() const override;
-
-private:
- /*
- * Smallest difference between the frame length and integration time,
- * in units of lines.
- */
- static constexpr int frameIntegrationDiff = 4;
-
- void PopulateMetadata(const MdParser::RegisterMap &registers,
- Metadata &metadata) const override;
-};
-
-CamHelperImx219::CamHelperImx219()
-#if ENABLE_EMBEDDED_DATA
- : CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff)
-#else
- : CamHelper({}, frameIntegrationDiff)
-#endif
-{
-}
-
-uint32_t CamHelperImx219::GainCode(double gain) const
-{
- return (uint32_t)(256 - 256 / gain);
-}
-
-double CamHelperImx219::Gain(uint32_t gain_code) const
-{
- return 256.0 / (256 - gain_code);
-}
-
-unsigned int CamHelperImx219::MistrustFramesModeSwitch() const
-{
- /*
- * For reasons unknown, we do occasionally get a bogus metadata frame
- * at a mode switch (though not at start-up). Possibly warrants some
- * investigation, though not a big deal.
- */
- return 1;
-}
-
-bool CamHelperImx219::SensorEmbeddedDataPresent() const
-{
- return ENABLE_EMBEDDED_DATA;
-}
-
-void CamHelperImx219::PopulateMetadata(const MdParser::RegisterMap &registers,
- Metadata &metadata) const
-{
- DeviceStatus deviceStatus;
-
- deviceStatus.shutter_speed = Exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg));
- deviceStatus.analogue_gain = Gain(registers.at(gainReg));
- deviceStatus.frame_length = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
-
- metadata.Set("device.status", deviceStatus);
-}
-
-static CamHelper *Create()
-{
- return new CamHelperImx219();
-}
-
-static RegisterCamHelper reg("imx219", &Create);
diff --git a/src/ipa/raspberrypi/cam_helper_imx290.cpp b/src/ipa/raspberrypi/cam_helper_imx290.cpp
deleted file mode 100644
index 871c1f8e..00000000
--- a/src/ipa/raspberrypi/cam_helper_imx290.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2021, Raspberry Pi (Trading) Limited
- *
- * cam_helper_imx290.cpp - camera helper for imx290 sensor
- */
-
-#include <math.h>
-
-#include "cam_helper.hpp"
-
-using namespace RPiController;
-
-class CamHelperImx290 : public CamHelper
-{
-public:
- CamHelperImx290();
- uint32_t GainCode(double gain) const override;
- double Gain(uint32_t gain_code) const override;
- void GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const override;
- unsigned int HideFramesModeSwitch() const override;
-
-private:
- /*
- * Smallest difference between the frame length and integration time,
- * in units of lines.
- */
- static constexpr int frameIntegrationDiff = 2;
-};
-
-CamHelperImx290::CamHelperImx290()
- : CamHelper({}, frameIntegrationDiff)
-{
-}
-
-uint32_t CamHelperImx290::GainCode(double gain) const
-{
- int code = 66.6667 * log10(gain);
- return std::max(0, std::min(code, 0xf0));
-}
-
-double CamHelperImx290::Gain(uint32_t gain_code) const
-{
- return pow(10, 0.015 * gain_code);
-}
-
-void CamHelperImx290::GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const
-{
- exposure_delay = 2;
- gain_delay = 2;
- vblank_delay = 2;
-}
-
-unsigned int CamHelperImx290::HideFramesModeSwitch() const
-{
- /* After a mode switch, we seem to get 1 bad frame. */
- return 1;
-}
-
-static CamHelper *Create()
-{
- return new CamHelperImx290();
-}
-
-static RegisterCamHelper reg("imx290", &Create);
diff --git a/src/ipa/raspberrypi/cam_helper_imx296.cpp b/src/ipa/raspberrypi/cam_helper_imx296.cpp
deleted file mode 100644
index a1a771cb..00000000
--- a/src/ipa/raspberrypi/cam_helper_imx296.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2020, Raspberry Pi (Trading) Limited
- *
- * cam_helper_imx296.cpp - Camera helper for IMX296 sensor
- */
-
-#include <algorithm>
-#include <cmath>
-#include <stddef.h>
-
-#include "cam_helper.hpp"
-
-using namespace RPiController;
-using libcamera::utils::Duration;
-using namespace std::literals::chrono_literals;
-
-class CamHelperImx296 : public CamHelper
-{
-public:
- CamHelperImx296();
- uint32_t GainCode(double gain) const override;
- double Gain(uint32_t gain_code) const override;
- uint32_t ExposureLines(Duration exposure) const override;
- Duration Exposure(uint32_t exposure_lines) const override;
-
-private:
- static constexpr uint32_t maxGainCode = 239;
- static constexpr Duration timePerLine = 550.0 / 37.125e6 * 1.0s;
-
- /*
- * Smallest difference between the frame length and integration time,
- * in units of lines.
- */
- static constexpr int frameIntegrationDiff = 4;
-};
-
-CamHelperImx296::CamHelperImx296()
- : CamHelper(nullptr, frameIntegrationDiff)
-{
-}
-
-uint32_t CamHelperImx296::GainCode(double gain) const
-{
- uint32_t code = 20 * std::log10(gain) * 10;
- return std::min(code, maxGainCode);
-}
-
-double CamHelperImx296::Gain(uint32_t gain_code) const
-{
- return std::pow(10.0, gain_code / 200.0);
-}
-
-uint32_t CamHelperImx296::ExposureLines(Duration exposure) const
-{
- return (exposure - 14.26us) / timePerLine;
-}
-
-Duration CamHelperImx296::Exposure(uint32_t exposure_lines) const
-{
- return exposure_lines * timePerLine + 14.26us;
-}
-
-static CamHelper *Create()
-{
- return new CamHelperImx296();
-}
-
-static RegisterCamHelper reg("imx296", &Create);
diff --git a/src/ipa/raspberrypi/cam_helper_imx477.cpp b/src/ipa/raspberrypi/cam_helper_imx477.cpp
deleted file mode 100644
index 0e1c0dbd..00000000
--- a/src/ipa/raspberrypi/cam_helper_imx477.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2020, Raspberry Pi (Trading) Limited
- *
- * cam_helper_imx477.cpp - camera helper for imx477 sensor
- */
-
-#include <algorithm>
-#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 IMX477 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 uint32_t temperatureReg = 0x013a;
-constexpr std::initializer_list<uint32_t> registerList =
- { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, frameLengthLoReg, temperatureReg };
-
-class CamHelperImx477 : public CamHelper
-{
-public:
- CamHelperImx477();
- 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 = 22;
- /* 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 &registers,
- Metadata &metadata) const override;
-};
-
-CamHelperImx477::CamHelperImx477()
- : CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff)
-{
-}
-
-uint32_t CamHelperImx477::GainCode(double gain) const
-{
- return static_cast<uint32_t>(1024 - 1024 / gain);
-}
-
-double CamHelperImx477::Gain(uint32_t gain_code) const
-{
- return 1024.0 / (1024 - gain_code);
-}
-
-void CamHelperImx477::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 CamHelperImx477::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 CamHelperImx477::GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const
-{
- exposure_delay = 2;
- gain_delay = 2;
- vblank_delay = 3;
-}
-
-bool CamHelperImx477::SensorEmbeddedDataPresent() const
-{
- return true;
-}
-
-void CamHelperImx477::PopulateMetadata(const MdParser::RegisterMap &registers,
- 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);
- deviceStatus.sensor_temperature = std::clamp<int8_t>(registers.at(temperatureReg), -20, 80);
-
- metadata.Set("device.status", deviceStatus);
-}
-
-static CamHelper *Create()
-{
- return new CamHelperImx477();
-}
-
-static RegisterCamHelper reg("imx477", &Create);
diff --git a/src/ipa/raspberrypi/cam_helper_imx519.cpp b/src/ipa/raspberrypi/cam_helper_imx519.cpp
deleted file mode 100644
index eaf24982..00000000
--- a/src/ipa/raspberrypi/cam_helper_imx519.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* 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 &registers,
- 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 &registers,
- 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/cam_helper_ov5647.cpp b/src/ipa/raspberrypi/cam_helper_ov5647.cpp
deleted file mode 100644
index 702c2d07..00000000
--- a/src/ipa/raspberrypi/cam_helper_ov5647.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * cam_helper_ov5647.cpp - camera information for ov5647 sensor
- */
-
-#include <assert.h>
-
-#include "cam_helper.hpp"
-
-using namespace RPiController;
-
-class CamHelperOv5647 : public CamHelper
-{
-public:
- CamHelperOv5647();
- uint32_t GainCode(double gain) const override;
- double Gain(uint32_t gain_code) const override;
- void GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const override;
- unsigned int HideFramesStartup() const override;
- unsigned int HideFramesModeSwitch() const override;
- unsigned int MistrustFramesStartup() const override;
- unsigned int MistrustFramesModeSwitch() const override;
-
-private:
- /*
- * Smallest difference between the frame length and integration time,
- * in units of lines.
- */
- static constexpr int frameIntegrationDiff = 4;
-};
-
-/*
- * OV5647 doesn't output metadata, so we have to use the "unicam parser" which
- * works by counting frames.
- */
-
-CamHelperOv5647::CamHelperOv5647()
- : CamHelper({}, frameIntegrationDiff)
-{
-}
-
-uint32_t CamHelperOv5647::GainCode(double gain) const
-{
- return static_cast<uint32_t>(gain * 16.0);
-}
-
-double CamHelperOv5647::Gain(uint32_t gain_code) const
-{
- return static_cast<double>(gain_code) / 16.0;
-}
-
-void CamHelperOv5647::GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const
-{
- /*
- * We run this sensor in a mode where the gain delay is bumped up to
- * 2. It seems to be the only way to make the delays "predictable".
- */
- exposure_delay = 2;
- gain_delay = 2;
- vblank_delay = 2;
-}
-
-unsigned int CamHelperOv5647::HideFramesStartup() const
-{
- /*
- * On startup, we get a couple of under-exposed frames which
- * we don't want shown.
- */
- return 2;
-}
-
-unsigned int CamHelperOv5647::HideFramesModeSwitch() const
-{
- /*
- * After a mode switch, we get a couple of under-exposed frames which
- * we don't want shown.
- */
- return 2;
-}
-
-unsigned int CamHelperOv5647::MistrustFramesStartup() const
-{
- /*
- * First couple of frames are under-exposed and are no good for control
- * algos.
- */
- return 2;
-}
-
-unsigned int CamHelperOv5647::MistrustFramesModeSwitch() const
-{
- /*
- * First couple of frames are under-exposed even after a simple
- * mode switch, and are no good for control algos.
- */
- return 2;
-}
-
-static CamHelper *Create()
-{
- return new CamHelperOv5647();
-}
-
-static RegisterCamHelper reg("ov5647", &Create);
diff --git a/src/ipa/raspberrypi/cam_helper_ov9281.cpp b/src/ipa/raspberrypi/cam_helper_ov9281.cpp
deleted file mode 100644
index 9de868c3..00000000
--- a/src/ipa/raspberrypi/cam_helper_ov9281.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2021, Raspberry Pi (Trading) Limited
- *
- * cam_helper_ov9281.cpp - camera information for ov9281 sensor
- */
-
-#include <assert.h>
-
-#include "cam_helper.hpp"
-
-using namespace RPiController;
-
-class CamHelperOv9281 : public CamHelper
-{
-public:
- CamHelperOv9281();
- uint32_t GainCode(double gain) const override;
- double Gain(uint32_t gain_code) const override;
- void GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const override;
-
-private:
- /*
- * Smallest difference between the frame length and integration time,
- * in units of lines.
- */
- static constexpr int frameIntegrationDiff = 4;
-};
-
-/*
- * OV9281 doesn't output metadata, so we have to use the "unicam parser" which
- * works by counting frames.
- */
-
-CamHelperOv9281::CamHelperOv9281()
- : CamHelper({}, frameIntegrationDiff)
-{
-}
-
-uint32_t CamHelperOv9281::GainCode(double gain) const
-{
- return static_cast<uint32_t>(gain * 16.0);
-}
-
-double CamHelperOv9281::Gain(uint32_t gain_code) const
-{
- return static_cast<double>(gain_code) / 16.0;
-}
-
-void CamHelperOv9281::GetDelays(int &exposure_delay, int &gain_delay,
- int &vblank_delay) const
-{
- /* The driver appears to behave as follows: */
- exposure_delay = 2;
- gain_delay = 2;
- vblank_delay = 2;
-}
-
-static CamHelper *Create()
-{
- return new CamHelperOv9281();
-}
-
-static RegisterCamHelper reg("ov9281", &Create);
diff --git a/src/ipa/raspberrypi/controller/agc_algorithm.hpp b/src/ipa/raspberrypi/controller/agc_algorithm.hpp
deleted file mode 100644
index 61595ea2..00000000
--- a/src/ipa/raspberrypi/controller/agc_algorithm.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * agc_algorithm.hpp - AGC/AEC control algorithm interface
- */
-#pragma once
-
-#include <libcamera/base/utils.h>
-
-#include "algorithm.hpp"
-
-namespace RPiController {
-
-class AgcAlgorithm : public Algorithm
-{
-public:
- AgcAlgorithm(Controller *controller) : Algorithm(controller) {}
- // An AGC algorithm must provide the following:
- virtual unsigned int GetConvergenceFrames() const = 0;
- virtual void SetEv(double ev) = 0;
- virtual void SetFlickerPeriod(libcamera::utils::Duration flicker_period) = 0;
- virtual void SetFixedShutter(libcamera::utils::Duration fixed_shutter) = 0;
- virtual void SetMaxShutter(libcamera::utils::Duration max_shutter) = 0;
- virtual void SetFixedAnalogueGain(double fixed_analogue_gain) = 0;
- virtual void SetMeteringMode(std::string const &metering_mode_name) = 0;
- virtual void SetExposureMode(std::string const &exposure_mode_name) = 0;
- virtual void
- SetConstraintMode(std::string const &contraint_mode_name) = 0;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/agc_status.h b/src/ipa/raspberrypi/controller/agc_status.h
deleted file mode 100644
index 20cb1b62..00000000
--- a/src/ipa/raspberrypi/controller/agc_status.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * agc_status.h - AGC/AEC control algorithm status
- */
-#pragma once
-
-#include <libcamera/base/utils.h>
-
-// The AGC algorithm should post the following structure into the image's
-// "agc.status" metadata.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Note: total_exposure_value will be reported as zero until the algorithm has
-// seen statistics and calculated meaningful values. The contents should be
-// ignored until then.
-
-struct AgcStatus {
- libcamera::utils::Duration total_exposure_value; // value for all exposure and gain for this image
- libcamera::utils::Duration target_exposure_value; // (unfiltered) target total exposure AGC is aiming for
- libcamera::utils::Duration shutter_time;
- double analogue_gain;
- char exposure_mode[32];
- char constraint_mode[32];
- char metering_mode[32];
- double ev;
- libcamera::utils::Duration flicker_period;
- int floating_region_enable;
- libcamera::utils::Duration fixed_shutter;
- double fixed_analogue_gain;
- double digital_gain;
- int locked;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/algorithm.cpp b/src/ipa/raspberrypi/controller/algorithm.cpp
deleted file mode 100644
index 43ad0a2b..00000000
--- a/src/ipa/raspberrypi/controller/algorithm.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * algorithm.cpp - ISP control algorithms
- */
-
-#include "algorithm.hpp"
-
-using namespace RPiController;
-
-void Algorithm::Read([[maybe_unused]] boost::property_tree::ptree const &params)
-{
-}
-
-void Algorithm::Initialise() {}
-
-void Algorithm::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,
- [[maybe_unused]] Metadata *metadata)
-{
-}
-
-void Algorithm::Prepare([[maybe_unused]] Metadata *image_metadata)
-{
-}
-
-void Algorithm::Process([[maybe_unused]] StatisticsPtr &stats,
- [[maybe_unused]] Metadata *image_metadata)
-{
-}
-
-// For registering algorithms with the system:
-
-static std::map<std::string, AlgoCreateFunc> algorithms;
-std::map<std::string, AlgoCreateFunc> const &RPiController::GetAlgorithms()
-{
- return algorithms;
-}
-
-RegisterAlgorithm::RegisterAlgorithm(char const *name,
- AlgoCreateFunc create_func)
-{
- algorithms[std::string(name)] = create_func;
-}
diff --git a/src/ipa/raspberrypi/controller/algorithm.hpp b/src/ipa/raspberrypi/controller/algorithm.hpp
deleted file mode 100644
index 5123c87b..00000000
--- a/src/ipa/raspberrypi/controller/algorithm.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * algorithm.hpp - ISP control algorithm interface
- */
-#pragma once
-
-// All algorithms should be derived from this class and made available to the
-// Controller.
-
-#include <string>
-#include <memory>
-#include <map>
-
-#include "controller.hpp"
-
-#include <boost/property_tree/ptree.hpp>
-
-namespace RPiController {
-
-// This defines the basic interface for all control algorithms.
-
-class Algorithm
-{
-public:
- Algorithm(Controller *controller)
- : controller_(controller), paused_(false)
- {
- }
- virtual ~Algorithm() = default;
- virtual char const *Name() const = 0;
- virtual bool IsPaused() const { return paused_; }
- virtual void Pause() { paused_ = true; }
- virtual void Resume() { paused_ = false; }
- virtual void Read(boost::property_tree::ptree const &params);
- virtual void Initialise();
- virtual void SwitchMode(CameraMode const &camera_mode, Metadata *metadata);
- virtual void Prepare(Metadata *image_metadata);
- virtual void Process(StatisticsPtr &stats, Metadata *image_metadata);
- Metadata &GetGlobalMetadata() const
- {
- return controller_->GetGlobalMetadata();
- }
-
-private:
- Controller *controller_;
- bool paused_;
-};
-
-// This code is for automatic registration of Front End algorithms with the
-// system.
-
-typedef Algorithm *(*AlgoCreateFunc)(Controller *controller);
-struct RegisterAlgorithm {
- RegisterAlgorithm(char const *name, AlgoCreateFunc create_func);
-};
-std::map<std::string, AlgoCreateFunc> const &GetAlgorithms();
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/alsc_status.h b/src/ipa/raspberrypi/controller/alsc_status.h
deleted file mode 100644
index d3f57971..00000000
--- a/src/ipa/raspberrypi/controller/alsc_status.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * alsc_status.h - ALSC (auto lens shading correction) control algorithm status
- */
-#pragma once
-
-// The ALSC algorithm should post the following structure into the image's
-// "alsc.status" metadata.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ALSC_CELLS_X 16
-#define ALSC_CELLS_Y 12
-
-struct AlscStatus {
- double r[ALSC_CELLS_Y][ALSC_CELLS_X];
- double g[ALSC_CELLS_Y][ALSC_CELLS_X];
- double b[ALSC_CELLS_Y][ALSC_CELLS_X];
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/awb_algorithm.hpp b/src/ipa/raspberrypi/controller/awb_algorithm.hpp
deleted file mode 100644
index 96f88afc..00000000
--- a/src/ipa/raspberrypi/controller/awb_algorithm.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * awb_algorithm.hpp - AWB control algorithm interface
- */
-#pragma once
-
-#include "algorithm.hpp"
-
-namespace RPiController {
-
-class AwbAlgorithm : public Algorithm
-{
-public:
- AwbAlgorithm(Controller *controller) : Algorithm(controller) {}
- // An AWB algorithm must provide the following:
- virtual unsigned int GetConvergenceFrames() const = 0;
- virtual void SetMode(std::string const &mode_name) = 0;
- virtual void SetManualGains(double manual_r, double manual_b) = 0;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/awb_status.h b/src/ipa/raspberrypi/controller/awb_status.h
deleted file mode 100644
index 46d7c842..00000000
--- a/src/ipa/raspberrypi/controller/awb_status.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * awb_status.h - AWB control algorithm status
- */
-#pragma once
-
-// The AWB algorithm places its results into both the image and global metadata,
-// under the tag "awb.status".
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AwbStatus {
- char mode[32];
- double temperature_K;
- double gain_r;
- double gain_g;
- double gain_b;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/black_level_status.h b/src/ipa/raspberrypi/controller/black_level_status.h
deleted file mode 100644
index d085f64b..00000000
--- a/src/ipa/raspberrypi/controller/black_level_status.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * black_level_status.h - black level control algorithm status
- */
-#pragma once
-
-// The "black level" algorithm stores the black levels to use.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct BlackLevelStatus {
- uint16_t black_level_r; // out of 16 bits
- uint16_t black_level_g;
- uint16_t black_level_b;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/camera_mode.h b/src/ipa/raspberrypi/controller/camera_mode.h
deleted file mode 100644
index e2b82828..00000000
--- a/src/ipa/raspberrypi/controller/camera_mode.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019-2020, Raspberry Pi (Trading) Limited
- *
- * camera_mode.h - description of a particular operating mode of a sensor
- */
-#pragma once
-
-#include <libcamera/transform.h>
-
-#include <libcamera/base/utils.h>
-
-// Description of a "camera mode", holding enough information for control
-// algorithms to adapt their behaviour to the different modes of the camera,
-// including binning, scaling, cropping etc.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define CAMERA_MODE_NAME_LEN 32
-
-struct CameraMode {
- // bit depth of the raw camera output
- uint32_t bitdepth;
- // size in pixels of frames in this mode
- uint16_t width, height;
- // size of full resolution uncropped frame ("sensor frame")
- uint16_t sensor_width, sensor_height;
- // binning factor (1 = no binning, 2 = 2-pixel binning etc.)
- uint8_t bin_x, bin_y;
- // location of top left pixel in the sensor frame
- uint16_t crop_x, crop_y;
- // scaling factor (so if uncropped, width*scale_x is sensor_width)
- double scale_x, scale_y;
- // scaling of the noise compared to the native sensor mode
- double noise_factor;
- // line time
- libcamera::utils::Duration line_length;
- // any camera transform *not* reflected already in the camera tuning
- libcamera::Transform transform;
- // minimum and maximum fame lengths in units of lines
- uint32_t min_frame_length, max_frame_length;
- // sensitivity of this mode
- double sensitivity;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/ccm_algorithm.hpp b/src/ipa/raspberrypi/controller/ccm_algorithm.hpp
deleted file mode 100644
index 33d0e30d..00000000
--- a/src/ipa/raspberrypi/controller/ccm_algorithm.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * ccm_algorithm.hpp - CCM (colour correction matrix) control algorithm interface
- */
-#pragma once
-
-#include "algorithm.hpp"
-
-namespace RPiController {
-
-class CcmAlgorithm : public Algorithm
-{
-public:
- CcmAlgorithm(Controller *controller) : Algorithm(controller) {}
- // A CCM algorithm must provide the following:
- virtual void SetSaturation(double saturation) = 0;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/ccm_status.h b/src/ipa/raspberrypi/controller/ccm_status.h
deleted file mode 100644
index 7e41dd1f..00000000
--- a/src/ipa/raspberrypi/controller/ccm_status.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * ccm_status.h - CCM (colour correction matrix) control algorithm status
- */
-#pragma once
-
-// The "ccm" algorithm generates an appropriate colour matrix.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct CcmStatus {
- double matrix[9];
- double saturation;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/contrast_algorithm.hpp b/src/ipa/raspberrypi/controller/contrast_algorithm.hpp
deleted file mode 100644
index 7f03bba5..00000000
--- a/src/ipa/raspberrypi/controller/contrast_algorithm.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * contrast_algorithm.hpp - contrast (gamma) control algorithm interface
- */
-#pragma once
-
-#include "algorithm.hpp"
-
-namespace RPiController {
-
-class ContrastAlgorithm : public Algorithm
-{
-public:
- ContrastAlgorithm(Controller *controller) : Algorithm(controller) {}
- // A contrast algorithm must provide the following:
- virtual void SetBrightness(double brightness) = 0;
- virtual void SetContrast(double contrast) = 0;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/contrast_status.h b/src/ipa/raspberrypi/controller/contrast_status.h
deleted file mode 100644
index d7edd4e9..00000000
--- a/src/ipa/raspberrypi/controller/contrast_status.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * contrast_status.h - contrast (gamma) control algorithm status
- */
-#pragma once
-
-// The "contrast" algorithm creates a gamma curve, optionally doing a little bit
-// of contrast stretching based on the AGC histogram.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define CONTRAST_NUM_POINTS 33
-
-struct ContrastPoint {
- uint16_t x;
- uint16_t y;
-};
-
-struct ContrastStatus {
- struct ContrastPoint points[CONTRAST_NUM_POINTS];
- double brightness;
- double contrast;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/controller.cpp b/src/ipa/raspberrypi/controller/controller.cpp
deleted file mode 100644
index d3433ad2..00000000
--- a/src/ipa/raspberrypi/controller/controller.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * controller.cpp - ISP controller
- */
-
-#include <libcamera/base/log.h>
-
-#include "algorithm.hpp"
-#include "controller.hpp"
-
-#include <boost/property_tree/json_parser.hpp>
-#include <boost/property_tree/ptree.hpp>
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiController)
-
-Controller::Controller()
- : switch_mode_called_(false) {}
-
-Controller::Controller(char const *json_filename)
- : switch_mode_called_(false)
-{
- Read(json_filename);
- Initialise();
-}
-
-Controller::~Controller() {}
-
-void Controller::Read(char const *filename)
-{
- boost::property_tree::ptree root;
- boost::property_tree::read_json(filename, root);
- for (auto const &key_and_value : root) {
- Algorithm *algo = CreateAlgorithm(key_and_value.first.c_str());
- if (algo) {
- algo->Read(key_and_value.second);
- algorithms_.push_back(AlgorithmPtr(algo));
- } else
- LOG(RPiController, Warning)
- << "No algorithm found for \"" << key_and_value.first << "\"";
- }
-}
-
-Algorithm *Controller::CreateAlgorithm(char const *name)
-{
- auto it = GetAlgorithms().find(std::string(name));
- return it != GetAlgorithms().end() ? (*it->second)(this) : nullptr;
-}
-
-void Controller::Initialise()
-{
- for (auto &algo : algorithms_)
- algo->Initialise();
-}
-
-void Controller::SwitchMode(CameraMode const &camera_mode, Metadata *metadata)
-{
- for (auto &algo : algorithms_)
- algo->SwitchMode(camera_mode, metadata);
- switch_mode_called_ = true;
-}
-
-void Controller::Prepare(Metadata *image_metadata)
-{
- assert(switch_mode_called_);
- for (auto &algo : algorithms_)
- if (!algo->IsPaused())
- algo->Prepare(image_metadata);
-}
-
-void Controller::Process(StatisticsPtr stats, Metadata *image_metadata)
-{
- assert(switch_mode_called_);
- for (auto &algo : algorithms_)
- if (!algo->IsPaused())
- algo->Process(stats, image_metadata);
-}
-
-Metadata &Controller::GetGlobalMetadata()
-{
- return global_metadata_;
-}
-
-Algorithm *Controller::GetAlgorithm(std::string const &name) const
-{
- // The passed name must be the entire algorithm name, or must match the
- // last part of it with a period (.) just before.
- size_t name_len = name.length();
- for (auto &algo : algorithms_) {
- char const *algo_name = algo->Name();
- size_t algo_name_len = strlen(algo_name);
- if (algo_name_len >= name_len &&
- strcasecmp(name.c_str(),
- algo_name + algo_name_len - name_len) == 0 &&
- (name_len == algo_name_len ||
- algo_name[algo_name_len - name_len - 1] == '.'))
- return algo.get();
- }
- return nullptr;
-}
diff --git a/src/ipa/raspberrypi/controller/controller.hpp b/src/ipa/raspberrypi/controller/controller.hpp
deleted file mode 100644
index 3b50ae77..00000000
--- a/src/ipa/raspberrypi/controller/controller.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * controller.hpp - ISP controller interface
- */
-#pragma once
-
-// The Controller is simply a container for a collecting together a number of
-// "control algorithms" (such as AWB etc.) and for running them all in a
-// convenient manner.
-
-#include <vector>
-#include <string>
-
-#include <linux/bcm2835-isp.h>
-
-#include "camera_mode.h"
-#include "device_status.h"
-#include "metadata.hpp"
-
-namespace RPiController {
-
-class Algorithm;
-typedef std::unique_ptr<Algorithm> AlgorithmPtr;
-typedef std::shared_ptr<bcm2835_isp_stats> StatisticsPtr;
-
-// The Controller holds a pointer to some global_metadata, which is how
-// different controllers and control algorithms within them can exchange
-// information. The Prepare function returns a pointer to metadata for this
-// specific image, and which should be passed on to the Process function.
-
-class Controller
-{
-public:
- Controller();
- Controller(char const *json_filename);
- ~Controller();
- Algorithm *CreateAlgorithm(char const *name);
- void Read(char const *filename);
- void Initialise();
- void SwitchMode(CameraMode const &camera_mode, Metadata *metadata);
- void Prepare(Metadata *image_metadata);
- void Process(StatisticsPtr stats, Metadata *image_metadata);
- Metadata &GetGlobalMetadata();
- Algorithm *GetAlgorithm(std::string const &name) const;
-
-protected:
- Metadata global_metadata_;
- std::vector<AlgorithmPtr> algorithms_;
- bool switch_mode_called_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/denoise_algorithm.hpp b/src/ipa/raspberrypi/controller/denoise_algorithm.hpp
deleted file mode 100644
index 39fcd7e9..00000000
--- a/src/ipa/raspberrypi/controller/denoise_algorithm.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2021, Raspberry Pi (Trading) Limited
- *
- * denoise.hpp - Denoise control algorithm interface
- */
-#pragma once
-
-#include "algorithm.hpp"
-
-namespace RPiController {
-
-enum class DenoiseMode { Off, ColourOff, ColourFast, ColourHighQuality };
-
-class DenoiseAlgorithm : public Algorithm
-{
-public:
- DenoiseAlgorithm(Controller *controller) : Algorithm(controller) {}
- // A Denoise algorithm must provide the following:
- virtual void SetMode(DenoiseMode mode) = 0;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/denoise_status.h b/src/ipa/raspberrypi/controller/denoise_status.h
deleted file mode 100644
index 67a3c361..00000000
--- a/src/ipa/raspberrypi/controller/denoise_status.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019-2021, Raspberry Pi (Trading) Limited
- *
- * denoise_status.h - Denoise control algorithm status
- */
-#pragma once
-
-// This stores the parameters required for Denoise.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct DenoiseStatus {
- double noise_constant;
- double noise_slope;
- double strength;
- unsigned int mode;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/device_status.cpp b/src/ipa/raspberrypi/controller/device_status.cpp
deleted file mode 100644
index a389c40d..00000000
--- a/src/ipa/raspberrypi/controller/device_status.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2021, Raspberry Pi (Trading) Limited
- *
- * device_status.cpp - device (image sensor) status
- */
-#include "device_status.h"
-
-using namespace libcamera; /* for the Duration operator<< overload */
-
-std::ostream &operator<<(std::ostream &out, const DeviceStatus &d)
-{
- out << "Exposure: " << d.shutter_speed
- << " Frame length: " << d.frame_length
- << " Gain: " << d.analogue_gain;
-
- if (d.aperture)
- out << " Aperture: " << *d.aperture;
-
- if (d.lens_position)
- out << " Lens: " << *d.lens_position;
-
- if (d.flash_intensity)
- out << " Flash: " << *d.flash_intensity;
-
- if (d.sensor_temperature)
- out << " Temperature: " << *d.sensor_temperature;
-
- return out;
-}
diff --git a/src/ipa/raspberrypi/controller/device_status.h b/src/ipa/raspberrypi/controller/device_status.h
deleted file mode 100644
index b33f0d09..00000000
--- a/src/ipa/raspberrypi/controller/device_status.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019-2021, Raspberry Pi (Trading) Limited
- *
- * device_status.h - device (image sensor) status
- */
-#pragma once
-
-#include <iostream>
-#include <optional>
-
-#include <libcamera/base/utils.h>
-
-/*
- * Definition of "device metadata" which stores things like shutter time and
- * analogue gain that downstream control algorithms will want to know.
- */
-
-struct DeviceStatus {
- DeviceStatus()
- : shutter_speed(std::chrono::seconds(0)), frame_length(0),
- analogue_gain(0.0)
- {
- }
-
- friend std::ostream &operator<<(std::ostream &out, const DeviceStatus &d);
-
- /* time shutter is open */
- libcamera::utils::Duration shutter_speed;
- /* frame length given in number of lines */
- uint32_t frame_length;
- double analogue_gain;
- /* 1.0/distance-in-metres, or 0 if unknown */
- std::optional<double> lens_position;
- /* 1/f so that brightness quadruples when this doubles, or 0 if unknown */
- std::optional<double> aperture;
- /* proportional to brightness with 0 = no flash, 1 = maximum flash */
- std::optional<double> flash_intensity;
- /* Sensor reported temperature value (in degrees) */
- std::optional<double> sensor_temperature;
-};
diff --git a/src/ipa/raspberrypi/controller/dpc_status.h b/src/ipa/raspberrypi/controller/dpc_status.h
deleted file mode 100644
index a3ec2762..00000000
--- a/src/ipa/raspberrypi/controller/dpc_status.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * dpc_status.h - DPC (defective pixel correction) control algorithm status
- */
-#pragma once
-
-// The "DPC" algorithm sets defective pixel correction strength.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct DpcStatus {
- int strength; // 0 = "off", 1 = "normal", 2 = "strong"
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/focus_status.h b/src/ipa/raspberrypi/controller/focus_status.h
deleted file mode 100644
index ace2fe2c..00000000
--- a/src/ipa/raspberrypi/controller/focus_status.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2020, Raspberry Pi (Trading) Limited
- *
- * focus_status.h - focus measurement status
- */
-#pragma once
-
-#include <linux/bcm2835-isp.h>
-
-// The focus algorithm should post the following structure into the image's
-// "focus.status" metadata. Recall that it's only reporting focus (contrast)
-// measurements, it's not driving any kind of auto-focus algorithm!
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct FocusStatus {
- unsigned int num;
- uint32_t focus_measures[FOCUS_REGIONS];
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/geq_status.h b/src/ipa/raspberrypi/controller/geq_status.h
deleted file mode 100644
index 07fd5f03..00000000
--- a/src/ipa/raspberrypi/controller/geq_status.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * geq_status.h - GEQ (green equalisation) control algorithm status
- */
-#pragma once
-
-// The "GEQ" algorithm calculates the green equalisation thresholds
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct GeqStatus {
- uint16_t offset;
- double slope;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/histogram.cpp b/src/ipa/raspberrypi/controller/histogram.cpp
deleted file mode 100644
index 9916b3ed..00000000
--- a/src/ipa/raspberrypi/controller/histogram.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * histogram.cpp - histogram calculations
- */
-#include <math.h>
-#include <stdio.h>
-
-#include "histogram.hpp"
-
-using namespace RPiController;
-
-uint64_t Histogram::CumulativeFreq(double bin) const
-{
- if (bin <= 0)
- return 0;
- else if (bin >= Bins())
- return Total();
- int b = (int)bin;
- return cumulative_[b] +
- (bin - b) * (cumulative_[b + 1] - cumulative_[b]);
-}
-
-double Histogram::Quantile(double q, int first, int last) const
-{
- if (first == -1)
- first = 0;
- if (last == -1)
- last = cumulative_.size() - 2;
- assert(first <= last);
- uint64_t items = q * Total();
- while (first < last) // binary search to find the right bin
- {
- int middle = (first + last) / 2;
- if (cumulative_[middle + 1] > items)
- last = middle; // between first and middle
- else
- first = middle + 1; // after middle
- }
- assert(items >= cumulative_[first] && items <= cumulative_[last + 1]);
- double frac = cumulative_[first + 1] == cumulative_[first] ? 0
- : (double)(items - cumulative_[first]) /
- (cumulative_[first + 1] - cumulative_[first]);
- return first + frac;
-}
-
-double Histogram::InterQuantileMean(double q_lo, double q_hi) const
-{
- assert(q_hi > q_lo);
- double p_lo = Quantile(q_lo);
- double p_hi = Quantile(q_hi, (int)p_lo);
- double sum_bin_freq = 0, cumul_freq = 0;
- for (double p_next = floor(p_lo) + 1.0; p_next <= ceil(p_hi);
- p_lo = p_next, p_next += 1.0) {
- int bin = floor(p_lo);
- double freq = (cumulative_[bin + 1] - cumulative_[bin]) *
- (std::min(p_next, p_hi) - p_lo);
- sum_bin_freq += bin * freq;
- cumul_freq += freq;
- }
- // add 0.5 to give an average for bin mid-points
- return sum_bin_freq / cumul_freq + 0.5;
-}
diff --git a/src/ipa/raspberrypi/controller/histogram.hpp b/src/ipa/raspberrypi/controller/histogram.hpp
deleted file mode 100644
index 90f5ac78..00000000
--- a/src/ipa/raspberrypi/controller/histogram.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * histogram.hpp - histogram calculation interface
- */
-#pragma once
-
-#include <stdint.h>
-#include <vector>
-#include <cassert>
-
-// A simple histogram class, for use in particular to find "quantiles" and
-// averages between "quantiles".
-
-namespace RPiController {
-
-class Histogram
-{
-public:
- template<typename T> Histogram(T *histogram, int num)
- {
- assert(num);
- cumulative_.reserve(num + 1);
- cumulative_.push_back(0);
- for (int i = 0; i < num; i++)
- cumulative_.push_back(cumulative_.back() +
- histogram[i]);
- }
- uint32_t Bins() const { return cumulative_.size() - 1; }
- uint64_t Total() const { return cumulative_[cumulative_.size() - 1]; }
- // Cumulative frequency up to a (fractional) point in a bin.
- uint64_t CumulativeFreq(double bin) const;
- // Return the (fractional) bin of the point q (0 <= q <= 1) through the
- // histogram. Optionally provide limits to help.
- double Quantile(double q, int first = -1, int last = -1) const;
- // Return the average histogram bin value between the two quantiles.
- double InterQuantileMean(double q_lo, double q_hi) const;
-
-private:
- std::vector<uint64_t> cumulative_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/lux_status.h b/src/ipa/raspberrypi/controller/lux_status.h
deleted file mode 100644
index 8ccfd933..00000000
--- a/src/ipa/raspberrypi/controller/lux_status.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * lux_status.h - Lux control algorithm status
- */
-#pragma once
-
-// The "lux" algorithm looks at the (AGC) histogram statistics of the frame and
-// estimates the current lux level of the scene. It does this by a simple ratio
-// calculation comparing to a reference image that was taken in known conditions
-// with known statistics and a properly measured lux level. There is a slight
-// problem with aperture, in that it may be variable without the system knowing
-// or being aware of it. In this case an external application may set a
-// "current_aperture" value if it wishes, which would be used in place of the
-// (presumably meaningless) value in the image metadata.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct LuxStatus {
- double lux;
- double aperture;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/metadata.hpp b/src/ipa/raspberrypi/controller/metadata.hpp
deleted file mode 100644
index 51e576cf..00000000
--- a/src/ipa/raspberrypi/controller/metadata.hpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019-2021, Raspberry Pi (Trading) Limited
- *
- * metadata.hpp - general metadata class
- */
-#pragma once
-
-// A simple class for carrying arbitrary metadata, for example about an image.
-
-#include <any>
-#include <map>
-#include <mutex>
-#include <string>
-
-namespace RPiController {
-
-class Metadata
-{
-public:
- Metadata() = default;
-
- Metadata(Metadata const &other)
- {
- std::scoped_lock other_lock(other.mutex_);
- data_ = other.data_;
- }
-
- Metadata(Metadata &&other)
- {
- std::scoped_lock other_lock(other.mutex_);
- data_ = std::move(other.data_);
- other.data_.clear();
- }
-
- template<typename T>
- void Set(std::string const &tag, T const &value)
- {
- std::scoped_lock lock(mutex_);
- data_[tag] = value;
- }
-
- template<typename T>
- int Get(std::string const &tag, T &value) const
- {
- std::scoped_lock lock(mutex_);
- auto it = data_.find(tag);
- if (it == data_.end())
- return -1;
- value = std::any_cast<T>(it->second);
- return 0;
- }
-
- void Clear()
- {
- std::scoped_lock lock(mutex_);
- data_.clear();
- }
-
- Metadata &operator=(Metadata const &other)
- {
- std::scoped_lock lock(mutex_, other.mutex_);
- data_ = other.data_;
- return *this;
- }
-
- Metadata &operator=(Metadata &&other)
- {
- std::scoped_lock lock(mutex_, other.mutex_);
- data_ = std::move(other.data_);
- other.data_.clear();
- return *this;
- }
-
- void Merge(Metadata &other)
- {
- std::scoped_lock lock(mutex_, other.mutex_);
- data_.merge(other.data_);
- }
-
- template<typename T>
- T *GetLocked(std::string const &tag)
- {
- // This allows in-place access to the Metadata contents,
- // for which you should be holding the lock.
- auto it = data_.find(tag);
- if (it == data_.end())
- return nullptr;
- return std::any_cast<T>(&it->second);
- }
-
- template<typename T>
- void SetLocked(std::string const &tag, T const &value)
- {
- // Use this only if you're holding the lock yourself.
- data_[tag] = value;
- }
-
- // Note: use of (lowercase) lock and unlock means you can create scoped
- // locks with the standard lock classes.
- // e.g. std::lock_guard<RPiController::Metadata> lock(metadata)
- void lock() { mutex_.lock(); }
- void unlock() { mutex_.unlock(); }
-
-private:
- mutable std::mutex mutex_;
- std::map<std::string, std::any> data_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/noise_status.h b/src/ipa/raspberrypi/controller/noise_status.h
deleted file mode 100644
index 8439a402..00000000
--- a/src/ipa/raspberrypi/controller/noise_status.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * noise_status.h - Noise control algorithm status
- */
-#pragma once
-
-// The "noise" algorithm stores an estimate of the noise profile for this image.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct NoiseStatus {
- double noise_constant;
- double noise_slope;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/controller/pwl.cpp b/src/ipa/raspberrypi/controller/pwl.cpp
deleted file mode 100644
index 130c820b..00000000
--- a/src/ipa/raspberrypi/controller/pwl.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * pwl.cpp - piecewise linear functions
- */
-
-#include <cassert>
-#include <stdexcept>
-
-#include "pwl.hpp"
-
-using namespace RPiController;
-
-void Pwl::Read(boost::property_tree::ptree const &params)
-{
- for (auto it = params.begin(); it != params.end(); it++) {
- double x = it->second.get_value<double>();
- assert(it == params.begin() || x > points_.back().x);
- it++;
- double y = it->second.get_value<double>();
- points_.push_back(Point(x, y));
- }
- assert(points_.size() >= 2);
-}
-
-void Pwl::Append(double x, double y, const double eps)
-{
- if (points_.empty() || points_.back().x + eps < x)
- points_.push_back(Point(x, y));
-}
-
-void Pwl::Prepend(double x, double y, const double eps)
-{
- if (points_.empty() || points_.front().x - eps > x)
- points_.insert(points_.begin(), Point(x, y));
-}
-
-Pwl::Interval Pwl::Domain() const
-{
- return Interval(points_[0].x, points_[points_.size() - 1].x);
-}
-
-Pwl::Interval Pwl::Range() const
-{
- double lo = points_[0].y, hi = lo;
- for (auto &p : points_)
- lo = std::min(lo, p.y), hi = std::max(hi, p.y);
- return Interval(lo, hi);
-}
-
-bool Pwl::Empty() const
-{
- return points_.empty();
-}
-
-double Pwl::Eval(double x, int *span_ptr, bool update_span) const
-{
- int span = findSpan(x, span_ptr && *span_ptr != -1
- ? *span_ptr
- : points_.size() / 2 - 1);
- if (span_ptr && update_span)
- *span_ptr = span;
- return points_[span].y +
- (x - points_[span].x) * (points_[span + 1].y - points_[span].y) /
- (points_[span + 1].x - points_[span].x);
-}
-
-int Pwl::findSpan(double x, int span) const
-{
- // Pwls are generally small, so linear search may well be faster than
- // binary, though could review this if large PWls start turning up.
- int last_span = points_.size() - 2;
- // some algorithms may call us with span pointing directly at the last
- // control point
- span = std::max(0, std::min(last_span, span));
- while (span < last_span && x >= points_[span + 1].x)
- span++;
- while (span && x < points_[span].x)
- span--;
- return span;
-}
-
-Pwl::PerpType Pwl::Invert(Point const &xy, Point &perp, int &span,
- const double eps) const
-{
- assert(span >= -1);
- bool prev_off_end = false;
- for (span = span + 1; span < (int)points_.size() - 1; span++) {
- Point span_vec = points_[span + 1] - points_[span];
- double t = ((xy - points_[span]) % span_vec) / span_vec.Len2();
- if (t < -eps) // off the start of this span
- {
- if (span == 0) {
- perp = points_[span];
- return PerpType::Start;
- } else if (prev_off_end) {
- perp = points_[span];
- return PerpType::Vertex;
- }
- } else if (t > 1 + eps) // off the end of this span
- {
- if (span == (int)points_.size() - 2) {
- perp = points_[span + 1];
- return PerpType::End;
- }
- prev_off_end = true;
- } else // a true perpendicular
- {
- perp = points_[span] + span_vec * t;
- return PerpType::Perpendicular;
- }
- }
- return PerpType::None;
-}
-
-Pwl Pwl::Inverse(bool *true_inverse, const double eps) const
-{
- bool appended = false, prepended = false, neither = false;
- Pwl inverse;
-
- for (Point const &p : points_) {
- if (inverse.Empty())
- inverse.Append(p.y, p.x, eps);
- else if (std::abs(inverse.points_.back().x - p.y) <= eps ||
- std::abs(inverse.points_.front().x - p.y) <= eps)
- /* do nothing */;
- else if (p.y > inverse.points_.back().x) {
- inverse.Append(p.y, p.x, eps);
- appended = true;
- } else if (p.y < inverse.points_.front().x) {
- inverse.Prepend(p.y, p.x, eps);
- prepended = true;
- } else
- neither = true;
- }
-
- // This is not a proper inverse if we found ourselves putting points
- // onto both ends of the inverse, or if there were points that couldn't
- // go on either.
- if (true_inverse)
- *true_inverse = !(neither || (appended && prepended));
-
- return inverse;
-}
-
-Pwl Pwl::Compose(Pwl const &other, const double eps) const
-{
- double this_x = points_[0].x, this_y = points_[0].y;
- int this_span = 0, other_span = other.findSpan(this_y, 0);
- Pwl result({ { this_x, other.Eval(this_y, &other_span, false) } });
- while (this_span != (int)points_.size() - 1) {
- double dx = points_[this_span + 1].x - points_[this_span].x,
- dy = points_[this_span + 1].y - points_[this_span].y;
- if (abs(dy) > eps &&
- other_span + 1 < (int)other.points_.size() &&
- points_[this_span + 1].y >=
- other.points_[other_span + 1].x + eps) {
- // next control point in result will be where this
- // function's y reaches the next span in other
- this_x = points_[this_span].x +
- (other.points_[other_span + 1].x -
- points_[this_span].y) * dx / dy;
- this_y = other.points_[++other_span].x;
- } else if (abs(dy) > eps && other_span > 0 &&
- points_[this_span + 1].y <=
- other.points_[other_span - 1].x - eps) {
- // next control point in result will be where this
- // function's y reaches the previous span in other
- this_x = points_[this_span].x +
- (other.points_[other_span + 1].x -
- points_[this_span].y) * dx / dy;
- this_y = other.points_[--other_span].x;
- } else {
- // we stay in the same span in other
- this_span++;
- this_x = points_[this_span].x,
- this_y = points_[this_span].y;
- }
- result.Append(this_x, other.Eval(this_y, &other_span, false),
- eps);
- }
- return result;
-}
-
-void Pwl::Map(std::function<void(double x, double y)> f) const
-{
- for (auto &pt : points_)
- f(pt.x, pt.y);
-}
-
-void Pwl::Map2(Pwl const &pwl0, Pwl const &pwl1,
- std::function<void(double x, double y0, double y1)> f)
-{
- int span0 = 0, span1 = 0;
- double x = std::min(pwl0.points_[0].x, pwl1.points_[0].x);
- f(x, pwl0.Eval(x, &span0, false), pwl1.Eval(x, &span1, false));
- while (span0 < (int)pwl0.points_.size() - 1 ||
- span1 < (int)pwl1.points_.size() - 1) {
- if (span0 == (int)pwl0.points_.size() - 1)
- x = pwl1.points_[++span1].x;
- else if (span1 == (int)pwl1.points_.size() - 1)
- x = pwl0.points_[++span0].x;
- else if (pwl0.points_[span0 + 1].x > pwl1.points_[span1 + 1].x)
- x = pwl1.points_[++span1].x;
- else
- x = pwl0.points_[++span0].x;
- f(x, pwl0.Eval(x, &span0, false), pwl1.Eval(x, &span1, false));
- }
-}
-
-Pwl Pwl::Combine(Pwl const &pwl0, Pwl const &pwl1,
- std::function<double(double x, double y0, double y1)> f,
- const double eps)
-{
- Pwl result;
- Map2(pwl0, pwl1, [&](double x, double y0, double y1) {
- result.Append(x, f(x, y0, y1), eps);
- });
- return result;
-}
-
-void Pwl::MatchDomain(Interval const &domain, bool clip, const double eps)
-{
- int span = 0;
- Prepend(domain.start, Eval(clip ? points_[0].x : domain.start, &span),
- eps);
- span = points_.size() - 2;
- Append(domain.end, Eval(clip ? points_.back().x : domain.end, &span),
- eps);
-}
-
-Pwl &Pwl::operator*=(double d)
-{
- for (auto &pt : points_)
- pt.y *= d;
- return *this;
-}
-
-void Pwl::Debug(FILE *fp) const
-{
- fprintf(fp, "Pwl {\n");
- for (auto &p : points_)
- fprintf(fp, "\t(%g, %g)\n", p.x, p.y);
- fprintf(fp, "}\n");
-}
diff --git a/src/ipa/raspberrypi/controller/pwl.hpp b/src/ipa/raspberrypi/controller/pwl.hpp
deleted file mode 100644
index 484672f6..00000000
--- a/src/ipa/raspberrypi/controller/pwl.hpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * pwl.hpp - piecewise linear functions interface
- */
-#pragma once
-
-#include <math.h>
-#include <vector>
-
-#include <boost/property_tree/ptree.hpp>
-
-namespace RPiController {
-
-class Pwl
-{
-public:
- struct Interval {
- Interval(double _start, double _end) : start(_start), end(_end)
- {
- }
- double start, end;
- bool Contains(double value)
- {
- return value >= start && value <= end;
- }
- double Clip(double value)
- {
- return value < start ? start
- : (value > end ? end : value);
- }
- double Len() const { return end - start; }
- };
- struct Point {
- Point() : x(0), y(0) {}
- Point(double _x, double _y) : x(_x), y(_y) {}
- double x, y;
- Point operator-(Point const &p) const
- {
- return Point(x - p.x, y - p.y);
- }
- Point operator+(Point const &p) const
- {
- return Point(x + p.x, y + p.y);
- }
- double operator%(Point const &p) const
- {
- return x * p.x + y * p.y;
- }
- Point operator*(double f) const { return Point(x * f, y * f); }
- Point operator/(double f) const { return Point(x / f, y / f); }
- double Len2() const { return x * x + y * y; }
- double Len() const { return sqrt(Len2()); }
- };
- Pwl() {}
- Pwl(std::vector<Point> const &points) : points_(points) {}
- void Read(boost::property_tree::ptree const &params);
- void Append(double x, double y, const double eps = 1e-6);
- void Prepend(double x, double y, const double eps = 1e-6);
- Interval Domain() const;
- Interval Range() const;
- bool Empty() const;
- // Evaluate Pwl, optionally supplying an initial guess for the
- // "span". The "span" may be optionally be updated. If you want to know
- // the "span" value but don't have an initial guess you can set it to
- // -1.
- double Eval(double x, int *span_ptr = nullptr,
- bool update_span = true) const;
- // Find perpendicular closest to xy, starting from span+1 so you can
- // call it repeatedly to check for multiple closest points (set span to
- // -1 on the first call). Also returns "pseudo" perpendiculars; see
- // PerpType enum.
- enum class PerpType {
- None, // no perpendicular found
- Start, // start of Pwl is closest point
- End, // end of Pwl is closest point
- Vertex, // vertex of Pwl is closest point
- Perpendicular // true perpendicular found
- };
- PerpType Invert(Point const &xy, Point &perp, int &span,
- const double eps = 1e-6) const;
- // Compute the inverse function. Indicate if it is a proper (true)
- // inverse, or only a best effort (e.g. input was non-monotonic).
- Pwl Inverse(bool *true_inverse = nullptr, const double eps = 1e-6) const;
- // Compose two Pwls together, doing "this" first and "other" after.
- Pwl Compose(Pwl const &other, const double eps = 1e-6) const;
- // Apply function to (x,y) values at every control point.
- void Map(std::function<void(double x, double y)> f) const;
- // Apply function to (x, y0, y1) values wherever either Pwl has a
- // control point.
- static void Map2(Pwl const &pwl0, Pwl const &pwl1,
- std::function<void(double x, double y0, double y1)> f);
- // Combine two Pwls, meaning we create a new Pwl where the y values are
- // given by running f wherever either has a knot.
- static Pwl
- Combine(Pwl const &pwl0, Pwl const &pwl1,
- std::function<double(double x, double y0, double y1)> f,
- const double eps = 1e-6);
- // Make "this" match (at least) the given domain. Any extension my be
- // clipped or linear.
- void MatchDomain(Interval const &domain, bool clip = true,
- const double eps = 1e-6);
- Pwl &operator*=(double d);
- void Debug(FILE *fp = stdout) const;
-
-private:
- int findSpan(double x, int span) const;
- std::vector<Point> points_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp
deleted file mode 100644
index f6a9cb0a..00000000
--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp
+++ /dev/null
@@ -1,797 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * agc.cpp - AGC/AEC control algorithm
- */
-
-#include <map>
-
-#include <linux/bcm2835-isp.h>
-
-#include <libcamera/base/log.h>
-
-#include "../awb_status.h"
-#include "../device_status.h"
-#include "../histogram.hpp"
-#include "../lux_status.h"
-#include "../metadata.hpp"
-
-#include "agc.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-using libcamera::utils::Duration;
-using namespace std::literals::chrono_literals;
-
-LOG_DEFINE_CATEGORY(RPiAgc)
-
-#define NAME "rpi.agc"
-
-#define PIPELINE_BITS 13 // seems to be a 13-bit pipeline
-
-void AgcMeteringMode::Read(boost::property_tree::ptree const &params)
-{
- int num = 0;
- for (auto &p : params.get_child("weights")) {
- if (num == AGC_STATS_SIZE)
- throw std::runtime_error("AgcConfig: too many weights");
- weights[num++] = p.second.get_value<double>();
- }
- if (num != AGC_STATS_SIZE)
- throw std::runtime_error("AgcConfig: insufficient weights");
-}
-
-static std::string
-read_metering_modes(std::map<std::string, AgcMeteringMode> &metering_modes,
- boost::property_tree::ptree const &params)
-{
- std::string first;
- for (auto &p : params) {
- AgcMeteringMode metering_mode;
- metering_mode.Read(p.second);
- metering_modes[p.first] = std::move(metering_mode);
- if (first.empty())
- first = p.first;
- }
- return first;
-}
-
-static int read_list(std::vector<double> &list,
- boost::property_tree::ptree const &params)
-{
- for (auto &p : params)
- list.push_back(p.second.get_value<double>());
- return list.size();
-}
-
-static int read_list(std::vector<Duration> &list,
- boost::property_tree::ptree const &params)
-{
- for (auto &p : params)
- list.push_back(p.second.get_value<double>() * 1us);
- return list.size();
-}
-
-void AgcExposureMode::Read(boost::property_tree::ptree const &params)
-{
- int num_shutters = read_list(shutter, params.get_child("shutter"));
- int num_ags = read_list(gain, params.get_child("gain"));
- if (num_shutters < 2 || num_ags < 2)
- throw std::runtime_error(
- "AgcConfig: must have at least two entries in exposure profile");
- if (num_shutters != num_ags)
- throw std::runtime_error(
- "AgcConfig: expect same number of exposure and gain entries in exposure profile");
-}
-
-static std::string
-read_exposure_modes(std::map<std::string, AgcExposureMode> &exposure_modes,
- boost::property_tree::ptree const &params)
-{
- std::string first;
- for (auto &p : params) {
- AgcExposureMode exposure_mode;
- exposure_mode.Read(p.second);
- exposure_modes[p.first] = std::move(exposure_mode);
- if (first.empty())
- first = p.first;
- }
- return first;
-}
-
-void AgcConstraint::Read(boost::property_tree::ptree const &params)
-{
- std::string bound_string = params.get<std::string>("bound", "");
- transform(bound_string.begin(), bound_string.end(),
- bound_string.begin(), ::toupper);
- if (bound_string != "UPPER" && bound_string != "LOWER")
- throw std::runtime_error(
- "AGC constraint type should be UPPER or LOWER");
- bound = bound_string == "UPPER" ? Bound::UPPER : Bound::LOWER;
- q_lo = params.get<double>("q_lo");
- q_hi = params.get<double>("q_hi");
- Y_target.Read(params.get_child("y_target"));
-}
-
-static AgcConstraintMode
-read_constraint_mode(boost::property_tree::ptree const &params)
-{
- AgcConstraintMode mode;
- for (auto &p : params) {
- AgcConstraint constraint;
- constraint.Read(p.second);
- mode.push_back(std::move(constraint));
- }
- return mode;
-}
-
-static std::string read_constraint_modes(
- std::map<std::string, AgcConstraintMode> &constraint_modes,
- boost::property_tree::ptree const &params)
-{
- std::string first;
- for (auto &p : params) {
- constraint_modes[p.first] = read_constraint_mode(p.second);
- if (first.empty())
- first = p.first;
- }
- return first;
-}
-
-void AgcConfig::Read(boost::property_tree::ptree const &params)
-{
- LOG(RPiAgc, Debug) << "AgcConfig";
- default_metering_mode = read_metering_modes(
- metering_modes, params.get_child("metering_modes"));
- default_exposure_mode = read_exposure_modes(
- exposure_modes, params.get_child("exposure_modes"));
- default_constraint_mode = read_constraint_modes(
- constraint_modes, params.get_child("constraint_modes"));
- Y_target.Read(params.get_child("y_target"));
- speed = params.get<double>("speed", 0.2);
- startup_frames = params.get<uint16_t>("startup_frames", 10);
- convergence_frames = params.get<unsigned int>("convergence_frames", 6);
- fast_reduce_threshold =
- params.get<double>("fast_reduce_threshold", 0.4);
- base_ev = params.get<double>("base_ev", 1.0);
- // Start with quite a low value as ramping up is easier than ramping down.
- default_exposure_time = params.get<double>("default_exposure_time", 1000) * 1us;
- default_analogue_gain = params.get<double>("default_analogue_gain", 1.0);
-}
-
-Agc::ExposureValues::ExposureValues()
- : shutter(0s), analogue_gain(0),
- total_exposure(0s), total_exposure_no_dg(0s)
-{
-}
-
-Agc::Agc(Controller *controller)
- : AgcAlgorithm(controller), metering_mode_(nullptr),
- exposure_mode_(nullptr), constraint_mode_(nullptr),
- frame_count_(0), lock_count_(0),
- last_target_exposure_(0s), last_sensitivity_(0.0),
- ev_(1.0), flicker_period_(0s),
- max_shutter_(0s), fixed_shutter_(0s), fixed_analogue_gain_(0.0)
-{
- memset(&awb_, 0, sizeof(awb_));
- // Setting status_.total_exposure_value_ to zero initially tells us
- // it's not been calculated yet (i.e. Process hasn't yet run).
- memset(&status_, 0, sizeof(status_));
- status_.ev = ev_;
-}
-
-char const *Agc::Name() const
-{
- return NAME;
-}
-
-void Agc::Read(boost::property_tree::ptree const &params)
-{
- LOG(RPiAgc, Debug) << "Agc";
- config_.Read(params);
- // Set the config's defaults (which are the first ones it read) as our
- // current modes, until someone changes them. (they're all known to
- // exist at this point)
- metering_mode_name_ = config_.default_metering_mode;
- metering_mode_ = &config_.metering_modes[metering_mode_name_];
- exposure_mode_name_ = config_.default_exposure_mode;
- exposure_mode_ = &config_.exposure_modes[exposure_mode_name_];
- constraint_mode_name_ = config_.default_constraint_mode;
- constraint_mode_ = &config_.constraint_modes[constraint_mode_name_];
- // Set up the "last shutter/gain" values, in case AGC starts "disabled".
- status_.shutter_time = config_.default_exposure_time;
- status_.analogue_gain = config_.default_analogue_gain;
-}
-
-bool Agc::IsPaused() const
-{
- return false;
-}
-
-void Agc::Pause()
-{
- fixed_shutter_ = status_.shutter_time;
- fixed_analogue_gain_ = status_.analogue_gain;
-}
-
-void Agc::Resume()
-{
- fixed_shutter_ = 0s;
- fixed_analogue_gain_ = 0;
-}
-
-unsigned int Agc::GetConvergenceFrames() const
-{
- // If shutter and gain have been explicitly set, there is no
- // convergence to happen, so no need to drop any frames - return zero.
- if (fixed_shutter_ && fixed_analogue_gain_)
- return 0;
- else
- return config_.convergence_frames;
-}
-
-void Agc::SetEv(double ev)
-{
- ev_ = ev;
-}
-
-void Agc::SetFlickerPeriod(Duration flicker_period)
-{
- flicker_period_ = flicker_period;
-}
-
-void Agc::SetMaxShutter(Duration max_shutter)
-{
- max_shutter_ = max_shutter;
-}
-
-void Agc::SetFixedShutter(Duration fixed_shutter)
-{
- fixed_shutter_ = fixed_shutter;
- // Set this in case someone calls Pause() straight after.
- status_.shutter_time = clipShutter(fixed_shutter_);
-}
-
-void Agc::SetFixedAnalogueGain(double fixed_analogue_gain)
-{
- fixed_analogue_gain_ = fixed_analogue_gain;
- // Set this in case someone calls Pause() straight after.
- status_.analogue_gain = fixed_analogue_gain;
-}
-
-void Agc::SetMeteringMode(std::string const &metering_mode_name)
-{
- metering_mode_name_ = metering_mode_name;
-}
-
-void Agc::SetExposureMode(std::string const &exposure_mode_name)
-{
- exposure_mode_name_ = exposure_mode_name;
-}
-
-void Agc::SetConstraintMode(std::string const &constraint_mode_name)
-{
- constraint_mode_name_ = constraint_mode_name;
-}
-
-void Agc::SwitchMode(CameraMode const &camera_mode,
- Metadata *metadata)
-{
- /* AGC expects the mode sensitivity always to be non-zero. */
- ASSERT(camera_mode.sensitivity);
-
- housekeepConfig();
-
- Duration fixed_shutter = clipShutter(fixed_shutter_);
- if (fixed_shutter && fixed_analogue_gain_) {
- // We're going to reset the algorithm here with these fixed values.
-
- fetchAwbStatus(metadata);
- double min_colour_gain = std::min({ awb_.gain_r, awb_.gain_g, awb_.gain_b, 1.0 });
- ASSERT(min_colour_gain != 0.0);
-
- // This is the equivalent of computeTargetExposure and applyDigitalGain.
- target_.total_exposure_no_dg = fixed_shutter * fixed_analogue_gain_;
- target_.total_exposure = target_.total_exposure_no_dg / min_colour_gain;
-
- // Equivalent of filterExposure. This resets any "history".
- filtered_ = target_;
-
- // Equivalent of divideUpExposure.
- filtered_.shutter = fixed_shutter;
- filtered_.analogue_gain = fixed_analogue_gain_;
- } else if (status_.total_exposure_value) {
- // On a mode switch, various things could happen:
- // - the exposure profile might change
- // - a fixed exposure or gain might be set
- // - the new mode's sensitivity might be different
- // We cope with the last of these by scaling the target values. After
- // that we just need to re-divide the exposure/gain according to the
- // current exposure profile, which takes care of everything else.
-
- double ratio = last_sensitivity_ / camera_mode.sensitivity;
- target_.total_exposure_no_dg *= ratio;
- target_.total_exposure *= ratio;
- filtered_.total_exposure_no_dg *= ratio;
- filtered_.total_exposure *= ratio;
-
- divideUpExposure();
- } else {
- // We come through here on startup, when at least one of the shutter
- // or gain has not been fixed. We must still write those values out so
- // that they will be applied immediately. We supply some arbitrary defaults
- // for any that weren't set.
-
- // Equivalent of divideUpExposure.
- filtered_.shutter = fixed_shutter ? fixed_shutter : config_.default_exposure_time;
- filtered_.analogue_gain = fixed_analogue_gain_ ? fixed_analogue_gain_ : config_.default_analogue_gain;
- }
-
- writeAndFinish(metadata, false);
-
- // We must remember the sensitivity of this mode for the next SwitchMode.
- last_sensitivity_ = camera_mode.sensitivity;
-}
-
-void Agc::Prepare(Metadata *image_metadata)
-{
- status_.digital_gain = 1.0;
- fetchAwbStatus(image_metadata); // always fetch it so that Process knows it's been done
-
- if (status_.total_exposure_value) {
- // Process has run, so we have meaningful values.
- DeviceStatus device_status;
- if (image_metadata->Get("device.status", device_status) == 0) {
- Duration actual_exposure = device_status.shutter_speed *
- device_status.analogue_gain;
- if (actual_exposure) {
- status_.digital_gain =
- status_.total_exposure_value /
- actual_exposure;
- LOG(RPiAgc, Debug) << "Want total exposure " << status_.total_exposure_value;
- // Never ask for a gain < 1.0, and also impose
- // some upper limit. Make it customisable?
- status_.digital_gain = std::max(
- 1.0,
- std::min(status_.digital_gain, 4.0));
- LOG(RPiAgc, Debug) << "Actual exposure " << actual_exposure;
- LOG(RPiAgc, Debug) << "Use digital_gain " << status_.digital_gain;
- LOG(RPiAgc, Debug) << "Effective exposure "
- << actual_exposure * status_.digital_gain;
- // Decide whether AEC/AGC has converged.
- updateLockStatus(device_status);
- }
- } else
- LOG(RPiAgc, Warning) << Name() << ": no device metadata";
- image_metadata->Set("agc.status", status_);
- }
-}
-
-void Agc::Process(StatisticsPtr &stats, Metadata *image_metadata)
-{
- frame_count_++;
- // First a little bit of housekeeping, fetching up-to-date settings and
- // configuration, that kind of thing.
- housekeepConfig();
- // Get the current exposure values for the frame that's just arrived.
- fetchCurrentExposure(image_metadata);
- // Compute the total gain we require relative to the current exposure.
- double gain, target_Y;
- computeGain(stats.get(), image_metadata, gain, target_Y);
- // Now compute the target (final) exposure which we think we want.
- computeTargetExposure(gain);
- // Some of the exposure has to be applied as digital gain, so work out
- // what that is. This function also tells us whether it's decided to
- // "desaturate" the image more quickly.
- bool desaturate = applyDigitalGain(gain, target_Y);
- // The results have to be filtered so as not to change too rapidly.
- filterExposure(desaturate);
- // The last thing is to divide up the exposure value into a shutter time
- // and analogue_gain, according to the current exposure mode.
- divideUpExposure();
- // Finally advertise what we've done.
- writeAndFinish(image_metadata, desaturate);
-}
-
-void Agc::updateLockStatus(DeviceStatus const &device_status)
-{
- const double ERROR_FACTOR = 0.10; // make these customisable?
- const int MAX_LOCK_COUNT = 5;
- // Reset "lock count" when we exceed this multiple of ERROR_FACTOR
- const double RESET_MARGIN = 1.5;
-
- // Add 200us to the exposure time error to allow for line quantisation.
- Duration exposure_error = last_device_status_.shutter_speed * ERROR_FACTOR + 200us;
- double gain_error = last_device_status_.analogue_gain * ERROR_FACTOR;
- Duration target_error = last_target_exposure_ * ERROR_FACTOR;
-
- // Note that we don't know the exposure/gain limits of the sensor, so
- // the values we keep requesting may be unachievable. For this reason
- // we only insist that we're close to values in the past few frames.
- if (device_status.shutter_speed > last_device_status_.shutter_speed - exposure_error &&
- device_status.shutter_speed < last_device_status_.shutter_speed + exposure_error &&
- device_status.analogue_gain > last_device_status_.analogue_gain - gain_error &&
- device_status.analogue_gain < last_device_status_.analogue_gain + gain_error &&
- status_.target_exposure_value > last_target_exposure_ - target_error &&
- status_.target_exposure_value < last_target_exposure_ + target_error)
- lock_count_ = std::min(lock_count_ + 1, MAX_LOCK_COUNT);
- else if (device_status.shutter_speed < last_device_status_.shutter_speed - RESET_MARGIN * exposure_error ||
- device_status.shutter_speed > last_device_status_.shutter_speed + RESET_MARGIN * exposure_error ||
- device_status.analogue_gain < last_device_status_.analogue_gain - RESET_MARGIN * gain_error ||
- device_status.analogue_gain > last_device_status_.analogue_gain + RESET_MARGIN * gain_error ||
- status_.target_exposure_value < last_target_exposure_ - RESET_MARGIN * target_error ||
- status_.target_exposure_value > last_target_exposure_ + RESET_MARGIN * target_error)
- lock_count_ = 0;
-
- last_device_status_ = device_status;
- last_target_exposure_ = status_.target_exposure_value;
-
- LOG(RPiAgc, Debug) << "Lock count updated to " << lock_count_;
- status_.locked = lock_count_ == MAX_LOCK_COUNT;
-}
-
-static void copy_string(std::string const &s, char *d, size_t size)
-{
- size_t length = s.copy(d, size - 1);
- d[length] = '\0';
-}
-
-void Agc::housekeepConfig()
-{
- // First fetch all the up-to-date settings, so no one else has to do it.
- status_.ev = ev_;
- status_.fixed_shutter = clipShutter(fixed_shutter_);
- status_.fixed_analogue_gain = fixed_analogue_gain_;
- status_.flicker_period = flicker_period_;
- LOG(RPiAgc, Debug) << "ev " << status_.ev << " fixed_shutter "
- << status_.fixed_shutter << " fixed_analogue_gain "
- << status_.fixed_analogue_gain;
- // Make sure the "mode" pointers point to the up-to-date things, if
- // they've changed.
- if (strcmp(metering_mode_name_.c_str(), status_.metering_mode)) {
- auto it = config_.metering_modes.find(metering_mode_name_);
- if (it == config_.metering_modes.end())
- throw std::runtime_error("Agc: no metering mode " +
- metering_mode_name_);
- metering_mode_ = &it->second;
- copy_string(metering_mode_name_, status_.metering_mode,
- sizeof(status_.metering_mode));
- }
- if (strcmp(exposure_mode_name_.c_str(), status_.exposure_mode)) {
- auto it = config_.exposure_modes.find(exposure_mode_name_);
- if (it == config_.exposure_modes.end())
- throw std::runtime_error("Agc: no exposure profile " +
- exposure_mode_name_);
- exposure_mode_ = &it->second;
- copy_string(exposure_mode_name_, status_.exposure_mode,
- sizeof(status_.exposure_mode));
- }
- if (strcmp(constraint_mode_name_.c_str(), status_.constraint_mode)) {
- auto it =
- config_.constraint_modes.find(constraint_mode_name_);
- if (it == config_.constraint_modes.end())
- throw std::runtime_error("Agc: no constraint list " +
- constraint_mode_name_);
- constraint_mode_ = &it->second;
- copy_string(constraint_mode_name_, status_.constraint_mode,
- sizeof(status_.constraint_mode));
- }
- LOG(RPiAgc, Debug) << "exposure_mode "
- << exposure_mode_name_ << " constraint_mode "
- << constraint_mode_name_ << " metering_mode "
- << metering_mode_name_;
-}
-
-void Agc::fetchCurrentExposure(Metadata *image_metadata)
-{
- std::unique_lock<Metadata> lock(*image_metadata);
- DeviceStatus *device_status =
- image_metadata->GetLocked<DeviceStatus>("device.status");
- if (!device_status)
- throw std::runtime_error("Agc: no device metadata");
- current_.shutter = device_status->shutter_speed;
- current_.analogue_gain = device_status->analogue_gain;
- AgcStatus *agc_status =
- image_metadata->GetLocked<AgcStatus>("agc.status");
- current_.total_exposure = agc_status ? agc_status->total_exposure_value : 0s;
- current_.total_exposure_no_dg = current_.shutter * current_.analogue_gain;
-}
-
-void Agc::fetchAwbStatus(Metadata *image_metadata)
-{
- awb_.gain_r = 1.0; // in case not found in metadata
- awb_.gain_g = 1.0;
- awb_.gain_b = 1.0;
- if (image_metadata->Get("awb.status", awb_) != 0)
- LOG(RPiAgc, Debug) << "Agc: no AWB status found";
-}
-
-static double compute_initial_Y(bcm2835_isp_stats *stats, AwbStatus const &awb,
- double weights[], double gain)
-{
- bcm2835_isp_stats_region *regions = stats->agc_stats;
- // Note how the calculation below means that equal weights give you
- // "average" metering (i.e. all pixels equally important).
- double R_sum = 0, G_sum = 0, B_sum = 0, pixel_sum = 0;
- for (int i = 0; i < AGC_STATS_SIZE; i++) {
- double counted = regions[i].counted;
- double r_sum = std::min(regions[i].r_sum * gain, ((1 << PIPELINE_BITS) - 1) * counted);
- double g_sum = std::min(regions[i].g_sum * gain, ((1 << PIPELINE_BITS) - 1) * counted);
- double b_sum = std::min(regions[i].b_sum * gain, ((1 << PIPELINE_BITS) - 1) * counted);
- R_sum += r_sum * weights[i];
- G_sum += g_sum * weights[i];
- B_sum += b_sum * weights[i];
- pixel_sum += counted * weights[i];
- }
- if (pixel_sum == 0.0) {
- LOG(RPiAgc, Warning) << "compute_initial_Y: pixel_sum is zero";
- return 0;
- }
- double Y_sum = R_sum * awb.gain_r * .299 +
- G_sum * awb.gain_g * .587 +
- B_sum * awb.gain_b * .114;
- return Y_sum / pixel_sum / (1 << PIPELINE_BITS);
-}
-
-// We handle extra gain through EV by adjusting our Y targets. However, you
-// simply can't monitor histograms once they get very close to (or beyond!)
-// saturation, so we clamp the Y targets to this value. It does mean that EV
-// increases don't necessarily do quite what you might expect in certain
-// (contrived) cases.
-
-#define EV_GAIN_Y_TARGET_LIMIT 0.9
-
-static double constraint_compute_gain(AgcConstraint &c, Histogram &h,
- double lux, double ev_gain,
- double &target_Y)
-{
- target_Y = c.Y_target.Eval(c.Y_target.Domain().Clip(lux));
- target_Y = std::min(EV_GAIN_Y_TARGET_LIMIT, target_Y * ev_gain);
- double iqm = h.InterQuantileMean(c.q_lo, c.q_hi);
- return (target_Y * NUM_HISTOGRAM_BINS) / iqm;
-}
-
-void Agc::computeGain(bcm2835_isp_stats *statistics, Metadata *image_metadata,
- double &gain, double &target_Y)
-{
- struct LuxStatus lux = {};
- lux.lux = 400; // default lux level to 400 in case no metadata found
- if (image_metadata->Get("lux.status", lux) != 0)
- LOG(RPiAgc, Warning) << "Agc: no lux level found";
- Histogram h(statistics->hist[0].g_hist, NUM_HISTOGRAM_BINS);
- double ev_gain = status_.ev * config_.base_ev;
- // The initial gain and target_Y come from some of the regions. After
- // that we consider the histogram constraints.
- target_Y =
- config_.Y_target.Eval(config_.Y_target.Domain().Clip(lux.lux));
- target_Y = std::min(EV_GAIN_Y_TARGET_LIMIT, target_Y * ev_gain);
-
- // Do this calculation a few times as brightness increase can be
- // non-linear when there are saturated regions.
- gain = 1.0;
- for (int i = 0; i < 8; i++) {
- double initial_Y = compute_initial_Y(statistics, awb_,
- metering_mode_->weights, gain);
- double extra_gain = std::min(10.0, target_Y / (initial_Y + .001));
- gain *= extra_gain;
- LOG(RPiAgc, Debug) << "Initial Y " << initial_Y << " target " << target_Y
- << " gives gain " << gain;
- if (extra_gain < 1.01) // close enough
- break;
- }
-
- for (auto &c : *constraint_mode_) {
- double new_target_Y;
- double new_gain =
- constraint_compute_gain(c, h, lux.lux, ev_gain,
- new_target_Y);
- LOG(RPiAgc, Debug) << "Constraint has target_Y "
- << new_target_Y << " giving gain " << new_gain;
- if (c.bound == AgcConstraint::Bound::LOWER &&
- new_gain > gain) {
- LOG(RPiAgc, Debug) << "Lower bound constraint adopted";
- gain = new_gain, target_Y = new_target_Y;
- } else if (c.bound == AgcConstraint::Bound::UPPER &&
- new_gain < gain) {
- LOG(RPiAgc, Debug) << "Upper bound constraint adopted";
- gain = new_gain, target_Y = new_target_Y;
- }
- }
- LOG(RPiAgc, Debug) << "Final gain " << gain << " (target_Y " << target_Y << " ev "
- << status_.ev << " base_ev " << config_.base_ev
- << ")";
-}
-
-void Agc::computeTargetExposure(double gain)
-{
- if (status_.fixed_shutter && status_.fixed_analogue_gain) {
- // When ag and shutter are both fixed, we need to drive the
- // total exposure so that we end up with a digital gain of at least
- // 1/min_colour_gain. Otherwise we'd desaturate channels causing
- // white to go cyan or magenta.
- double min_colour_gain = std::min({ awb_.gain_r, awb_.gain_g, awb_.gain_b, 1.0 });
- ASSERT(min_colour_gain != 0.0);
- target_.total_exposure =
- status_.fixed_shutter * status_.fixed_analogue_gain / min_colour_gain;
- } else {
- // The statistics reflect the image without digital gain, so the final
- // total exposure we're aiming for is:
- target_.total_exposure = current_.total_exposure_no_dg * gain;
- // The final target exposure is also limited to what the exposure
- // mode allows.
- Duration max_shutter = status_.fixed_shutter
- ? status_.fixed_shutter
- : exposure_mode_->shutter.back();
- max_shutter = clipShutter(max_shutter);
- Duration max_total_exposure =
- max_shutter *
- (status_.fixed_analogue_gain != 0.0
- ? status_.fixed_analogue_gain
- : exposure_mode_->gain.back());
- target_.total_exposure = std::min(target_.total_exposure,
- max_total_exposure);
- }
- LOG(RPiAgc, Debug) << "Target total_exposure " << target_.total_exposure;
-}
-
-bool Agc::applyDigitalGain(double gain, double target_Y)
-{
- double min_colour_gain = std::min({ awb_.gain_r, awb_.gain_g, awb_.gain_b, 1.0 });
- ASSERT(min_colour_gain != 0.0);
- double dg = 1.0 / min_colour_gain;
- // I think this pipeline subtracts black level and rescales before we
- // get the stats, so no need to worry about it.
- LOG(RPiAgc, Debug) << "after AWB, target dg " << dg << " gain " << gain
- << " target_Y " << target_Y;
- // Finally, if we're trying to reduce exposure but the target_Y is
- // "close" to 1.0, then the gain computed for that constraint will be
- // only slightly less than one, because the measured Y can never be
- // larger than 1.0. When this happens, demand a large digital gain so
- // that the exposure can be reduced, de-saturating the image much more
- // quickly (and we then approach the correct value more quickly from
- // below).
- bool desaturate = target_Y > config_.fast_reduce_threshold &&
- gain < sqrt(target_Y);
- if (desaturate)
- dg /= config_.fast_reduce_threshold;
- LOG(RPiAgc, Debug) << "Digital gain " << dg << " desaturate? " << desaturate;
- target_.total_exposure_no_dg = target_.total_exposure / dg;
- LOG(RPiAgc, Debug) << "Target total_exposure_no_dg " << target_.total_exposure_no_dg;
- return desaturate;
-}
-
-void Agc::filterExposure(bool desaturate)
-{
- double speed = config_.speed;
- // AGC adapts instantly if both shutter and gain are directly specified
- // or we're in the startup phase.
- if ((status_.fixed_shutter && status_.fixed_analogue_gain) ||
- frame_count_ <= config_.startup_frames)
- speed = 1.0;
- if (!filtered_.total_exposure) {
- filtered_.total_exposure = target_.total_exposure;
- filtered_.total_exposure_no_dg = target_.total_exposure_no_dg;
- } else {
- // If close to the result go faster, to save making so many
- // micro-adjustments on the way. (Make this customisable?)
- if (filtered_.total_exposure < 1.2 * target_.total_exposure &&
- filtered_.total_exposure > 0.8 * target_.total_exposure)
- speed = sqrt(speed);
- filtered_.total_exposure = speed * target_.total_exposure +
- filtered_.total_exposure * (1.0 - speed);
- // When desaturing, take a big jump down in exposure_no_dg,
- // which we'll hide with digital gain.
- if (desaturate)
- filtered_.total_exposure_no_dg =
- target_.total_exposure_no_dg;
- else
- filtered_.total_exposure_no_dg =
- speed * target_.total_exposure_no_dg +
- filtered_.total_exposure_no_dg * (1.0 - speed);
- }
- // We can't let the no_dg exposure deviate too far below the
- // total exposure, as there might not be enough digital gain available
- // in the ISP to hide it (which will cause nasty oscillation).
- if (filtered_.total_exposure_no_dg <
- filtered_.total_exposure * config_.fast_reduce_threshold)
- filtered_.total_exposure_no_dg = filtered_.total_exposure *
- config_.fast_reduce_threshold;
- LOG(RPiAgc, Debug) << "After filtering, total_exposure " << filtered_.total_exposure
- << " no dg " << filtered_.total_exposure_no_dg;
-}
-
-void Agc::divideUpExposure()
-{
- // Sending the fixed shutter/gain cases through the same code may seem
- // unnecessary, but it will make more sense when extend this to cover
- // variable aperture.
- Duration exposure_value = filtered_.total_exposure_no_dg;
- Duration shutter_time;
- double analogue_gain;
- shutter_time = status_.fixed_shutter
- ? status_.fixed_shutter
- : exposure_mode_->shutter[0];
- shutter_time = clipShutter(shutter_time);
- analogue_gain = status_.fixed_analogue_gain != 0.0
- ? status_.fixed_analogue_gain
- : exposure_mode_->gain[0];
- if (shutter_time * analogue_gain < exposure_value) {
- for (unsigned int stage = 1;
- stage < exposure_mode_->gain.size(); stage++) {
- if (!status_.fixed_shutter) {
- Duration stage_shutter =
- clipShutter(exposure_mode_->shutter[stage]);
- if (stage_shutter * analogue_gain >=
- exposure_value) {
- shutter_time =
- exposure_value / analogue_gain;
- break;
- }
- shutter_time = stage_shutter;
- }
- if (status_.fixed_analogue_gain == 0.0) {
- if (exposure_mode_->gain[stage] *
- shutter_time >=
- exposure_value) {
- analogue_gain =
- exposure_value / shutter_time;
- break;
- }
- analogue_gain = exposure_mode_->gain[stage];
- }
- }
- }
- LOG(RPiAgc, Debug) << "Divided up shutter and gain are " << shutter_time << " and "
- << analogue_gain;
- // Finally adjust shutter time for flicker avoidance (require both
- // shutter and gain not to be fixed).
- if (!status_.fixed_shutter && !status_.fixed_analogue_gain &&
- status_.flicker_period) {
- int flicker_periods = shutter_time / status_.flicker_period;
- if (flicker_periods) {
- Duration new_shutter_time = flicker_periods * status_.flicker_period;
- analogue_gain *= shutter_time / new_shutter_time;
- // We should still not allow the ag to go over the
- // largest value in the exposure mode. Note that this
- // may force more of the total exposure into the digital
- // gain as a side-effect.
- analogue_gain = std::min(analogue_gain,
- exposure_mode_->gain.back());
- shutter_time = new_shutter_time;
- }
- LOG(RPiAgc, Debug) << "After flicker avoidance, shutter "
- << shutter_time << " gain " << analogue_gain;
- }
- filtered_.shutter = shutter_time;
- filtered_.analogue_gain = analogue_gain;
-}
-
-void Agc::writeAndFinish(Metadata *image_metadata, bool desaturate)
-{
- status_.total_exposure_value = filtered_.total_exposure;
- status_.target_exposure_value = desaturate ? 0s : target_.total_exposure_no_dg;
- status_.shutter_time = filtered_.shutter;
- status_.analogue_gain = filtered_.analogue_gain;
- // Write to metadata as well, in case anyone wants to update the camera
- // immediately.
- image_metadata->Set("agc.status", status_);
- LOG(RPiAgc, Debug) << "Output written, total exposure requested is "
- << filtered_.total_exposure;
- LOG(RPiAgc, Debug) << "Camera exposure update: shutter time " << filtered_.shutter
- << " analogue gain " << filtered_.analogue_gain;
-}
-
-Duration Agc::clipShutter(Duration shutter)
-{
- if (max_shutter_)
- shutter = std::min(shutter, max_shutter_);
- return shutter;
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Agc(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp
deleted file mode 100644
index c100d312..00000000
--- a/src/ipa/raspberrypi/controller/rpi/agc.hpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * agc.hpp - AGC/AEC control algorithm
- */
-#pragma once
-
-#include <vector>
-#include <mutex>
-
-#include <libcamera/base/utils.h>
-
-#include "../agc_algorithm.hpp"
-#include "../agc_status.h"
-#include "../pwl.hpp"
-
-// This is our implementation of AGC.
-
-// This is the number actually set up by the firmware, not the maximum possible
-// number (which is 16).
-
-#define AGC_STATS_SIZE 15
-
-namespace RPiController {
-
-struct AgcMeteringMode {
- double weights[AGC_STATS_SIZE];
- void Read(boost::property_tree::ptree const &params);
-};
-
-struct AgcExposureMode {
- std::vector<libcamera::utils::Duration> shutter;
- std::vector<double> gain;
- void Read(boost::property_tree::ptree const &params);
-};
-
-struct AgcConstraint {
- enum class Bound { LOWER = 0, UPPER = 1 };
- Bound bound;
- double q_lo;
- double q_hi;
- Pwl Y_target;
- void Read(boost::property_tree::ptree const &params);
-};
-
-typedef std::vector<AgcConstraint> AgcConstraintMode;
-
-struct AgcConfig {
- void Read(boost::property_tree::ptree const &params);
- std::map<std::string, AgcMeteringMode> metering_modes;
- std::map<std::string, AgcExposureMode> exposure_modes;
- std::map<std::string, AgcConstraintMode> constraint_modes;
- Pwl Y_target;
- double speed;
- uint16_t startup_frames;
- unsigned int convergence_frames;
- double max_change;
- double min_change;
- double fast_reduce_threshold;
- double speed_up_threshold;
- std::string default_metering_mode;
- std::string default_exposure_mode;
- std::string default_constraint_mode;
- double base_ev;
- libcamera::utils::Duration default_exposure_time;
- double default_analogue_gain;
-};
-
-class Agc : public AgcAlgorithm
-{
-public:
- Agc(Controller *controller);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- // AGC handles "pausing" for itself.
- bool IsPaused() const override;
- void Pause() override;
- void Resume() override;
- unsigned int GetConvergenceFrames() const override;
- void SetEv(double ev) override;
- void SetFlickerPeriod(libcamera::utils::Duration flicker_period) override;
- void SetMaxShutter(libcamera::utils::Duration max_shutter) override;
- void SetFixedShutter(libcamera::utils::Duration fixed_shutter) override;
- void SetFixedAnalogueGain(double fixed_analogue_gain) override;
- void SetMeteringMode(std::string const &metering_mode_name) override;
- void SetExposureMode(std::string const &exposure_mode_name) override;
- void SetConstraintMode(std::string const &contraint_mode_name) override;
- void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Prepare(Metadata *image_metadata) override;
- void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
-
-private:
- void updateLockStatus(DeviceStatus const &device_status);
- AgcConfig config_;
- void housekeepConfig();
- void fetchCurrentExposure(Metadata *image_metadata);
- void fetchAwbStatus(Metadata *image_metadata);
- void computeGain(bcm2835_isp_stats *statistics, Metadata *image_metadata,
- double &gain, double &target_Y);
- void computeTargetExposure(double gain);
- bool applyDigitalGain(double gain, double target_Y);
- void filterExposure(bool desaturate);
- void divideUpExposure();
- void writeAndFinish(Metadata *image_metadata, bool desaturate);
- libcamera::utils::Duration clipShutter(libcamera::utils::Duration shutter);
- AgcMeteringMode *metering_mode_;
- AgcExposureMode *exposure_mode_;
- AgcConstraintMode *constraint_mode_;
- uint64_t frame_count_;
- AwbStatus awb_;
- struct ExposureValues {
- ExposureValues();
-
- libcamera::utils::Duration shutter;
- double analogue_gain;
- libcamera::utils::Duration total_exposure;
- libcamera::utils::Duration total_exposure_no_dg; // without digital gain
- };
- ExposureValues current_; // values for the current frame
- ExposureValues target_; // calculate the values we want here
- ExposureValues filtered_; // these values are filtered towards target
- AgcStatus status_;
- int lock_count_;
- DeviceStatus last_device_status_;
- libcamera::utils::Duration last_target_exposure_;
- double last_sensitivity_; // sensitivity of the previous camera mode
- // Below here the "settings" that applications can change.
- std::string metering_mode_name_;
- std::string exposure_mode_name_;
- std::string constraint_mode_name_;
- double ev_;
- libcamera::utils::Duration flicker_period_;
- libcamera::utils::Duration max_shutter_;
- libcamera::utils::Duration fixed_shutter_;
- double fixed_analogue_gain_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
deleted file mode 100644
index e575c14a..00000000
--- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp
+++ /dev/null
@@ -1,787 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * alsc.cpp - ALSC (auto lens shading correction) control algorithm
- */
-
-#include <math.h>
-#include <numeric>
-
-#include <libcamera/base/log.h>
-#include <libcamera/base/span.h>
-
-#include "../awb_status.h"
-#include "alsc.hpp"
-
-// Raspberry Pi ALSC (Auto Lens Shading Correction) algorithm.
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiAlsc)
-
-#define NAME "rpi.alsc"
-
-static const int X = ALSC_CELLS_X;
-static const int Y = ALSC_CELLS_Y;
-static const int XY = X * Y;
-static const double INSUFFICIENT_DATA = -1.0;
-
-Alsc::Alsc(Controller *controller)
- : Algorithm(controller)
-{
- async_abort_ = async_start_ = async_started_ = async_finished_ = false;
- async_thread_ = std::thread(std::bind(&Alsc::asyncFunc, this));
-}
-
-Alsc::~Alsc()
-{
- {
- std::lock_guard<std::mutex> lock(mutex_);
- async_abort_ = true;
- }
- async_signal_.notify_one();
- async_thread_.join();
-}
-
-char const *Alsc::Name() const
-{
- return NAME;
-}
-
-static void generate_lut(double *lut, boost::property_tree::ptree const &params)
-{
- double cstrength = params.get<double>("corner_strength", 2.0);
- if (cstrength <= 1.0)
- throw std::runtime_error("Alsc: corner_strength must be > 1.0");
- double asymmetry = params.get<double>("asymmetry", 1.0);
- if (asymmetry < 0)
- throw std::runtime_error("Alsc: asymmetry must be >= 0");
- double f1 = cstrength - 1, f2 = 1 + sqrt(cstrength);
- double R2 = X * Y / 4 * (1 + asymmetry * asymmetry);
- int num = 0;
- for (int y = 0; y < Y; y++) {
- for (int x = 0; x < X; x++) {
- double dy = y - Y / 2 + 0.5,
- dx = (x - X / 2 + 0.5) * asymmetry;
- double r2 = (dx * dx + dy * dy) / R2;
- lut[num++] =
- (f1 * r2 + f2) * (f1 * r2 + f2) /
- (f2 * f2); // this reproduces the cos^4 rule
- }
- }
-}
-
-static void read_lut(double *lut, boost::property_tree::ptree const &params)
-{
- int num = 0;
- const int max_num = XY;
- for (auto &p : params) {
- if (num == max_num)
- throw std::runtime_error(
- "Alsc: too many entries in LSC table");
- lut[num++] = p.second.get_value<double>();
- }
- if (num < max_num)
- throw std::runtime_error("Alsc: too few entries in LSC table");
-}
-
-static void read_calibrations(std::vector<AlscCalibration> &calibrations,
- boost::property_tree::ptree const &params,
- std::string const &name)
-{
- if (params.get_child_optional(name)) {
- double last_ct = 0;
- for (auto &p : params.get_child(name)) {
- double ct = p.second.get<double>("ct");
- if (ct <= last_ct)
- throw std::runtime_error(
- "Alsc: entries in " + name +
- " must be in increasing ct order");
- AlscCalibration calibration;
- calibration.ct = last_ct = ct;
- boost::property_tree::ptree const &table =
- p.second.get_child("table");
- int num = 0;
- for (auto it = table.begin(); it != table.end(); it++) {
- if (num == XY)
- throw std::runtime_error(
- "Alsc: too many values for ct " +
- std::to_string(ct) + " in " +
- name);
- calibration.table[num++] =
- it->second.get_value<double>();
- }
- if (num != XY)
- throw std::runtime_error(
- "Alsc: too few values for ct " +
- std::to_string(ct) + " in " + name);
- calibrations.push_back(calibration);
- LOG(RPiAlsc, Debug)
- << "Read " << name << " calibration for ct " << ct;
- }
- }
-}
-
-void Alsc::Read(boost::property_tree::ptree const &params)
-{
- config_.frame_period = params.get<uint16_t>("frame_period", 12);
- config_.startup_frames = params.get<uint16_t>("startup_frames", 10);
- config_.speed = params.get<double>("speed", 0.05);
- double sigma = params.get<double>("sigma", 0.01);
- config_.sigma_Cr = params.get<double>("sigma_Cr", sigma);
- config_.sigma_Cb = params.get<double>("sigma_Cb", sigma);
- config_.min_count = params.get<double>("min_count", 10.0);
- config_.min_G = params.get<uint16_t>("min_G", 50);
- config_.omega = params.get<double>("omega", 1.3);
- config_.n_iter = params.get<uint32_t>("n_iter", X + Y);
- config_.luminance_strength =
- params.get<double>("luminance_strength", 1.0);
- for (int i = 0; i < XY; i++)
- config_.luminance_lut[i] = 1.0;
- if (params.get_child_optional("corner_strength"))
- generate_lut(config_.luminance_lut, params);
- else if (params.get_child_optional("luminance_lut"))
- read_lut(config_.luminance_lut,
- params.get_child("luminance_lut"));
- else
- LOG(RPiAlsc, Warning)
- << "no luminance table - assume unity everywhere";
- read_calibrations(config_.calibrations_Cr, params, "calibrations_Cr");
- read_calibrations(config_.calibrations_Cb, params, "calibrations_Cb");
- config_.default_ct = params.get<double>("default_ct", 4500.0);
- config_.threshold = params.get<double>("threshold", 1e-3);
- config_.lambda_bound = params.get<double>("lambda_bound", 0.05);
-}
-
-static double get_ct(Metadata *metadata, double default_ct);
-static void get_cal_table(double ct,
- std::vector<AlscCalibration> const &calibrations,
- double cal_table[XY]);
-static void resample_cal_table(double const cal_table_in[XY],
- CameraMode const &camera_mode,
- double cal_table_out[XY]);
-static void compensate_lambdas_for_cal(double const cal_table[XY],
- double const old_lambdas[XY],
- double new_lambdas[XY]);
-static void add_luminance_to_tables(double results[3][Y][X],
- double const lambda_r[XY], double lambda_g,
- double const lambda_b[XY],
- double const luminance_lut[XY],
- double luminance_strength);
-
-void Alsc::Initialise()
-{
- frame_count2_ = frame_count_ = frame_phase_ = 0;
- first_time_ = true;
- ct_ = config_.default_ct;
- // The lambdas are initialised in the SwitchMode.
-}
-
-void Alsc::waitForAysncThread()
-{
- if (async_started_) {
- async_started_ = false;
- std::unique_lock<std::mutex> lock(mutex_);
- sync_signal_.wait(lock, [&] {
- return async_finished_;
- });
- async_finished_ = false;
- }
-}
-
-static bool compare_modes(CameraMode const &cm0, CameraMode const &cm1)
-{
- // Return true if the modes crop from the sensor significantly differently,
- // or if the user transform has changed.
- if (cm0.transform != cm1.transform)
- return true;
- int left_diff = abs(cm0.crop_x - cm1.crop_x);
- int top_diff = abs(cm0.crop_y - cm1.crop_y);
- int right_diff = fabs(cm0.crop_x + cm0.scale_x * cm0.width -
- cm1.crop_x - cm1.scale_x * cm1.width);
- int bottom_diff = fabs(cm0.crop_y + cm0.scale_y * cm0.height -
- cm1.crop_y - cm1.scale_y * cm1.height);
- // These thresholds are a rather arbitrary amount chosen to trigger
- // when carrying on with the previously calculated tables might be
- // worse than regenerating them (but without the adaptive algorithm).
- int threshold_x = cm0.sensor_width >> 4;
- int threshold_y = cm0.sensor_height >> 4;
- return left_diff > threshold_x || right_diff > threshold_x ||
- top_diff > threshold_y || bottom_diff > threshold_y;
-}
-
-void Alsc::SwitchMode(CameraMode const &camera_mode,
- [[maybe_unused]] Metadata *metadata)
-{
- // We're going to start over with the tables if there's any "significant"
- // change.
- bool reset_tables = first_time_ || compare_modes(camera_mode_, camera_mode);
-
- // Believe the colour temperature from the AWB, if there is one.
- ct_ = get_ct(metadata, ct_);
-
- // Ensure the other thread isn't running while we do this.
- waitForAysncThread();
-
- camera_mode_ = camera_mode;
-
- // We must resample the luminance table like we do the others, but it's
- // fixed so we can simply do it up front here.
- resample_cal_table(config_.luminance_lut, camera_mode_, luminance_table_);
-
- if (reset_tables) {
- // Upon every "table reset", arrange for something sensible to be
- // generated. Construct the tables for the previous recorded colour
- // temperature. In order to start over from scratch we initialise
- // the lambdas, but the rest of this code then echoes the code in
- // doAlsc, without the adaptive algorithm.
- for (int i = 0; i < XY; i++)
- lambda_r_[i] = lambda_b_[i] = 1.0;
- double cal_table_r[XY], cal_table_b[XY], cal_table_tmp[XY];
- get_cal_table(ct_, config_.calibrations_Cr, cal_table_tmp);
- resample_cal_table(cal_table_tmp, camera_mode_, cal_table_r);
- get_cal_table(ct_, config_.calibrations_Cb, cal_table_tmp);
- resample_cal_table(cal_table_tmp, camera_mode_, cal_table_b);
- compensate_lambdas_for_cal(cal_table_r, lambda_r_,
- async_lambda_r_);
- compensate_lambdas_for_cal(cal_table_b, lambda_b_,
- async_lambda_b_);
- add_luminance_to_tables(sync_results_, async_lambda_r_, 1.0,
- async_lambda_b_, luminance_table_,
- config_.luminance_strength);
- memcpy(prev_sync_results_, sync_results_,
- sizeof(prev_sync_results_));
- frame_phase_ = config_.frame_period; // run the algo again asap
- first_time_ = false;
- }
-}
-
-void Alsc::fetchAsyncResults()
-{
- LOG(RPiAlsc, Debug) << "Fetch ALSC results";
- async_finished_ = false;
- async_started_ = false;
- memcpy(sync_results_, async_results_, sizeof(sync_results_));
-}
-
-double get_ct(Metadata *metadata, double default_ct)
-{
- AwbStatus awb_status;
- awb_status.temperature_K = default_ct; // in case nothing found
- if (metadata->Get("awb.status", awb_status) != 0)
- LOG(RPiAlsc, Debug) << "no AWB results found, using "
- << awb_status.temperature_K;
- else
- LOG(RPiAlsc, Debug) << "AWB results found, using "
- << awb_status.temperature_K;
- return awb_status.temperature_K;
-}
-
-static void copy_stats(bcm2835_isp_stats_region regions[XY], StatisticsPtr &stats,
- AlscStatus const &status)
-{
- bcm2835_isp_stats_region *input_regions = stats->awb_stats;
- double *r_table = (double *)status.r;
- double *g_table = (double *)status.g;
- double *b_table = (double *)status.b;
- for (int i = 0; i < XY; i++) {
- regions[i].r_sum = input_regions[i].r_sum / r_table[i];
- regions[i].g_sum = input_regions[i].g_sum / g_table[i];
- regions[i].b_sum = input_regions[i].b_sum / b_table[i];
- regions[i].counted = input_regions[i].counted;
- // (don't care about the uncounted value)
- }
-}
-
-void Alsc::restartAsync(StatisticsPtr &stats, Metadata *image_metadata)
-{
- LOG(RPiAlsc, Debug) << "Starting ALSC calculation";
- // Get the current colour temperature. It's all we need from the
- // metadata. Default to the last CT value (which could be the default).
- ct_ = get_ct(image_metadata, ct_);
- // We have to copy the statistics here, dividing out our best guess of
- // the LSC table that the pipeline applied to them.
- AlscStatus alsc_status;
- if (image_metadata->Get("alsc.status", alsc_status) != 0) {
- LOG(RPiAlsc, Warning)
- << "No ALSC status found for applied gains!";
- for (int y = 0; y < Y; y++)
- for (int x = 0; x < X; x++) {
- alsc_status.r[y][x] = 1.0;
- alsc_status.g[y][x] = 1.0;
- alsc_status.b[y][x] = 1.0;
- }
- }
- copy_stats(statistics_, stats, alsc_status);
- frame_phase_ = 0;
- async_started_ = true;
- {
- std::lock_guard<std::mutex> lock(mutex_);
- async_start_ = true;
- }
- async_signal_.notify_one();
-}
-
-void Alsc::Prepare(Metadata *image_metadata)
-{
- // Count frames since we started, and since we last poked the async
- // thread.
- if (frame_count_ < (int)config_.startup_frames)
- frame_count_++;
- double speed = frame_count_ < (int)config_.startup_frames
- ? 1.0
- : config_.speed;
- LOG(RPiAlsc, Debug)
- << "frame_count " << frame_count_ << " speed " << speed;
- {
- std::unique_lock<std::mutex> lock(mutex_);
- if (async_started_ && async_finished_)
- fetchAsyncResults();
- }
- // Apply IIR filter to results and program into the pipeline.
- double *ptr = (double *)sync_results_,
- *pptr = (double *)prev_sync_results_;
- for (unsigned int i = 0;
- i < sizeof(sync_results_) / sizeof(double); i++)
- pptr[i] = speed * ptr[i] + (1.0 - speed) * pptr[i];
- // Put output values into status metadata.
- AlscStatus status;
- memcpy(status.r, prev_sync_results_[0], sizeof(status.r));
- memcpy(status.g, prev_sync_results_[1], sizeof(status.g));
- memcpy(status.b, prev_sync_results_[2], sizeof(status.b));
- image_metadata->Set("alsc.status", status);
-}
-
-void Alsc::Process(StatisticsPtr &stats, Metadata *image_metadata)
-{
- // Count frames since we started, and since we last poked the async
- // thread.
- if (frame_phase_ < (int)config_.frame_period)
- frame_phase_++;
- if (frame_count2_ < (int)config_.startup_frames)
- frame_count2_++;
- LOG(RPiAlsc, Debug) << "frame_phase " << frame_phase_;
- if (frame_phase_ >= (int)config_.frame_period ||
- frame_count2_ < (int)config_.startup_frames) {
- if (async_started_ == false)
- restartAsync(stats, image_metadata);
- }
-}
-
-void Alsc::asyncFunc()
-{
- while (true) {
- {
- std::unique_lock<std::mutex> lock(mutex_);
- async_signal_.wait(lock, [&] {
- return async_start_ || async_abort_;
- });
- async_start_ = false;
- if (async_abort_)
- break;
- }
- doAlsc();
- {
- std::lock_guard<std::mutex> lock(mutex_);
- async_finished_ = true;
- }
- sync_signal_.notify_one();
- }
-}
-
-void get_cal_table(double ct, std::vector<AlscCalibration> const &calibrations,
- double cal_table[XY])
-{
- if (calibrations.empty()) {
- for (int i = 0; i < XY; i++)
- cal_table[i] = 1.0;
- LOG(RPiAlsc, Debug) << "no calibrations found";
- } else if (ct <= calibrations.front().ct) {
- memcpy(cal_table, calibrations.front().table,
- XY * sizeof(double));
- LOG(RPiAlsc, Debug) << "using calibration for "
- << calibrations.front().ct;
- } else if (ct >= calibrations.back().ct) {
- memcpy(cal_table, calibrations.back().table,
- XY * sizeof(double));
- LOG(RPiAlsc, Debug) << "using calibration for "
- << calibrations.back().ct;
- } else {
- int idx = 0;
- while (ct > calibrations[idx + 1].ct)
- idx++;
- double ct0 = calibrations[idx].ct,
- ct1 = calibrations[idx + 1].ct;
- LOG(RPiAlsc, Debug)
- << "ct is " << ct << ", interpolating between "
- << ct0 << " and " << ct1;
- for (int i = 0; i < XY; i++)
- cal_table[i] =
- (calibrations[idx].table[i] * (ct1 - ct) +
- calibrations[idx + 1].table[i] * (ct - ct0)) /
- (ct1 - ct0);
- }
-}
-
-void resample_cal_table(double const cal_table_in[XY],
- CameraMode const &camera_mode, double cal_table_out[XY])
-{
- // Precalculate and cache the x sampling locations and phases to save
- // recomputing them on every row.
- int x_lo[X], x_hi[X];
- double xf[X];
- double scale_x = camera_mode.sensor_width /
- (camera_mode.width * camera_mode.scale_x);
- double x_off = camera_mode.crop_x / (double)camera_mode.sensor_width;
- double x = .5 / scale_x + x_off * X - .5;
- double x_inc = 1 / scale_x;
- for (int i = 0; i < X; i++, x += x_inc) {
- x_lo[i] = floor(x);
- xf[i] = x - x_lo[i];
- x_hi[i] = std::min(x_lo[i] + 1, X - 1);
- x_lo[i] = std::max(x_lo[i], 0);
- if (!!(camera_mode.transform & libcamera::Transform::HFlip)) {
- x_lo[i] = X - 1 - x_lo[i];
- x_hi[i] = X - 1 - x_hi[i];
- }
- }
- // Now march over the output table generating the new values.
- double scale_y = camera_mode.sensor_height /
- (camera_mode.height * camera_mode.scale_y);
- double y_off = camera_mode.crop_y / (double)camera_mode.sensor_height;
- double y = .5 / scale_y + y_off * Y - .5;
- double y_inc = 1 / scale_y;
- for (int j = 0; j < Y; j++, y += y_inc) {
- int y_lo = floor(y);
- double yf = y - y_lo;
- int y_hi = std::min(y_lo + 1, Y - 1);
- y_lo = std::max(y_lo, 0);
- if (!!(camera_mode.transform & libcamera::Transform::VFlip)) {
- y_lo = Y - 1 - y_lo;
- y_hi = Y - 1 - y_hi;
- }
- double const *row_above = cal_table_in + X * y_lo;
- double const *row_below = cal_table_in + X * y_hi;
- for (int i = 0; i < X; i++) {
- double above = row_above[x_lo[i]] * (1 - xf[i]) +
- row_above[x_hi[i]] * xf[i];
- double below = row_below[x_lo[i]] * (1 - xf[i]) +
- row_below[x_hi[i]] * xf[i];
- *(cal_table_out++) = above * (1 - yf) + below * yf;
- }
- }
-}
-
-// Calculate chrominance statistics (R/G and B/G) for each region.
-static_assert(XY == AWB_REGIONS, "ALSC/AWB statistics region mismatch");
-static void calculate_Cr_Cb(bcm2835_isp_stats_region *awb_region, double Cr[XY],
- double Cb[XY], uint32_t min_count, uint16_t min_G)
-{
- for (int i = 0; i < XY; i++) {
- bcm2835_isp_stats_region &zone = awb_region[i];
- if (zone.counted <= min_count ||
- zone.g_sum / zone.counted <= min_G) {
- Cr[i] = Cb[i] = INSUFFICIENT_DATA;
- continue;
- }
- Cr[i] = zone.r_sum / (double)zone.g_sum;
- Cb[i] = zone.b_sum / (double)zone.g_sum;
- }
-}
-
-static void apply_cal_table(double const cal_table[XY], double C[XY])
-{
- for (int i = 0; i < XY; i++)
- if (C[i] != INSUFFICIENT_DATA)
- C[i] *= cal_table[i];
-}
-
-void compensate_lambdas_for_cal(double const cal_table[XY],
- double const old_lambdas[XY],
- double new_lambdas[XY])
-{
- double min_new_lambda = std::numeric_limits<double>::max();
- for (int i = 0; i < XY; i++) {
- new_lambdas[i] = old_lambdas[i] * cal_table[i];
- min_new_lambda = std::min(min_new_lambda, new_lambdas[i]);
- }
- for (int i = 0; i < XY; i++)
- new_lambdas[i] /= min_new_lambda;
-}
-
-[[maybe_unused]] static void print_cal_table(double const C[XY])
-{
- printf("table: [\n");
- for (int j = 0; j < Y; j++) {
- for (int i = 0; i < X; i++) {
- printf("%5.3f", 1.0 / C[j * X + i]);
- if (i != X - 1 || j != Y - 1)
- printf(",");
- }
- printf("\n");
- }
- printf("]\n");
-}
-
-// Compute weight out of 1.0 which reflects how similar we wish to make the
-// colours of these two regions.
-static double compute_weight(double C_i, double C_j, double sigma)
-{
- if (C_i == INSUFFICIENT_DATA || C_j == INSUFFICIENT_DATA)
- return 0;
- double diff = (C_i - C_j) / sigma;
- return exp(-diff * diff / 2);
-}
-
-// Compute all weights.
-static void compute_W(double const C[XY], double sigma, double W[XY][4])
-{
- for (int i = 0; i < XY; i++) {
- // Start with neighbour above and go clockwise.
- W[i][0] = i >= X ? compute_weight(C[i], C[i - X], sigma) : 0;
- W[i][1] = i % X < X - 1 ? compute_weight(C[i], C[i + 1], sigma)
- : 0;
- W[i][2] =
- i < XY - X ? compute_weight(C[i], C[i + X], sigma) : 0;
- W[i][3] = i % X ? compute_weight(C[i], C[i - 1], sigma) : 0;
- }
-}
-
-// Compute M, the large but sparse matrix such that M * lambdas = 0.
-static void construct_M(double const C[XY], double const W[XY][4],
- double M[XY][4])
-{
- double epsilon = 0.001;
- for (int i = 0; i < XY; i++) {
- // Note how, if C[i] == INSUFFICIENT_DATA, the weights will all
- // be zero so the equation is still set up correctly.
- int m = !!(i >= X) + !!(i % X < X - 1) + !!(i < XY - X) +
- !!(i % X); // total number of neighbours
- // we'll divide the diagonal out straight away
- double diagonal =
- (epsilon + W[i][0] + W[i][1] + W[i][2] + W[i][3]) *
- C[i];
- M[i][0] = i >= X ? (W[i][0] * C[i - X] + epsilon / m * C[i]) /
- diagonal
- : 0;
- M[i][1] = i % X < X - 1
- ? (W[i][1] * C[i + 1] + epsilon / m * C[i]) /
- diagonal
- : 0;
- M[i][2] = i < XY - X
- ? (W[i][2] * C[i + X] + epsilon / m * C[i]) /
- diagonal
- : 0;
- M[i][3] = i % X ? (W[i][3] * C[i - 1] + epsilon / m * C[i]) /
- diagonal
- : 0;
- }
-}
-
-// In the compute_lambda_ functions, note that the matrix coefficients for the
-// left/right neighbours are zero down the left/right edges, so we don't need
-// need to test the i value to exclude them.
-static double compute_lambda_bottom(int i, double const M[XY][4],
- double lambda[XY])
-{
- return M[i][1] * lambda[i + 1] + M[i][2] * lambda[i + X] +
- M[i][3] * lambda[i - 1];
-}
-static double compute_lambda_bottom_start(int i, double const M[XY][4],
- double lambda[XY])
-{
- return M[i][1] * lambda[i + 1] + M[i][2] * lambda[i + X];
-}
-static double compute_lambda_interior(int i, double const M[XY][4],
- double lambda[XY])
-{
- return M[i][0] * lambda[i - X] + M[i][1] * lambda[i + 1] +
- M[i][2] * lambda[i + X] + M[i][3] * lambda[i - 1];
-}
-static double compute_lambda_top(int i, double const M[XY][4],
- double lambda[XY])
-{
- return M[i][0] * lambda[i - X] + M[i][1] * lambda[i + 1] +
- M[i][3] * lambda[i - 1];
-}
-static double compute_lambda_top_end(int i, double const M[XY][4],
- double lambda[XY])
-{
- return M[i][0] * lambda[i - X] + M[i][3] * lambda[i - 1];
-}
-
-// Gauss-Seidel iteration with over-relaxation.
-static double gauss_seidel2_SOR(double const M[XY][4], double omega,
- double lambda[XY], double lambda_bound)
-{
- const double min = 1 - lambda_bound, max = 1 + lambda_bound;
- double old_lambda[XY];
- int i;
- for (i = 0; i < XY; i++)
- old_lambda[i] = lambda[i];
- lambda[0] = compute_lambda_bottom_start(0, M, lambda);
- lambda[0] = std::clamp(lambda[0], min, max);
- for (i = 1; i < X; i++) {
- lambda[i] = compute_lambda_bottom(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- }
- for (; i < XY - X; i++) {
- lambda[i] = compute_lambda_interior(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- }
- for (; i < XY - 1; i++) {
- lambda[i] = compute_lambda_top(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- }
- lambda[i] = compute_lambda_top_end(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- // Also solve the system from bottom to top, to help spread the updates
- // better.
- lambda[i] = compute_lambda_top_end(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- for (i = XY - 2; i >= XY - X; i--) {
- lambda[i] = compute_lambda_top(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- }
- for (; i >= X; i--) {
- lambda[i] = compute_lambda_interior(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- }
- for (; i >= 1; i--) {
- lambda[i] = compute_lambda_bottom(i, M, lambda);
- lambda[i] = std::clamp(lambda[i], min, max);
- }
- lambda[0] = compute_lambda_bottom_start(0, M, lambda);
- lambda[0] = std::clamp(lambda[0], min, max);
- double max_diff = 0;
- for (i = 0; i < XY; i++) {
- lambda[i] = old_lambda[i] + (lambda[i] - old_lambda[i]) * omega;
- if (fabs(lambda[i] - old_lambda[i]) > fabs(max_diff))
- max_diff = lambda[i] - old_lambda[i];
- }
- return max_diff;
-}
-
-// Normalise the values so that the smallest value is 1.
-static void normalise(double *ptr, size_t n)
-{
- double minval = ptr[0];
- for (size_t i = 1; i < n; i++)
- minval = std::min(minval, ptr[i]);
- for (size_t i = 0; i < n; i++)
- ptr[i] /= minval;
-}
-
-// Rescale the values so that the average value is 1.
-static void reaverage(Span<double> data)
-{
- double sum = std::accumulate(data.begin(), data.end(), 0.0);
- double ratio = 1 / (sum / data.size());
- for (double &d : data)
- d *= ratio;
-}
-
-static void run_matrix_iterations(double const C[XY], double lambda[XY],
- double const W[XY][4], double omega,
- int n_iter, double threshold, double lambda_bound)
-{
- double M[XY][4];
- construct_M(C, W, M);
- double last_max_diff = std::numeric_limits<double>::max();
- for (int i = 0; i < n_iter; i++) {
- double max_diff = fabs(gauss_seidel2_SOR(M, omega, lambda, lambda_bound));
- if (max_diff < threshold) {
- LOG(RPiAlsc, Debug)
- << "Stop after " << i + 1 << " iterations";
- break;
- }
- // this happens very occasionally (so make a note), though
- // doesn't seem to matter
- if (max_diff > last_max_diff)
- LOG(RPiAlsc, Debug)
- << "Iteration " << i << ": max_diff gone up "
- << last_max_diff << " to " << max_diff;
- last_max_diff = max_diff;
- }
- // We're going to normalise the lambdas so the total average is 1.
- reaverage({ lambda, XY });
-}
-
-static void add_luminance_rb(double result[XY], double const lambda[XY],
- double const luminance_lut[XY],
- double luminance_strength)
-{
- for (int i = 0; i < XY; i++)
- result[i] = lambda[i] *
- ((luminance_lut[i] - 1) * luminance_strength + 1);
-}
-
-static void add_luminance_g(double result[XY], double lambda,
- double const luminance_lut[XY],
- double luminance_strength)
-{
- for (int i = 0; i < XY; i++)
- result[i] = lambda *
- ((luminance_lut[i] - 1) * luminance_strength + 1);
-}
-
-void add_luminance_to_tables(double results[3][Y][X], double const lambda_r[XY],
- double lambda_g, double const lambda_b[XY],
- double const luminance_lut[XY],
- double luminance_strength)
-{
- add_luminance_rb((double *)results[0], lambda_r, luminance_lut,
- luminance_strength);
- add_luminance_g((double *)results[1], lambda_g, luminance_lut,
- luminance_strength);
- add_luminance_rb((double *)results[2], lambda_b, luminance_lut,
- luminance_strength);
- normalise((double *)results, 3 * XY);
-}
-
-void Alsc::doAlsc()
-{
- double Cr[XY], Cb[XY], Wr[XY][4], Wb[XY][4], cal_table_r[XY],
- cal_table_b[XY], cal_table_tmp[XY];
- // Calculate our R/B ("Cr"/"Cb") colour statistics, and assess which are
- // usable.
- calculate_Cr_Cb(statistics_, Cr, Cb, config_.min_count, config_.min_G);
- // Fetch the new calibrations (if any) for this CT. Resample them in
- // case the camera mode is not full-frame.
- get_cal_table(ct_, config_.calibrations_Cr, cal_table_tmp);
- resample_cal_table(cal_table_tmp, camera_mode_, cal_table_r);
- get_cal_table(ct_, config_.calibrations_Cb, cal_table_tmp);
- resample_cal_table(cal_table_tmp, camera_mode_, cal_table_b);
- // You could print out the cal tables for this image here, if you're
- // tuning the algorithm...
- // Apply any calibration to the statistics, so the adaptive algorithm
- // makes only the extra adjustments.
- apply_cal_table(cal_table_r, Cr);
- apply_cal_table(cal_table_b, Cb);
- // Compute weights between zones.
- compute_W(Cr, config_.sigma_Cr, Wr);
- compute_W(Cb, config_.sigma_Cb, Wb);
- // Run Gauss-Seidel iterations over the resulting matrix, for R and B.
- run_matrix_iterations(Cr, lambda_r_, Wr, config_.omega, config_.n_iter,
- config_.threshold, config_.lambda_bound);
- run_matrix_iterations(Cb, lambda_b_, Wb, config_.omega, config_.n_iter,
- config_.threshold, config_.lambda_bound);
- // Fold the calibrated gains into our final lambda values. (Note that on
- // the next run, we re-start with the lambda values that don't have the
- // calibration gains included.)
- compensate_lambdas_for_cal(cal_table_r, lambda_r_, async_lambda_r_);
- compensate_lambdas_for_cal(cal_table_b, lambda_b_, async_lambda_b_);
- // Fold in the luminance table at the appropriate strength.
- add_luminance_to_tables(async_results_, async_lambda_r_, 1.0,
- async_lambda_b_, luminance_table_,
- config_.luminance_strength);
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Alsc(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.hpp b/src/ipa/raspberrypi/controller/rpi/alsc.hpp
deleted file mode 100644
index d1dbe0d1..00000000
--- a/src/ipa/raspberrypi/controller/rpi/alsc.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * alsc.hpp - ALSC (auto lens shading correction) control algorithm
- */
-#pragma once
-
-#include <mutex>
-#include <condition_variable>
-#include <thread>
-
-#include "../algorithm.hpp"
-#include "../alsc_status.h"
-
-namespace RPiController {
-
-// Algorithm to generate automagic LSC (Lens Shading Correction) tables.
-
-struct AlscCalibration {
- double ct;
- double table[ALSC_CELLS_X * ALSC_CELLS_Y];
-};
-
-struct AlscConfig {
- // Only repeat the ALSC calculation every "this many" frames
- uint16_t frame_period;
- // number of initial frames for which speed taken as 1.0 (maximum)
- uint16_t startup_frames;
- // IIR filter speed applied to algorithm results
- double speed;
- double sigma_Cr;
- double sigma_Cb;
- double min_count;
- uint16_t min_G;
- double omega;
- uint32_t n_iter;
- double luminance_lut[ALSC_CELLS_X * ALSC_CELLS_Y];
- double luminance_strength;
- std::vector<AlscCalibration> calibrations_Cr;
- std::vector<AlscCalibration> calibrations_Cb;
- double default_ct; // colour temperature if no metadata found
- double threshold; // iteration termination threshold
- double lambda_bound; // upper/lower bound for lambda from a value of 1
-};
-
-class Alsc : public Algorithm
-{
-public:
- Alsc(Controller *controller = NULL);
- ~Alsc();
- char const *Name() const override;
- void Initialise() override;
- void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Read(boost::property_tree::ptree const &params) override;
- void Prepare(Metadata *image_metadata) override;
- void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
-
-private:
- // configuration is read-only, and available to both threads
- AlscConfig config_;
- bool first_time_;
- CameraMode camera_mode_;
- double luminance_table_[ALSC_CELLS_X * ALSC_CELLS_Y];
- std::thread async_thread_;
- void asyncFunc(); // asynchronous thread function
- std::mutex mutex_;
- // condvar for async thread to wait on
- std::condition_variable async_signal_;
- // condvar for synchronous thread to wait on
- std::condition_variable sync_signal_;
- // for sync thread to check if async thread finished (requires mutex)
- bool async_finished_;
- // for async thread to check if it's been told to run (requires mutex)
- bool async_start_;
- // for async thread to check if it's been told to quit (requires mutex)
- bool async_abort_;
-
- // The following are only for the synchronous thread to use:
- // for sync thread to note its has asked async thread to run
- bool async_started_;
- // counts up to frame_period before restarting the async thread
- int frame_phase_;
- // counts up to startup_frames
- int frame_count_;
- // counts up to startup_frames for Process function
- int frame_count2_;
- double sync_results_[3][ALSC_CELLS_Y][ALSC_CELLS_X];
- double prev_sync_results_[3][ALSC_CELLS_Y][ALSC_CELLS_X];
- void waitForAysncThread();
- // The following are for the asynchronous thread to use, though the main
- // thread can set/reset them if the async thread is known to be idle:
- void restartAsync(StatisticsPtr &stats, Metadata *image_metadata);
- // copy out the results from the async thread so that it can be restarted
- void fetchAsyncResults();
- double ct_;
- bcm2835_isp_stats_region statistics_[ALSC_CELLS_Y * ALSC_CELLS_X];
- double async_results_[3][ALSC_CELLS_Y][ALSC_CELLS_X];
- double async_lambda_r_[ALSC_CELLS_X * ALSC_CELLS_Y];
- double async_lambda_b_[ALSC_CELLS_X * ALSC_CELLS_Y];
- void doAlsc();
- double lambda_r_[ALSC_CELLS_X * ALSC_CELLS_Y];
- double lambda_b_[ALSC_CELLS_X * ALSC_CELLS_Y];
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp b/src/ipa/raspberrypi/controller/rpi/awb.cpp
deleted file mode 100644
index d4c93447..00000000
--- a/src/ipa/raspberrypi/controller/rpi/awb.cpp
+++ /dev/null
@@ -1,667 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * awb.cpp - AWB control algorithm
- */
-
-#include <libcamera/base/log.h>
-
-#include "../lux_status.h"
-
-#include "awb.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiAwb)
-
-#define NAME "rpi.awb"
-
-#define AWB_STATS_SIZE_X DEFAULT_AWB_REGIONS_X
-#define AWB_STATS_SIZE_Y DEFAULT_AWB_REGIONS_Y
-
-// todo - the locking in this algorithm needs some tidying up as has been done
-// elsewhere (ALSC and AGC).
-
-void AwbMode::Read(boost::property_tree::ptree const &params)
-{
- ct_lo = params.get<double>("lo");
- ct_hi = params.get<double>("hi");
-}
-
-void AwbPrior::Read(boost::property_tree::ptree const &params)
-{
- lux = params.get<double>("lux");
- prior.Read(params.get_child("prior"));
-}
-
-static void read_ct_curve(Pwl &ct_r, Pwl &ct_b,
- boost::property_tree::ptree const &params)
-{
- int num = 0;
- for (auto it = params.begin(); it != params.end(); it++) {
- double ct = it->second.get_value<double>();
- assert(it == params.begin() || ct != ct_r.Domain().end);
- if (++it == params.end())
- throw std::runtime_error(
- "AwbConfig: incomplete CT curve entry");
- ct_r.Append(ct, it->second.get_value<double>());
- if (++it == params.end())
- throw std::runtime_error(
- "AwbConfig: incomplete CT curve entry");
- ct_b.Append(ct, it->second.get_value<double>());
- num++;
- }
- if (num < 2)
- throw std::runtime_error(
- "AwbConfig: insufficient points in CT curve");
-}
-
-void AwbConfig::Read(boost::property_tree::ptree const &params)
-{
- bayes = params.get<int>("bayes", 1);
- frame_period = params.get<uint16_t>("frame_period", 10);
- startup_frames = params.get<uint16_t>("startup_frames", 10);
- convergence_frames = params.get<unsigned int>("convergence_frames", 3);
- speed = params.get<double>("speed", 0.05);
- if (params.get_child_optional("ct_curve"))
- read_ct_curve(ct_r, ct_b, params.get_child("ct_curve"));
- if (params.get_child_optional("priors")) {
- for (auto &p : params.get_child("priors")) {
- AwbPrior prior;
- prior.Read(p.second);
- if (!priors.empty() && prior.lux <= priors.back().lux)
- throw std::runtime_error(
- "AwbConfig: Prior must be ordered in increasing lux value");
- priors.push_back(prior);
- }
- if (priors.empty())
- throw std::runtime_error(
- "AwbConfig: no AWB priors configured");
- }
- if (params.get_child_optional("modes")) {
- for (auto &p : params.get_child("modes")) {
- modes[p.first].Read(p.second);
- if (default_mode == nullptr)
- default_mode = &modes[p.first];
- }
- if (default_mode == nullptr)
- throw std::runtime_error(
- "AwbConfig: no AWB modes configured");
- }
- min_pixels = params.get<double>("min_pixels", 16.0);
- min_G = params.get<uint16_t>("min_G", 32);
- min_regions = params.get<uint32_t>("min_regions", 10);
- delta_limit = params.get<double>("delta_limit", 0.2);
- coarse_step = params.get<double>("coarse_step", 0.2);
- transverse_pos = params.get<double>("transverse_pos", 0.01);
- transverse_neg = params.get<double>("transverse_neg", 0.01);
- if (transverse_pos <= 0 || transverse_neg <= 0)
- throw std::runtime_error(
- "AwbConfig: transverse_pos/neg must be > 0");
- sensitivity_r = params.get<double>("sensitivity_r", 1.0);
- sensitivity_b = params.get<double>("sensitivity_b", 1.0);
- if (bayes) {
- if (ct_r.Empty() || ct_b.Empty() || priors.empty() ||
- default_mode == nullptr) {
- LOG(RPiAwb, Warning)
- << "Bayesian AWB mis-configured - switch to Grey method";
- bayes = false;
- }
- }
- fast = params.get<int>(
- "fast", bayes); // default to fast for Bayesian, otherwise slow
- whitepoint_r = params.get<double>("whitepoint_r", 0.0);
- whitepoint_b = params.get<double>("whitepoint_b", 0.0);
- if (bayes == false)
- sensitivity_r = sensitivity_b =
- 1.0; // nor do sensitivities make any sense
-}
-
-Awb::Awb(Controller *controller)
- : AwbAlgorithm(controller)
-{
- async_abort_ = async_start_ = async_started_ = async_finished_ = false;
- mode_ = nullptr;
- manual_r_ = manual_b_ = 0.0;
- first_switch_mode_ = true;
- async_thread_ = std::thread(std::bind(&Awb::asyncFunc, this));
-}
-
-Awb::~Awb()
-{
- {
- std::lock_guard<std::mutex> lock(mutex_);
- async_abort_ = true;
- }
- async_signal_.notify_one();
- async_thread_.join();
-}
-
-char const *Awb::Name() const
-{
- return NAME;
-}
-
-void Awb::Read(boost::property_tree::ptree const &params)
-{
- config_.Read(params);
-}
-
-void Awb::Initialise()
-{
- frame_count_ = frame_phase_ = 0;
- // Put something sane into the status that we are filtering towards,
- // just in case the first few frames don't have anything meaningful in
- // them.
- if (!config_.ct_r.Empty() && !config_.ct_b.Empty()) {
- sync_results_.temperature_K = config_.ct_r.Domain().Clip(4000);
- sync_results_.gain_r =
- 1.0 / config_.ct_r.Eval(sync_results_.temperature_K);
- sync_results_.gain_g = 1.0;
- sync_results_.gain_b =
- 1.0 / config_.ct_b.Eval(sync_results_.temperature_K);
- } else {
- // random values just to stop the world blowing up
- sync_results_.temperature_K = 4500;
- sync_results_.gain_r = sync_results_.gain_g =
- sync_results_.gain_b = 1.0;
- }
- prev_sync_results_ = sync_results_;
- async_results_ = sync_results_;
-}
-
-bool Awb::IsPaused() const
-{
- return false;
-}
-
-void Awb::Pause()
-{
- // "Pause" by fixing everything to the most recent values.
- manual_r_ = sync_results_.gain_r = prev_sync_results_.gain_r;
- manual_b_ = sync_results_.gain_b = prev_sync_results_.gain_b;
- sync_results_.gain_g = prev_sync_results_.gain_g;
- sync_results_.temperature_K = prev_sync_results_.temperature_K;
-}
-
-void Awb::Resume()
-{
- manual_r_ = 0.0;
- manual_b_ = 0.0;
-}
-
-unsigned int Awb::GetConvergenceFrames() const
-{
- // If not in auto mode, there is no convergence
- // to happen, so no need to drop any frames - return zero.
- if (!isAutoEnabled())
- return 0;
- else
- return config_.convergence_frames;
-}
-
-void Awb::SetMode(std::string const &mode_name)
-{
- mode_name_ = mode_name;
-}
-
-void Awb::SetManualGains(double manual_r, double manual_b)
-{
- // If any of these are 0.0, we swich back to auto.
- manual_r_ = manual_r;
- manual_b_ = manual_b;
- // If not in auto mode, set these values into the sync_results which
- // means that Prepare() will adopt them immediately.
- if (!isAutoEnabled()) {
- sync_results_.gain_r = prev_sync_results_.gain_r = manual_r_;
- sync_results_.gain_g = prev_sync_results_.gain_g = 1.0;
- sync_results_.gain_b = prev_sync_results_.gain_b = manual_b_;
- }
-}
-
-void Awb::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,
- Metadata *metadata)
-{
- // On the first mode switch we'll have no meaningful colour
- // temperature, so try to dead reckon one if in manual mode.
- if (!isAutoEnabled() && first_switch_mode_ && config_.bayes) {
- Pwl ct_r_inverse = config_.ct_r.Inverse();
- Pwl ct_b_inverse = config_.ct_b.Inverse();
- double ct_r = ct_r_inverse.Eval(ct_r_inverse.Domain().Clip(1 / manual_r_));
- double ct_b = ct_b_inverse.Eval(ct_b_inverse.Domain().Clip(1 / manual_b_));
- prev_sync_results_.temperature_K = (ct_r + ct_b) / 2;
- sync_results_.temperature_K = prev_sync_results_.temperature_K;
- }
- // Let other algorithms know the current white balance values.
- metadata->Set("awb.status", prev_sync_results_);
- first_switch_mode_ = false;
-}
-
-bool Awb::isAutoEnabled() const
-{
- return manual_r_ == 0.0 || manual_b_ == 0.0;
-}
-
-void Awb::fetchAsyncResults()
-{
- LOG(RPiAwb, Debug) << "Fetch AWB results";
- async_finished_ = false;
- async_started_ = false;
- // It's possible manual gains could be set even while the async
- // thread was running, so only copy the results if still in auto mode.
- if (isAutoEnabled())
- sync_results_ = async_results_;
-}
-
-void Awb::restartAsync(StatisticsPtr &stats, double lux)
-{
- LOG(RPiAwb, Debug) << "Starting AWB calculation";
- // this makes a new reference which belongs to the asynchronous thread
- statistics_ = stats;
- // store the mode as it could technically change
- auto m = config_.modes.find(mode_name_);
- mode_ = m != config_.modes.end()
- ? &m->second
- : (mode_ == nullptr ? config_.default_mode : mode_);
- lux_ = lux;
- frame_phase_ = 0;
- async_started_ = true;
- size_t len = mode_name_.copy(async_results_.mode,
- sizeof(async_results_.mode) - 1);
- async_results_.mode[len] = '\0';
- {
- std::lock_guard<std::mutex> lock(mutex_);
- async_start_ = true;
- }
- async_signal_.notify_one();
-}
-
-void Awb::Prepare(Metadata *image_metadata)
-{
- if (frame_count_ < (int)config_.startup_frames)
- frame_count_++;
- double speed = frame_count_ < (int)config_.startup_frames
- ? 1.0
- : config_.speed;
- LOG(RPiAwb, Debug)
- << "frame_count " << frame_count_ << " speed " << speed;
- {
- std::unique_lock<std::mutex> lock(mutex_);
- if (async_started_ && async_finished_)
- fetchAsyncResults();
- }
- // Finally apply IIR filter to results and put into metadata.
- memcpy(prev_sync_results_.mode, sync_results_.mode,
- sizeof(prev_sync_results_.mode));
- prev_sync_results_.temperature_K =
- speed * sync_results_.temperature_K +
- (1.0 - speed) * prev_sync_results_.temperature_K;
- prev_sync_results_.gain_r = speed * sync_results_.gain_r +
- (1.0 - speed) * prev_sync_results_.gain_r;
- prev_sync_results_.gain_g = speed * sync_results_.gain_g +
- (1.0 - speed) * prev_sync_results_.gain_g;
- prev_sync_results_.gain_b = speed * sync_results_.gain_b +
- (1.0 - speed) * prev_sync_results_.gain_b;
- image_metadata->Set("awb.status", prev_sync_results_);
- LOG(RPiAwb, Debug)
- << "Using AWB gains r " << prev_sync_results_.gain_r << " g "
- << prev_sync_results_.gain_g << " b "
- << prev_sync_results_.gain_b;
-}
-
-void Awb::Process(StatisticsPtr &stats, Metadata *image_metadata)
-{
- // Count frames since we last poked the async thread.
- if (frame_phase_ < (int)config_.frame_period)
- frame_phase_++;
- LOG(RPiAwb, Debug) << "frame_phase " << frame_phase_;
- // We do not restart the async thread if we're not in auto mode.
- if (isAutoEnabled() &&
- (frame_phase_ >= (int)config_.frame_period ||
- frame_count_ < (int)config_.startup_frames)) {
- // Update any settings and any image metadata that we need.
- struct LuxStatus lux_status = {};
- lux_status.lux = 400; // in case no metadata
- if (image_metadata->Get("lux.status", lux_status) != 0)
- LOG(RPiAwb, Debug) << "No lux metadata found";
- LOG(RPiAwb, Debug) << "Awb lux value is " << lux_status.lux;
-
- if (async_started_ == false)
- restartAsync(stats, lux_status.lux);
- }
-}
-
-void Awb::asyncFunc()
-{
- while (true) {
- {
- std::unique_lock<std::mutex> lock(mutex_);
- async_signal_.wait(lock, [&] {
- return async_start_ || async_abort_;
- });
- async_start_ = false;
- if (async_abort_)
- break;
- }
- doAwb();
- {
- std::lock_guard<std::mutex> lock(mutex_);
- async_finished_ = true;
- }
- sync_signal_.notify_one();
- }
-}
-
-static void generate_stats(std::vector<Awb::RGB> &zones,
- bcm2835_isp_stats_region *stats, double min_pixels,
- double min_G)
-{
- for (int i = 0; i < AWB_STATS_SIZE_X * AWB_STATS_SIZE_Y; i++) {
- Awb::RGB zone;
- double counted = stats[i].counted;
- if (counted >= min_pixels) {
- zone.G = stats[i].g_sum / counted;
- if (zone.G >= min_G) {
- zone.R = stats[i].r_sum / counted;
- zone.B = stats[i].b_sum / counted;
- zones.push_back(zone);
- }
- }
- }
-}
-
-void Awb::prepareStats()
-{
- zones_.clear();
- // LSC has already been applied to the stats in this pipeline, so stop
- // any LSC compensation. We also ignore config_.fast in this version.
- generate_stats(zones_, statistics_->awb_stats, config_.min_pixels,
- config_.min_G);
- // we're done with these; we may as well relinquish our hold on the
- // pointer.
- statistics_.reset();
- // apply sensitivities, so values appear to come from our "canonical"
- // sensor.
- for (auto &zone : zones_)
- zone.R *= config_.sensitivity_r,
- zone.B *= config_.sensitivity_b;
-}
-
-double Awb::computeDelta2Sum(double gain_r, double gain_b)
-{
- // Compute the sum of the squared colour error (non-greyness) as it
- // appears in the log likelihood equation.
- double delta2_sum = 0;
- for (auto &z : zones_) {
- double delta_r = gain_r * z.R - 1 - config_.whitepoint_r;
- double delta_b = gain_b * z.B - 1 - config_.whitepoint_b;
- double delta2 = delta_r * delta_r + delta_b * delta_b;
- //LOG(RPiAwb, Debug) << "delta_r " << delta_r << " delta_b " << delta_b << " delta2 " << delta2;
- delta2 = std::min(delta2, config_.delta_limit);
- delta2_sum += delta2;
- }
- return delta2_sum;
-}
-
-Pwl Awb::interpolatePrior()
-{
- // Interpolate the prior log likelihood function for our current lux
- // value.
- if (lux_ <= config_.priors.front().lux)
- return config_.priors.front().prior;
- else if (lux_ >= config_.priors.back().lux)
- return config_.priors.back().prior;
- else {
- int idx = 0;
- // find which two we lie between
- while (config_.priors[idx + 1].lux < lux_)
- idx++;
- double lux0 = config_.priors[idx].lux,
- lux1 = config_.priors[idx + 1].lux;
- return Pwl::Combine(config_.priors[idx].prior,
- config_.priors[idx + 1].prior,
- [&](double /*x*/, double y0, double y1) {
- return y0 + (y1 - y0) *
- (lux_ - lux0) / (lux1 - lux0);
- });
- }
-}
-
-static double interpolate_quadatric(Pwl::Point const &A, Pwl::Point const &B,
- Pwl::Point const &C)
-{
- // Given 3 points on a curve, find the extremum of the function in that
- // interval by fitting a quadratic.
- const double eps = 1e-3;
- Pwl::Point CA = C - A, BA = B - A;
- double denominator = 2 * (BA.y * CA.x - CA.y * BA.x);
- if (abs(denominator) > eps) {
- double numerator = BA.y * CA.x * CA.x - CA.y * BA.x * BA.x;
- double result = numerator / denominator + A.x;
- return std::max(A.x, std::min(C.x, result));
- }
- // has degenerated to straight line segment
- return A.y < C.y - eps ? A.x : (C.y < A.y - eps ? C.x : B.x);
-}
-
-double Awb::coarseSearch(Pwl const &prior)
-{
- points_.clear(); // assume doesn't deallocate memory
- size_t best_point = 0;
- double t = mode_->ct_lo;
- int span_r = 0, span_b = 0;
- // Step down the CT curve evaluating log likelihood.
- while (true) {
- double r = config_.ct_r.Eval(t, &span_r);
- double b = config_.ct_b.Eval(t, &span_b);
- double gain_r = 1 / r, gain_b = 1 / b;
- double delta2_sum = computeDelta2Sum(gain_r, gain_b);
- double prior_log_likelihood =
- prior.Eval(prior.Domain().Clip(t));
- double final_log_likelihood = delta2_sum - prior_log_likelihood;
- LOG(RPiAwb, Debug)
- << "t: " << t << " gain_r " << gain_r << " gain_b "
- << gain_b << " delta2_sum " << delta2_sum
- << " prior " << prior_log_likelihood << " final "
- << final_log_likelihood;
- points_.push_back(Pwl::Point(t, final_log_likelihood));
- if (points_.back().y < points_[best_point].y)
- best_point = points_.size() - 1;
- if (t == mode_->ct_hi)
- break;
- // for even steps along the r/b curve scale them by the current t
- t = std::min(t + t / 10 * config_.coarse_step,
- mode_->ct_hi);
- }
- t = points_[best_point].x;
- LOG(RPiAwb, Debug) << "Coarse search found CT " << t;
- // We have the best point of the search, but refine it with a quadratic
- // interpolation around its neighbours.
- if (points_.size() > 2) {
- unsigned long bp = std::min(best_point, points_.size() - 2);
- best_point = std::max(1UL, bp);
- t = interpolate_quadatric(points_[best_point - 1],
- points_[best_point],
- points_[best_point + 1]);
- LOG(RPiAwb, Debug)
- << "After quadratic refinement, coarse search has CT "
- << t;
- }
- return t;
-}
-
-void Awb::fineSearch(double &t, double &r, double &b, Pwl const &prior)
-{
- int span_r = -1, span_b = -1;
- config_.ct_r.Eval(t, &span_r);
- config_.ct_b.Eval(t, &span_b);
- double step = t / 10 * config_.coarse_step * 0.1;
- int nsteps = 5;
- double r_diff = config_.ct_r.Eval(t + nsteps * step, &span_r) -
- config_.ct_r.Eval(t - nsteps * step, &span_r);
- double b_diff = config_.ct_b.Eval(t + nsteps * step, &span_b) -
- config_.ct_b.Eval(t - nsteps * step, &span_b);
- Pwl::Point transverse(b_diff, -r_diff);
- if (transverse.Len2() < 1e-6)
- return;
- // unit vector orthogonal to the b vs. r function (pointing outwards
- // with r and b increasing)
- transverse = transverse / transverse.Len();
- double best_log_likelihood = 0, best_t = 0, best_r = 0, best_b = 0;
- double transverse_range =
- config_.transverse_neg + config_.transverse_pos;
- const int MAX_NUM_DELTAS = 12;
- // a transverse step approximately every 0.01 r/b units
- int num_deltas = floor(transverse_range * 100 + 0.5) + 1;
- num_deltas = num_deltas < 3 ? 3 :
- (num_deltas > MAX_NUM_DELTAS ? MAX_NUM_DELTAS : num_deltas);
- // Step down CT curve. March a bit further if the transverse range is
- // large.
- nsteps += num_deltas;
- for (int i = -nsteps; i <= nsteps; i++) {
- double t_test = t + i * step;
- double prior_log_likelihood =
- prior.Eval(prior.Domain().Clip(t_test));
- double r_curve = config_.ct_r.Eval(t_test, &span_r);
- double b_curve = config_.ct_b.Eval(t_test, &span_b);
- // x will be distance off the curve, y the log likelihood there
- Pwl::Point points[MAX_NUM_DELTAS];
- int best_point = 0;
- // Take some measurements transversely *off* the CT curve.
- for (int j = 0; j < num_deltas; j++) {
- points[j].x = -config_.transverse_neg +
- (transverse_range * j) / (num_deltas - 1);
- Pwl::Point rb_test = Pwl::Point(r_curve, b_curve) +
- transverse * points[j].x;
- double r_test = rb_test.x, b_test = rb_test.y;
- double gain_r = 1 / r_test, gain_b = 1 / b_test;
- double delta2_sum = computeDelta2Sum(gain_r, gain_b);
- points[j].y = delta2_sum - prior_log_likelihood;
- LOG(RPiAwb, Debug)
- << "At t " << t_test << " r " << r_test << " b "
- << b_test << ": " << points[j].y;
- if (points[j].y < points[best_point].y)
- best_point = j;
- }
- // We have NUM_DELTAS points transversely across the CT curve,
- // now let's do a quadratic interpolation for the best result.
- best_point = std::max(1, std::min(best_point, num_deltas - 2));
- Pwl::Point rb_test =
- Pwl::Point(r_curve, b_curve) +
- transverse *
- interpolate_quadatric(points[best_point - 1],
- points[best_point],
- points[best_point + 1]);
- double r_test = rb_test.x, b_test = rb_test.y;
- double gain_r = 1 / r_test, gain_b = 1 / b_test;
- double delta2_sum = computeDelta2Sum(gain_r, gain_b);
- double final_log_likelihood = delta2_sum - prior_log_likelihood;
- LOG(RPiAwb, Debug)
- << "Finally "
- << t_test << " r " << r_test << " b " << b_test << ": "
- << final_log_likelihood
- << (final_log_likelihood < best_log_likelihood ? " BEST" : "");
- if (best_t == 0 || final_log_likelihood < best_log_likelihood)
- best_log_likelihood = final_log_likelihood,
- best_t = t_test, best_r = r_test, best_b = b_test;
- }
- t = best_t, r = best_r, b = best_b;
- LOG(RPiAwb, Debug)
- << "Fine search found t " << t << " r " << r << " b " << b;
-}
-
-void Awb::awbBayes()
-{
- // May as well divide out G to save computeDelta2Sum from doing it over
- // and over.
- for (auto &z : zones_)
- z.R = z.R / (z.G + 1), z.B = z.B / (z.G + 1);
- // Get the current prior, and scale according to how many zones are
- // valid... not entirely sure about this.
- Pwl prior = interpolatePrior();
- prior *= zones_.size() / (double)(AWB_STATS_SIZE_X * AWB_STATS_SIZE_Y);
- prior.Map([](double x, double y) {
- LOG(RPiAwb, Debug) << "(" << x << "," << y << ")";
- });
- double t = coarseSearch(prior);
- double r = config_.ct_r.Eval(t);
- double b = config_.ct_b.Eval(t);
- LOG(RPiAwb, Debug)
- << "After coarse search: r " << r << " b " << b << " (gains r "
- << 1 / r << " b " << 1 / b << ")";
- // Not entirely sure how to handle the fine search yet. Mostly the
- // estimated CT is already good enough, but the fine search allows us to
- // wander transverely off the CT curve. Under some illuminants, where
- // there may be more or less green light, this may prove beneficial,
- // though I probably need more real datasets before deciding exactly how
- // this should be controlled and tuned.
- fineSearch(t, r, b, prior);
- LOG(RPiAwb, Debug)
- << "After fine search: r " << r << " b " << b << " (gains r "
- << 1 / r << " b " << 1 / b << ")";
- // Write results out for the main thread to pick up. Remember to adjust
- // the gains from the ones that the "canonical sensor" would require to
- // the ones needed by *this* sensor.
- async_results_.temperature_K = t;
- async_results_.gain_r = 1.0 / r * config_.sensitivity_r;
- async_results_.gain_g = 1.0;
- async_results_.gain_b = 1.0 / b * config_.sensitivity_b;
-}
-
-void Awb::awbGrey()
-{
- LOG(RPiAwb, Debug) << "Grey world AWB";
- // Make a separate list of the derivatives for each of red and blue, so
- // that we can sort them to exclude the extreme gains. We could
- // consider some variations, such as normalising all the zones first, or
- // doing an L2 average etc.
- std::vector<RGB> &derivs_R(zones_);
- std::vector<RGB> derivs_B(derivs_R);
- std::sort(derivs_R.begin(), derivs_R.end(),
- [](RGB const &a, RGB const &b) {
- return a.G * b.R < b.G * a.R;
- });
- std::sort(derivs_B.begin(), derivs_B.end(),
- [](RGB const &a, RGB const &b) {
- return a.G * b.B < b.G * a.B;
- });
- // Average the middle half of the values.
- int discard = derivs_R.size() / 4;
- RGB sum_R(0, 0, 0), sum_B(0, 0, 0);
- for (auto ri = derivs_R.begin() + discard,
- bi = derivs_B.begin() + discard;
- ri != derivs_R.end() - discard; ri++, bi++)
- sum_R += *ri, sum_B += *bi;
- double gain_r = sum_R.G / (sum_R.R + 1),
- gain_b = sum_B.G / (sum_B.B + 1);
- async_results_.temperature_K = 4500; // don't know what it is
- async_results_.gain_r = gain_r;
- async_results_.gain_g = 1.0;
- async_results_.gain_b = gain_b;
-}
-
-void Awb::doAwb()
-{
- prepareStats();
- LOG(RPiAwb, Debug) << "Valid zones: " << zones_.size();
- if (zones_.size() > config_.min_regions) {
- if (config_.bayes)
- awbBayes();
- else
- awbGrey();
- LOG(RPiAwb, Debug)
- << "CT found is "
- << async_results_.temperature_K
- << " with gains r " << async_results_.gain_r
- << " and b " << async_results_.gain_b;
- }
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Awb(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp b/src/ipa/raspberrypi/controller/rpi/awb.hpp
deleted file mode 100644
index ac3dca6f..00000000
--- a/src/ipa/raspberrypi/controller/rpi/awb.hpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * awb.hpp - AWB control algorithm
- */
-#pragma once
-
-#include <mutex>
-#include <condition_variable>
-#include <thread>
-
-#include "../awb_algorithm.hpp"
-#include "../pwl.hpp"
-#include "../awb_status.h"
-
-namespace RPiController {
-
-// Control algorithm to perform AWB calculations.
-
-struct AwbMode {
- void Read(boost::property_tree::ptree const &params);
- double ct_lo; // low CT value for search
- double ct_hi; // high CT value for search
-};
-
-struct AwbPrior {
- void Read(boost::property_tree::ptree const &params);
- double lux; // lux level
- Pwl prior; // maps CT to prior log likelihood for this lux level
-};
-
-struct AwbConfig {
- AwbConfig() : default_mode(nullptr) {}
- void Read(boost::property_tree::ptree const &params);
- // Only repeat the AWB calculation every "this many" frames
- uint16_t frame_period;
- // number of initial frames for which speed taken as 1.0 (maximum)
- uint16_t startup_frames;
- unsigned int convergence_frames; // approx number of frames to converge
- double speed; // IIR filter speed applied to algorithm results
- bool fast; // "fast" mode uses a 16x16 rather than 32x32 grid
- Pwl ct_r; // function maps CT to r (= R/G)
- Pwl ct_b; // function maps CT to b (= B/G)
- // table of illuminant priors at different lux levels
- std::vector<AwbPrior> priors;
- // AWB "modes" (determines the search range)
- std::map<std::string, AwbMode> modes;
- AwbMode *default_mode; // mode used if no mode selected
- // minimum proportion of pixels counted within AWB region for it to be
- // "useful"
- double min_pixels;
- // minimum G value of those pixels, to be regarded a "useful"
- uint16_t min_G;
- // number of AWB regions that must be "useful" in order to do the AWB
- // calculation
- uint32_t min_regions;
- // clamp on colour error term (so as not to penalise non-grey excessively)
- double delta_limit;
- // step size control in coarse search
- double coarse_step;
- // how far to wander off CT curve towards "more purple"
- double transverse_pos;
- // how far to wander off CT curve towards "more green"
- double transverse_neg;
- // red sensitivity ratio (set to canonical sensor's R/G divided by this
- // sensor's R/G)
- double sensitivity_r;
- // blue sensitivity ratio (set to canonical sensor's B/G divided by this
- // sensor's B/G)
- double sensitivity_b;
- // The whitepoint (which we normally "aim" for) can be moved.
- double whitepoint_r;
- double whitepoint_b;
- bool bayes; // use Bayesian algorithm
-};
-
-class Awb : public AwbAlgorithm
-{
-public:
- Awb(Controller *controller = NULL);
- ~Awb();
- char const *Name() const override;
- void Initialise() override;
- void Read(boost::property_tree::ptree const &params) override;
- // AWB handles "pausing" for itself.
- bool IsPaused() const override;
- void Pause() override;
- void Resume() override;
- unsigned int GetConvergenceFrames() const override;
- void SetMode(std::string const &name) override;
- void SetManualGains(double manual_r, double manual_b) override;
- void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Prepare(Metadata *image_metadata) override;
- void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
- struct RGB {
- RGB(double _R = 0, double _G = 0, double _B = 0)
- : R(_R), G(_G), B(_B)
- {
- }
- double R, G, B;
- RGB &operator+=(RGB const &other)
- {
- R += other.R, G += other.G, B += other.B;
- return *this;
- }
- };
-
-private:
- bool isAutoEnabled() const;
- // configuration is read-only, and available to both threads
- AwbConfig config_;
- std::thread async_thread_;
- void asyncFunc(); // asynchronous thread function
- std::mutex mutex_;
- // condvar for async thread to wait on
- std::condition_variable async_signal_;
- // condvar for synchronous thread to wait on
- std::condition_variable sync_signal_;
- // for sync thread to check if async thread finished (requires mutex)
- bool async_finished_;
- // for async thread to check if it's been told to run (requires mutex)
- bool async_start_;
- // for async thread to check if it's been told to quit (requires mutex)
- bool async_abort_;
-
- // The following are only for the synchronous thread to use:
- // for sync thread to note its has asked async thread to run
- bool async_started_;
- // counts up to frame_period before restarting the async thread
- int frame_phase_;
- int frame_count_; // counts up to startup_frames
- AwbStatus sync_results_;
- AwbStatus prev_sync_results_;
- std::string mode_name_;
- // The following are for the asynchronous thread to use, though the main
- // thread can set/reset them if the async thread is known to be idle:
- void restartAsync(StatisticsPtr &stats, double lux);
- // copy out the results from the async thread so that it can be restarted
- void fetchAsyncResults();
- StatisticsPtr statistics_;
- AwbMode *mode_;
- double lux_;
- AwbStatus async_results_;
- void doAwb();
- void awbBayes();
- void awbGrey();
- void prepareStats();
- double computeDelta2Sum(double gain_r, double gain_b);
- Pwl interpolatePrior();
- double coarseSearch(Pwl const &prior);
- void fineSearch(double &t, double &r, double &b, Pwl const &prior);
- std::vector<RGB> zones_;
- std::vector<Pwl::Point> points_;
- // manual r setting
- double manual_r_;
- // manual b setting
- double manual_b_;
- bool first_switch_mode_; // is this the first call to SwitchMode?
-};
-
-static inline Awb::RGB operator+(Awb::RGB const &a, Awb::RGB const &b)
-{
- return Awb::RGB(a.R + b.R, a.G + b.G, a.B + b.B);
-}
-static inline Awb::RGB operator-(Awb::RGB const &a, Awb::RGB const &b)
-{
- return Awb::RGB(a.R - b.R, a.G - b.G, a.B - b.B);
-}
-static inline Awb::RGB operator*(double d, Awb::RGB const &rgb)
-{
- return Awb::RGB(d * rgb.R, d * rgb.G, d * rgb.B);
-}
-static inline Awb::RGB operator*(Awb::RGB const &rgb, double d)
-{
- return d * rgb;
-}
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/black_level.cpp b/src/ipa/raspberrypi/controller/rpi/black_level.cpp
deleted file mode 100644
index 6b3497f1..00000000
--- a/src/ipa/raspberrypi/controller/rpi/black_level.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * black_level.cpp - black level control algorithm
- */
-
-#include <math.h>
-#include <stdint.h>
-
-#include <libcamera/base/log.h>
-
-#include "../black_level_status.h"
-
-#include "black_level.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiBlackLevel)
-
-#define NAME "rpi.black_level"
-
-BlackLevel::BlackLevel(Controller *controller)
- : Algorithm(controller)
-{
-}
-
-char const *BlackLevel::Name() const
-{
- return NAME;
-}
-
-void BlackLevel::Read(boost::property_tree::ptree const &params)
-{
- uint16_t black_level = params.get<uint16_t>(
- "black_level", 4096); // 64 in 10 bits scaled to 16 bits
- black_level_r_ = params.get<uint16_t>("black_level_r", black_level);
- black_level_g_ = params.get<uint16_t>("black_level_g", black_level);
- black_level_b_ = params.get<uint16_t>("black_level_b", black_level);
- LOG(RPiBlackLevel, Debug)
- << " Read black levels red " << black_level_r_
- << " green " << black_level_g_
- << " blue " << black_level_b_;
-}
-
-void BlackLevel::Prepare(Metadata *image_metadata)
-{
- // Possibly we should think about doing this in a switch_mode or
- // something?
- struct BlackLevelStatus status;
- status.black_level_r = black_level_r_;
- status.black_level_g = black_level_g_;
- status.black_level_b = black_level_b_;
- image_metadata->Set("black_level.status", status);
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return new BlackLevel(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/black_level.hpp b/src/ipa/raspberrypi/controller/rpi/black_level.hpp
deleted file mode 100644
index 65ec4d0e..00000000
--- a/src/ipa/raspberrypi/controller/rpi/black_level.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * black_level.hpp - black level control algorithm
- */
-#pragma once
-
-#include "../algorithm.hpp"
-#include "../black_level_status.h"
-
-// This is our implementation of the "black level algorithm".
-
-namespace RPiController {
-
-class BlackLevel : public Algorithm
-{
-public:
- BlackLevel(Controller *controller);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- void Prepare(Metadata *image_metadata) override;
-
-private:
- double black_level_r_;
- double black_level_g_;
- double black_level_b_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/ccm.cpp b/src/ipa/raspberrypi/controller/rpi/ccm.cpp
deleted file mode 100644
index 821a4c7c..00000000
--- a/src/ipa/raspberrypi/controller/rpi/ccm.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * ccm.cpp - CCM (colour correction matrix) control algorithm
- */
-
-#include <libcamera/base/log.h>
-
-#include "../awb_status.h"
-#include "../ccm_status.h"
-#include "../lux_status.h"
-#include "../metadata.hpp"
-
-#include "ccm.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiCcm)
-
-// This algorithm selects a CCM (Colour Correction Matrix) according to the
-// colour temperature estimated by AWB (interpolating between known matricies as
-// necessary). Additionally the amount of colour saturation can be controlled
-// both according to the current estimated lux level and according to a
-// saturation setting that is exposed to applications.
-
-#define NAME "rpi.ccm"
-
-Matrix::Matrix()
-{
- memset(m, 0, sizeof(m));
-}
-Matrix::Matrix(double m0, double m1, double m2, double m3, double m4, double m5,
- double m6, double m7, double m8)
-{
- m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] = m4,
- m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8;
-}
-void Matrix::Read(boost::property_tree::ptree const &params)
-{
- double *ptr = (double *)m;
- int n = 0;
- for (auto it = params.begin(); it != params.end(); it++) {
- if (n++ == 9)
- throw std::runtime_error("Ccm: too many values in CCM");
- *ptr++ = it->second.get_value<double>();
- }
- if (n < 9)
- throw std::runtime_error("Ccm: too few values in CCM");
-}
-
-Ccm::Ccm(Controller *controller)
- : CcmAlgorithm(controller), saturation_(1.0) {}
-
-char const *Ccm::Name() const
-{
- return NAME;
-}
-
-void Ccm::Read(boost::property_tree::ptree const &params)
-{
- if (params.get_child_optional("saturation"))
- config_.saturation.Read(params.get_child("saturation"));
- for (auto &p : params.get_child("ccms")) {
- CtCcm ct_ccm;
- ct_ccm.ct = p.second.get<double>("ct");
- ct_ccm.ccm.Read(p.second.get_child("ccm"));
- if (!config_.ccms.empty() &&
- ct_ccm.ct <= config_.ccms.back().ct)
- throw std::runtime_error(
- "Ccm: CCM not in increasing colour temperature order");
- config_.ccms.push_back(std::move(ct_ccm));
- }
- if (config_.ccms.empty())
- throw std::runtime_error("Ccm: no CCMs specified");
-}
-
-void Ccm::SetSaturation(double saturation)
-{
- saturation_ = saturation;
-}
-
-void Ccm::Initialise() {}
-
-template<typename T>
-static bool get_locked(Metadata *metadata, std::string const &tag, T &value)
-{
- T *ptr = metadata->GetLocked<T>(tag);
- if (ptr == nullptr)
- return false;
- value = *ptr;
- return true;
-}
-
-Matrix calculate_ccm(std::vector<CtCcm> const &ccms, double ct)
-{
- if (ct <= ccms.front().ct)
- return ccms.front().ccm;
- else if (ct >= ccms.back().ct)
- return ccms.back().ccm;
- else {
- int i = 0;
- for (; ct > ccms[i].ct; i++)
- ;
- double lambda =
- (ct - ccms[i - 1].ct) / (ccms[i].ct - ccms[i - 1].ct);
- return lambda * ccms[i].ccm + (1.0 - lambda) * ccms[i - 1].ccm;
- }
-}
-
-Matrix apply_saturation(Matrix const &ccm, double saturation)
-{
- Matrix RGB2Y(0.299, 0.587, 0.114, -0.169, -0.331, 0.500, 0.500, -0.419,
- -0.081);
- Matrix Y2RGB(1.000, 0.000, 1.402, 1.000, -0.345, -0.714, 1.000, 1.771,
- 0.000);
- Matrix S(1, 0, 0, 0, saturation, 0, 0, 0, saturation);
- return Y2RGB * S * RGB2Y * ccm;
-}
-
-void Ccm::Prepare(Metadata *image_metadata)
-{
- bool awb_ok = false, lux_ok = false;
- struct AwbStatus awb = {};
- awb.temperature_K = 4000; // in case no metadata
- struct LuxStatus lux = {};
- lux.lux = 400; // in case no metadata
- {
- // grab mutex just once to get everything
- std::lock_guard<Metadata> lock(*image_metadata);
- awb_ok = get_locked(image_metadata, "awb.status", awb);
- lux_ok = get_locked(image_metadata, "lux.status", lux);
- }
- if (!awb_ok)
- LOG(RPiCcm, Warning) << "no colour temperature found";
- if (!lux_ok)
- LOG(RPiCcm, Warning) << "no lux value found";
- Matrix ccm = calculate_ccm(config_.ccms, awb.temperature_K);
- double saturation = saturation_;
- struct CcmStatus ccm_status;
- ccm_status.saturation = saturation;
- if (!config_.saturation.Empty())
- saturation *= config_.saturation.Eval(
- config_.saturation.Domain().Clip(lux.lux));
- ccm = apply_saturation(ccm, saturation);
- for (int j = 0; j < 3; j++)
- for (int i = 0; i < 3; i++)
- ccm_status.matrix[j * 3 + i] =
- std::max(-8.0, std::min(7.9999, ccm.m[j][i]));
- LOG(RPiCcm, Debug)
- << "colour temperature " << awb.temperature_K << "K";
- LOG(RPiCcm, Debug)
- << "CCM: " << ccm_status.matrix[0] << " " << ccm_status.matrix[1]
- << " " << ccm_status.matrix[2] << " "
- << ccm_status.matrix[3] << " " << ccm_status.matrix[4]
- << " " << ccm_status.matrix[5] << " "
- << ccm_status.matrix[6] << " " << ccm_status.matrix[7]
- << " " << ccm_status.matrix[8];
- image_metadata->Set("ccm.status", ccm_status);
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Ccm(controller);
- ;
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/ccm.hpp b/src/ipa/raspberrypi/controller/rpi/ccm.hpp
deleted file mode 100644
index 330ed51f..00000000
--- a/src/ipa/raspberrypi/controller/rpi/ccm.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * ccm.hpp - CCM (colour correction matrix) control algorithm
- */
-#pragma once
-
-#include <vector>
-
-#include "../ccm_algorithm.hpp"
-#include "../pwl.hpp"
-
-namespace RPiController {
-
-// Algorithm to calculate colour matrix. Should be placed after AWB.
-
-struct Matrix {
- Matrix(double m0, double m1, double m2, double m3, double m4, double m5,
- double m6, double m7, double m8);
- Matrix();
- double m[3][3];
- void Read(boost::property_tree::ptree const &params);
-};
-static inline Matrix operator*(double d, Matrix const &m)
-{
- return Matrix(m.m[0][0] * d, m.m[0][1] * d, m.m[0][2] * d,
- m.m[1][0] * d, m.m[1][1] * d, m.m[1][2] * d,
- m.m[2][0] * d, m.m[2][1] * d, m.m[2][2] * d);
-}
-static inline Matrix operator*(Matrix const &m1, Matrix const &m2)
-{
- Matrix m;
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- m.m[i][j] = m1.m[i][0] * m2.m[0][j] +
- m1.m[i][1] * m2.m[1][j] +
- m1.m[i][2] * m2.m[2][j];
- return m;
-}
-static inline Matrix operator+(Matrix const &m1, Matrix const &m2)
-{
- Matrix m;
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- m.m[i][j] = m1.m[i][j] + m2.m[i][j];
- return m;
-}
-
-struct CtCcm {
- double ct;
- Matrix ccm;
-};
-
-struct CcmConfig {
- std::vector<CtCcm> ccms;
- Pwl saturation;
-};
-
-class Ccm : public CcmAlgorithm
-{
-public:
- Ccm(Controller *controller = NULL);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- void SetSaturation(double saturation) override;
- void Initialise() override;
- void Prepare(Metadata *image_metadata) override;
-
-private:
- CcmConfig config_;
- double saturation_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/contrast.cpp b/src/ipa/raspberrypi/controller/rpi/contrast.cpp
deleted file mode 100644
index ae55aad5..00000000
--- a/src/ipa/raspberrypi/controller/rpi/contrast.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * contrast.cpp - contrast (gamma) control algorithm
- */
-#include <stdint.h>
-
-#include <libcamera/base/log.h>
-
-#include "../contrast_status.h"
-#include "../histogram.hpp"
-
-#include "contrast.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiContrast)
-
-// This is a very simple control algorithm which simply retrieves the results of
-// AGC and AWB via their "status" metadata, and applies digital gain to the
-// colour channels in accordance with those instructions. We take care never to
-// apply less than unity gains, as that would cause fully saturated pixels to go
-// off-white.
-
-#define NAME "rpi.contrast"
-
-Contrast::Contrast(Controller *controller)
- : ContrastAlgorithm(controller), brightness_(0.0), contrast_(1.0)
-{
-}
-
-char const *Contrast::Name() const
-{
- return NAME;
-}
-
-void Contrast::Read(boost::property_tree::ptree const &params)
-{
- // enable adaptive enhancement by default
- config_.ce_enable = params.get<int>("ce_enable", 1);
- // the point near the bottom of the histogram to move
- config_.lo_histogram = params.get<double>("lo_histogram", 0.01);
- // where in the range to try and move it to
- config_.lo_level = params.get<double>("lo_level", 0.015);
- // but don't move by more than this
- config_.lo_max = params.get<double>("lo_max", 500);
- // equivalent values for the top of the histogram...
- config_.hi_histogram = params.get<double>("hi_histogram", 0.95);
- config_.hi_level = params.get<double>("hi_level", 0.95);
- config_.hi_max = params.get<double>("hi_max", 2000);
- config_.gamma_curve.Read(params.get_child("gamma_curve"));
-}
-
-void Contrast::SetBrightness(double brightness)
-{
- brightness_ = brightness;
-}
-
-void Contrast::SetContrast(double contrast)
-{
- contrast_ = contrast;
-}
-
-static void fill_in_status(ContrastStatus &status, double brightness,
- double contrast, Pwl &gamma_curve)
-{
- status.brightness = brightness;
- status.contrast = contrast;
- for (int i = 0; i < CONTRAST_NUM_POINTS - 1; i++) {
- int x = i < 16 ? i * 1024
- : (i < 24 ? (i - 16) * 2048 + 16384
- : (i - 24) * 4096 + 32768);
- status.points[i].x = x;
- status.points[i].y = std::min(65535.0, gamma_curve.Eval(x));
- }
- status.points[CONTRAST_NUM_POINTS - 1].x = 65535;
- status.points[CONTRAST_NUM_POINTS - 1].y = 65535;
-}
-
-void Contrast::Initialise()
-{
- // Fill in some default values as Prepare will run before Process gets
- // called.
- fill_in_status(status_, brightness_, contrast_, config_.gamma_curve);
-}
-
-void Contrast::Prepare(Metadata *image_metadata)
-{
- std::unique_lock<std::mutex> lock(mutex_);
- image_metadata->Set("contrast.status", status_);
-}
-
-Pwl compute_stretch_curve(Histogram const &histogram,
- ContrastConfig const &config)
-{
- Pwl enhance;
- enhance.Append(0, 0);
- // If the start of the histogram is rather empty, try to pull it down a
- // bit.
- double hist_lo = histogram.Quantile(config.lo_histogram) *
- (65536 / NUM_HISTOGRAM_BINS);
- double level_lo = config.lo_level * 65536;
- LOG(RPiContrast, Debug)
- << "Move histogram point " << hist_lo << " to " << level_lo;
- hist_lo = std::max(
- level_lo,
- std::min(65535.0, std::min(hist_lo, level_lo + config.lo_max)));
- LOG(RPiContrast, Debug)
- << "Final values " << hist_lo << " -> " << level_lo;
- enhance.Append(hist_lo, level_lo);
- // Keep the mid-point (median) in the same place, though, to limit the
- // apparent amount of global brightness shift.
- double mid = histogram.Quantile(0.5) * (65536 / NUM_HISTOGRAM_BINS);
- enhance.Append(mid, mid);
-
- // If the top to the histogram is empty, try to pull the pixel values
- // there up.
- double hist_hi = histogram.Quantile(config.hi_histogram) *
- (65536 / NUM_HISTOGRAM_BINS);
- double level_hi = config.hi_level * 65536;
- LOG(RPiContrast, Debug)
- << "Move histogram point " << hist_hi << " to " << level_hi;
- hist_hi = std::min(
- level_hi,
- std::max(0.0, std::max(hist_hi, level_hi - config.hi_max)));
- LOG(RPiContrast, Debug)
- << "Final values " << hist_hi << " -> " << level_hi;
- enhance.Append(hist_hi, level_hi);
- enhance.Append(65535, 65535);
- return enhance;
-}
-
-Pwl apply_manual_contrast(Pwl const &gamma_curve, double brightness,
- double contrast)
-{
- Pwl new_gamma_curve;
- LOG(RPiContrast, Debug)
- << "Manual brightness " << brightness << " contrast " << contrast;
- gamma_curve.Map([&](double x, double y) {
- new_gamma_curve.Append(
- x, std::max(0.0, std::min(65535.0,
- (y - 32768) * contrast +
- 32768 + brightness)));
- });
- return new_gamma_curve;
-}
-
-void Contrast::Process(StatisticsPtr &stats,
- [[maybe_unused]] Metadata *image_metadata)
-{
- Histogram histogram(stats->hist[0].g_hist, NUM_HISTOGRAM_BINS);
- // We look at the histogram and adjust the gamma curve in the following
- // ways: 1. Adjust the gamma curve so as to pull the start of the
- // histogram down, and possibly push the end up.
- Pwl gamma_curve = config_.gamma_curve;
- if (config_.ce_enable) {
- if (config_.lo_max != 0 || config_.hi_max != 0)
- gamma_curve = compute_stretch_curve(histogram, config_)
- .Compose(gamma_curve);
- // We could apply other adjustments (e.g. partial equalisation)
- // based on the histogram...?
- }
- // 2. Finally apply any manually selected brightness/contrast
- // adjustment.
- if (brightness_ != 0 || contrast_ != 1.0)
- gamma_curve = apply_manual_contrast(gamma_curve, brightness_,
- contrast_);
- // And fill in the status for output. Use more points towards the bottom
- // of the curve.
- ContrastStatus status;
- fill_in_status(status, brightness_, contrast_, gamma_curve);
- {
- std::unique_lock<std::mutex> lock(mutex_);
- status_ = status;
- }
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Contrast(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/contrast.hpp b/src/ipa/raspberrypi/controller/rpi/contrast.hpp
deleted file mode 100644
index 85624539..00000000
--- a/src/ipa/raspberrypi/controller/rpi/contrast.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * contrast.hpp - contrast (gamma) control algorithm
- */
-#pragma once
-
-#include <mutex>
-
-#include "../contrast_algorithm.hpp"
-#include "../pwl.hpp"
-
-namespace RPiController {
-
-// Back End algorithm to appaly correct digital gain. Should be placed after
-// Back End AWB.
-
-struct ContrastConfig {
- bool ce_enable;
- double lo_histogram;
- double lo_level;
- double lo_max;
- double hi_histogram;
- double hi_level;
- double hi_max;
- Pwl gamma_curve;
-};
-
-class Contrast : public ContrastAlgorithm
-{
-public:
- Contrast(Controller *controller = NULL);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- void SetBrightness(double brightness) override;
- void SetContrast(double contrast) override;
- void Initialise() override;
- void Prepare(Metadata *image_metadata) override;
- void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
-
-private:
- ContrastConfig config_;
- double brightness_;
- double contrast_;
- ContrastStatus status_;
- std::mutex mutex_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/dpc.cpp b/src/ipa/raspberrypi/controller/rpi/dpc.cpp
deleted file mode 100644
index 110f5056..00000000
--- a/src/ipa/raspberrypi/controller/rpi/dpc.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * dpc.cpp - DPC (defective pixel correction) control algorithm
- */
-
-#include <libcamera/base/log.h>
-
-#include "dpc.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiDpc)
-
-// We use the lux status so that we can apply stronger settings in darkness (if
-// necessary).
-
-#define NAME "rpi.dpc"
-
-Dpc::Dpc(Controller *controller)
- : Algorithm(controller)
-{
-}
-
-char const *Dpc::Name() const
-{
- return NAME;
-}
-
-void Dpc::Read(boost::property_tree::ptree const &params)
-{
- config_.strength = params.get<int>("strength", 1);
- if (config_.strength < 0 || config_.strength > 2)
- throw std::runtime_error("Dpc: bad strength value");
-}
-
-void Dpc::Prepare(Metadata *image_metadata)
-{
- DpcStatus dpc_status = {};
- // Should we vary this with lux level or analogue gain? TBD.
- dpc_status.strength = config_.strength;
- LOG(RPiDpc, Debug) << "strength " << dpc_status.strength;
- image_metadata->Set("dpc.status", dpc_status);
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Dpc(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/dpc.hpp b/src/ipa/raspberrypi/controller/rpi/dpc.hpp
deleted file mode 100644
index d90285c4..00000000
--- a/src/ipa/raspberrypi/controller/rpi/dpc.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * dpc.hpp - DPC (defective pixel correction) control algorithm
- */
-#pragma once
-
-#include "../algorithm.hpp"
-#include "../dpc_status.h"
-
-namespace RPiController {
-
-// Back End algorithm to apply appropriate GEQ settings.
-
-struct DpcConfig {
- int strength;
-};
-
-class Dpc : public Algorithm
-{
-public:
- Dpc(Controller *controller);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- void Prepare(Metadata *image_metadata) override;
-
-private:
- DpcConfig config_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/focus.cpp b/src/ipa/raspberrypi/controller/rpi/focus.cpp
deleted file mode 100644
index a87ec802..00000000
--- a/src/ipa/raspberrypi/controller/rpi/focus.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2020, Raspberry Pi (Trading) Limited
- *
- * focus.cpp - focus algorithm
- */
-#include <stdint.h>
-
-#include <libcamera/base/log.h>
-
-#include "../focus_status.h"
-#include "focus.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiFocus)
-
-#define NAME "rpi.focus"
-
-Focus::Focus(Controller *controller)
- : Algorithm(controller)
-{
-}
-
-char const *Focus::Name() const
-{
- return NAME;
-}
-
-void Focus::Process(StatisticsPtr &stats, Metadata *image_metadata)
-{
- FocusStatus status;
- unsigned int i;
- for (i = 0; i < FOCUS_REGIONS; i++)
- status.focus_measures[i] = stats->focus_stats[i].contrast_val[1][1] / 1000;
- status.num = i;
- image_metadata->Set("focus.status", status);
-
- LOG(RPiFocus, Debug)
- << "Focus contrast measure: "
- << (status.focus_measures[5] + status.focus_measures[6]) / 10;
-}
-
-/* Register algorithm with the system. */
-static Algorithm *Create(Controller *controller)
-{
- return new Focus(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/focus.hpp b/src/ipa/raspberrypi/controller/rpi/focus.hpp
deleted file mode 100644
index 131b1d0f..00000000
--- a/src/ipa/raspberrypi/controller/rpi/focus.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2020, Raspberry Pi (Trading) Limited
- *
- * focus.hpp - focus algorithm
- */
-#pragma once
-
-#include "../algorithm.hpp"
-#include "../metadata.hpp"
-
-/*
- * The "focus" algorithm. All it does it print out a version of the
- * focus contrast measure; there is no actual auto-focus mechanism to
- * control.
- */
-
-namespace RPiController {
-
-class Focus : public Algorithm
-{
-public:
- Focus(Controller *controller);
- char const *Name() const override;
- void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
-};
-
-} /* namespace RPiController */
diff --git a/src/ipa/raspberrypi/controller/rpi/geq.cpp b/src/ipa/raspberrypi/controller/rpi/geq.cpp
deleted file mode 100644
index 4530cb75..00000000
--- a/src/ipa/raspberrypi/controller/rpi/geq.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * geq.cpp - GEQ (green equalisation) control algorithm
- */
-
-#include <libcamera/base/log.h>
-
-#include "../device_status.h"
-#include "../lux_status.h"
-#include "../pwl.hpp"
-
-#include "geq.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiGeq)
-
-// We use the lux status so that we can apply stronger settings in darkness (if
-// necessary).
-
-#define NAME "rpi.geq"
-
-Geq::Geq(Controller *controller)
- : Algorithm(controller)
-{
-}
-
-char const *Geq::Name() const
-{
- return NAME;
-}
-
-void Geq::Read(boost::property_tree::ptree const &params)
-{
- config_.offset = params.get<uint16_t>("offset", 0);
- config_.slope = params.get<double>("slope", 0.0);
- if (config_.slope < 0.0 || config_.slope >= 1.0)
- throw std::runtime_error("Geq: bad slope value");
- if (params.get_child_optional("strength"))
- config_.strength.Read(params.get_child("strength"));
-}
-
-void Geq::Prepare(Metadata *image_metadata)
-{
- LuxStatus lux_status = {};
- lux_status.lux = 400;
- if (image_metadata->Get("lux.status", lux_status))
- LOG(RPiGeq, Warning) << "no lux data found";
- DeviceStatus device_status;
- device_status.analogue_gain = 1.0; // in case not found
- if (image_metadata->Get("device.status", device_status))
- LOG(RPiGeq, Warning)
- << "no device metadata - use analogue gain of 1x";
- GeqStatus geq_status = {};
- double strength =
- config_.strength.Empty()
- ? 1.0
- : config_.strength.Eval(config_.strength.Domain().Clip(
- lux_status.lux));
- strength *= device_status.analogue_gain;
- double offset = config_.offset * strength;
- double slope = config_.slope * strength;
- geq_status.offset = std::min(65535.0, std::max(0.0, offset));
- geq_status.slope = std::min(.99999, std::max(0.0, slope));
- LOG(RPiGeq, Debug)
- << "offset " << geq_status.offset << " slope "
- << geq_status.slope << " (analogue gain "
- << device_status.analogue_gain << " lux "
- << lux_status.lux << ")";
- image_metadata->Set("geq.status", geq_status);
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Geq(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/geq.hpp b/src/ipa/raspberrypi/controller/rpi/geq.hpp
deleted file mode 100644
index 8ba3046b..00000000
--- a/src/ipa/raspberrypi/controller/rpi/geq.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * geq.hpp - GEQ (green equalisation) control algorithm
- */
-#pragma once
-
-#include "../algorithm.hpp"
-#include "../geq_status.h"
-
-namespace RPiController {
-
-// Back End algorithm to apply appropriate GEQ settings.
-
-struct GeqConfig {
- uint16_t offset;
- double slope;
- Pwl strength; // lux to strength factor
-};
-
-class Geq : public Algorithm
-{
-public:
- Geq(Controller *controller);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- void Prepare(Metadata *image_metadata) override;
-
-private:
- GeqConfig config_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/lux.cpp b/src/ipa/raspberrypi/controller/rpi/lux.cpp
deleted file mode 100644
index 4d145b6f..00000000
--- a/src/ipa/raspberrypi/controller/rpi/lux.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * lux.cpp - Lux control algorithm
- */
-#include <math.h>
-
-#include <linux/bcm2835-isp.h>
-
-#include <libcamera/base/log.h>
-
-#include "../device_status.h"
-
-#include "lux.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-using namespace std::literals::chrono_literals;
-
-LOG_DEFINE_CATEGORY(RPiLux)
-
-#define NAME "rpi.lux"
-
-Lux::Lux(Controller *controller)
- : Algorithm(controller)
-{
- // Put in some defaults as there will be no meaningful values until
- // Process has run.
- status_.aperture = 1.0;
- status_.lux = 400;
-}
-
-char const *Lux::Name() const
-{
- return NAME;
-}
-
-void Lux::Read(boost::property_tree::ptree const &params)
-{
- reference_shutter_speed_ =
- params.get<double>("reference_shutter_speed") * 1.0us;
- reference_gain_ = params.get<double>("reference_gain");
- reference_aperture_ = params.get<double>("reference_aperture", 1.0);
- reference_Y_ = params.get<double>("reference_Y");
- reference_lux_ = params.get<double>("reference_lux");
- current_aperture_ = reference_aperture_;
-}
-
-void Lux::SetCurrentAperture(double aperture)
-{
- current_aperture_ = aperture;
-}
-
-void Lux::Prepare(Metadata *image_metadata)
-{
- std::unique_lock<std::mutex> lock(mutex_);
- image_metadata->Set("lux.status", status_);
-}
-
-void Lux::Process(StatisticsPtr &stats, Metadata *image_metadata)
-{
- DeviceStatus device_status;
- if (image_metadata->Get("device.status", device_status) == 0) {
- double current_gain = device_status.analogue_gain;
- double current_aperture = device_status.aperture.value_or(current_aperture_);
- uint64_t sum = 0;
- uint32_t num = 0;
- uint32_t *bin = stats->hist[0].g_hist;
- const int num_bins = sizeof(stats->hist[0].g_hist) /
- sizeof(stats->hist[0].g_hist[0]);
- for (int i = 0; i < num_bins; i++)
- sum += bin[i] * (uint64_t)i, num += bin[i];
- // add .5 to reflect the mid-points of bins
- double current_Y = sum / (double)num + .5;
- double gain_ratio = reference_gain_ / current_gain;
- double shutter_speed_ratio =
- reference_shutter_speed_ / device_status.shutter_speed;
- double aperture_ratio = reference_aperture_ / current_aperture;
- double Y_ratio = current_Y * (65536 / num_bins) / reference_Y_;
- double estimated_lux = shutter_speed_ratio * gain_ratio *
- aperture_ratio * aperture_ratio *
- Y_ratio * reference_lux_;
- LuxStatus status;
- status.lux = estimated_lux;
- status.aperture = current_aperture;
- LOG(RPiLux, Debug) << ": estimated lux " << estimated_lux;
- {
- std::unique_lock<std::mutex> lock(mutex_);
- status_ = status;
- }
- // Overwrite the metadata here as well, so that downstream
- // algorithms get the latest value.
- image_metadata->Set("lux.status", status);
- } else
- LOG(RPiLux, Warning) << ": no device metadata";
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Lux(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/lux.hpp b/src/ipa/raspberrypi/controller/rpi/lux.hpp
deleted file mode 100644
index 3ebd35d1..00000000
--- a/src/ipa/raspberrypi/controller/rpi/lux.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * lux.hpp - Lux control algorithm
- */
-#pragma once
-
-#include <mutex>
-
-#include <libcamera/base/utils.h>
-
-#include "../lux_status.h"
-#include "../algorithm.hpp"
-
-// This is our implementation of the "lux control algorithm".
-
-namespace RPiController {
-
-class Lux : public Algorithm
-{
-public:
- Lux(Controller *controller);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- void Prepare(Metadata *image_metadata) override;
- void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
- void SetCurrentAperture(double aperture);
-
-private:
- // These values define the conditions of the reference image, against
- // which we compare the new image.
- libcamera::utils::Duration reference_shutter_speed_;
- double reference_gain_;
- double reference_aperture_; // units of 1/f
- double reference_Y_; // out of 65536
- double reference_lux_;
- double current_aperture_;
- LuxStatus status_;
- std::mutex mutex_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/noise.cpp b/src/ipa/raspberrypi/controller/rpi/noise.cpp
deleted file mode 100644
index 63cad639..00000000
--- a/src/ipa/raspberrypi/controller/rpi/noise.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * noise.cpp - Noise control algorithm
- */
-
-#include <math.h>
-
-#include <libcamera/base/log.h>
-
-#include "../device_status.h"
-#include "../noise_status.h"
-
-#include "noise.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiNoise)
-
-#define NAME "rpi.noise"
-
-Noise::Noise(Controller *controller)
- : Algorithm(controller), mode_factor_(1.0)
-{
-}
-
-char const *Noise::Name() const
-{
- return NAME;
-}
-
-void Noise::SwitchMode(CameraMode const &camera_mode,
- [[maybe_unused]] Metadata *metadata)
-{
- // For example, we would expect a 2x2 binned mode to have a "noise
- // factor" of sqrt(2x2) = 2. (can't be less than one, right?)
- mode_factor_ = std::max(1.0, camera_mode.noise_factor);
-}
-
-void Noise::Read(boost::property_tree::ptree const &params)
-{
- reference_constant_ = params.get<double>("reference_constant");
- reference_slope_ = params.get<double>("reference_slope");
-}
-
-void Noise::Prepare(Metadata *image_metadata)
-{
- struct DeviceStatus device_status;
- device_status.analogue_gain = 1.0; // keep compiler calm
- if (image_metadata->Get("device.status", device_status) == 0) {
- // There is a slight question as to exactly how the noise
- // profile, specifically the constant part of it, scales. For
- // now we assume it all scales the same, and we'll revisit this
- // if it proves substantially wrong. NOTE: we may also want to
- // make some adjustments based on the camera mode (such as
- // binning), if we knew how to discover it...
- double factor = sqrt(device_status.analogue_gain) / mode_factor_;
- struct NoiseStatus status;
- status.noise_constant = reference_constant_ * factor;
- status.noise_slope = reference_slope_ * factor;
- image_metadata->Set("noise.status", status);
- LOG(RPiNoise, Debug)
- << "constant " << status.noise_constant
- << " slope " << status.noise_slope;
- } else
- LOG(RPiNoise, Warning) << " no metadata";
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return new Noise(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/noise.hpp b/src/ipa/raspberrypi/controller/rpi/noise.hpp
deleted file mode 100644
index 1c9de5c8..00000000
--- a/src/ipa/raspberrypi/controller/rpi/noise.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * noise.hpp - Noise control algorithm
- */
-#pragma once
-
-#include "../algorithm.hpp"
-#include "../noise_status.h"
-
-// This is our implementation of the "noise algorithm".
-
-namespace RPiController {
-
-class Noise : public Algorithm
-{
-public:
- Noise(Controller *controller);
- char const *Name() const override;
- void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Read(boost::property_tree::ptree const &params) override;
- void Prepare(Metadata *image_metadata) override;
-
-private:
- // the noise profile for analogue gain of 1.0
- double reference_constant_;
- double reference_slope_;
- double mode_factor_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/sdn.cpp b/src/ipa/raspberrypi/controller/rpi/sdn.cpp
deleted file mode 100644
index 93845509..00000000
--- a/src/ipa/raspberrypi/controller/rpi/sdn.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019-2021, Raspberry Pi (Trading) Limited
- *
- * sdn.cpp - SDN (spatial denoise) control algorithm
- */
-
-#include <libcamera/base/log.h>
-
-#include "../denoise_status.h"
-#include "../noise_status.h"
-
-#include "sdn.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiSdn)
-
-// Calculate settings for the spatial denoise block using the noise profile in
-// the image metadata.
-
-#define NAME "rpi.sdn"
-
-Sdn::Sdn(Controller *controller)
- : DenoiseAlgorithm(controller), mode_(DenoiseMode::ColourOff)
-{
-}
-
-char const *Sdn::Name() const
-{
- return NAME;
-}
-
-void Sdn::Read(boost::property_tree::ptree const &params)
-{
- deviation_ = params.get<double>("deviation", 3.2);
- strength_ = params.get<double>("strength", 0.75);
-}
-
-void Sdn::Initialise() {}
-
-void Sdn::Prepare(Metadata *image_metadata)
-{
- struct NoiseStatus noise_status = {};
- noise_status.noise_slope = 3.0; // in case no metadata
- if (image_metadata->Get("noise.status", noise_status) != 0)
- LOG(RPiSdn, Warning) << "no noise profile found";
- LOG(RPiSdn, Debug)
- << "Noise profile: constant " << noise_status.noise_constant
- << " slope " << noise_status.noise_slope;
- struct DenoiseStatus status;
- status.noise_constant = noise_status.noise_constant * deviation_;
- status.noise_slope = noise_status.noise_slope * deviation_;
- status.strength = strength_;
- status.mode = static_cast<std::underlying_type_t<DenoiseMode>>(mode_);
- image_metadata->Set("denoise.status", status);
- LOG(RPiSdn, Debug)
- << "programmed constant " << status.noise_constant
- << " slope " << status.noise_slope
- << " strength " << status.strength;
-}
-
-void Sdn::SetMode(DenoiseMode mode)
-{
- // We only distinguish between off and all other modes.
- mode_ = mode;
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return (Algorithm *)new Sdn(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/sdn.hpp b/src/ipa/raspberrypi/controller/rpi/sdn.hpp
deleted file mode 100644
index 2371ce04..00000000
--- a/src/ipa/raspberrypi/controller/rpi/sdn.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * sdn.hpp - SDN (spatial denoise) control algorithm
- */
-#pragma once
-
-#include "../algorithm.hpp"
-#include "../denoise_algorithm.hpp"
-
-namespace RPiController {
-
-// Algorithm to calculate correct spatial denoise (SDN) settings.
-
-class Sdn : public DenoiseAlgorithm
-{
-public:
- Sdn(Controller *controller = NULL);
- char const *Name() const override;
- void Read(boost::property_tree::ptree const &params) override;
- void Initialise() override;
- void Prepare(Metadata *image_metadata) override;
- void SetMode(DenoiseMode mode) override;
-
-private:
- double deviation_;
- double strength_;
- DenoiseMode mode_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/rpi/sharpen.cpp b/src/ipa/raspberrypi/controller/rpi/sharpen.cpp
deleted file mode 100644
index 18825a43..00000000
--- a/src/ipa/raspberrypi/controller/rpi/sharpen.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * sharpen.cpp - sharpening control algorithm
- */
-
-#include <math.h>
-
-#include <libcamera/base/log.h>
-
-#include "../sharpen_status.h"
-
-#include "sharpen.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY(RPiSharpen)
-
-#define NAME "rpi.sharpen"
-
-Sharpen::Sharpen(Controller *controller)
- : SharpenAlgorithm(controller), user_strength_(1.0)
-{
-}
-
-char const *Sharpen::Name() const
-{
- return NAME;
-}
-
-void Sharpen::SwitchMode(CameraMode const &camera_mode,
- [[maybe_unused]] Metadata *metadata)
-{
- // can't be less than one, right?
- mode_factor_ = std::max(1.0, camera_mode.noise_factor);
-}
-
-void Sharpen::Read(boost::property_tree::ptree const &params)
-{
- threshold_ = params.get<double>("threshold", 1.0);
- strength_ = params.get<double>("strength", 1.0);
- limit_ = params.get<double>("limit", 1.0);
- LOG(RPiSharpen, Debug)
- << "Read threshold " << threshold_
- << " strength " << strength_
- << " limit " << limit_;
-}
-
-void Sharpen::SetStrength(double strength)
-{
- // Note that this function is how an application sets the overall
- // sharpening "strength". We call this the "user strength" field
- // as there already is a strength_ field - being an internal gain
- // parameter that gets passed to the ISP control code. Negative
- // values are not allowed - coerce them to zero (no sharpening).
- user_strength_ = std::max(0.0, strength);
-}
-
-void Sharpen::Prepare(Metadata *image_metadata)
-{
- // The user_strength_ affects the algorithm's internal gain directly, but
- // we adjust the limit and threshold less aggressively. Using a sqrt
- // function is an arbitrary but gentle way of accomplishing this.
- double user_strength_sqrt = sqrt(user_strength_);
- struct SharpenStatus status;
- // Binned modes seem to need the sharpening toned down with this
- // pipeline, thus we use the mode_factor here. Also avoid
- // divide-by-zero with the user_strength_sqrt.
- status.threshold = threshold_ * mode_factor_ /
- std::max(0.01, user_strength_sqrt);
- status.strength = strength_ / mode_factor_ * user_strength_;
- status.limit = limit_ / mode_factor_ * user_strength_sqrt;
- // Finally, report any application-supplied parameters that were used.
- status.user_strength = user_strength_;
- image_metadata->Set("sharpen.status", status);
-}
-
-// Register algorithm with the system.
-static Algorithm *Create(Controller *controller)
-{
- return new Sharpen(controller);
-}
-static RegisterAlgorithm reg(NAME, &Create);
diff --git a/src/ipa/raspberrypi/controller/rpi/sharpen.hpp b/src/ipa/raspberrypi/controller/rpi/sharpen.hpp
deleted file mode 100644
index 13a076a8..00000000
--- a/src/ipa/raspberrypi/controller/rpi/sharpen.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * sharpen.hpp - sharpening control algorithm
- */
-#pragma once
-
-#include "../sharpen_algorithm.hpp"
-#include "../sharpen_status.h"
-
-// This is our implementation of the "sharpen algorithm".
-
-namespace RPiController {
-
-class Sharpen : public SharpenAlgorithm
-{
-public:
- Sharpen(Controller *controller);
- char const *Name() const override;
- void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
- void Read(boost::property_tree::ptree const &params) override;
- void SetStrength(double strength) override;
- void Prepare(Metadata *image_metadata) override;
-
-private:
- double threshold_;
- double strength_;
- double limit_;
- double mode_factor_;
- double user_strength_;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/sharpen_algorithm.hpp b/src/ipa/raspberrypi/controller/sharpen_algorithm.hpp
deleted file mode 100644
index ca800308..00000000
--- a/src/ipa/raspberrypi/controller/sharpen_algorithm.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2020, Raspberry Pi (Trading) Limited
- *
- * sharpen_algorithm.hpp - sharpness control algorithm interface
- */
-#pragma once
-
-#include "algorithm.hpp"
-
-namespace RPiController {
-
-class SharpenAlgorithm : public Algorithm
-{
-public:
- SharpenAlgorithm(Controller *controller) : Algorithm(controller) {}
- // A sharpness control algorithm must provide the following:
- virtual void SetStrength(double strength) = 0;
-};
-
-} // namespace RPiController
diff --git a/src/ipa/raspberrypi/controller/sharpen_status.h b/src/ipa/raspberrypi/controller/sharpen_status.h
deleted file mode 100644
index 7501b191..00000000
--- a/src/ipa/raspberrypi/controller/sharpen_status.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * sharpen_status.h - Sharpen control algorithm status
- */
-#pragma once
-
-// The "sharpen" algorithm stores the strength to use.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct SharpenStatus {
- // controls the smallest level of detail (or noise!) that sharpening will pick up
- double threshold;
- // the rate at which the sharpening response ramps once above the threshold
- double strength;
- // upper limit of the allowed sharpening response
- double limit;
- // The sharpening strength requested by the user or application.
- double user_strength;
-};
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/ipa/raspberrypi/data/imx219.json b/src/ipa/raspberrypi/data/imx219.json
deleted file mode 100644
index de59d936..00000000
--- a/src/ipa/raspberrypi/data/imx219.json
+++ /dev/null
@@ -1,412 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.dpc":
- {
-
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 27685,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 998,
- "reference_Y": 12744
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 3.67
- },
- "rpi.geq":
- {
- "offset": 204,
- "slope": 0.01633
- },
- "rpi.sdn":
- {
-
- },
- "rpi.awb":
- {
- "priors":
- [
- {
- "lux": 0, "prior":
- [
- 2000, 1.0, 3000, 0.0, 13000, 0.0
- ]
- },
- {
- "lux": 800, "prior":
- [
- 2000, 0.0, 6000, 2.0, 13000, 2.0
- ]
- },
- {
- "lux": 1500, "prior":
- [
- 2000, 0.0, 4000, 1.0, 6000, 6.0, 6500, 7.0, 7000, 1.0, 13000, 1.0
- ]
- }
- ],
- "modes":
- {
- "auto":
- {
- "lo": 2500,
- "hi": 8000
- },
- "incandescent":
- {
- "lo": 2500,
- "hi": 3000
- },
- "tungsten":
- {
- "lo": 3000,
- "hi": 3500
- },
- "fluorescent":
- {
- "lo": 4000,
- "hi": 4700
- },
- "indoor":
- {
- "lo": 3000,
- "hi": 5000
- },
- "daylight":
- {
- "lo": 5500,
- "hi": 6500
- },
- "cloudy":
- {
- "lo": 7000,
- "hi": 8600
- }
- },
- "bayes": 1,
- "ct_curve":
- [
- 2498.0, 0.9309, 0.3599, 2911.0, 0.8682, 0.4283, 2919.0, 0.8358, 0.4621, 3627.0, 0.7646, 0.5327, 4600.0, 0.6079, 0.6721, 5716.0,
- 0.5712, 0.7017, 8575.0, 0.4331, 0.8037
- ],
- "sensitivity_r": 1.05,
- "sensitivity_b": 1.05,
- "transverse_pos": 0.04791,
- "transverse_neg": 0.04881
- },
- "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, 66666
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 33333
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "long":
- {
- "shutter":
- [
- 100, 10000, 30000, 60000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 12.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
- ]
- }
- ],
- "shadows":
- [
- {
- "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target":
- [
- 0, 0.17, 1000, 0.17
- ]
- }
- ]
- },
- "y_target":
- [
- 0, 0.16, 1000, 0.165, 10000, 0.17
- ]
- },
- "rpi.alsc":
- {
- "omega": 1.3,
- "n_iter": 100,
- "luminance_strength": 0.7,
- "calibrations_Cr":
- [
- {
- "ct": 3000, "table":
- [
- 1.487, 1.481, 1.481, 1.445, 1.389, 1.327, 1.307, 1.307, 1.307, 1.309, 1.341, 1.405, 1.458, 1.494, 1.494, 1.497,
- 1.491, 1.481, 1.448, 1.397, 1.331, 1.275, 1.243, 1.229, 1.229, 1.249, 1.287, 1.349, 1.409, 1.463, 1.494, 1.497,
- 1.491, 1.469, 1.405, 1.331, 1.275, 1.217, 1.183, 1.172, 1.172, 1.191, 1.231, 1.287, 1.349, 1.424, 1.484, 1.499,
- 1.487, 1.444, 1.363, 1.283, 1.217, 1.183, 1.148, 1.138, 1.138, 1.159, 1.191, 1.231, 1.302, 1.385, 1.461, 1.492,
- 1.481, 1.423, 1.334, 1.253, 1.189, 1.148, 1.135, 1.119, 1.123, 1.137, 1.159, 1.203, 1.272, 1.358, 1.442, 1.488,
- 1.479, 1.413, 1.321, 1.236, 1.176, 1.139, 1.118, 1.114, 1.116, 1.123, 1.149, 1.192, 1.258, 1.344, 1.432, 1.487,
- 1.479, 1.413, 1.321, 1.236, 1.176, 1.139, 1.116, 1.114, 1.115, 1.123, 1.149, 1.192, 1.258, 1.344, 1.432, 1.487,
- 1.479, 1.425, 1.336, 1.251, 1.189, 1.149, 1.136, 1.118, 1.121, 1.138, 1.158, 1.206, 1.275, 1.358, 1.443, 1.488,
- 1.488, 1.448, 1.368, 1.285, 1.219, 1.189, 1.149, 1.139, 1.139, 1.158, 1.195, 1.235, 1.307, 1.387, 1.462, 1.493,
- 1.496, 1.475, 1.411, 1.337, 1.284, 1.219, 1.189, 1.176, 1.176, 1.195, 1.235, 1.296, 1.356, 1.429, 1.487, 1.501,
- 1.495, 1.489, 1.458, 1.407, 1.337, 1.287, 1.253, 1.239, 1.239, 1.259, 1.296, 1.356, 1.419, 1.472, 1.499, 1.499,
- 1.494, 1.489, 1.489, 1.453, 1.398, 1.336, 1.317, 1.317, 1.317, 1.321, 1.351, 1.416, 1.467, 1.501, 1.501, 1.499
- ]
- },
- {
- "ct": 3850, "table":
- [
- 1.694, 1.688, 1.688, 1.649, 1.588, 1.518, 1.495, 1.495, 1.495, 1.497, 1.532, 1.602, 1.659, 1.698, 1.698, 1.703,
- 1.698, 1.688, 1.653, 1.597, 1.525, 1.464, 1.429, 1.413, 1.413, 1.437, 1.476, 1.542, 1.606, 1.665, 1.698, 1.703,
- 1.697, 1.673, 1.605, 1.525, 1.464, 1.401, 1.369, 1.354, 1.354, 1.377, 1.417, 1.476, 1.542, 1.623, 1.687, 1.705,
- 1.692, 1.646, 1.561, 1.472, 1.401, 1.368, 1.337, 1.323, 1.324, 1.348, 1.377, 1.417, 1.492, 1.583, 1.661, 1.697,
- 1.686, 1.625, 1.528, 1.439, 1.372, 1.337, 1.321, 1.311, 1.316, 1.324, 1.348, 1.389, 1.461, 1.553, 1.642, 1.694,
- 1.684, 1.613, 1.514, 1.423, 1.359, 1.328, 1.311, 1.306, 1.306, 1.316, 1.339, 1.378, 1.446, 1.541, 1.633, 1.693,
- 1.684, 1.613, 1.514, 1.423, 1.359, 1.328, 1.311, 1.305, 1.305, 1.316, 1.339, 1.378, 1.446, 1.541, 1.633, 1.693,
- 1.685, 1.624, 1.529, 1.438, 1.372, 1.336, 1.324, 1.309, 1.314, 1.323, 1.348, 1.392, 1.462, 1.555, 1.646, 1.694,
- 1.692, 1.648, 1.561, 1.473, 1.403, 1.372, 1.336, 1.324, 1.324, 1.348, 1.378, 1.423, 1.495, 1.585, 1.667, 1.701,
- 1.701, 1.677, 1.608, 1.527, 1.471, 1.403, 1.375, 1.359, 1.359, 1.378, 1.423, 1.488, 1.549, 1.631, 1.694, 1.709,
- 1.702, 1.694, 1.656, 1.601, 1.527, 1.473, 1.441, 1.424, 1.424, 1.443, 1.488, 1.549, 1.621, 1.678, 1.706, 1.707,
- 1.699, 1.694, 1.694, 1.654, 1.593, 1.525, 1.508, 1.508, 1.508, 1.509, 1.546, 1.614, 1.674, 1.708, 1.708, 1.707
- ]
- },
- {
- "ct": 6000, "table":
- [
- 2.179, 2.176, 2.176, 2.125, 2.048, 1.975, 1.955, 1.954, 1.954, 1.956, 1.993, 2.071, 2.141, 2.184, 2.185, 2.188,
- 2.189, 2.176, 2.128, 2.063, 1.973, 1.908, 1.872, 1.856, 1.856, 1.876, 1.922, 1.999, 2.081, 2.144, 2.184, 2.192,
- 2.187, 2.152, 2.068, 1.973, 1.907, 1.831, 1.797, 1.786, 1.786, 1.804, 1.853, 1.922, 1.999, 2.089, 2.166, 2.191,
- 2.173, 2.117, 2.013, 1.908, 1.831, 1.791, 1.755, 1.749, 1.749, 1.767, 1.804, 1.853, 1.939, 2.041, 2.135, 2.181,
- 2.166, 2.089, 1.975, 1.869, 1.792, 1.755, 1.741, 1.731, 1.734, 1.749, 1.767, 1.818, 1.903, 2.005, 2.111, 2.173,
- 2.165, 2.074, 1.956, 1.849, 1.777, 1.742, 1.729, 1.725, 1.729, 1.734, 1.758, 1.804, 1.884, 1.991, 2.099, 2.172,
- 2.165, 2.074, 1.956, 1.849, 1.777, 1.742, 1.727, 1.724, 1.725, 1.734, 1.758, 1.804, 1.884, 1.991, 2.099, 2.172,
- 2.166, 2.085, 1.975, 1.869, 1.791, 1.755, 1.741, 1.729, 1.733, 1.749, 1.769, 1.819, 1.904, 2.009, 2.114, 2.174,
- 2.174, 2.118, 2.015, 1.913, 1.831, 1.791, 1.755, 1.749, 1.749, 1.769, 1.811, 1.855, 1.943, 2.047, 2.139, 2.183,
- 2.187, 2.151, 2.072, 1.979, 1.911, 1.831, 1.801, 1.791, 1.791, 1.811, 1.855, 1.933, 2.006, 2.101, 2.173, 2.197,
- 2.189, 2.178, 2.132, 2.069, 1.979, 1.913, 1.879, 1.867, 1.867, 1.891, 1.933, 2.006, 2.091, 2.156, 2.195, 2.197,
- 2.181, 2.179, 2.178, 2.131, 2.057, 1.981, 1.965, 1.965, 1.965, 1.969, 1.999, 2.083, 2.153, 2.197, 2.197, 2.196
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 3000, "table":
- [
- 1.967, 1.961, 1.955, 1.953, 1.954, 1.957, 1.961, 1.963, 1.963, 1.961, 1.959, 1.957, 1.954, 1.951, 1.951, 1.955,
- 1.961, 1.959, 1.957, 1.956, 1.962, 1.967, 1.975, 1.979, 1.979, 1.975, 1.971, 1.967, 1.957, 1.952, 1.951, 1.951,
- 1.959, 1.959, 1.959, 1.966, 1.976, 1.989, 1.999, 2.004, 2.003, 1.997, 1.991, 1.981, 1.967, 1.956, 1.951, 1.951,
- 1.959, 1.962, 1.967, 1.978, 1.993, 2.009, 2.021, 2.028, 2.026, 2.021, 2.011, 1.995, 1.981, 1.964, 1.953, 1.951,
- 1.961, 1.965, 1.977, 1.993, 2.009, 2.023, 2.041, 2.047, 2.047, 2.037, 2.024, 2.011, 1.995, 1.975, 1.958, 1.953,
- 1.963, 1.968, 1.981, 2.001, 2.019, 2.039, 2.046, 2.052, 2.052, 2.051, 2.035, 2.021, 2.001, 1.978, 1.959, 1.955,
- 1.961, 1.966, 1.981, 2.001, 2.019, 2.038, 2.043, 2.051, 2.052, 2.042, 2.034, 2.019, 2.001, 1.978, 1.959, 1.954,
- 1.957, 1.961, 1.972, 1.989, 2.003, 2.021, 2.038, 2.039, 2.039, 2.034, 2.019, 2.004, 1.988, 1.971, 1.954, 1.949,
- 1.952, 1.953, 1.959, 1.972, 1.989, 2.003, 2.016, 2.019, 2.019, 2.014, 2.003, 1.988, 1.971, 1.955, 1.948, 1.947,
- 1.949, 1.948, 1.949, 1.957, 1.971, 1.978, 1.991, 1.994, 1.994, 1.989, 1.979, 1.967, 1.954, 1.946, 1.947, 1.947,
- 1.949, 1.946, 1.944, 1.946, 1.949, 1.954, 1.962, 1.967, 1.967, 1.963, 1.956, 1.948, 1.943, 1.943, 1.946, 1.949,
- 1.951, 1.946, 1.944, 1.942, 1.943, 1.943, 1.947, 1.948, 1.949, 1.947, 1.945, 1.941, 1.938, 1.939, 1.948, 1.952
- ]
- },
- {
- "ct": 3850, "table":
- [
- 1.726, 1.724, 1.722, 1.723, 1.731, 1.735, 1.743, 1.746, 1.746, 1.741, 1.735, 1.729, 1.725, 1.721, 1.721, 1.721,
- 1.724, 1.723, 1.723, 1.727, 1.735, 1.744, 1.749, 1.756, 1.756, 1.749, 1.744, 1.735, 1.727, 1.719, 1.719, 1.719,
- 1.723, 1.723, 1.724, 1.735, 1.746, 1.759, 1.767, 1.775, 1.775, 1.766, 1.758, 1.746, 1.735, 1.723, 1.718, 1.716,
- 1.723, 1.725, 1.732, 1.746, 1.759, 1.775, 1.782, 1.792, 1.792, 1.782, 1.772, 1.759, 1.745, 1.729, 1.718, 1.716,
- 1.725, 1.729, 1.738, 1.756, 1.775, 1.785, 1.796, 1.803, 1.804, 1.794, 1.783, 1.772, 1.757, 1.736, 1.722, 1.718,
- 1.728, 1.731, 1.741, 1.759, 1.781, 1.795, 1.803, 1.806, 1.808, 1.805, 1.791, 1.779, 1.762, 1.739, 1.722, 1.721,
- 1.727, 1.731, 1.741, 1.759, 1.781, 1.791, 1.799, 1.804, 1.806, 1.801, 1.791, 1.779, 1.762, 1.739, 1.722, 1.717,
- 1.722, 1.724, 1.733, 1.751, 1.768, 1.781, 1.791, 1.796, 1.799, 1.791, 1.781, 1.766, 1.754, 1.731, 1.717, 1.714,
- 1.718, 1.718, 1.724, 1.737, 1.752, 1.768, 1.776, 1.782, 1.784, 1.781, 1.766, 1.754, 1.737, 1.724, 1.713, 1.709,
- 1.716, 1.715, 1.716, 1.725, 1.737, 1.749, 1.756, 1.763, 1.764, 1.762, 1.749, 1.737, 1.724, 1.717, 1.709, 1.708,
- 1.715, 1.714, 1.712, 1.715, 1.722, 1.729, 1.736, 1.741, 1.742, 1.739, 1.731, 1.723, 1.717, 1.712, 1.711, 1.709,
- 1.716, 1.714, 1.711, 1.712, 1.715, 1.719, 1.723, 1.728, 1.731, 1.729, 1.723, 1.718, 1.711, 1.711, 1.713, 1.713
- ]
- },
- {
- "ct": 6000, "table":
- [
- 1.374, 1.372, 1.373, 1.374, 1.375, 1.378, 1.378, 1.381, 1.382, 1.382, 1.378, 1.373, 1.372, 1.369, 1.365, 1.365,
- 1.371, 1.371, 1.372, 1.374, 1.378, 1.381, 1.384, 1.386, 1.388, 1.387, 1.384, 1.377, 1.372, 1.368, 1.364, 1.362,
- 1.369, 1.371, 1.372, 1.377, 1.383, 1.391, 1.394, 1.396, 1.397, 1.395, 1.391, 1.382, 1.374, 1.369, 1.362, 1.361,
- 1.369, 1.371, 1.375, 1.383, 1.391, 1.399, 1.402, 1.404, 1.405, 1.403, 1.398, 1.391, 1.379, 1.371, 1.363, 1.361,
- 1.371, 1.373, 1.378, 1.388, 1.399, 1.407, 1.411, 1.413, 1.413, 1.411, 1.405, 1.397, 1.385, 1.374, 1.366, 1.362,
- 1.371, 1.374, 1.379, 1.389, 1.405, 1.411, 1.414, 1.414, 1.415, 1.415, 1.411, 1.401, 1.388, 1.376, 1.367, 1.363,
- 1.371, 1.373, 1.379, 1.389, 1.405, 1.408, 1.413, 1.414, 1.414, 1.413, 1.409, 1.401, 1.388, 1.376, 1.367, 1.362,
- 1.366, 1.369, 1.374, 1.384, 1.396, 1.404, 1.407, 1.408, 1.408, 1.408, 1.401, 1.395, 1.382, 1.371, 1.363, 1.359,
- 1.364, 1.365, 1.368, 1.375, 1.386, 1.396, 1.399, 1.401, 1.399, 1.399, 1.395, 1.385, 1.374, 1.365, 1.359, 1.357,
- 1.361, 1.363, 1.365, 1.368, 1.377, 1.384, 1.388, 1.391, 1.391, 1.388, 1.385, 1.375, 1.366, 1.361, 1.358, 1.356,
- 1.361, 1.362, 1.362, 1.364, 1.367, 1.373, 1.376, 1.377, 1.377, 1.375, 1.373, 1.366, 1.362, 1.358, 1.358, 1.358,
- 1.361, 1.362, 1.362, 1.362, 1.363, 1.367, 1.369, 1.368, 1.367, 1.367, 1.367, 1.364, 1.358, 1.357, 1.358, 1.359
- ]
- }
- ],
- "luminance_lut":
- [
- 2.716, 2.568, 2.299, 2.065, 1.845, 1.693, 1.605, 1.597, 1.596, 1.634, 1.738, 1.914, 2.145, 2.394, 2.719, 2.901,
- 2.593, 2.357, 2.093, 1.876, 1.672, 1.528, 1.438, 1.393, 1.394, 1.459, 1.569, 1.731, 1.948, 2.169, 2.481, 2.756,
- 2.439, 2.197, 1.922, 1.691, 1.521, 1.365, 1.266, 1.222, 1.224, 1.286, 1.395, 1.573, 1.747, 1.988, 2.299, 2.563,
- 2.363, 2.081, 1.797, 1.563, 1.376, 1.244, 1.152, 1.099, 1.101, 1.158, 1.276, 1.421, 1.607, 1.851, 2.163, 2.455,
- 2.342, 2.003, 1.715, 1.477, 1.282, 1.152, 1.074, 1.033, 1.035, 1.083, 1.163, 1.319, 1.516, 1.759, 2.064, 2.398,
- 2.342, 1.985, 1.691, 1.446, 1.249, 1.111, 1.034, 1.004, 1.004, 1.028, 1.114, 1.274, 1.472, 1.716, 2.019, 2.389,
- 2.342, 1.991, 1.691, 1.446, 1.249, 1.112, 1.034, 1.011, 1.005, 1.035, 1.114, 1.274, 1.472, 1.716, 2.019, 2.389,
- 2.365, 2.052, 1.751, 1.499, 1.299, 1.171, 1.089, 1.039, 1.042, 1.084, 1.162, 1.312, 1.516, 1.761, 2.059, 2.393,
- 2.434, 2.159, 1.856, 1.601, 1.403, 1.278, 1.166, 1.114, 1.114, 1.162, 1.266, 1.402, 1.608, 1.847, 2.146, 2.435,
- 2.554, 2.306, 2.002, 1.748, 1.563, 1.396, 1.299, 1.247, 1.243, 1.279, 1.386, 1.551, 1.746, 1.977, 2.272, 2.518,
- 2.756, 2.493, 2.195, 1.947, 1.739, 1.574, 1.481, 1.429, 1.421, 1.457, 1.559, 1.704, 1.929, 2.159, 2.442, 2.681,
- 2.935, 2.739, 2.411, 2.151, 1.922, 1.749, 1.663, 1.628, 1.625, 1.635, 1.716, 1.872, 2.113, 2.368, 2.663, 2.824
- ],
- "sigma": 0.00381,
- "sigma_Cb": 0.00216
- },
- "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": 2498, "ccm":
- [
- 1.58731, -0.18011, -0.40721, -0.60639, 2.03422, -0.42782, -0.19612, -1.69203, 2.88815
- ]
- },
- {
- "ct": 2811, "ccm":
- [
- 1.61593, -0.33164, -0.28429, -0.55048, 1.97779, -0.42731, -0.12042, -1.42847, 2.54889
- ]
- },
- {
- "ct": 2911, "ccm":
- [
- 1.62771, -0.41282, -0.21489, -0.57991, 2.04176, -0.46186, -0.07613, -1.13359, 2.20972
- ]
- },
- {
- "ct": 2919, "ccm":
- [
- 1.62661, -0.37736, -0.24925, -0.52519, 1.95233, -0.42714, -0.10842, -1.34929, 2.45771
- ]
- },
- {
- "ct": 3627, "ccm":
- [
- 1.70385, -0.57231, -0.13154, -0.47763, 1.85998, -0.38235, -0.07467, -0.82678, 1.90145
- ]
- },
- {
- "ct": 4600, "ccm":
- [
- 1.68486, -0.61085, -0.07402, -0.41927, 2.04016, -0.62089, -0.08633, -0.67672, 1.76305
- ]
- },
- {
- "ct": 5716, "ccm":
- [
- 1.80439, -0.73699, -0.06739, -0.36073, 1.83327, -0.47255, -0.08378, -0.56403, 1.64781
- ]
- },
- {
- "ct": 8575, "ccm":
- [
- 1.89357, -0.76427, -0.12931, -0.27399, 2.15605, -0.88206, -0.12035, -0.68256, 1.80292
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
-
- },
- "rpi.dpc":
- {
-
- }
-}
diff --git a/src/ipa/raspberrypi/data/imx219_noir.json b/src/ipa/raspberrypi/data/imx219_noir.json
deleted file mode 100644
index 9a3f03ec..00000000
--- a/src/ipa/raspberrypi/data/imx219_noir.json
+++ /dev/null
@@ -1,344 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.dpc":
- {
-
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 27685,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 998,
- "reference_Y": 12744
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 3.67
- },
- "rpi.geq":
- {
- "offset": 204,
- "slope": 0.01633
- },
- "rpi.sdn":
- {
-
- },
- "rpi.awb":
- {
- "bayes": 0
- },
- "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, 66666
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 33333
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "long":
- {
- "shutter":
- [
- 100, 10000, 30000, 60000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 12.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
- ]
- }
- ],
- "shadows":
- [
- {
- "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target":
- [
- 0, 0.17, 1000, 0.17
- ]
- }
- ]
- },
- "y_target":
- [
- 0, 0.16, 1000, 0.165, 10000, 0.17
- ]
- },
- "rpi.alsc":
- {
- "omega": 1.3,
- "n_iter": 100,
- "luminance_strength": 0.7,
- "calibrations_Cr":
- [
- {
- "ct": 3000, "table":
- [
- 1.487, 1.481, 1.481, 1.445, 1.389, 1.327, 1.307, 1.307, 1.307, 1.309, 1.341, 1.405, 1.458, 1.494, 1.494, 1.497,
- 1.491, 1.481, 1.448, 1.397, 1.331, 1.275, 1.243, 1.229, 1.229, 1.249, 1.287, 1.349, 1.409, 1.463, 1.494, 1.497,
- 1.491, 1.469, 1.405, 1.331, 1.275, 1.217, 1.183, 1.172, 1.172, 1.191, 1.231, 1.287, 1.349, 1.424, 1.484, 1.499,
- 1.487, 1.444, 1.363, 1.283, 1.217, 1.183, 1.148, 1.138, 1.138, 1.159, 1.191, 1.231, 1.302, 1.385, 1.461, 1.492,
- 1.481, 1.423, 1.334, 1.253, 1.189, 1.148, 1.135, 1.119, 1.123, 1.137, 1.159, 1.203, 1.272, 1.358, 1.442, 1.488,
- 1.479, 1.413, 1.321, 1.236, 1.176, 1.139, 1.118, 1.114, 1.116, 1.123, 1.149, 1.192, 1.258, 1.344, 1.432, 1.487,
- 1.479, 1.413, 1.321, 1.236, 1.176, 1.139, 1.116, 1.114, 1.115, 1.123, 1.149, 1.192, 1.258, 1.344, 1.432, 1.487,
- 1.479, 1.425, 1.336, 1.251, 1.189, 1.149, 1.136, 1.118, 1.121, 1.138, 1.158, 1.206, 1.275, 1.358, 1.443, 1.488,
- 1.488, 1.448, 1.368, 1.285, 1.219, 1.189, 1.149, 1.139, 1.139, 1.158, 1.195, 1.235, 1.307, 1.387, 1.462, 1.493,
- 1.496, 1.475, 1.411, 1.337, 1.284, 1.219, 1.189, 1.176, 1.176, 1.195, 1.235, 1.296, 1.356, 1.429, 1.487, 1.501,
- 1.495, 1.489, 1.458, 1.407, 1.337, 1.287, 1.253, 1.239, 1.239, 1.259, 1.296, 1.356, 1.419, 1.472, 1.499, 1.499,
- 1.494, 1.489, 1.489, 1.453, 1.398, 1.336, 1.317, 1.317, 1.317, 1.321, 1.351, 1.416, 1.467, 1.501, 1.501, 1.499
- ]
- },
- {
- "ct": 3850, "table":
- [
- 1.694, 1.688, 1.688, 1.649, 1.588, 1.518, 1.495, 1.495, 1.495, 1.497, 1.532, 1.602, 1.659, 1.698, 1.698, 1.703,
- 1.698, 1.688, 1.653, 1.597, 1.525, 1.464, 1.429, 1.413, 1.413, 1.437, 1.476, 1.542, 1.606, 1.665, 1.698, 1.703,
- 1.697, 1.673, 1.605, 1.525, 1.464, 1.401, 1.369, 1.354, 1.354, 1.377, 1.417, 1.476, 1.542, 1.623, 1.687, 1.705,
- 1.692, 1.646, 1.561, 1.472, 1.401, 1.368, 1.337, 1.323, 1.324, 1.348, 1.377, 1.417, 1.492, 1.583, 1.661, 1.697,
- 1.686, 1.625, 1.528, 1.439, 1.372, 1.337, 1.321, 1.311, 1.316, 1.324, 1.348, 1.389, 1.461, 1.553, 1.642, 1.694,
- 1.684, 1.613, 1.514, 1.423, 1.359, 1.328, 1.311, 1.306, 1.306, 1.316, 1.339, 1.378, 1.446, 1.541, 1.633, 1.693,
- 1.684, 1.613, 1.514, 1.423, 1.359, 1.328, 1.311, 1.305, 1.305, 1.316, 1.339, 1.378, 1.446, 1.541, 1.633, 1.693,
- 1.685, 1.624, 1.529, 1.438, 1.372, 1.336, 1.324, 1.309, 1.314, 1.323, 1.348, 1.392, 1.462, 1.555, 1.646, 1.694,
- 1.692, 1.648, 1.561, 1.473, 1.403, 1.372, 1.336, 1.324, 1.324, 1.348, 1.378, 1.423, 1.495, 1.585, 1.667, 1.701,
- 1.701, 1.677, 1.608, 1.527, 1.471, 1.403, 1.375, 1.359, 1.359, 1.378, 1.423, 1.488, 1.549, 1.631, 1.694, 1.709,
- 1.702, 1.694, 1.656, 1.601, 1.527, 1.473, 1.441, 1.424, 1.424, 1.443, 1.488, 1.549, 1.621, 1.678, 1.706, 1.707,
- 1.699, 1.694, 1.694, 1.654, 1.593, 1.525, 1.508, 1.508, 1.508, 1.509, 1.546, 1.614, 1.674, 1.708, 1.708, 1.707
- ]
- },
- {
- "ct": 6000, "table":
- [
- 2.179, 2.176, 2.176, 2.125, 2.048, 1.975, 1.955, 1.954, 1.954, 1.956, 1.993, 2.071, 2.141, 2.184, 2.185, 2.188,
- 2.189, 2.176, 2.128, 2.063, 1.973, 1.908, 1.872, 1.856, 1.856, 1.876, 1.922, 1.999, 2.081, 2.144, 2.184, 2.192,
- 2.187, 2.152, 2.068, 1.973, 1.907, 1.831, 1.797, 1.786, 1.786, 1.804, 1.853, 1.922, 1.999, 2.089, 2.166, 2.191,
- 2.173, 2.117, 2.013, 1.908, 1.831, 1.791, 1.755, 1.749, 1.749, 1.767, 1.804, 1.853, 1.939, 2.041, 2.135, 2.181,
- 2.166, 2.089, 1.975, 1.869, 1.792, 1.755, 1.741, 1.731, 1.734, 1.749, 1.767, 1.818, 1.903, 2.005, 2.111, 2.173,
- 2.165, 2.074, 1.956, 1.849, 1.777, 1.742, 1.729, 1.725, 1.729, 1.734, 1.758, 1.804, 1.884, 1.991, 2.099, 2.172,
- 2.165, 2.074, 1.956, 1.849, 1.777, 1.742, 1.727, 1.724, 1.725, 1.734, 1.758, 1.804, 1.884, 1.991, 2.099, 2.172,
- 2.166, 2.085, 1.975, 1.869, 1.791, 1.755, 1.741, 1.729, 1.733, 1.749, 1.769, 1.819, 1.904, 2.009, 2.114, 2.174,
- 2.174, 2.118, 2.015, 1.913, 1.831, 1.791, 1.755, 1.749, 1.749, 1.769, 1.811, 1.855, 1.943, 2.047, 2.139, 2.183,
- 2.187, 2.151, 2.072, 1.979, 1.911, 1.831, 1.801, 1.791, 1.791, 1.811, 1.855, 1.933, 2.006, 2.101, 2.173, 2.197,
- 2.189, 2.178, 2.132, 2.069, 1.979, 1.913, 1.879, 1.867, 1.867, 1.891, 1.933, 2.006, 2.091, 2.156, 2.195, 2.197,
- 2.181, 2.179, 2.178, 2.131, 2.057, 1.981, 1.965, 1.965, 1.965, 1.969, 1.999, 2.083, 2.153, 2.197, 2.197, 2.196
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 3000, "table":
- [
- 1.967, 1.961, 1.955, 1.953, 1.954, 1.957, 1.961, 1.963, 1.963, 1.961, 1.959, 1.957, 1.954, 1.951, 1.951, 1.955,
- 1.961, 1.959, 1.957, 1.956, 1.962, 1.967, 1.975, 1.979, 1.979, 1.975, 1.971, 1.967, 1.957, 1.952, 1.951, 1.951,
- 1.959, 1.959, 1.959, 1.966, 1.976, 1.989, 1.999, 2.004, 2.003, 1.997, 1.991, 1.981, 1.967, 1.956, 1.951, 1.951,
- 1.959, 1.962, 1.967, 1.978, 1.993, 2.009, 2.021, 2.028, 2.026, 2.021, 2.011, 1.995, 1.981, 1.964, 1.953, 1.951,
- 1.961, 1.965, 1.977, 1.993, 2.009, 2.023, 2.041, 2.047, 2.047, 2.037, 2.024, 2.011, 1.995, 1.975, 1.958, 1.953,
- 1.963, 1.968, 1.981, 2.001, 2.019, 2.039, 2.046, 2.052, 2.052, 2.051, 2.035, 2.021, 2.001, 1.978, 1.959, 1.955,
- 1.961, 1.966, 1.981, 2.001, 2.019, 2.038, 2.043, 2.051, 2.052, 2.042, 2.034, 2.019, 2.001, 1.978, 1.959, 1.954,
- 1.957, 1.961, 1.972, 1.989, 2.003, 2.021, 2.038, 2.039, 2.039, 2.034, 2.019, 2.004, 1.988, 1.971, 1.954, 1.949,
- 1.952, 1.953, 1.959, 1.972, 1.989, 2.003, 2.016, 2.019, 2.019, 2.014, 2.003, 1.988, 1.971, 1.955, 1.948, 1.947,
- 1.949, 1.948, 1.949, 1.957, 1.971, 1.978, 1.991, 1.994, 1.994, 1.989, 1.979, 1.967, 1.954, 1.946, 1.947, 1.947,
- 1.949, 1.946, 1.944, 1.946, 1.949, 1.954, 1.962, 1.967, 1.967, 1.963, 1.956, 1.948, 1.943, 1.943, 1.946, 1.949,
- 1.951, 1.946, 1.944, 1.942, 1.943, 1.943, 1.947, 1.948, 1.949, 1.947, 1.945, 1.941, 1.938, 1.939, 1.948, 1.952
- ]
- },
- {
- "ct": 3850, "table":
- [
- 1.726, 1.724, 1.722, 1.723, 1.731, 1.735, 1.743, 1.746, 1.746, 1.741, 1.735, 1.729, 1.725, 1.721, 1.721, 1.721,
- 1.724, 1.723, 1.723, 1.727, 1.735, 1.744, 1.749, 1.756, 1.756, 1.749, 1.744, 1.735, 1.727, 1.719, 1.719, 1.719,
- 1.723, 1.723, 1.724, 1.735, 1.746, 1.759, 1.767, 1.775, 1.775, 1.766, 1.758, 1.746, 1.735, 1.723, 1.718, 1.716,
- 1.723, 1.725, 1.732, 1.746, 1.759, 1.775, 1.782, 1.792, 1.792, 1.782, 1.772, 1.759, 1.745, 1.729, 1.718, 1.716,
- 1.725, 1.729, 1.738, 1.756, 1.775, 1.785, 1.796, 1.803, 1.804, 1.794, 1.783, 1.772, 1.757, 1.736, 1.722, 1.718,
- 1.728, 1.731, 1.741, 1.759, 1.781, 1.795, 1.803, 1.806, 1.808, 1.805, 1.791, 1.779, 1.762, 1.739, 1.722, 1.721,
- 1.727, 1.731, 1.741, 1.759, 1.781, 1.791, 1.799, 1.804, 1.806, 1.801, 1.791, 1.779, 1.762, 1.739, 1.722, 1.717,
- 1.722, 1.724, 1.733, 1.751, 1.768, 1.781, 1.791, 1.796, 1.799, 1.791, 1.781, 1.766, 1.754, 1.731, 1.717, 1.714,
- 1.718, 1.718, 1.724, 1.737, 1.752, 1.768, 1.776, 1.782, 1.784, 1.781, 1.766, 1.754, 1.737, 1.724, 1.713, 1.709,
- 1.716, 1.715, 1.716, 1.725, 1.737, 1.749, 1.756, 1.763, 1.764, 1.762, 1.749, 1.737, 1.724, 1.717, 1.709, 1.708,
- 1.715, 1.714, 1.712, 1.715, 1.722, 1.729, 1.736, 1.741, 1.742, 1.739, 1.731, 1.723, 1.717, 1.712, 1.711, 1.709,
- 1.716, 1.714, 1.711, 1.712, 1.715, 1.719, 1.723, 1.728, 1.731, 1.729, 1.723, 1.718, 1.711, 1.711, 1.713, 1.713
- ]
- },
- {
- "ct": 6000, "table":
- [
- 1.374, 1.372, 1.373, 1.374, 1.375, 1.378, 1.378, 1.381, 1.382, 1.382, 1.378, 1.373, 1.372, 1.369, 1.365, 1.365,
- 1.371, 1.371, 1.372, 1.374, 1.378, 1.381, 1.384, 1.386, 1.388, 1.387, 1.384, 1.377, 1.372, 1.368, 1.364, 1.362,
- 1.369, 1.371, 1.372, 1.377, 1.383, 1.391, 1.394, 1.396, 1.397, 1.395, 1.391, 1.382, 1.374, 1.369, 1.362, 1.361,
- 1.369, 1.371, 1.375, 1.383, 1.391, 1.399, 1.402, 1.404, 1.405, 1.403, 1.398, 1.391, 1.379, 1.371, 1.363, 1.361,
- 1.371, 1.373, 1.378, 1.388, 1.399, 1.407, 1.411, 1.413, 1.413, 1.411, 1.405, 1.397, 1.385, 1.374, 1.366, 1.362,
- 1.371, 1.374, 1.379, 1.389, 1.405, 1.411, 1.414, 1.414, 1.415, 1.415, 1.411, 1.401, 1.388, 1.376, 1.367, 1.363,
- 1.371, 1.373, 1.379, 1.389, 1.405, 1.408, 1.413, 1.414, 1.414, 1.413, 1.409, 1.401, 1.388, 1.376, 1.367, 1.362,
- 1.366, 1.369, 1.374, 1.384, 1.396, 1.404, 1.407, 1.408, 1.408, 1.408, 1.401, 1.395, 1.382, 1.371, 1.363, 1.359,
- 1.364, 1.365, 1.368, 1.375, 1.386, 1.396, 1.399, 1.401, 1.399, 1.399, 1.395, 1.385, 1.374, 1.365, 1.359, 1.357,
- 1.361, 1.363, 1.365, 1.368, 1.377, 1.384, 1.388, 1.391, 1.391, 1.388, 1.385, 1.375, 1.366, 1.361, 1.358, 1.356,
- 1.361, 1.362, 1.362, 1.364, 1.367, 1.373, 1.376, 1.377, 1.377, 1.375, 1.373, 1.366, 1.362, 1.358, 1.358, 1.358,
- 1.361, 1.362, 1.362, 1.362, 1.363, 1.367, 1.369, 1.368, 1.367, 1.367, 1.367, 1.364, 1.358, 1.357, 1.358, 1.359
- ]
- }
- ],
- "luminance_lut":
- [
- 2.716, 2.568, 2.299, 2.065, 1.845, 1.693, 1.605, 1.597, 1.596, 1.634, 1.738, 1.914, 2.145, 2.394, 2.719, 2.901,
- 2.593, 2.357, 2.093, 1.876, 1.672, 1.528, 1.438, 1.393, 1.394, 1.459, 1.569, 1.731, 1.948, 2.169, 2.481, 2.756,
- 2.439, 2.197, 1.922, 1.691, 1.521, 1.365, 1.266, 1.222, 1.224, 1.286, 1.395, 1.573, 1.747, 1.988, 2.299, 2.563,
- 2.363, 2.081, 1.797, 1.563, 1.376, 1.244, 1.152, 1.099, 1.101, 1.158, 1.276, 1.421, 1.607, 1.851, 2.163, 2.455,
- 2.342, 2.003, 1.715, 1.477, 1.282, 1.152, 1.074, 1.033, 1.035, 1.083, 1.163, 1.319, 1.516, 1.759, 2.064, 2.398,
- 2.342, 1.985, 1.691, 1.446, 1.249, 1.111, 1.034, 1.004, 1.004, 1.028, 1.114, 1.274, 1.472, 1.716, 2.019, 2.389,
- 2.342, 1.991, 1.691, 1.446, 1.249, 1.112, 1.034, 1.011, 1.005, 1.035, 1.114, 1.274, 1.472, 1.716, 2.019, 2.389,
- 2.365, 2.052, 1.751, 1.499, 1.299, 1.171, 1.089, 1.039, 1.042, 1.084, 1.162, 1.312, 1.516, 1.761, 2.059, 2.393,
- 2.434, 2.159, 1.856, 1.601, 1.403, 1.278, 1.166, 1.114, 1.114, 1.162, 1.266, 1.402, 1.608, 1.847, 2.146, 2.435,
- 2.554, 2.306, 2.002, 1.748, 1.563, 1.396, 1.299, 1.247, 1.243, 1.279, 1.386, 1.551, 1.746, 1.977, 2.272, 2.518,
- 2.756, 2.493, 2.195, 1.947, 1.739, 1.574, 1.481, 1.429, 1.421, 1.457, 1.559, 1.704, 1.929, 2.159, 2.442, 2.681,
- 2.935, 2.739, 2.411, 2.151, 1.922, 1.749, 1.663, 1.628, 1.625, 1.635, 1.716, 1.872, 2.113, 2.368, 2.663, 2.824
- ],
- "sigma": 0.00381,
- "sigma_Cb": 0.00216
- },
- "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": 2498, "ccm":
- [
- 1.58731, -0.18011, -0.40721, -0.60639, 2.03422, -0.42782, -0.19612, -1.69203, 2.88815
- ]
- },
- {
- "ct": 2811, "ccm":
- [
- 1.61593, -0.33164, -0.28429, -0.55048, 1.97779, -0.42731, -0.12042, -1.42847, 2.54889
- ]
- },
- {
- "ct": 2911, "ccm":
- [
- 1.62771, -0.41282, -0.21489, -0.57991, 2.04176, -0.46186, -0.07613, -1.13359, 2.20972
- ]
- },
- {
- "ct": 2919, "ccm":
- [
- 1.62661, -0.37736, -0.24925, -0.52519, 1.95233, -0.42714, -0.10842, -1.34929, 2.45771
- ]
- },
- {
- "ct": 3627, "ccm":
- [
- 1.70385, -0.57231, -0.13154, -0.47763, 1.85998, -0.38235, -0.07467, -0.82678, 1.90145
- ]
- },
- {
- "ct": 4600, "ccm":
- [
- 1.68486, -0.61085, -0.07402, -0.41927, 2.04016, -0.62089, -0.08633, -0.67672, 1.76305
- ]
- },
- {
- "ct": 5716, "ccm":
- [
- 1.80439, -0.73699, -0.06739, -0.36073, 1.83327, -0.47255, -0.08378, -0.56403, 1.64781
- ]
- },
- {
- "ct": 8575, "ccm":
- [
- 1.89357, -0.76427, -0.12931, -0.27399, 2.15605, -0.88206, -0.12035, -0.68256, 1.80292
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
-
- },
- "rpi.dpc":
- {
-
- }
-}
diff --git a/src/ipa/raspberrypi/data/imx290.json b/src/ipa/raspberrypi/data/imx290.json
deleted file mode 100644
index 20b45c16..00000000
--- a/src/ipa/raspberrypi/data/imx290.json
+++ /dev/null
@@ -1,165 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 3840
- },
- "rpi.dpc":
- {
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 6813,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 890,
- "reference_Y": 12900
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 2.67
- },
- "rpi.geq":
- {
- "offset": 187,
- "slope": 0.00842
- },
- "rpi.sdn":
- {
- },
- "rpi.awb":
- {
- "bayes": 0
- },
- "rpi.agc":
- {
- "speed": 0.2,
- "metering_modes":
- {
- "matrix":
- {
- "weights":
- [
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- ]
- },
- "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
- ]
- }
- },
- "exposure_modes":
- {
- "normal":
- {
- "shutter":
- [
- 10, 30000, 60000
- ],
- "gain":
- [
- 1.0, 2.0, 8.0
- ]
- },
- "sport":
- {
- "shutter":
- [
- 10, 5000, 10000, 20000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- }
- },
- "constraint_modes":
- {
- "normal":
- [
- ],
- "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.16, 10000, 0.16
- ]
- },
- "rpi.alsc":
- {
- "omega": 1.3,
- "n_iter": 100,
- "luminance_strength": 0.7,
- "luminance_lut":
- [
- 2.844, 2.349, 2.018, 1.775, 1.599, 1.466, 1.371, 1.321, 1.306, 1.316, 1.357, 1.439, 1.552, 1.705, 1.915, 2.221,
- 2.576, 2.151, 1.851, 1.639, 1.478, 1.358, 1.272, 1.231, 1.218, 1.226, 1.262, 1.335, 1.438, 1.571, 1.766, 2.067,
- 2.381, 2.005, 1.739, 1.545, 1.389, 1.278, 1.204, 1.166, 1.153, 1.161, 1.194, 1.263, 1.356, 1.489, 1.671, 1.943,
- 2.242, 1.899, 1.658, 1.481, 1.329, 1.225, 1.156, 1.113, 1.096, 1.107, 1.143, 1.201, 1.289, 1.423, 1.607, 1.861,
- 2.152, 1.831, 1.602, 1.436, 1.291, 1.193, 1.121, 1.069, 1.047, 1.062, 1.107, 1.166, 1.249, 1.384, 1.562, 1.801,
- 2.104, 1.795, 1.572, 1.407, 1.269, 1.174, 1.099, 1.041, 1.008, 1.029, 1.083, 1.146, 1.232, 1.364, 1.547, 1.766,
- 2.104, 1.796, 1.572, 1.403, 1.264, 1.171, 1.097, 1.036, 1.001, 1.025, 1.077, 1.142, 1.231, 1.363, 1.549, 1.766,
- 2.148, 1.827, 1.594, 1.413, 1.276, 1.184, 1.114, 1.062, 1.033, 1.049, 1.092, 1.153, 1.242, 1.383, 1.577, 1.795,
- 2.211, 1.881, 1.636, 1.455, 1.309, 1.214, 1.149, 1.104, 1.081, 1.089, 1.125, 1.184, 1.273, 1.423, 1.622, 1.846,
- 2.319, 1.958, 1.698, 1.516, 1.362, 1.262, 1.203, 1.156, 1.137, 1.142, 1.171, 1.229, 1.331, 1.484, 1.682, 1.933,
- 2.459, 2.072, 1.789, 1.594, 1.441, 1.331, 1.261, 1.219, 1.199, 1.205, 1.232, 1.301, 1.414, 1.571, 1.773, 2.052,
- 2.645, 2.206, 1.928, 1.728, 1.559, 1.451, 1.352, 1.301, 1.282, 1.289, 1.319, 1.395, 1.519, 1.685, 1.904, 2.227
- ],
- "sigma": 0.005,
- "sigma_Cb": 0.005
- },
- "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.sharpen":
- {
- },
- "rpi.ccm":
- {
- "ccms":
- [
- {
- "ct": 3900, "ccm":
- [
- 1.54659, -0.17707, -0.36953, -0.51471, 1.72733, -0.21262, 0.06667, -0.92279, 1.85612
- ]
- }
- ]
- },
- "rpi.focus":
- {
- }
-}
diff --git a/src/ipa/raspberrypi/data/imx296.json b/src/ipa/raspberrypi/data/imx296.json
deleted file mode 100644
index 837feff5..00000000
--- a/src/ipa/raspberrypi/data/imx296.json
+++ /dev/null
@@ -1,191 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.dpc":
- {
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 19184,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 432,
- "reference_Y": 13773
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 2.957
- },
- "rpi.geq":
- {
- "offset": 185,
- "slope": 0.0105
- },
- "rpi.sdn":
- {
- },
- "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": 0,
- "luminance_strength": 0.5,
- "calibrations_Cr":
- [
- {
- "ct": 4000, "table":
- [
- 2.554, 2.554, 2.541, 2.534, 2.495, 2.506, 2.516, 2.517, 2.518, 2.515, 2.513, 2.495, 2.481, 2.533, 2.533, 2.521,
- 2.522, 2.534, 2.539, 2.531, 2.531, 2.506, 2.506, 2.513, 2.513, 2.509, 2.498, 2.496, 2.508, 2.517, 2.521, 2.521,
- 2.509, 2.517, 2.534, 2.529, 2.531, 2.521, 2.517, 2.517, 2.515, 2.514, 2.506, 2.499, 2.508, 2.508, 2.521, 2.537,
- 2.507, 2.508, 2.517, 2.516, 2.495, 2.487, 2.519, 2.534, 2.535, 2.531, 2.499, 2.494, 2.501, 2.511, 2.526, 2.526,
- 2.509, 2.517, 2.507, 2.501, 2.494, 2.519, 2.539, 2.539, 2.537, 2.537, 2.533, 2.499, 2.503, 2.511, 2.529, 2.525,
- 2.521, 2.522, 2.476, 2.501, 2.501, 2.539, 2.546, 2.538, 2.531, 2.538, 2.541, 2.531, 2.529, 2.526, 2.529, 2.525,
- 2.516, 2.519, 2.469, 2.499, 2.499, 2.543, 2.543, 2.531, 2.528, 2.534, 2.541, 2.535, 2.531, 2.526, 2.531, 2.528,
- 2.509, 2.515, 2.465, 2.487, 2.487, 2.539, 2.543, 2.539, 2.533, 2.549, 2.542, 2.531, 2.529, 2.524, 2.532, 2.533,
- 2.499, 2.499, 2.475, 2.482, 2.471, 2.509, 2.539, 2.544, 2.543, 2.545, 2.533, 2.498, 2.521, 2.521, 2.537, 2.536,
- 2.499, 2.488, 2.488, 2.488, 2.471, 2.462, 2.509, 2.539, 2.539, 2.532, 2.498, 2.498, 2.518, 2.518, 2.539, 2.539,
- 2.483, 2.484, 2.488, 2.488, 2.502, 2.496, 2.508, 2.514, 2.518, 2.517, 2.521, 2.518, 2.518, 2.518, 2.525, 2.539,
- 2.483, 2.487, 2.478, 2.478, 2.507, 2.509, 2.514, 2.513, 2.514, 2.517, 2.536, 2.559, 2.501, 2.501, 2.503, 2.525
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 4000, "table":
- [
- 2.619, 2.603, 2.599, 2.597, 2.595, 2.594, 2.589, 2.587, 2.586, 2.589, 2.592, 2.597, 2.601, 2.608, 2.621, 2.621,
- 2.619, 2.615, 2.603, 2.601, 2.596, 2.595, 2.591, 2.589, 2.589, 2.592, 2.599, 2.593, 2.601, 2.613, 2.622, 2.631,
- 2.617, 2.617, 2.612, 2.611, 2.604, 2.598, 2.593, 2.591, 2.592, 2.591, 2.593, 2.595, 2.599, 2.614, 2.623, 2.631,
- 2.624, 2.619, 2.615, 2.612, 2.605, 2.602, 2.597, 2.596, 2.592, 2.592, 2.595, 2.599, 2.602, 2.606, 2.619, 2.624,
- 2.629, 2.627, 2.627, 2.617, 2.609, 2.598, 2.612, 2.623, 2.615, 2.604, 2.589, 2.595, 2.599, 2.608, 2.611, 2.614,
- 2.629, 2.632, 2.637, 2.627, 2.612, 2.612, 2.629, 2.631, 2.628, 2.621, 2.604, 2.597, 2.598, 2.604, 2.609, 2.609,
- 2.635, 2.636, 2.642, 2.628, 2.623, 2.623, 2.636, 2.636, 2.634, 2.628, 2.616, 2.599, 2.597, 2.601, 2.603, 2.601,
- 2.641, 2.639, 2.646, 2.632, 2.627, 2.625, 2.632, 2.635, 2.634, 2.627, 2.614, 2.596, 2.595, 2.599, 2.599, 2.598,
- 2.643, 2.644, 2.651, 2.649, 2.629, 2.617, 2.624, 2.629, 2.625, 2.614, 2.586, 2.599, 2.595, 2.597, 2.592, 2.595,
- 2.645, 2.646, 2.649, 2.649, 2.638, 2.624, 2.616, 2.617, 2.609, 2.604, 2.603, 2.603, 2.595, 2.589, 2.587, 2.592,
- 2.641, 2.643, 2.649, 2.647, 2.638, 2.618, 2.615, 2.608, 2.602, 2.595, 2.596, 2.595, 2.593, 2.584, 2.581, 2.583,
- 2.638, 2.637, 2.647, 2.634, 2.634, 2.618, 2.621, 2.621, 2.611, 2.602, 2.596, 2.583, 2.581, 2.581, 2.576, 2.574
- ]
- }
- ],
- "luminance_lut":
- [
- 1.308, 1.293, 1.228, 1.175, 1.139, 1.108, 1.092, 1.082, 1.082, 1.086, 1.097, 1.114, 1.149, 1.199, 1.279, 1.303,
- 1.293, 1.249, 1.199, 1.162, 1.136, 1.109, 1.087, 1.077, 1.072, 1.081, 1.095, 1.103, 1.133, 1.172, 1.225, 1.282,
- 1.251, 1.212, 1.186, 1.159, 1.129, 1.114, 1.102, 1.088, 1.088, 1.088, 1.095, 1.117, 1.123, 1.158, 1.198, 1.249,
- 1.223, 1.192, 1.177, 1.163, 1.147, 1.139, 1.132, 1.112, 1.111, 1.107, 1.113, 1.118, 1.139, 1.155, 1.186, 1.232,
- 1.207, 1.186, 1.171, 1.162, 1.168, 1.163, 1.153, 1.138, 1.129, 1.128, 1.132, 1.136, 1.149, 1.167, 1.189, 1.216,
- 1.198, 1.186, 1.176, 1.176, 1.177, 1.185, 1.171, 1.157, 1.146, 1.144, 1.146, 1.149, 1.161, 1.181, 1.201, 1.221,
- 1.203, 1.181, 1.176, 1.178, 1.191, 1.189, 1.188, 1.174, 1.159, 1.153, 1.158, 1.161, 1.169, 1.185, 1.211, 1.227,
- 1.211, 1.179, 1.177, 1.187, 1.194, 1.196, 1.194, 1.187, 1.176, 1.169, 1.171, 1.171, 1.175, 1.189, 1.214, 1.226,
- 1.219, 1.182, 1.184, 1.191, 1.195, 1.199, 1.197, 1.194, 1.188, 1.185, 1.179, 1.179, 1.182, 1.194, 1.212, 1.227,
- 1.237, 1.192, 1.194, 1.194, 1.198, 1.199, 1.198, 1.197, 1.196, 1.193, 1.189, 1.189, 1.192, 1.203, 1.214, 1.231,
- 1.282, 1.199, 1.199, 1.197, 1.199, 1.199, 1.192, 1.193, 1.193, 1.194, 1.196, 1.197, 1.206, 1.216, 1.228, 1.244,
- 1.309, 1.236, 1.204, 1.203, 1.202, 1.194, 1.194, 1.188, 1.192, 1.192, 1.199, 1.201, 1.212, 1.221, 1.235, 1.247
- ],
- "sigma": 0.005,
- "sigma_Cb": 0.005
- },
- "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.sharpen":
- {
- }
-}
diff --git a/src/ipa/raspberrypi/data/imx378.json b/src/ipa/raspberrypi/data/imx378.json
deleted file mode 100644
index 66200345..00000000
--- a/src/ipa/raspberrypi/data/imx378.json
+++ /dev/null
@@ -1,338 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.dpc":
- {
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 9999,
- "reference_gain": 1.95,
- "reference_aperture": 1.0,
- "reference_lux": 1000,
- "reference_Y": 12996
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 2.641
- },
- "rpi.geq":
- {
- "offset": 235,
- "slope": 0.00902
- },
- "rpi.sdn":
- {
- },
- "rpi.awb":
- {
- "priors":
- [
- {
- "lux": 0, "prior":
- [
- 2000, 1.0, 3000, 0.0, 13000, 0.0
- ]
- },
- {
- "lux": 800, "prior":
- [
- 2000, 0.0, 6000, 2.0, 13000, 2.0
- ]
- },
- {
- "lux": 1500, "prior":
- [
- 2000, 0.0, 4000, 1.0, 6000, 6.0, 6500, 7.0, 7000, 1.0, 13000, 1.0
- ]
- }
- ],
- "modes":
- {
- "auto":
- {
- "lo": 2500,
- "hi": 8000
- },
- "incandescent":
- {
- "lo": 2500,
- "hi": 3000
- },
- "tungsten":
- {
- "lo": 3000,
- "hi": 3500
- },
- "fluorescent":
- {
- "lo": 4000,
- "hi": 4700
- },
- "indoor":
- {
- "lo": 3000,
- "hi": 5000
- },
- "daylight":
- {
- "lo": 5500,
- "hi": 6500
- },
- "cloudy":
- {
- "lo": 7000,
- "hi": 8100
- }
- },
- "bayes": 1,
- "ct_curve":
- [
- 2850.0, 0.6361, 0.3911, 3550.0, 0.5386, 0.5077, 4500.0, 0.4472, 0.6171, 5600.0, 0.3906, 0.6848, 8000.0, 0.3412, 0.7441
- ],
- "sensitivity_r": 1.0,
- "sensitivity_b": 1.0,
- "transverse_pos": 0.01667,
- "transverse_neg": 0.01195
- },
- "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, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.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": 2800, "table":
- [
- 1.604, 1.601, 1.593, 1.581, 1.568, 1.561, 1.561, 1.561, 1.561, 1.567, 1.582, 1.596, 1.609, 1.622, 1.632, 1.636,
- 1.601, 1.594, 1.586, 1.571, 1.555, 1.546, 1.543, 1.543, 1.547, 1.555, 1.572, 1.584, 1.599, 1.614, 1.625, 1.632,
- 1.599, 1.586, 1.571, 1.555, 1.542, 1.528, 1.518, 1.518, 1.523, 1.537, 1.555, 1.572, 1.589, 1.607, 1.622, 1.629,
- 1.597, 1.579, 1.561, 1.542, 1.528, 1.512, 1.493, 1.493, 1.499, 1.523, 1.537, 1.563, 1.582, 1.601, 1.619, 1.629,
- 1.597, 1.577, 1.557, 1.535, 1.512, 1.493, 1.481, 1.479, 1.492, 1.499, 1.524, 1.555, 1.578, 1.599, 1.619, 1.629,
- 1.597, 1.577, 1.557, 1.534, 1.508, 1.483, 1.476, 1.476, 1.481, 1.496, 1.522, 1.554, 1.578, 1.599, 1.619, 1.629,
- 1.597, 1.578, 1.557, 1.534, 1.508, 1.483, 1.481, 1.479, 1.481, 1.496, 1.522, 1.554, 1.579, 1.601, 1.619, 1.631,
- 1.597, 1.581, 1.562, 1.539, 1.517, 1.504, 1.483, 1.481, 1.496, 1.511, 1.531, 1.561, 1.585, 1.607, 1.623, 1.632,
- 1.601, 1.589, 1.569, 1.554, 1.539, 1.517, 1.504, 1.504, 1.511, 1.531, 1.553, 1.573, 1.596, 1.614, 1.629, 1.636,
- 1.609, 1.601, 1.586, 1.569, 1.554, 1.542, 1.535, 1.535, 1.541, 1.553, 1.573, 1.592, 1.608, 1.625, 1.637, 1.645,
- 1.617, 1.611, 1.601, 1.586, 1.574, 1.565, 1.564, 1.564, 1.571, 1.579, 1.592, 1.608, 1.622, 1.637, 1.646, 1.654,
- 1.619, 1.617, 1.611, 1.601, 1.588, 1.585, 1.585, 1.585, 1.588, 1.592, 1.607, 1.622, 1.637, 1.645, 1.654, 1.655
- ]
- },
- {
- "ct": 5500, "table":
- [
- 2.664, 2.658, 2.645, 2.629, 2.602, 2.602, 2.602, 2.606, 2.617, 2.628, 2.649, 2.677, 2.699, 2.722, 2.736, 2.747,
- 2.658, 2.653, 2.629, 2.605, 2.576, 2.575, 2.577, 2.592, 2.606, 2.618, 2.629, 2.651, 2.678, 2.707, 2.727, 2.741,
- 2.649, 2.631, 2.605, 2.576, 2.563, 2.552, 2.552, 2.557, 2.577, 2.604, 2.619, 2.641, 2.669, 2.698, 2.721, 2.741,
- 2.643, 2.613, 2.583, 2.563, 2.552, 2.531, 2.527, 2.527, 2.551, 2.577, 2.604, 2.638, 2.665, 2.694, 2.721, 2.741,
- 2.643, 2.606, 2.575, 2.558, 2.531, 2.516, 2.504, 2.516, 2.527, 2.551, 2.596, 2.635, 2.665, 2.694, 2.721, 2.741,
- 2.643, 2.606, 2.575, 2.558, 2.531, 2.503, 2.501, 2.502, 2.522, 2.551, 2.592, 2.635, 2.669, 2.696, 2.727, 2.744,
- 2.648, 2.611, 2.579, 2.558, 2.532, 2.511, 2.502, 2.511, 2.522, 2.552, 2.592, 2.642, 2.673, 2.702, 2.731, 2.752,
- 2.648, 2.619, 2.589, 2.571, 2.556, 2.532, 2.519, 2.522, 2.552, 2.568, 2.605, 2.648, 2.683, 2.715, 2.743, 2.758,
- 2.659, 2.637, 2.613, 2.589, 2.571, 2.556, 2.555, 2.555, 2.568, 2.605, 2.641, 2.671, 2.699, 2.729, 2.758, 2.776,
- 2.679, 2.665, 2.637, 2.613, 2.602, 2.599, 2.599, 2.606, 2.619, 2.641, 2.671, 2.698, 2.723, 2.754, 2.776, 2.787,
- 2.695, 2.684, 2.671, 2.646, 2.636, 2.636, 2.641, 2.648, 2.661, 2.681, 2.698, 2.723, 2.751, 2.776, 2.788, 2.803,
- 2.702, 2.699, 2.684, 2.671, 2.664, 2.664, 2.664, 2.668, 2.681, 2.698, 2.723, 2.751, 2.773, 2.788, 2.803, 2.805
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 2800, "table":
- [
- 2.876, 2.868, 2.863, 2.851, 2.846, 2.846, 2.847, 2.851, 2.851, 2.857, 2.867, 2.875, 2.889, 2.899, 2.913, 2.926,
- 2.863, 2.861, 2.856, 2.846, 2.846, 2.847, 2.848, 2.851, 2.857, 2.859, 2.875, 2.882, 2.886, 2.896, 2.909, 2.917,
- 2.861, 2.856, 2.846, 2.841, 2.841, 2.855, 2.867, 2.875, 2.888, 2.888, 2.885, 2.883, 2.886, 2.889, 2.901, 2.913,
- 2.858, 2.851, 2.846, 2.846, 2.855, 2.867, 2.884, 2.895, 2.902, 2.902, 2.901, 2.891, 2.891, 2.894, 2.901, 2.909,
- 2.858, 2.851, 2.846, 2.846, 2.867, 2.884, 2.895, 2.902, 2.909, 2.915, 2.911, 2.901, 2.895, 2.898, 2.904, 2.909,
- 2.858, 2.851, 2.849, 2.853, 2.874, 2.888, 2.901, 2.909, 2.917, 2.922, 2.917, 2.911, 2.901, 2.899, 2.905, 2.908,
- 2.861, 2.855, 2.853, 2.855, 2.874, 2.888, 2.901, 2.913, 2.918, 2.922, 2.921, 2.911, 2.901, 2.901, 2.907, 2.908,
- 2.862, 2.859, 2.855, 2.856, 2.872, 2.885, 2.899, 2.906, 2.915, 2.917, 2.911, 2.907, 2.907, 2.907, 2.908, 2.909,
- 2.863, 2.863, 2.859, 2.864, 2.871, 2.881, 2.885, 2.899, 2.905, 2.905, 2.904, 2.904, 2.907, 2.909, 2.913, 2.913,
- 2.866, 2.865, 2.865, 2.867, 2.868, 2.872, 2.881, 2.885, 2.889, 2.894, 2.895, 2.902, 2.906, 2.913, 2.914, 2.917,
- 2.875, 2.875, 2.871, 2.871, 2.871, 2.871, 2.869, 2.869, 2.878, 2.889, 2.894, 2.895, 2.906, 2.914, 2.917, 2.921,
- 2.882, 2.879, 2.876, 2.874, 2.871, 2.871, 2.869, 2.869, 2.869, 2.878, 2.891, 2.894, 2.905, 2.914, 2.919, 2.921
- ]
- },
- {
- "ct": 5500, "table":
- [
- 1.488, 1.488, 1.488, 1.488, 1.491, 1.492, 1.492, 1.491, 1.491, 1.491, 1.492, 1.495, 1.497, 1.499, 1.499, 1.503,
- 1.482, 1.485, 1.485, 1.487, 1.489, 1.492, 1.492, 1.492, 1.492, 1.492, 1.494, 1.494, 1.492, 1.491, 1.493, 1.494,
- 1.482, 1.482, 1.484, 1.485, 1.487, 1.492, 1.496, 1.498, 1.499, 1.498, 1.494, 1.492, 1.491, 1.491, 1.491, 1.491,
- 1.481, 1.481, 1.482, 1.485, 1.491, 1.496, 1.498, 1.499, 1.501, 1.499, 1.498, 1.493, 1.491, 1.488, 1.488, 1.488,
- 1.481, 1.481, 1.481, 1.483, 1.491, 1.497, 1.498, 1.499, 1.501, 1.499, 1.498, 1.492, 1.488, 1.485, 1.483, 1.483,
- 1.479, 1.479, 1.481, 1.482, 1.489, 1.495, 1.497, 1.498, 1.499, 1.499, 1.495, 1.492, 1.485, 1.482, 1.482, 1.481,
- 1.479, 1.479, 1.479, 1.481, 1.489, 1.494, 1.496, 1.497, 1.497, 1.496, 1.495, 1.489, 1.482, 1.481, 1.479, 1.477,
- 1.478, 1.478, 1.479, 1.481, 1.487, 1.491, 1.494, 1.496, 1.496, 1.495, 1.492, 1.487, 1.482, 1.479, 1.478, 1.476,
- 1.478, 1.478, 1.479, 1.482, 1.486, 1.488, 1.491, 1.493, 1.493, 1.492, 1.487, 1.484, 1.481, 1.479, 1.476, 1.476,
- 1.477, 1.479, 1.481, 1.483, 1.485, 1.486, 1.488, 1.488, 1.487, 1.487, 1.484, 1.483, 1.481, 1.479, 1.476, 1.476,
- 1.477, 1.479, 1.482, 1.483, 1.484, 1.485, 1.484, 1.482, 1.482, 1.484, 1.483, 1.482, 1.481, 1.479, 1.477, 1.476,
- 1.477, 1.479, 1.482, 1.483, 1.484, 1.484, 1.482, 1.482, 1.482, 1.482, 1.482, 1.481, 1.479, 1.479, 1.479, 1.479
- ]
- }
- ],
- "luminance_lut":
- [
- 2.764, 2.654, 2.321, 2.043, 1.768, 1.594, 1.558, 1.558, 1.558, 1.568, 1.661, 1.904, 2.193, 2.497, 2.888, 3.043,
- 2.654, 2.373, 2.049, 1.819, 1.569, 1.446, 1.381, 1.356, 1.356, 1.403, 1.501, 1.679, 1.939, 2.218, 2.586, 2.888,
- 2.376, 2.154, 1.819, 1.569, 1.438, 1.301, 1.246, 1.224, 1.224, 1.263, 1.349, 1.501, 1.679, 1.985, 2.359, 2.609,
- 2.267, 1.987, 1.662, 1.438, 1.301, 1.235, 1.132, 1.105, 1.105, 1.164, 1.263, 1.349, 1.528, 1.808, 2.184, 2.491,
- 2.218, 1.876, 1.568, 1.367, 1.235, 1.132, 1.087, 1.022, 1.023, 1.104, 1.164, 1.278, 1.439, 1.695, 2.066, 2.429,
- 2.218, 1.832, 1.533, 1.341, 1.206, 1.089, 1.013, 1.002, 1.013, 1.026, 1.122, 1.246, 1.399, 1.642, 2.004, 2.426,
- 2.218, 1.832, 1.533, 1.341, 1.206, 1.089, 1.011, 1.001, 1.009, 1.026, 1.122, 1.246, 1.399, 1.642, 2.004, 2.426,
- 2.224, 1.896, 1.584, 1.382, 1.248, 1.147, 1.088, 1.016, 1.026, 1.118, 1.168, 1.283, 1.444, 1.697, 2.066, 2.428,
- 2.292, 2.019, 1.689, 1.462, 1.322, 1.247, 1.147, 1.118, 1.118, 1.168, 1.275, 1.358, 1.532, 1.809, 2.189, 2.491,
- 2.444, 2.204, 1.856, 1.606, 1.462, 1.322, 1.257, 1.234, 1.234, 1.275, 1.358, 1.516, 1.686, 1.993, 2.371, 2.622,
- 2.748, 2.444, 2.108, 1.856, 1.606, 1.476, 1.399, 1.376, 1.376, 1.422, 1.516, 1.686, 1.968, 2.238, 2.611, 2.935,
- 2.862, 2.748, 2.395, 2.099, 1.811, 1.621, 1.582, 1.582, 1.582, 1.592, 1.677, 1.919, 2.223, 2.534, 2.935, 3.078
- ],
- "sigma": 0.00428,
- "sigma_Cb": 0.00363
- },
- "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": 2850, "ccm":
- [
- 1.42601, -0.20537, -0.22063, -0.47682, 1.81987, -0.34305, 0.01854, -0.86036, 1.84181
- ]
- },
- {
- "ct": 2900, "ccm":
- [
- 1.29755, 0.04602, -0.34356, -0.41491, 1.73477, -0.31987, -0.01345, -0.97115, 1.98459
- ]
- },
- {
- "ct": 3550, "ccm":
- [
- 1.49811, -0.33412, -0.16398, -0.40869, 1.72995, -0.32127, -0.01924, -0.62181, 1.64105
- ]
- },
- {
- "ct": 4500, "ccm":
- [
- 1.47015, -0.29229, -0.17786, -0.36561, 1.88919, -0.52358, -0.03552, -0.56717, 1.60269
- ]
- },
- {
- "ct": 5600, "ccm":
- [
- 1.60962, -0.47434, -0.13528, -0.32701, 1.73797, -0.41096, -0.07626, -0.40171, 1.47796
- ]
- },
- {
- "ct": 8000, "ccm":
- [
- 1.54642, -0.20396, -0.34246, -0.31748, 2.22559, -0.90811, -0.10035, -0.65877, 1.75912
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
- }
-}
diff --git a/src/ipa/raspberrypi/data/imx477.json b/src/ipa/raspberrypi/data/imx477.json
deleted file mode 100644
index d07febd2..00000000
--- a/src/ipa/raspberrypi/data/imx477.json
+++ /dev/null
@@ -1,430 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.dpc":
- {
-
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 27242,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 830,
- "reference_Y": 17755
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 2.767
- },
- "rpi.geq":
- {
- "offset": 204,
- "slope": 0.01078
- },
- "rpi.sdn":
- {
-
- },
- "rpi.awb":
- {
- "priors":
- [
- {
- "lux": 0, "prior":
- [
- 2000, 1.0, 3000, 0.0, 13000, 0.0
- ]
- },
- {
- "lux": 800, "prior":
- [
- 2000, 0.0, 6000, 2.0, 13000, 2.0
- ]
- },
- {
- "lux": 1500, "prior":
- [
- 2000, 0.0, 4000, 1.0, 6000, 6.0, 6500, 7.0, 7000, 1.0, 13000, 1.0
- ]
- }
- ],
- "modes":
- {
- "auto":
- {
- "lo": 2500,
- "hi": 8000
- },
- "incandescent":
- {
- "lo": 2500,
- "hi": 3000
- },
- "tungsten":
- {
- "lo": 3000,
- "hi": 3500
- },
- "fluorescent":
- {
- "lo": 4000,
- "hi": 4700
- },
- "indoor":
- {
- "lo": 3000,
- "hi": 5000
- },
- "daylight":
- {
- "lo": 5500,
- "hi": 6500
- },
- "cloudy":
- {
- "lo": 7000,
- "hi": 8600
- }
- },
- "bayes": 1,
- "ct_curve":
- [
- 2360.0, 0.6009, 0.3093, 2870.0, 0.5047, 0.3936, 2970.0, 0.4782, 0.4221, 3700.0, 0.4212, 0.4923, 3870.0, 0.4037, 0.5166, 4000.0,
- 0.3965, 0.5271, 4400.0, 0.3703, 0.5666, 4715.0, 0.3411, 0.6147, 5920.0, 0.3108, 0.6687, 9050.0, 0.2524, 0.7856
- ],
- "sensitivity_r": 1.05,
- "sensitivity_b": 1.05,
- "transverse_pos": 0.0238,
- "transverse_neg": 0.04429
- },
- "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, 66666
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 33333
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "long":
- {
- "shutter":
- [
- 100, 10000, 30000, 60000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 12.0
- ]
- }
- },
- "constraint_modes":
- {
- "normal":
- [
- {
- "bound": "LOWER", "q_lo": 0.98, "q_hi": 1.0, "y_target":
- [
- 0, 0.3, 1000, 0.3
- ]
- }
- ],
- "highlight":
- [
- {
- "bound": "LOWER", "q_lo": 0.98, "q_hi": 1.0, "y_target":
- [
- 0, 0.3, 1000, 0.3
- ]
- },
- {
- "bound": "UPPER", "q_lo": 0.98, "q_hi": 1.0, "y_target":
- [
- 0, 0.8, 1000, 0.8
- ]
- }
- ],
- "shadows":
- [
- {
- "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target":
- [
- 0, 0.17, 1000, 0.17
- ]
- }
- ]
- },
- "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": 2960, "table":
- [
- 2.088, 2.086, 2.082, 2.081, 2.077, 2.071, 2.068, 2.068, 2.072, 2.073, 2.075, 2.078, 2.084, 2.092, 2.095, 2.098,
- 2.086, 2.084, 2.079, 2.078, 2.075, 2.068, 2.064, 2.063, 2.068, 2.071, 2.072, 2.075, 2.081, 2.089, 2.092, 2.094,
- 2.083, 2.081, 2.077, 2.072, 2.069, 2.062, 2.059, 2.059, 2.063, 2.067, 2.069, 2.072, 2.079, 2.088, 2.089, 2.089,
- 2.081, 2.077, 2.072, 2.068, 2.065, 2.058, 2.055, 2.054, 2.057, 2.062, 2.066, 2.069, 2.077, 2.084, 2.086, 2.086,
- 2.078, 2.075, 2.069, 2.065, 2.061, 2.055, 2.052, 2.049, 2.051, 2.056, 2.062, 2.065, 2.072, 2.079, 2.081, 2.079,
- 2.079, 2.075, 2.069, 2.064, 2.061, 2.053, 2.049, 2.046, 2.049, 2.051, 2.057, 2.062, 2.069, 2.075, 2.077, 2.075,
- 2.082, 2.079, 2.072, 2.065, 2.061, 2.054, 2.049, 2.047, 2.049, 2.051, 2.056, 2.061, 2.066, 2.073, 2.073, 2.069,
- 2.086, 2.082, 2.075, 2.068, 2.062, 2.054, 2.051, 2.049, 2.051, 2.052, 2.056, 2.061, 2.066, 2.073, 2.073, 2.072,
- 2.088, 2.086, 2.079, 2.074, 2.066, 2.057, 2.051, 2.051, 2.054, 2.055, 2.056, 2.061, 2.067, 2.072, 2.073, 2.072,
- 2.091, 2.087, 2.079, 2.075, 2.068, 2.057, 2.052, 2.052, 2.056, 2.055, 2.055, 2.059, 2.066, 2.072, 2.072, 2.072,
- 2.093, 2.088, 2.081, 2.077, 2.069, 2.059, 2.054, 2.054, 2.057, 2.056, 2.056, 2.058, 2.066, 2.072, 2.073, 2.073,
- 2.095, 2.091, 2.084, 2.078, 2.075, 2.067, 2.057, 2.057, 2.059, 2.059, 2.058, 2.059, 2.068, 2.073, 2.075, 2.078
- ]
- },
- {
- "ct": 4850, "table":
- [
- 2.973, 2.968, 2.956, 2.943, 2.941, 2.932, 2.923, 2.921, 2.924, 2.929, 2.931, 2.939, 2.953, 2.965, 2.966, 2.976,
- 2.969, 2.962, 2.951, 2.941, 2.934, 2.928, 2.919, 2.918, 2.919, 2.923, 2.927, 2.933, 2.945, 2.957, 2.962, 2.962,
- 2.964, 2.956, 2.944, 2.932, 2.929, 2.924, 2.915, 2.914, 2.915, 2.919, 2.924, 2.928, 2.941, 2.952, 2.958, 2.959,
- 2.957, 2.951, 2.939, 2.928, 2.924, 2.919, 2.913, 2.911, 2.911, 2.915, 2.919, 2.925, 2.936, 2.947, 2.952, 2.953,
- 2.954, 2.947, 2.935, 2.924, 2.919, 2.915, 2.908, 2.906, 2.906, 2.907, 2.914, 2.921, 2.932, 2.941, 2.943, 2.942,
- 2.953, 2.946, 2.932, 2.921, 2.916, 2.911, 2.904, 2.902, 2.901, 2.904, 2.909, 2.919, 2.926, 2.937, 2.939, 2.939,
- 2.953, 2.947, 2.932, 2.918, 2.915, 2.909, 2.903, 2.901, 2.901, 2.906, 2.911, 2.918, 2.924, 2.936, 2.936, 2.932,
- 2.956, 2.948, 2.934, 2.919, 2.916, 2.908, 2.903, 2.901, 2.902, 2.907, 2.909, 2.917, 2.926, 2.936, 2.939, 2.939,
- 2.957, 2.951, 2.936, 2.923, 2.917, 2.907, 2.904, 2.901, 2.902, 2.908, 2.911, 2.919, 2.929, 2.939, 2.942, 2.942,
- 2.961, 2.951, 2.936, 2.922, 2.918, 2.906, 2.904, 2.901, 2.901, 2.907, 2.911, 2.921, 2.931, 2.941, 2.942, 2.944,
- 2.964, 2.954, 2.936, 2.924, 2.918, 2.909, 2.905, 2.905, 2.905, 2.907, 2.912, 2.923, 2.933, 2.942, 2.944, 2.944,
- 2.964, 2.958, 2.943, 2.927, 2.921, 2.914, 2.909, 2.907, 2.907, 2.912, 2.916, 2.928, 2.936, 2.944, 2.947, 2.952
- ]
- },
- {
- "ct": 5930, "table":
- [
- 3.312, 3.308, 3.301, 3.294, 3.288, 3.277, 3.268, 3.261, 3.259, 3.261, 3.267, 3.273, 3.285, 3.301, 3.303, 3.312,
- 3.308, 3.304, 3.294, 3.291, 3.283, 3.271, 3.263, 3.259, 3.257, 3.258, 3.261, 3.268, 3.278, 3.293, 3.299, 3.299,
- 3.302, 3.296, 3.288, 3.282, 3.276, 3.267, 3.259, 3.254, 3.252, 3.253, 3.256, 3.261, 3.273, 3.289, 3.292, 3.292,
- 3.296, 3.289, 3.282, 3.276, 3.269, 3.263, 3.256, 3.251, 3.248, 3.249, 3.251, 3.257, 3.268, 3.279, 3.284, 3.284,
- 3.292, 3.285, 3.279, 3.271, 3.264, 3.257, 3.249, 3.243, 3.241, 3.241, 3.246, 3.252, 3.261, 3.274, 3.275, 3.273,
- 3.291, 3.285, 3.276, 3.268, 3.259, 3.251, 3.242, 3.239, 3.236, 3.238, 3.244, 3.248, 3.258, 3.268, 3.269, 3.265,
- 3.294, 3.288, 3.275, 3.266, 3.257, 3.248, 3.239, 3.238, 3.237, 3.238, 3.243, 3.246, 3.255, 3.264, 3.264, 3.257,
- 3.297, 3.293, 3.279, 3.268, 3.258, 3.249, 3.238, 3.237, 3.239, 3.239, 3.243, 3.245, 3.255, 3.264, 3.264, 3.263,
- 3.301, 3.295, 3.281, 3.271, 3.259, 3.248, 3.237, 3.237, 3.239, 3.241, 3.243, 3.246, 3.257, 3.265, 3.266, 3.264,
- 3.306, 3.295, 3.279, 3.271, 3.261, 3.247, 3.235, 3.234, 3.239, 3.239, 3.243, 3.247, 3.258, 3.265, 3.265, 3.264,
- 3.308, 3.297, 3.279, 3.272, 3.261, 3.249, 3.239, 3.239, 3.241, 3.243, 3.245, 3.248, 3.261, 3.265, 3.266, 3.265,
- 3.309, 3.301, 3.286, 3.276, 3.267, 3.256, 3.246, 3.242, 3.244, 3.244, 3.249, 3.253, 3.263, 3.267, 3.271, 3.274
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 2960, "table":
- [
- 2.133, 2.134, 2.139, 2.143, 2.148, 2.155, 2.158, 2.158, 2.158, 2.161, 2.161, 2.162, 2.159, 2.156, 2.152, 2.151,
- 2.132, 2.133, 2.135, 2.142, 2.147, 2.153, 2.158, 2.158, 2.158, 2.158, 2.159, 2.159, 2.157, 2.154, 2.151, 2.148,
- 2.133, 2.133, 2.135, 2.142, 2.149, 2.154, 2.158, 2.158, 2.157, 2.156, 2.158, 2.157, 2.155, 2.153, 2.148, 2.146,
- 2.133, 2.133, 2.138, 2.145, 2.149, 2.154, 2.158, 2.159, 2.158, 2.155, 2.157, 2.156, 2.153, 2.149, 2.146, 2.144,
- 2.133, 2.134, 2.139, 2.146, 2.149, 2.154, 2.158, 2.159, 2.159, 2.156, 2.154, 2.154, 2.149, 2.145, 2.143, 2.139,
- 2.135, 2.135, 2.139, 2.146, 2.151, 2.155, 2.158, 2.159, 2.158, 2.156, 2.153, 2.151, 2.146, 2.143, 2.139, 2.136,
- 2.135, 2.135, 2.138, 2.145, 2.151, 2.154, 2.157, 2.158, 2.157, 2.156, 2.153, 2.151, 2.147, 2.143, 2.141, 2.137,
- 2.135, 2.134, 2.135, 2.141, 2.149, 2.154, 2.157, 2.157, 2.157, 2.157, 2.157, 2.153, 2.149, 2.146, 2.142, 2.139,
- 2.132, 2.133, 2.135, 2.139, 2.148, 2.153, 2.158, 2.159, 2.159, 2.161, 2.161, 2.157, 2.154, 2.149, 2.144, 2.141,
- 2.132, 2.133, 2.135, 2.141, 2.149, 2.155, 2.161, 2.161, 2.162, 2.162, 2.163, 2.159, 2.154, 2.149, 2.144, 2.138,
- 2.136, 2.136, 2.137, 2.143, 2.149, 2.156, 2.162, 2.163, 2.162, 2.163, 2.164, 2.161, 2.157, 2.152, 2.146, 2.138,
- 2.137, 2.137, 2.141, 2.147, 2.152, 2.157, 2.162, 2.162, 2.159, 2.161, 2.162, 2.162, 2.157, 2.152, 2.148, 2.148
- ]
- },
- {
- "ct": 4850, "table":
- [
- 1.463, 1.464, 1.471, 1.478, 1.479, 1.483, 1.484, 1.486, 1.486, 1.484, 1.483, 1.481, 1.478, 1.475, 1.471, 1.468,
- 1.463, 1.463, 1.468, 1.476, 1.479, 1.482, 1.484, 1.487, 1.486, 1.484, 1.483, 1.482, 1.478, 1.473, 1.469, 1.468,
- 1.463, 1.464, 1.468, 1.476, 1.479, 1.483, 1.484, 1.486, 1.486, 1.485, 1.484, 1.482, 1.477, 1.473, 1.469, 1.468,
- 1.463, 1.464, 1.469, 1.477, 1.481, 1.483, 1.485, 1.487, 1.487, 1.485, 1.485, 1.482, 1.478, 1.474, 1.469, 1.468,
- 1.465, 1.465, 1.471, 1.478, 1.481, 1.484, 1.486, 1.488, 1.488, 1.487, 1.485, 1.482, 1.477, 1.472, 1.468, 1.467,
- 1.465, 1.466, 1.472, 1.479, 1.482, 1.485, 1.486, 1.488, 1.488, 1.486, 1.484, 1.479, 1.475, 1.472, 1.468, 1.466,
- 1.466, 1.466, 1.472, 1.478, 1.482, 1.484, 1.485, 1.488, 1.487, 1.485, 1.483, 1.479, 1.475, 1.472, 1.469, 1.468,
- 1.465, 1.466, 1.469, 1.476, 1.481, 1.485, 1.485, 1.486, 1.486, 1.485, 1.483, 1.479, 1.477, 1.474, 1.471, 1.469,
- 1.464, 1.465, 1.469, 1.476, 1.481, 1.484, 1.485, 1.487, 1.487, 1.486, 1.485, 1.481, 1.478, 1.475, 1.471, 1.469,
- 1.463, 1.464, 1.469, 1.477, 1.481, 1.485, 1.485, 1.488, 1.488, 1.487, 1.486, 1.481, 1.478, 1.475, 1.471, 1.468,
- 1.464, 1.465, 1.471, 1.478, 1.482, 1.486, 1.486, 1.488, 1.488, 1.487, 1.486, 1.481, 1.478, 1.475, 1.472, 1.468,
- 1.465, 1.466, 1.472, 1.481, 1.483, 1.487, 1.487, 1.488, 1.488, 1.486, 1.485, 1.481, 1.479, 1.476, 1.473, 1.472
- ]
- },
- {
- "ct": 5930, "table":
- [
- 1.443, 1.444, 1.448, 1.453, 1.459, 1.463, 1.465, 1.467, 1.469, 1.469, 1.467, 1.466, 1.462, 1.457, 1.454, 1.451,
- 1.443, 1.444, 1.445, 1.451, 1.459, 1.463, 1.465, 1.467, 1.469, 1.469, 1.467, 1.465, 1.461, 1.456, 1.452, 1.451,
- 1.444, 1.444, 1.445, 1.451, 1.459, 1.463, 1.466, 1.468, 1.469, 1.469, 1.467, 1.465, 1.461, 1.456, 1.452, 1.449,
- 1.444, 1.444, 1.447, 1.452, 1.459, 1.464, 1.467, 1.469, 1.471, 1.469, 1.467, 1.466, 1.461, 1.456, 1.452, 1.449,
- 1.444, 1.445, 1.448, 1.452, 1.459, 1.465, 1.469, 1.471, 1.471, 1.471, 1.468, 1.465, 1.461, 1.455, 1.451, 1.449,
- 1.445, 1.446, 1.449, 1.453, 1.461, 1.466, 1.469, 1.471, 1.472, 1.469, 1.467, 1.465, 1.459, 1.455, 1.451, 1.447,
- 1.446, 1.446, 1.449, 1.453, 1.461, 1.466, 1.469, 1.469, 1.469, 1.469, 1.467, 1.465, 1.459, 1.455, 1.452, 1.449,
- 1.446, 1.446, 1.447, 1.451, 1.459, 1.466, 1.469, 1.469, 1.469, 1.469, 1.467, 1.465, 1.461, 1.457, 1.454, 1.451,
- 1.444, 1.444, 1.447, 1.451, 1.459, 1.466, 1.469, 1.469, 1.471, 1.471, 1.468, 1.466, 1.462, 1.458, 1.454, 1.452,
- 1.444, 1.444, 1.448, 1.453, 1.459, 1.466, 1.469, 1.471, 1.472, 1.472, 1.468, 1.466, 1.462, 1.458, 1.454, 1.449,
- 1.446, 1.447, 1.449, 1.454, 1.461, 1.466, 1.471, 1.471, 1.471, 1.471, 1.468, 1.466, 1.462, 1.459, 1.455, 1.449,
- 1.447, 1.447, 1.452, 1.457, 1.462, 1.468, 1.472, 1.472, 1.471, 1.471, 1.468, 1.466, 1.462, 1.459, 1.456, 1.455
- ]
- }
- ],
- "luminance_lut":
- [
- 1.548, 1.499, 1.387, 1.289, 1.223, 1.183, 1.164, 1.154, 1.153, 1.169, 1.211, 1.265, 1.345, 1.448, 1.581, 1.619,
- 1.513, 1.412, 1.307, 1.228, 1.169, 1.129, 1.105, 1.098, 1.103, 1.127, 1.157, 1.209, 1.272, 1.361, 1.481, 1.583,
- 1.449, 1.365, 1.257, 1.175, 1.124, 1.085, 1.062, 1.054, 1.059, 1.079, 1.113, 1.151, 1.211, 1.293, 1.407, 1.488,
- 1.424, 1.324, 1.222, 1.139, 1.089, 1.056, 1.034, 1.031, 1.034, 1.049, 1.075, 1.115, 1.164, 1.241, 1.351, 1.446,
- 1.412, 1.297, 1.203, 1.119, 1.069, 1.039, 1.021, 1.016, 1.022, 1.032, 1.052, 1.086, 1.135, 1.212, 1.321, 1.439,
- 1.406, 1.287, 1.195, 1.115, 1.059, 1.028, 1.014, 1.012, 1.015, 1.026, 1.041, 1.074, 1.125, 1.201, 1.302, 1.425,
- 1.406, 1.294, 1.205, 1.126, 1.062, 1.031, 1.013, 1.009, 1.011, 1.019, 1.042, 1.079, 1.129, 1.203, 1.302, 1.435,
- 1.415, 1.318, 1.229, 1.146, 1.076, 1.039, 1.019, 1.014, 1.017, 1.031, 1.053, 1.093, 1.144, 1.219, 1.314, 1.436,
- 1.435, 1.348, 1.246, 1.164, 1.094, 1.059, 1.036, 1.032, 1.037, 1.049, 1.072, 1.114, 1.167, 1.257, 1.343, 1.462,
- 1.471, 1.385, 1.278, 1.189, 1.124, 1.084, 1.064, 1.061, 1.069, 1.078, 1.101, 1.146, 1.207, 1.298, 1.415, 1.496,
- 1.522, 1.436, 1.323, 1.228, 1.169, 1.118, 1.101, 1.094, 1.099, 1.113, 1.146, 1.194, 1.265, 1.353, 1.474, 1.571,
- 1.578, 1.506, 1.378, 1.281, 1.211, 1.156, 1.135, 1.134, 1.139, 1.158, 1.194, 1.251, 1.327, 1.427, 1.559, 1.611
- ],
- "sigma": 0.00121,
- "sigma_Cb": 0.00115
- },
- "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": 2360, "ccm":
- [
- 1.66078, -0.23588, -0.42491, -0.47456, 1.82763, -0.35307, -0.00545, -1.44729, 2.45273
- ]
- },
- {
- "ct": 2870, "ccm":
- [
- 1.78373, -0.55344, -0.23029, -0.39951, 1.69701, -0.29751, 0.01986, -1.06525, 2.04539
- ]
- },
- {
- "ct": 2970, "ccm":
- [
- 1.73511, -0.56973, -0.16537, -0.36338, 1.69878, -0.33539, -0.02354, -0.76813, 1.79168
- ]
- },
- {
- "ct": 3000, "ccm":
- [
- 2.06374, -0.92218, -0.14156, -0.41721, 1.69289, -0.27568, -0.00554, -0.92741, 1.93295
- ]
- },
- {
- "ct": 3700, "ccm":
- [
- 2.13792, -1.08136, -0.05655, -0.34739, 1.58989, -0.24249, -0.00349, -0.76789, 1.77138
- ]
- },
- {
- "ct": 3870, "ccm":
- [
- 1.83834, -0.70528, -0.13307, -0.30499, 1.60523, -0.30024, -0.05701, -0.58313, 1.64014
- ]
- },
- {
- "ct": 4000, "ccm":
- [
- 2.15741, -1.10295, -0.05447, -0.34631, 1.61158, -0.26528, -0.02723, -0.70288, 1.73011
- ]
- },
- {
- "ct": 4400, "ccm":
- [
- 2.05729, -0.95007, -0.10723, -0.41712, 1.78606, -0.36894, -0.11899, -0.55727, 1.67626
- ]
- },
-
- {
- "ct": 4715, "ccm":
- [
- 1.90255, -0.77478, -0.12777, -0.31338, 1.88197, -0.56858, -0.06001, -0.61785, 1.67786
- ]
- },
- {
- "ct": 5920, "ccm":
- [
- 1.98691, -0.84671, -0.14019, -0.26581, 1.70615, -0.44035, -0.09532, -0.47332, 1.56864
- ]
- },
- {
- "ct": 9050, "ccm":
- [
- 2.09255, -0.76541, -0.32714, -0.28973, 2.27462, -0.98489, -0.17299, -0.61275, 1.78574
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
-
- },
- "rpi.focus":
- {
- }
-}
diff --git a/src/ipa/raspberrypi/data/imx477_noir.json b/src/ipa/raspberrypi/data/imx477_noir.json
deleted file mode 100644
index 7d4fc7da..00000000
--- a/src/ipa/raspberrypi/data/imx477_noir.json
+++ /dev/null
@@ -1,362 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.dpc":
- {
-
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 27242,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 830,
- "reference_Y": 17755
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 2.767
- },
- "rpi.geq":
- {
- "offset": 204,
- "slope": 0.01078
- },
- "rpi.sdn":
- {
-
- },
- "rpi.awb":
- {
- "bayes": 0
- },
- "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, 66666
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 33333
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "long":
- {
- "shutter":
- [
- 100, 10000, 30000, 60000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 12.0
- ]
- }
- },
- "constraint_modes":
- {
- "normal":
- [
- {
- "bound": "LOWER", "q_lo": 0.98, "q_hi": 1.0, "y_target":
- [
- 0, 0.3, 1000, 0.3
- ]
- }
- ],
- "highlight":
- [
- {
- "bound": "LOWER", "q_lo": 0.98, "q_hi": 1.0, "y_target":
- [
- 0, 0.3, 1000, 0.3
- ]
- },
- {
- "bound": "UPPER", "q_lo": 0.98, "q_hi": 1.0, "y_target":
- [
- 0, 0.8, 1000, 0.8
- ]
- }
- ],
- "shadows":
- [
- {
- "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target":
- [
- 0, 0.17, 1000, 0.17
- ]
- }
- ]
- },
- "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": 2960, "table":
- [
- 2.088, 2.086, 2.082, 2.081, 2.077, 2.071, 2.068, 2.068, 2.072, 2.073, 2.075, 2.078, 2.084, 2.092, 2.095, 2.098,
- 2.086, 2.084, 2.079, 2.078, 2.075, 2.068, 2.064, 2.063, 2.068, 2.071, 2.072, 2.075, 2.081, 2.089, 2.092, 2.094,
- 2.083, 2.081, 2.077, 2.072, 2.069, 2.062, 2.059, 2.059, 2.063, 2.067, 2.069, 2.072, 2.079, 2.088, 2.089, 2.089,
- 2.081, 2.077, 2.072, 2.068, 2.065, 2.058, 2.055, 2.054, 2.057, 2.062, 2.066, 2.069, 2.077, 2.084, 2.086, 2.086,
- 2.078, 2.075, 2.069, 2.065, 2.061, 2.055, 2.052, 2.049, 2.051, 2.056, 2.062, 2.065, 2.072, 2.079, 2.081, 2.079,
- 2.079, 2.075, 2.069, 2.064, 2.061, 2.053, 2.049, 2.046, 2.049, 2.051, 2.057, 2.062, 2.069, 2.075, 2.077, 2.075,
- 2.082, 2.079, 2.072, 2.065, 2.061, 2.054, 2.049, 2.047, 2.049, 2.051, 2.056, 2.061, 2.066, 2.073, 2.073, 2.069,
- 2.086, 2.082, 2.075, 2.068, 2.062, 2.054, 2.051, 2.049, 2.051, 2.052, 2.056, 2.061, 2.066, 2.073, 2.073, 2.072,
- 2.088, 2.086, 2.079, 2.074, 2.066, 2.057, 2.051, 2.051, 2.054, 2.055, 2.056, 2.061, 2.067, 2.072, 2.073, 2.072,
- 2.091, 2.087, 2.079, 2.075, 2.068, 2.057, 2.052, 2.052, 2.056, 2.055, 2.055, 2.059, 2.066, 2.072, 2.072, 2.072,
- 2.093, 2.088, 2.081, 2.077, 2.069, 2.059, 2.054, 2.054, 2.057, 2.056, 2.056, 2.058, 2.066, 2.072, 2.073, 2.073,
- 2.095, 2.091, 2.084, 2.078, 2.075, 2.067, 2.057, 2.057, 2.059, 2.059, 2.058, 2.059, 2.068, 2.073, 2.075, 2.078
- ]
- },
- {
- "ct": 4850, "table":
- [
- 2.973, 2.968, 2.956, 2.943, 2.941, 2.932, 2.923, 2.921, 2.924, 2.929, 2.931, 2.939, 2.953, 2.965, 2.966, 2.976,
- 2.969, 2.962, 2.951, 2.941, 2.934, 2.928, 2.919, 2.918, 2.919, 2.923, 2.927, 2.933, 2.945, 2.957, 2.962, 2.962,
- 2.964, 2.956, 2.944, 2.932, 2.929, 2.924, 2.915, 2.914, 2.915, 2.919, 2.924, 2.928, 2.941, 2.952, 2.958, 2.959,
- 2.957, 2.951, 2.939, 2.928, 2.924, 2.919, 2.913, 2.911, 2.911, 2.915, 2.919, 2.925, 2.936, 2.947, 2.952, 2.953,
- 2.954, 2.947, 2.935, 2.924, 2.919, 2.915, 2.908, 2.906, 2.906, 2.907, 2.914, 2.921, 2.932, 2.941, 2.943, 2.942,
- 2.953, 2.946, 2.932, 2.921, 2.916, 2.911, 2.904, 2.902, 2.901, 2.904, 2.909, 2.919, 2.926, 2.937, 2.939, 2.939,
- 2.953, 2.947, 2.932, 2.918, 2.915, 2.909, 2.903, 2.901, 2.901, 2.906, 2.911, 2.918, 2.924, 2.936, 2.936, 2.932,
- 2.956, 2.948, 2.934, 2.919, 2.916, 2.908, 2.903, 2.901, 2.902, 2.907, 2.909, 2.917, 2.926, 2.936, 2.939, 2.939,
- 2.957, 2.951, 2.936, 2.923, 2.917, 2.907, 2.904, 2.901, 2.902, 2.908, 2.911, 2.919, 2.929, 2.939, 2.942, 2.942,
- 2.961, 2.951, 2.936, 2.922, 2.918, 2.906, 2.904, 2.901, 2.901, 2.907, 2.911, 2.921, 2.931, 2.941, 2.942, 2.944,
- 2.964, 2.954, 2.936, 2.924, 2.918, 2.909, 2.905, 2.905, 2.905, 2.907, 2.912, 2.923, 2.933, 2.942, 2.944, 2.944,
- 2.964, 2.958, 2.943, 2.927, 2.921, 2.914, 2.909, 2.907, 2.907, 2.912, 2.916, 2.928, 2.936, 2.944, 2.947, 2.952
- ]
- },
- {
- "ct": 5930, "table":
- [
- 3.312, 3.308, 3.301, 3.294, 3.288, 3.277, 3.268, 3.261, 3.259, 3.261, 3.267, 3.273, 3.285, 3.301, 3.303, 3.312,
- 3.308, 3.304, 3.294, 3.291, 3.283, 3.271, 3.263, 3.259, 3.257, 3.258, 3.261, 3.268, 3.278, 3.293, 3.299, 3.299,
- 3.302, 3.296, 3.288, 3.282, 3.276, 3.267, 3.259, 3.254, 3.252, 3.253, 3.256, 3.261, 3.273, 3.289, 3.292, 3.292,
- 3.296, 3.289, 3.282, 3.276, 3.269, 3.263, 3.256, 3.251, 3.248, 3.249, 3.251, 3.257, 3.268, 3.279, 3.284, 3.284,
- 3.292, 3.285, 3.279, 3.271, 3.264, 3.257, 3.249, 3.243, 3.241, 3.241, 3.246, 3.252, 3.261, 3.274, 3.275, 3.273,
- 3.291, 3.285, 3.276, 3.268, 3.259, 3.251, 3.242, 3.239, 3.236, 3.238, 3.244, 3.248, 3.258, 3.268, 3.269, 3.265,
- 3.294, 3.288, 3.275, 3.266, 3.257, 3.248, 3.239, 3.238, 3.237, 3.238, 3.243, 3.246, 3.255, 3.264, 3.264, 3.257,
- 3.297, 3.293, 3.279, 3.268, 3.258, 3.249, 3.238, 3.237, 3.239, 3.239, 3.243, 3.245, 3.255, 3.264, 3.264, 3.263,
- 3.301, 3.295, 3.281, 3.271, 3.259, 3.248, 3.237, 3.237, 3.239, 3.241, 3.243, 3.246, 3.257, 3.265, 3.266, 3.264,
- 3.306, 3.295, 3.279, 3.271, 3.261, 3.247, 3.235, 3.234, 3.239, 3.239, 3.243, 3.247, 3.258, 3.265, 3.265, 3.264,
- 3.308, 3.297, 3.279, 3.272, 3.261, 3.249, 3.239, 3.239, 3.241, 3.243, 3.245, 3.248, 3.261, 3.265, 3.266, 3.265,
- 3.309, 3.301, 3.286, 3.276, 3.267, 3.256, 3.246, 3.242, 3.244, 3.244, 3.249, 3.253, 3.263, 3.267, 3.271, 3.274
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 2960, "table":
- [
- 2.133, 2.134, 2.139, 2.143, 2.148, 2.155, 2.158, 2.158, 2.158, 2.161, 2.161, 2.162, 2.159, 2.156, 2.152, 2.151,
- 2.132, 2.133, 2.135, 2.142, 2.147, 2.153, 2.158, 2.158, 2.158, 2.158, 2.159, 2.159, 2.157, 2.154, 2.151, 2.148,
- 2.133, 2.133, 2.135, 2.142, 2.149, 2.154, 2.158, 2.158, 2.157, 2.156, 2.158, 2.157, 2.155, 2.153, 2.148, 2.146,
- 2.133, 2.133, 2.138, 2.145, 2.149, 2.154, 2.158, 2.159, 2.158, 2.155, 2.157, 2.156, 2.153, 2.149, 2.146, 2.144,
- 2.133, 2.134, 2.139, 2.146, 2.149, 2.154, 2.158, 2.159, 2.159, 2.156, 2.154, 2.154, 2.149, 2.145, 2.143, 2.139,
- 2.135, 2.135, 2.139, 2.146, 2.151, 2.155, 2.158, 2.159, 2.158, 2.156, 2.153, 2.151, 2.146, 2.143, 2.139, 2.136,
- 2.135, 2.135, 2.138, 2.145, 2.151, 2.154, 2.157, 2.158, 2.157, 2.156, 2.153, 2.151, 2.147, 2.143, 2.141, 2.137,
- 2.135, 2.134, 2.135, 2.141, 2.149, 2.154, 2.157, 2.157, 2.157, 2.157, 2.157, 2.153, 2.149, 2.146, 2.142, 2.139,
- 2.132, 2.133, 2.135, 2.139, 2.148, 2.153, 2.158, 2.159, 2.159, 2.161, 2.161, 2.157, 2.154, 2.149, 2.144, 2.141,
- 2.132, 2.133, 2.135, 2.141, 2.149, 2.155, 2.161, 2.161, 2.162, 2.162, 2.163, 2.159, 2.154, 2.149, 2.144, 2.138,
- 2.136, 2.136, 2.137, 2.143, 2.149, 2.156, 2.162, 2.163, 2.162, 2.163, 2.164, 2.161, 2.157, 2.152, 2.146, 2.138,
- 2.137, 2.137, 2.141, 2.147, 2.152, 2.157, 2.162, 2.162, 2.159, 2.161, 2.162, 2.162, 2.157, 2.152, 2.148, 2.148
- ]
- },
- {
- "ct": 4850, "table":
- [
- 1.463, 1.464, 1.471, 1.478, 1.479, 1.483, 1.484, 1.486, 1.486, 1.484, 1.483, 1.481, 1.478, 1.475, 1.471, 1.468,
- 1.463, 1.463, 1.468, 1.476, 1.479, 1.482, 1.484, 1.487, 1.486, 1.484, 1.483, 1.482, 1.478, 1.473, 1.469, 1.468,
- 1.463, 1.464, 1.468, 1.476, 1.479, 1.483, 1.484, 1.486, 1.486, 1.485, 1.484, 1.482, 1.477, 1.473, 1.469, 1.468,
- 1.463, 1.464, 1.469, 1.477, 1.481, 1.483, 1.485, 1.487, 1.487, 1.485, 1.485, 1.482, 1.478, 1.474, 1.469, 1.468,
- 1.465, 1.465, 1.471, 1.478, 1.481, 1.484, 1.486, 1.488, 1.488, 1.487, 1.485, 1.482, 1.477, 1.472, 1.468, 1.467,
- 1.465, 1.466, 1.472, 1.479, 1.482, 1.485, 1.486, 1.488, 1.488, 1.486, 1.484, 1.479, 1.475, 1.472, 1.468, 1.466,
- 1.466, 1.466, 1.472, 1.478, 1.482, 1.484, 1.485, 1.488, 1.487, 1.485, 1.483, 1.479, 1.475, 1.472, 1.469, 1.468,
- 1.465, 1.466, 1.469, 1.476, 1.481, 1.485, 1.485, 1.486, 1.486, 1.485, 1.483, 1.479, 1.477, 1.474, 1.471, 1.469,
- 1.464, 1.465, 1.469, 1.476, 1.481, 1.484, 1.485, 1.487, 1.487, 1.486, 1.485, 1.481, 1.478, 1.475, 1.471, 1.469,
- 1.463, 1.464, 1.469, 1.477, 1.481, 1.485, 1.485, 1.488, 1.488, 1.487, 1.486, 1.481, 1.478, 1.475, 1.471, 1.468,
- 1.464, 1.465, 1.471, 1.478, 1.482, 1.486, 1.486, 1.488, 1.488, 1.487, 1.486, 1.481, 1.478, 1.475, 1.472, 1.468,
- 1.465, 1.466, 1.472, 1.481, 1.483, 1.487, 1.487, 1.488, 1.488, 1.486, 1.485, 1.481, 1.479, 1.476, 1.473, 1.472
- ]
- },
- {
- "ct": 5930, "table":
- [
- 1.443, 1.444, 1.448, 1.453, 1.459, 1.463, 1.465, 1.467, 1.469, 1.469, 1.467, 1.466, 1.462, 1.457, 1.454, 1.451,
- 1.443, 1.444, 1.445, 1.451, 1.459, 1.463, 1.465, 1.467, 1.469, 1.469, 1.467, 1.465, 1.461, 1.456, 1.452, 1.451,
- 1.444, 1.444, 1.445, 1.451, 1.459, 1.463, 1.466, 1.468, 1.469, 1.469, 1.467, 1.465, 1.461, 1.456, 1.452, 1.449,
- 1.444, 1.444, 1.447, 1.452, 1.459, 1.464, 1.467, 1.469, 1.471, 1.469, 1.467, 1.466, 1.461, 1.456, 1.452, 1.449,
- 1.444, 1.445, 1.448, 1.452, 1.459, 1.465, 1.469, 1.471, 1.471, 1.471, 1.468, 1.465, 1.461, 1.455, 1.451, 1.449,
- 1.445, 1.446, 1.449, 1.453, 1.461, 1.466, 1.469, 1.471, 1.472, 1.469, 1.467, 1.465, 1.459, 1.455, 1.451, 1.447,
- 1.446, 1.446, 1.449, 1.453, 1.461, 1.466, 1.469, 1.469, 1.469, 1.469, 1.467, 1.465, 1.459, 1.455, 1.452, 1.449,
- 1.446, 1.446, 1.447, 1.451, 1.459, 1.466, 1.469, 1.469, 1.469, 1.469, 1.467, 1.465, 1.461, 1.457, 1.454, 1.451,
- 1.444, 1.444, 1.447, 1.451, 1.459, 1.466, 1.469, 1.469, 1.471, 1.471, 1.468, 1.466, 1.462, 1.458, 1.454, 1.452,
- 1.444, 1.444, 1.448, 1.453, 1.459, 1.466, 1.469, 1.471, 1.472, 1.472, 1.468, 1.466, 1.462, 1.458, 1.454, 1.449,
- 1.446, 1.447, 1.449, 1.454, 1.461, 1.466, 1.471, 1.471, 1.471, 1.471, 1.468, 1.466, 1.462, 1.459, 1.455, 1.449,
- 1.447, 1.447, 1.452, 1.457, 1.462, 1.468, 1.472, 1.472, 1.471, 1.471, 1.468, 1.466, 1.462, 1.459, 1.456, 1.455
- ]
- }
- ],
- "luminance_lut":
- [
- 1.548, 1.499, 1.387, 1.289, 1.223, 1.183, 1.164, 1.154, 1.153, 1.169, 1.211, 1.265, 1.345, 1.448, 1.581, 1.619,
- 1.513, 1.412, 1.307, 1.228, 1.169, 1.129, 1.105, 1.098, 1.103, 1.127, 1.157, 1.209, 1.272, 1.361, 1.481, 1.583,
- 1.449, 1.365, 1.257, 1.175, 1.124, 1.085, 1.062, 1.054, 1.059, 1.079, 1.113, 1.151, 1.211, 1.293, 1.407, 1.488,
- 1.424, 1.324, 1.222, 1.139, 1.089, 1.056, 1.034, 1.031, 1.034, 1.049, 1.075, 1.115, 1.164, 1.241, 1.351, 1.446,
- 1.412, 1.297, 1.203, 1.119, 1.069, 1.039, 1.021, 1.016, 1.022, 1.032, 1.052, 1.086, 1.135, 1.212, 1.321, 1.439,
- 1.406, 1.287, 1.195, 1.115, 1.059, 1.028, 1.014, 1.012, 1.015, 1.026, 1.041, 1.074, 1.125, 1.201, 1.302, 1.425,
- 1.406, 1.294, 1.205, 1.126, 1.062, 1.031, 1.013, 1.009, 1.011, 1.019, 1.042, 1.079, 1.129, 1.203, 1.302, 1.435,
- 1.415, 1.318, 1.229, 1.146, 1.076, 1.039, 1.019, 1.014, 1.017, 1.031, 1.053, 1.093, 1.144, 1.219, 1.314, 1.436,
- 1.435, 1.348, 1.246, 1.164, 1.094, 1.059, 1.036, 1.032, 1.037, 1.049, 1.072, 1.114, 1.167, 1.257, 1.343, 1.462,
- 1.471, 1.385, 1.278, 1.189, 1.124, 1.084, 1.064, 1.061, 1.069, 1.078, 1.101, 1.146, 1.207, 1.298, 1.415, 1.496,
- 1.522, 1.436, 1.323, 1.228, 1.169, 1.118, 1.101, 1.094, 1.099, 1.113, 1.146, 1.194, 1.265, 1.353, 1.474, 1.571,
- 1.578, 1.506, 1.378, 1.281, 1.211, 1.156, 1.135, 1.134, 1.139, 1.158, 1.194, 1.251, 1.327, 1.427, 1.559, 1.611
- ],
- "sigma": 0.00121,
- "sigma_Cb": 0.00115
- },
- "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": 2360, "ccm":
- [
- 1.66078, -0.23588, -0.42491, -0.47456, 1.82763, -0.35307, -0.00545, -1.44729, 2.45273
- ]
- },
- {
- "ct": 2870, "ccm":
- [
- 1.78373, -0.55344, -0.23029, -0.39951, 1.69701, -0.29751, 0.01986, -1.06525, 2.04539
- ]
- },
- {
- "ct": 2970, "ccm":
- [
- 1.73511, -0.56973, -0.16537, -0.36338, 1.69878, -0.33539, -0.02354, -0.76813, 1.79168
- ]
- },
- {
- "ct": 3000, "ccm":
- [
- 2.06374, -0.92218, -0.14156, -0.41721, 1.69289, -0.27568, -0.00554, -0.92741, 1.93295
- ]
- },
- {
- "ct": 3700, "ccm":
- [
- 2.13792, -1.08136, -0.05655, -0.34739, 1.58989, -0.24249, -0.00349, -0.76789, 1.77138
- ]
- },
- {
- "ct": 3870, "ccm":
- [
- 1.83834, -0.70528, -0.13307, -0.30499, 1.60523, -0.30024, -0.05701, -0.58313, 1.64014
- ]
- },
- {
- "ct": 4000, "ccm":
- [
- 2.15741, -1.10295, -0.05447, -0.34631, 1.61158, -0.26528, -0.02723, -0.70288, 1.73011
- ]
- },
- {
- "ct": 4400, "ccm":
- [
- 2.05729, -0.95007, -0.10723, -0.41712, 1.78606, -0.36894, -0.11899, -0.55727, 1.67626
- ]
- },
-
- {
- "ct": 4715, "ccm":
- [
- 1.90255, -0.77478, -0.12777, -0.31338, 1.88197, -0.56858, -0.06001, -0.61785, 1.67786
- ]
- },
- {
- "ct": 5920, "ccm":
- [
- 1.98691, -0.84671, -0.14019, -0.26581, 1.70615, -0.44035, -0.09532, -0.47332, 1.56864
- ]
- },
- {
- "ct": 9050, "ccm":
- [
- 2.09255, -0.76541, -0.32714, -0.28973, 2.27462, -0.98489, -0.17299, -0.61275, 1.78574
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
-
- },
- "rpi.focus":
- {
- }
-}
diff --git a/src/ipa/raspberrypi/data/imx519.json b/src/ipa/raspberrypi/data/imx519.json
deleted file mode 100644
index 2ce6a08c..00000000
--- a/src/ipa/raspberrypi/data/imx519.json
+++ /dev/null
@@ -1,338 +0,0 @@
-{
- "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, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.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
deleted file mode 100644
index 211811cf..00000000
--- a/src/ipa/raspberrypi/data/meson.build
+++ /dev/null
@@ -1,20 +0,0 @@
-# SPDX-License-Identifier: CC0-1.0
-
-conf_files = files([
- 'imx219.json',
- 'imx219_noir.json',
- 'imx290.json',
- 'imx296.json',
- 'imx378.json',
- 'imx477.json',
- 'imx477_noir.json',
- 'imx519.json',
- 'ov5647.json',
- 'ov5647_noir.json',
- 'ov9281.json',
- 'se327m12.json',
- 'uncalibrated.json',
-])
-
-install_data(conf_files,
- install_dir : ipa_data_dir / 'raspberrypi')
diff --git a/src/ipa/raspberrypi/data/ov5647.json b/src/ipa/raspberrypi/data/ov5647.json
deleted file mode 100644
index 24bc06fb..00000000
--- a/src/ipa/raspberrypi/data/ov5647.json
+++ /dev/null
@@ -1,409 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 1024
- },
- "rpi.dpc":
- {
-
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 21663,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 987,
- "reference_Y": 8961
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 4.25
- },
- "rpi.geq":
- {
- "offset": 401,
- "slope": 0.05619
- },
- "rpi.sdn":
- {
-
- },
- "rpi.awb":
- {
- "priors":
- [
- {
- "lux": 0, "prior":
- [
- 2000, 1.0, 3000, 0.0, 13000, 0.0
- ]
- },
- {
- "lux": 800, "prior":
- [
- 2000, 0.0, 6000, 2.0, 13000, 2.0
- ]
- },
- {
- "lux": 1500, "prior":
- [
- 2000, 0.0, 4000, 1.0, 6000, 6.0, 6500, 7.0, 7000, 1.0, 13000, 1.0
- ]
- }
- ],
- "modes":
- {
- "auto":
- {
- "lo": 2500,
- "hi": 8000
- },
- "incandescent":
- {
- "lo": 2500,
- "hi": 3000
- },
- "tungsten":
- {
- "lo": 3000,
- "hi": 3500
- },
- "fluorescent":
- {
- "lo": 4000,
- "hi": 4700
- },
- "indoor":
- {
- "lo": 3000,
- "hi": 5000
- },
- "daylight":
- {
- "lo": 5500,
- "hi": 6500
- },
- "cloudy":
- {
- "lo": 7000,
- "hi": 8600
- }
- },
- "bayes": 1,
- "ct_curve":
- [
- 2500.0, 1.0289, 0.4503, 2803.0, 0.9428, 0.5108, 2914.0, 0.9406, 0.5127, 3605.0, 0.8261, 0.6249, 4540.0, 0.7331, 0.7533, 5699.0,
- 0.6715, 0.8627, 8625.0, 0.6081, 1.0012
- ],
- "sensitivity_r": 1.05,
- "sensitivity_b": 1.05,
- "transverse_pos": 0.0321,
- "transverse_neg": 0.04313
- },
- "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, 66666
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 33333
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "long":
- {
- "shutter":
- [
- 100, 10000, 30000, 60000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 12.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
- ]
- }
- ],
- "shadows":
- [
- {
- "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target":
- [
- 0, 0.17, 1000, 0.17
- ]
- }
- ]
- },
- "y_target":
- [
- 0, 0.16, 1000, 0.165, 10000, 0.17
- ],
- "base_ev": 1.25
- },
- "rpi.alsc":
- {
- "omega": 1.3,
- "n_iter": 100,
- "luminance_strength": 0.5,
- "calibrations_Cr":
- [
- {
- "ct": 3000, "table":
- [
- 1.105, 1.103, 1.093, 1.083, 1.071, 1.065, 1.065, 1.065, 1.066, 1.069, 1.072, 1.077, 1.084, 1.089, 1.093, 1.093,
- 1.103, 1.096, 1.084, 1.072, 1.059, 1.051, 1.047, 1.047, 1.051, 1.053, 1.059, 1.067, 1.075, 1.082, 1.085, 1.086,
- 1.096, 1.084, 1.072, 1.059, 1.051, 1.045, 1.039, 1.038, 1.039, 1.045, 1.049, 1.057, 1.063, 1.072, 1.081, 1.082,
- 1.092, 1.075, 1.061, 1.052, 1.045, 1.039, 1.036, 1.035, 1.035, 1.039, 1.044, 1.049, 1.056, 1.063, 1.072, 1.081,
- 1.092, 1.073, 1.058, 1.048, 1.043, 1.038, 1.035, 1.033, 1.033, 1.035, 1.039, 1.044, 1.051, 1.057, 1.069, 1.078,
- 1.091, 1.068, 1.054, 1.045, 1.041, 1.038, 1.035, 1.032, 1.032, 1.032, 1.036, 1.041, 1.045, 1.055, 1.069, 1.078,
- 1.091, 1.068, 1.052, 1.043, 1.041, 1.038, 1.035, 1.032, 1.031, 1.032, 1.034, 1.036, 1.043, 1.055, 1.069, 1.078,
- 1.092, 1.068, 1.052, 1.047, 1.042, 1.041, 1.038, 1.035, 1.032, 1.032, 1.035, 1.039, 1.043, 1.055, 1.071, 1.079,
- 1.092, 1.073, 1.057, 1.051, 1.047, 1.047, 1.044, 1.041, 1.038, 1.038, 1.039, 1.043, 1.051, 1.059, 1.076, 1.083,
- 1.092, 1.081, 1.068, 1.058, 1.056, 1.056, 1.053, 1.052, 1.049, 1.048, 1.048, 1.051, 1.059, 1.066, 1.083, 1.085,
- 1.091, 1.087, 1.081, 1.068, 1.065, 1.064, 1.062, 1.062, 1.061, 1.056, 1.056, 1.056, 1.064, 1.069, 1.084, 1.089,
- 1.091, 1.089, 1.085, 1.079, 1.069, 1.068, 1.067, 1.067, 1.067, 1.063, 1.061, 1.063, 1.068, 1.069, 1.081, 1.092
- ]
- },
- {
- "ct": 5000, "table":
- [
- 1.486, 1.484, 1.468, 1.449, 1.427, 1.403, 1.399, 1.399, 1.399, 1.404, 1.413, 1.433, 1.454, 1.473, 1.482, 1.488,
- 1.484, 1.472, 1.454, 1.431, 1.405, 1.381, 1.365, 1.365, 1.367, 1.373, 1.392, 1.411, 1.438, 1.458, 1.476, 1.481,
- 1.476, 1.458, 1.433, 1.405, 1.381, 1.361, 1.339, 1.334, 1.334, 1.346, 1.362, 1.391, 1.411, 1.438, 1.462, 1.474,
- 1.471, 1.443, 1.417, 1.388, 1.361, 1.339, 1.321, 1.313, 1.313, 1.327, 1.346, 1.362, 1.391, 1.422, 1.453, 1.473,
- 1.469, 1.439, 1.408, 1.377, 1.349, 1.321, 1.312, 1.299, 1.299, 1.311, 1.327, 1.348, 1.378, 1.415, 1.446, 1.468,
- 1.468, 1.434, 1.402, 1.371, 1.341, 1.316, 1.299, 1.296, 1.295, 1.299, 1.314, 1.338, 1.371, 1.408, 1.441, 1.466,
- 1.468, 1.434, 1.401, 1.371, 1.341, 1.316, 1.301, 1.296, 1.295, 1.297, 1.314, 1.338, 1.369, 1.408, 1.441, 1.465,
- 1.469, 1.436, 1.401, 1.374, 1.348, 1.332, 1.315, 1.301, 1.301, 1.313, 1.324, 1.342, 1.372, 1.409, 1.442, 1.465,
- 1.471, 1.444, 1.413, 1.388, 1.371, 1.348, 1.332, 1.323, 1.323, 1.324, 1.342, 1.362, 1.386, 1.418, 1.449, 1.467,
- 1.473, 1.454, 1.431, 1.407, 1.388, 1.371, 1.359, 1.352, 1.351, 1.351, 1.362, 1.383, 1.404, 1.433, 1.462, 1.472,
- 1.474, 1.461, 1.447, 1.424, 1.407, 1.394, 1.385, 1.381, 1.379, 1.381, 1.383, 1.401, 1.419, 1.444, 1.466, 1.481,
- 1.474, 1.464, 1.455, 1.442, 1.421, 1.408, 1.403, 1.403, 1.403, 1.399, 1.402, 1.415, 1.432, 1.446, 1.467, 1.483
- ]
- },
- {
- "ct": 6500, "table":
- [
- 1.567, 1.565, 1.555, 1.541, 1.525, 1.518, 1.518, 1.518, 1.521, 1.527, 1.532, 1.541, 1.551, 1.559, 1.567, 1.569,
- 1.565, 1.557, 1.542, 1.527, 1.519, 1.515, 1.511, 1.516, 1.519, 1.524, 1.528, 1.533, 1.542, 1.553, 1.559, 1.562,
- 1.561, 1.546, 1.532, 1.521, 1.518, 1.515, 1.511, 1.516, 1.519, 1.524, 1.528, 1.529, 1.533, 1.542, 1.554, 1.559,
- 1.561, 1.539, 1.526, 1.524, 1.521, 1.521, 1.522, 1.524, 1.525, 1.531, 1.529, 1.529, 1.531, 1.538, 1.549, 1.558,
- 1.559, 1.538, 1.526, 1.525, 1.524, 1.528, 1.534, 1.536, 1.536, 1.536, 1.532, 1.529, 1.531, 1.537, 1.548, 1.556,
- 1.561, 1.537, 1.525, 1.524, 1.526, 1.532, 1.537, 1.539, 1.538, 1.537, 1.532, 1.529, 1.529, 1.537, 1.546, 1.556,
- 1.561, 1.536, 1.524, 1.522, 1.525, 1.532, 1.538, 1.538, 1.537, 1.533, 1.528, 1.526, 1.527, 1.536, 1.546, 1.555,
- 1.561, 1.537, 1.522, 1.521, 1.524, 1.531, 1.536, 1.537, 1.534, 1.529, 1.526, 1.522, 1.523, 1.534, 1.547, 1.555,
- 1.561, 1.538, 1.524, 1.522, 1.526, 1.531, 1.535, 1.535, 1.534, 1.527, 1.524, 1.522, 1.522, 1.535, 1.549, 1.556,
- 1.558, 1.543, 1.532, 1.526, 1.526, 1.529, 1.534, 1.535, 1.533, 1.526, 1.523, 1.522, 1.524, 1.537, 1.552, 1.557,
- 1.555, 1.546, 1.541, 1.528, 1.527, 1.528, 1.531, 1.533, 1.531, 1.527, 1.522, 1.522, 1.526, 1.536, 1.552, 1.561,
- 1.555, 1.547, 1.542, 1.538, 1.526, 1.526, 1.529, 1.531, 1.529, 1.528, 1.519, 1.519, 1.527, 1.531, 1.543, 1.561
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 3000, "table":
- [
- 1.684, 1.688, 1.691, 1.697, 1.709, 1.722, 1.735, 1.745, 1.747, 1.745, 1.731, 1.719, 1.709, 1.705, 1.699, 1.699,
- 1.684, 1.689, 1.694, 1.708, 1.721, 1.735, 1.747, 1.762, 1.762, 1.758, 1.745, 1.727, 1.716, 1.707, 1.701, 1.699,
- 1.684, 1.691, 1.704, 1.719, 1.734, 1.755, 1.772, 1.786, 1.789, 1.788, 1.762, 1.745, 1.724, 1.709, 1.702, 1.698,
- 1.682, 1.694, 1.709, 1.729, 1.755, 1.773, 1.798, 1.815, 1.817, 1.808, 1.788, 1.762, 1.733, 1.714, 1.704, 1.699,
- 1.682, 1.693, 1.713, 1.742, 1.772, 1.798, 1.815, 1.829, 1.831, 1.821, 1.807, 1.773, 1.742, 1.716, 1.703, 1.699,
- 1.681, 1.693, 1.713, 1.742, 1.772, 1.799, 1.828, 1.839, 1.839, 1.828, 1.807, 1.774, 1.742, 1.715, 1.699, 1.695,
- 1.679, 1.691, 1.712, 1.739, 1.771, 1.798, 1.825, 1.829, 1.831, 1.818, 1.801, 1.774, 1.738, 1.712, 1.695, 1.691,
- 1.676, 1.685, 1.703, 1.727, 1.761, 1.784, 1.801, 1.817, 1.817, 1.801, 1.779, 1.761, 1.729, 1.706, 1.691, 1.684,
- 1.669, 1.678, 1.692, 1.714, 1.741, 1.764, 1.784, 1.795, 1.795, 1.779, 1.761, 1.738, 1.713, 1.696, 1.683, 1.679,
- 1.664, 1.671, 1.679, 1.693, 1.716, 1.741, 1.762, 1.769, 1.769, 1.753, 1.738, 1.713, 1.701, 1.687, 1.681, 1.676,
- 1.661, 1.664, 1.671, 1.679, 1.693, 1.714, 1.732, 1.739, 1.739, 1.729, 1.708, 1.701, 1.685, 1.679, 1.676, 1.677,
- 1.659, 1.661, 1.664, 1.671, 1.679, 1.693, 1.712, 1.714, 1.714, 1.708, 1.701, 1.687, 1.679, 1.672, 1.673, 1.677
- ]
- },
- {
- "ct": 5000, "table":
- [
- 1.177, 1.183, 1.187, 1.191, 1.197, 1.206, 1.213, 1.215, 1.215, 1.215, 1.211, 1.204, 1.196, 1.191, 1.183, 1.182,
- 1.179, 1.185, 1.191, 1.196, 1.206, 1.217, 1.224, 1.229, 1.229, 1.226, 1.221, 1.212, 1.202, 1.195, 1.188, 1.182,
- 1.183, 1.191, 1.196, 1.206, 1.217, 1.229, 1.239, 1.245, 1.245, 1.245, 1.233, 1.221, 1.212, 1.199, 1.193, 1.187,
- 1.183, 1.192, 1.201, 1.212, 1.229, 1.241, 1.252, 1.259, 1.259, 1.257, 1.245, 1.233, 1.217, 1.201, 1.194, 1.192,
- 1.183, 1.192, 1.202, 1.219, 1.238, 1.252, 1.261, 1.269, 1.268, 1.261, 1.257, 1.241, 1.223, 1.204, 1.194, 1.191,
- 1.182, 1.192, 1.202, 1.219, 1.239, 1.255, 1.266, 1.271, 1.271, 1.265, 1.258, 1.242, 1.223, 1.205, 1.192, 1.191,
- 1.181, 1.189, 1.199, 1.218, 1.239, 1.254, 1.262, 1.268, 1.268, 1.258, 1.253, 1.241, 1.221, 1.204, 1.191, 1.187,
- 1.179, 1.184, 1.193, 1.211, 1.232, 1.243, 1.254, 1.257, 1.256, 1.253, 1.242, 1.232, 1.216, 1.199, 1.187, 1.183,
- 1.174, 1.179, 1.187, 1.202, 1.218, 1.232, 1.243, 1.246, 1.246, 1.239, 1.232, 1.218, 1.207, 1.191, 1.183, 1.179,
- 1.169, 1.175, 1.181, 1.189, 1.202, 1.218, 1.229, 1.232, 1.232, 1.224, 1.218, 1.207, 1.199, 1.185, 1.181, 1.174,
- 1.164, 1.168, 1.175, 1.179, 1.189, 1.201, 1.209, 1.213, 1.213, 1.209, 1.201, 1.198, 1.186, 1.181, 1.174, 1.173,
- 1.161, 1.166, 1.171, 1.175, 1.179, 1.189, 1.197, 1.198, 1.198, 1.197, 1.196, 1.186, 1.182, 1.175, 1.173, 1.173
- ]
- },
- {
- "ct": 6500, "table":
- [
- 1.166, 1.171, 1.173, 1.178, 1.187, 1.193, 1.201, 1.205, 1.205, 1.205, 1.199, 1.191, 1.184, 1.179, 1.174, 1.171,
- 1.166, 1.172, 1.176, 1.184, 1.195, 1.202, 1.209, 1.216, 1.216, 1.213, 1.208, 1.201, 1.189, 1.182, 1.176, 1.171,
- 1.166, 1.173, 1.183, 1.195, 1.202, 1.214, 1.221, 1.228, 1.229, 1.228, 1.221, 1.209, 1.201, 1.186, 1.179, 1.174,
- 1.165, 1.174, 1.187, 1.201, 1.214, 1.223, 1.235, 1.241, 1.242, 1.241, 1.229, 1.221, 1.205, 1.188, 1.181, 1.177,
- 1.165, 1.174, 1.189, 1.207, 1.223, 1.235, 1.242, 1.253, 1.252, 1.245, 1.241, 1.228, 1.211, 1.189, 1.181, 1.178,
- 1.164, 1.173, 1.189, 1.207, 1.224, 1.238, 1.249, 1.255, 1.255, 1.249, 1.242, 1.228, 1.211, 1.191, 1.179, 1.176,
- 1.163, 1.172, 1.187, 1.207, 1.223, 1.237, 1.245, 1.253, 1.252, 1.243, 1.237, 1.228, 1.207, 1.188, 1.176, 1.173,
- 1.159, 1.167, 1.179, 1.199, 1.217, 1.227, 1.237, 1.241, 1.241, 1.237, 1.228, 1.217, 1.201, 1.184, 1.174, 1.169,
- 1.156, 1.164, 1.172, 1.189, 1.205, 1.217, 1.226, 1.229, 1.229, 1.222, 1.217, 1.204, 1.192, 1.177, 1.171, 1.166,
- 1.154, 1.159, 1.166, 1.177, 1.189, 1.205, 1.213, 1.216, 1.216, 1.209, 1.204, 1.192, 1.183, 1.172, 1.168, 1.162,
- 1.152, 1.155, 1.161, 1.166, 1.177, 1.188, 1.195, 1.198, 1.199, 1.196, 1.187, 1.183, 1.173, 1.168, 1.163, 1.162,
- 1.151, 1.154, 1.158, 1.162, 1.168, 1.177, 1.183, 1.184, 1.184, 1.184, 1.182, 1.172, 1.168, 1.165, 1.162, 1.161
- ]
- }
- ],
- "luminance_lut":
- [
- 2.236, 2.111, 1.912, 1.741, 1.579, 1.451, 1.379, 1.349, 1.349, 1.361, 1.411, 1.505, 1.644, 1.816, 2.034, 2.159,
- 2.139, 1.994, 1.796, 1.625, 1.467, 1.361, 1.285, 1.248, 1.239, 1.265, 1.321, 1.408, 1.536, 1.703, 1.903, 2.087,
- 2.047, 1.898, 1.694, 1.511, 1.373, 1.254, 1.186, 1.152, 1.142, 1.166, 1.226, 1.309, 1.441, 1.598, 1.799, 1.978,
- 1.999, 1.824, 1.615, 1.429, 1.281, 1.179, 1.113, 1.077, 1.071, 1.096, 1.153, 1.239, 1.357, 1.525, 1.726, 1.915,
- 1.976, 1.773, 1.563, 1.374, 1.222, 1.119, 1.064, 1.032, 1.031, 1.049, 1.099, 1.188, 1.309, 1.478, 1.681, 1.893,
- 1.973, 1.756, 1.542, 1.351, 1.196, 1.088, 1.028, 1.011, 1.004, 1.029, 1.077, 1.169, 1.295, 1.459, 1.663, 1.891,
- 1.973, 1.761, 1.541, 1.349, 1.193, 1.087, 1.031, 1.006, 1.006, 1.023, 1.075, 1.169, 1.298, 1.463, 1.667, 1.891,
- 1.982, 1.789, 1.568, 1.373, 1.213, 1.111, 1.051, 1.029, 1.024, 1.053, 1.106, 1.199, 1.329, 1.495, 1.692, 1.903,
- 2.015, 1.838, 1.621, 1.426, 1.268, 1.159, 1.101, 1.066, 1.068, 1.099, 1.166, 1.259, 1.387, 1.553, 1.751, 1.937,
- 2.076, 1.911, 1.692, 1.507, 1.346, 1.236, 1.169, 1.136, 1.139, 1.174, 1.242, 1.349, 1.475, 1.641, 1.833, 2.004,
- 2.193, 2.011, 1.798, 1.604, 1.444, 1.339, 1.265, 1.235, 1.237, 1.273, 1.351, 1.461, 1.598, 1.758, 1.956, 2.125,
- 2.263, 2.154, 1.916, 1.711, 1.549, 1.432, 1.372, 1.356, 1.356, 1.383, 1.455, 1.578, 1.726, 1.914, 2.119, 2.211
- ],
- "sigma": 0.006,
- "sigma_Cb": 0.00208
- },
- "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": 2500, "ccm":
- [
- 1.70741, -0.05307, -0.65433, -0.62822, 1.68836, -0.06014, -0.04452, -1.87628, 2.92079
- ]
- },
- {
- "ct": 2803, "ccm":
- [
- 1.74383, -0.18731, -0.55652, -0.56491, 1.67772, -0.11281, -0.01522, -1.60635, 2.62157
- ]
- },
- {
- "ct": 2912, "ccm":
- [
- 1.75215, -0.22221, -0.52995, -0.54568, 1.63522, -0.08954, 0.02633, -1.56997, 2.54364
- ]
- },
- {
- "ct": 2914, "ccm":
- [
- 1.72423, -0.28939, -0.43484, -0.55188, 1.62925, -0.07737, 0.01959, -1.28661, 2.26702
- ]
- },
- {
- "ct": 3605, "ccm":
- [
- 1.80381, -0.43646, -0.36735, -0.46505, 1.56814, -0.10309, 0.00929, -1.00424, 1.99495
- ]
- },
- {
- "ct": 4540, "ccm":
- [
- 1.85263, -0.46545, -0.38719, -0.44136, 1.68443, -0.24307, 0.04108, -0.85599, 1.81491
- ]
- },
- {
- "ct": 5699, "ccm":
- [
- 1.98595, -0.63542, -0.35054, -0.34623, 1.54146, -0.19522, 0.00411, -0.70936, 1.70525
- ]
- },
- {
- "ct": 8625, "ccm":
- [
- 2.21637, -0.56663, -0.64974, -0.41133, 1.96625, -0.55492, -0.02307, -0.83529, 1.85837
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
-
- }
-}
diff --git a/src/ipa/raspberrypi/data/ov5647_noir.json b/src/ipa/raspberrypi/data/ov5647_noir.json
deleted file mode 100644
index 1c628ed1..00000000
--- a/src/ipa/raspberrypi/data/ov5647_noir.json
+++ /dev/null
@@ -1,341 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 1024
- },
- "rpi.dpc":
- {
-
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 21663,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 987,
- "reference_Y": 8961
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 4.25
- },
- "rpi.geq":
- {
- "offset": 401,
- "slope": 0.05619
- },
- "rpi.sdn":
- {
-
- },
- "rpi.awb":
- {
- "bayes": 0
- },
- "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, 66666
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 33333
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.0
- ]
- },
- "long":
- {
- "shutter":
- [
- 100, 10000, 30000, 60000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 12.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
- ]
- }
- ],
- "shadows":
- [
- {
- "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target":
- [
- 0, 0.17, 1000, 0.17
- ]
- }
- ]
- },
- "y_target":
- [
- 0, 0.16, 1000, 0.165, 10000, 0.17
- ],
- "base_ev": 1.25
- },
- "rpi.alsc":
- {
- "omega": 1.3,
- "n_iter": 100,
- "luminance_strength": 0.5,
- "calibrations_Cr":
- [
- {
- "ct": 3000, "table":
- [
- 1.105, 1.103, 1.093, 1.083, 1.071, 1.065, 1.065, 1.065, 1.066, 1.069, 1.072, 1.077, 1.084, 1.089, 1.093, 1.093,
- 1.103, 1.096, 1.084, 1.072, 1.059, 1.051, 1.047, 1.047, 1.051, 1.053, 1.059, 1.067, 1.075, 1.082, 1.085, 1.086,
- 1.096, 1.084, 1.072, 1.059, 1.051, 1.045, 1.039, 1.038, 1.039, 1.045, 1.049, 1.057, 1.063, 1.072, 1.081, 1.082,
- 1.092, 1.075, 1.061, 1.052, 1.045, 1.039, 1.036, 1.035, 1.035, 1.039, 1.044, 1.049, 1.056, 1.063, 1.072, 1.081,
- 1.092, 1.073, 1.058, 1.048, 1.043, 1.038, 1.035, 1.033, 1.033, 1.035, 1.039, 1.044, 1.051, 1.057, 1.069, 1.078,
- 1.091, 1.068, 1.054, 1.045, 1.041, 1.038, 1.035, 1.032, 1.032, 1.032, 1.036, 1.041, 1.045, 1.055, 1.069, 1.078,
- 1.091, 1.068, 1.052, 1.043, 1.041, 1.038, 1.035, 1.032, 1.031, 1.032, 1.034, 1.036, 1.043, 1.055, 1.069, 1.078,
- 1.092, 1.068, 1.052, 1.047, 1.042, 1.041, 1.038, 1.035, 1.032, 1.032, 1.035, 1.039, 1.043, 1.055, 1.071, 1.079,
- 1.092, 1.073, 1.057, 1.051, 1.047, 1.047, 1.044, 1.041, 1.038, 1.038, 1.039, 1.043, 1.051, 1.059, 1.076, 1.083,
- 1.092, 1.081, 1.068, 1.058, 1.056, 1.056, 1.053, 1.052, 1.049, 1.048, 1.048, 1.051, 1.059, 1.066, 1.083, 1.085,
- 1.091, 1.087, 1.081, 1.068, 1.065, 1.064, 1.062, 1.062, 1.061, 1.056, 1.056, 1.056, 1.064, 1.069, 1.084, 1.089,
- 1.091, 1.089, 1.085, 1.079, 1.069, 1.068, 1.067, 1.067, 1.067, 1.063, 1.061, 1.063, 1.068, 1.069, 1.081, 1.092
- ]
- },
- {
- "ct": 5000, "table":
- [
- 1.486, 1.484, 1.468, 1.449, 1.427, 1.403, 1.399, 1.399, 1.399, 1.404, 1.413, 1.433, 1.454, 1.473, 1.482, 1.488,
- 1.484, 1.472, 1.454, 1.431, 1.405, 1.381, 1.365, 1.365, 1.367, 1.373, 1.392, 1.411, 1.438, 1.458, 1.476, 1.481,
- 1.476, 1.458, 1.433, 1.405, 1.381, 1.361, 1.339, 1.334, 1.334, 1.346, 1.362, 1.391, 1.411, 1.438, 1.462, 1.474,
- 1.471, 1.443, 1.417, 1.388, 1.361, 1.339, 1.321, 1.313, 1.313, 1.327, 1.346, 1.362, 1.391, 1.422, 1.453, 1.473,
- 1.469, 1.439, 1.408, 1.377, 1.349, 1.321, 1.312, 1.299, 1.299, 1.311, 1.327, 1.348, 1.378, 1.415, 1.446, 1.468,
- 1.468, 1.434, 1.402, 1.371, 1.341, 1.316, 1.299, 1.296, 1.295, 1.299, 1.314, 1.338, 1.371, 1.408, 1.441, 1.466,
- 1.468, 1.434, 1.401, 1.371, 1.341, 1.316, 1.301, 1.296, 1.295, 1.297, 1.314, 1.338, 1.369, 1.408, 1.441, 1.465,
- 1.469, 1.436, 1.401, 1.374, 1.348, 1.332, 1.315, 1.301, 1.301, 1.313, 1.324, 1.342, 1.372, 1.409, 1.442, 1.465,
- 1.471, 1.444, 1.413, 1.388, 1.371, 1.348, 1.332, 1.323, 1.323, 1.324, 1.342, 1.362, 1.386, 1.418, 1.449, 1.467,
- 1.473, 1.454, 1.431, 1.407, 1.388, 1.371, 1.359, 1.352, 1.351, 1.351, 1.362, 1.383, 1.404, 1.433, 1.462, 1.472,
- 1.474, 1.461, 1.447, 1.424, 1.407, 1.394, 1.385, 1.381, 1.379, 1.381, 1.383, 1.401, 1.419, 1.444, 1.466, 1.481,
- 1.474, 1.464, 1.455, 1.442, 1.421, 1.408, 1.403, 1.403, 1.403, 1.399, 1.402, 1.415, 1.432, 1.446, 1.467, 1.483
- ]
- },
- {
- "ct": 6500, "table":
- [
- 1.567, 1.565, 1.555, 1.541, 1.525, 1.518, 1.518, 1.518, 1.521, 1.527, 1.532, 1.541, 1.551, 1.559, 1.567, 1.569,
- 1.565, 1.557, 1.542, 1.527, 1.519, 1.515, 1.511, 1.516, 1.519, 1.524, 1.528, 1.533, 1.542, 1.553, 1.559, 1.562,
- 1.561, 1.546, 1.532, 1.521, 1.518, 1.515, 1.511, 1.516, 1.519, 1.524, 1.528, 1.529, 1.533, 1.542, 1.554, 1.559,
- 1.561, 1.539, 1.526, 1.524, 1.521, 1.521, 1.522, 1.524, 1.525, 1.531, 1.529, 1.529, 1.531, 1.538, 1.549, 1.558,
- 1.559, 1.538, 1.526, 1.525, 1.524, 1.528, 1.534, 1.536, 1.536, 1.536, 1.532, 1.529, 1.531, 1.537, 1.548, 1.556,
- 1.561, 1.537, 1.525, 1.524, 1.526, 1.532, 1.537, 1.539, 1.538, 1.537, 1.532, 1.529, 1.529, 1.537, 1.546, 1.556,
- 1.561, 1.536, 1.524, 1.522, 1.525, 1.532, 1.538, 1.538, 1.537, 1.533, 1.528, 1.526, 1.527, 1.536, 1.546, 1.555,
- 1.561, 1.537, 1.522, 1.521, 1.524, 1.531, 1.536, 1.537, 1.534, 1.529, 1.526, 1.522, 1.523, 1.534, 1.547, 1.555,
- 1.561, 1.538, 1.524, 1.522, 1.526, 1.531, 1.535, 1.535, 1.534, 1.527, 1.524, 1.522, 1.522, 1.535, 1.549, 1.556,
- 1.558, 1.543, 1.532, 1.526, 1.526, 1.529, 1.534, 1.535, 1.533, 1.526, 1.523, 1.522, 1.524, 1.537, 1.552, 1.557,
- 1.555, 1.546, 1.541, 1.528, 1.527, 1.528, 1.531, 1.533, 1.531, 1.527, 1.522, 1.522, 1.526, 1.536, 1.552, 1.561,
- 1.555, 1.547, 1.542, 1.538, 1.526, 1.526, 1.529, 1.531, 1.529, 1.528, 1.519, 1.519, 1.527, 1.531, 1.543, 1.561
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 3000, "table":
- [
- 1.684, 1.688, 1.691, 1.697, 1.709, 1.722, 1.735, 1.745, 1.747, 1.745, 1.731, 1.719, 1.709, 1.705, 1.699, 1.699,
- 1.684, 1.689, 1.694, 1.708, 1.721, 1.735, 1.747, 1.762, 1.762, 1.758, 1.745, 1.727, 1.716, 1.707, 1.701, 1.699,
- 1.684, 1.691, 1.704, 1.719, 1.734, 1.755, 1.772, 1.786, 1.789, 1.788, 1.762, 1.745, 1.724, 1.709, 1.702, 1.698,
- 1.682, 1.694, 1.709, 1.729, 1.755, 1.773, 1.798, 1.815, 1.817, 1.808, 1.788, 1.762, 1.733, 1.714, 1.704, 1.699,
- 1.682, 1.693, 1.713, 1.742, 1.772, 1.798, 1.815, 1.829, 1.831, 1.821, 1.807, 1.773, 1.742, 1.716, 1.703, 1.699,
- 1.681, 1.693, 1.713, 1.742, 1.772, 1.799, 1.828, 1.839, 1.839, 1.828, 1.807, 1.774, 1.742, 1.715, 1.699, 1.695,
- 1.679, 1.691, 1.712, 1.739, 1.771, 1.798, 1.825, 1.829, 1.831, 1.818, 1.801, 1.774, 1.738, 1.712, 1.695, 1.691,
- 1.676, 1.685, 1.703, 1.727, 1.761, 1.784, 1.801, 1.817, 1.817, 1.801, 1.779, 1.761, 1.729, 1.706, 1.691, 1.684,
- 1.669, 1.678, 1.692, 1.714, 1.741, 1.764, 1.784, 1.795, 1.795, 1.779, 1.761, 1.738, 1.713, 1.696, 1.683, 1.679,
- 1.664, 1.671, 1.679, 1.693, 1.716, 1.741, 1.762, 1.769, 1.769, 1.753, 1.738, 1.713, 1.701, 1.687, 1.681, 1.676,
- 1.661, 1.664, 1.671, 1.679, 1.693, 1.714, 1.732, 1.739, 1.739, 1.729, 1.708, 1.701, 1.685, 1.679, 1.676, 1.677,
- 1.659, 1.661, 1.664, 1.671, 1.679, 1.693, 1.712, 1.714, 1.714, 1.708, 1.701, 1.687, 1.679, 1.672, 1.673, 1.677
- ]
- },
- {
- "ct": 5000, "table":
- [
- 1.177, 1.183, 1.187, 1.191, 1.197, 1.206, 1.213, 1.215, 1.215, 1.215, 1.211, 1.204, 1.196, 1.191, 1.183, 1.182,
- 1.179, 1.185, 1.191, 1.196, 1.206, 1.217, 1.224, 1.229, 1.229, 1.226, 1.221, 1.212, 1.202, 1.195, 1.188, 1.182,
- 1.183, 1.191, 1.196, 1.206, 1.217, 1.229, 1.239, 1.245, 1.245, 1.245, 1.233, 1.221, 1.212, 1.199, 1.193, 1.187,
- 1.183, 1.192, 1.201, 1.212, 1.229, 1.241, 1.252, 1.259, 1.259, 1.257, 1.245, 1.233, 1.217, 1.201, 1.194, 1.192,
- 1.183, 1.192, 1.202, 1.219, 1.238, 1.252, 1.261, 1.269, 1.268, 1.261, 1.257, 1.241, 1.223, 1.204, 1.194, 1.191,
- 1.182, 1.192, 1.202, 1.219, 1.239, 1.255, 1.266, 1.271, 1.271, 1.265, 1.258, 1.242, 1.223, 1.205, 1.192, 1.191,
- 1.181, 1.189, 1.199, 1.218, 1.239, 1.254, 1.262, 1.268, 1.268, 1.258, 1.253, 1.241, 1.221, 1.204, 1.191, 1.187,
- 1.179, 1.184, 1.193, 1.211, 1.232, 1.243, 1.254, 1.257, 1.256, 1.253, 1.242, 1.232, 1.216, 1.199, 1.187, 1.183,
- 1.174, 1.179, 1.187, 1.202, 1.218, 1.232, 1.243, 1.246, 1.246, 1.239, 1.232, 1.218, 1.207, 1.191, 1.183, 1.179,
- 1.169, 1.175, 1.181, 1.189, 1.202, 1.218, 1.229, 1.232, 1.232, 1.224, 1.218, 1.207, 1.199, 1.185, 1.181, 1.174,
- 1.164, 1.168, 1.175, 1.179, 1.189, 1.201, 1.209, 1.213, 1.213, 1.209, 1.201, 1.198, 1.186, 1.181, 1.174, 1.173,
- 1.161, 1.166, 1.171, 1.175, 1.179, 1.189, 1.197, 1.198, 1.198, 1.197, 1.196, 1.186, 1.182, 1.175, 1.173, 1.173
- ]
- },
- {
- "ct": 6500, "table":
- [
- 1.166, 1.171, 1.173, 1.178, 1.187, 1.193, 1.201, 1.205, 1.205, 1.205, 1.199, 1.191, 1.184, 1.179, 1.174, 1.171,
- 1.166, 1.172, 1.176, 1.184, 1.195, 1.202, 1.209, 1.216, 1.216, 1.213, 1.208, 1.201, 1.189, 1.182, 1.176, 1.171,
- 1.166, 1.173, 1.183, 1.195, 1.202, 1.214, 1.221, 1.228, 1.229, 1.228, 1.221, 1.209, 1.201, 1.186, 1.179, 1.174,
- 1.165, 1.174, 1.187, 1.201, 1.214, 1.223, 1.235, 1.241, 1.242, 1.241, 1.229, 1.221, 1.205, 1.188, 1.181, 1.177,
- 1.165, 1.174, 1.189, 1.207, 1.223, 1.235, 1.242, 1.253, 1.252, 1.245, 1.241, 1.228, 1.211, 1.189, 1.181, 1.178,
- 1.164, 1.173, 1.189, 1.207, 1.224, 1.238, 1.249, 1.255, 1.255, 1.249, 1.242, 1.228, 1.211, 1.191, 1.179, 1.176,
- 1.163, 1.172, 1.187, 1.207, 1.223, 1.237, 1.245, 1.253, 1.252, 1.243, 1.237, 1.228, 1.207, 1.188, 1.176, 1.173,
- 1.159, 1.167, 1.179, 1.199, 1.217, 1.227, 1.237, 1.241, 1.241, 1.237, 1.228, 1.217, 1.201, 1.184, 1.174, 1.169,
- 1.156, 1.164, 1.172, 1.189, 1.205, 1.217, 1.226, 1.229, 1.229, 1.222, 1.217, 1.204, 1.192, 1.177, 1.171, 1.166,
- 1.154, 1.159, 1.166, 1.177, 1.189, 1.205, 1.213, 1.216, 1.216, 1.209, 1.204, 1.192, 1.183, 1.172, 1.168, 1.162,
- 1.152, 1.155, 1.161, 1.166, 1.177, 1.188, 1.195, 1.198, 1.199, 1.196, 1.187, 1.183, 1.173, 1.168, 1.163, 1.162,
- 1.151, 1.154, 1.158, 1.162, 1.168, 1.177, 1.183, 1.184, 1.184, 1.184, 1.182, 1.172, 1.168, 1.165, 1.162, 1.161
- ]
- }
- ],
- "luminance_lut":
- [
- 2.236, 2.111, 1.912, 1.741, 1.579, 1.451, 1.379, 1.349, 1.349, 1.361, 1.411, 1.505, 1.644, 1.816, 2.034, 2.159,
- 2.139, 1.994, 1.796, 1.625, 1.467, 1.361, 1.285, 1.248, 1.239, 1.265, 1.321, 1.408, 1.536, 1.703, 1.903, 2.087,
- 2.047, 1.898, 1.694, 1.511, 1.373, 1.254, 1.186, 1.152, 1.142, 1.166, 1.226, 1.309, 1.441, 1.598, 1.799, 1.978,
- 1.999, 1.824, 1.615, 1.429, 1.281, 1.179, 1.113, 1.077, 1.071, 1.096, 1.153, 1.239, 1.357, 1.525, 1.726, 1.915,
- 1.976, 1.773, 1.563, 1.374, 1.222, 1.119, 1.064, 1.032, 1.031, 1.049, 1.099, 1.188, 1.309, 1.478, 1.681, 1.893,
- 1.973, 1.756, 1.542, 1.351, 1.196, 1.088, 1.028, 1.011, 1.004, 1.029, 1.077, 1.169, 1.295, 1.459, 1.663, 1.891,
- 1.973, 1.761, 1.541, 1.349, 1.193, 1.087, 1.031, 1.006, 1.006, 1.023, 1.075, 1.169, 1.298, 1.463, 1.667, 1.891,
- 1.982, 1.789, 1.568, 1.373, 1.213, 1.111, 1.051, 1.029, 1.024, 1.053, 1.106, 1.199, 1.329, 1.495, 1.692, 1.903,
- 2.015, 1.838, 1.621, 1.426, 1.268, 1.159, 1.101, 1.066, 1.068, 1.099, 1.166, 1.259, 1.387, 1.553, 1.751, 1.937,
- 2.076, 1.911, 1.692, 1.507, 1.346, 1.236, 1.169, 1.136, 1.139, 1.174, 1.242, 1.349, 1.475, 1.641, 1.833, 2.004,
- 2.193, 2.011, 1.798, 1.604, 1.444, 1.339, 1.265, 1.235, 1.237, 1.273, 1.351, 1.461, 1.598, 1.758, 1.956, 2.125,
- 2.263, 2.154, 1.916, 1.711, 1.549, 1.432, 1.372, 1.356, 1.356, 1.383, 1.455, 1.578, 1.726, 1.914, 2.119, 2.211
- ],
- "sigma": 0.006,
- "sigma_Cb": 0.00208
- },
- "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": 2500, "ccm":
- [
- 1.70741, -0.05307, -0.65433, -0.62822, 1.68836, -0.06014, -0.04452, -1.87628, 2.92079
- ]
- },
- {
- "ct": 2803, "ccm":
- [
- 1.74383, -0.18731, -0.55652, -0.56491, 1.67772, -0.11281, -0.01522, -1.60635, 2.62157
- ]
- },
- {
- "ct": 2912, "ccm":
- [
- 1.75215, -0.22221, -0.52995, -0.54568, 1.63522, -0.08954, 0.02633, -1.56997, 2.54364
- ]
- },
- {
- "ct": 2914, "ccm":
- [
- 1.72423, -0.28939, -0.43484, -0.55188, 1.62925, -0.07737, 0.01959, -1.28661, 2.26702
- ]
- },
- {
- "ct": 3605, "ccm":
- [
- 1.80381, -0.43646, -0.36735, -0.46505, 1.56814, -0.10309, 0.00929, -1.00424, 1.99495
- ]
- },
- {
- "ct": 4540, "ccm":
- [
- 1.85263, -0.46545, -0.38719, -0.44136, 1.68443, -0.24307, 0.04108, -0.85599, 1.81491
- ]
- },
- {
- "ct": 5699, "ccm":
- [
- 1.98595, -0.63542, -0.35054, -0.34623, 1.54146, -0.19522, 0.00411, -0.70936, 1.70525
- ]
- },
- {
- "ct": 8625, "ccm":
- [
- 2.21637, -0.56663, -0.64974, -0.41133, 1.96625, -0.55492, -0.02307, -0.83529, 1.85837
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
-
- }
-}
diff --git a/src/ipa/raspberrypi/data/ov9281.json b/src/ipa/raspberrypi/data/ov9281.json
deleted file mode 100644
index 2319448b..00000000
--- a/src/ipa/raspberrypi/data/ov9281.json
+++ /dev/null
@@ -1,92 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 2000,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 800,
- "reference_Y": 20000
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 2.5
- },
- "rpi.sdn":
- {
- },
- "rpi.agc":
- {
- "metering_modes":
- {
- "centre-weighted": {
- "weights": [4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0]
- }
- },
- "exposure_modes":
- {
- "normal":
- {
- "shutter": [ 100, 15000, 30000, 60000, 120000 ],
- "gain": [ 1.0, 2.0, 3.0, 4.0, 8.0 ]
- }
- },
- "constraint_modes":
- {
- "normal":
- [
- { "bound": "LOWER", "q_lo": 0.98, "q_hi": 1.0, "y_target": [ 0, 0.4, 1000, 0.4 ] }
- ]
- },
- "y_target": [ 0, 0.16, 1000, 0.165, 10000, 0.17 ]
- },
- "rpi.alsc":
- {
- "n_iter": 0,
- "luminance_strength": 1.0,
- "corner_strength": 1.5
- },
- "rpi.contrast":
- {
- "ce_enable": 0,
- "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
- ]
- }
-}
diff --git a/src/ipa/raspberrypi/data/se327m12.json b/src/ipa/raspberrypi/data/se327m12.json
deleted file mode 100644
index 94af2239..00000000
--- a/src/ipa/raspberrypi/data/se327m12.json
+++ /dev/null
@@ -1,341 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 3840
- },
- "rpi.dpc":
- {
- },
- "rpi.lux":
- {
- "reference_shutter_speed": 6873,
- "reference_gain": 1.0,
- "reference_aperture": 1.0,
- "reference_lux": 800,
- "reference_Y": 12293
- },
- "rpi.noise":
- {
- "reference_constant": 0,
- "reference_slope": 1.986
- },
- "rpi.geq":
- {
- "offset": 207,
- "slope": 0.00539
- },
- "rpi.sdn":
- {
- },
- "rpi.awb":
- {
- "priors":
- [
- {
- "lux": 0, "prior":
- [
- 2000, 1.0, 3000, 0.0, 13000, 0.0
- ]
- },
- {
- "lux": 800, "prior":
- [
- 2000, 0.0, 6000, 2.0, 13000, 2.0
- ]
- },
- {
- "lux": 1500, "prior":
- [
- 2000, 0.0, 4000, 1.0, 6000, 6.0, 6500, 7.0, 7000, 1.0, 13000, 1.0
- ]
- }
- ],
- "modes":
- {
- "auto":
- {
- "lo": 2500,
- "hi": 8000
- },
- "incandescent":
- {
- "lo": 2500,
- "hi": 3000
- },
- "tungsten":
- {
- "lo": 3000,
- "hi": 3500
- },
- "fluorescent":
- {
- "lo": 4000,
- "hi": 4700
- },
- "indoor":
- {
- "lo": 3000,
- "hi": 5000
- },
- "daylight":
- {
- "lo": 5500,
- "hi": 6500
- },
- "cloudy":
- {
- "lo": 7000,
- "hi": 8600
- }
- },
- "bayes": 1,
- "ct_curve":
- [
- 2900.0, 0.9217, 0.3657, 3600.0, 0.7876, 0.4651, 4600.0, 0.6807, 0.5684, 5800.0, 0.5937, 0.6724, 8100.0, 0.5447, 0.7403
- ],
- "sensitivity_r": 1.0,
- "sensitivity_b": 1.0,
- "transverse_pos": 0.0162,
- "transverse_neg": 0.0204
- },
- "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, 8.0
- ]
- },
- "short":
- {
- "shutter":
- [
- 100, 5000, 10000, 20000, 120000
- ],
- "gain":
- [
- 1.0, 2.0, 4.0, 6.0, 8.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": 4000, "table":
- [
- 1.481, 1.471, 1.449, 1.429, 1.416, 1.404, 1.394, 1.389, 1.389, 1.389, 1.392, 1.397, 1.404, 1.416, 1.429, 1.437,
- 1.472, 1.456, 1.436, 1.418, 1.405, 1.394, 1.389, 1.384, 1.382, 1.382, 1.386, 1.388, 1.398, 1.407, 1.422, 1.429,
- 1.465, 1.443, 1.426, 1.411, 1.397, 1.389, 1.383, 1.377, 1.377, 1.377, 1.379, 1.384, 1.388, 1.398, 1.411, 1.422,
- 1.462, 1.441, 1.423, 1.409, 1.395, 1.385, 1.379, 1.376, 1.374, 1.374, 1.375, 1.379, 1.384, 1.394, 1.407, 1.418,
- 1.461, 1.439, 1.421, 1.407, 1.394, 1.385, 1.381, 1.376, 1.373, 1.373, 1.373, 1.376, 1.381, 1.389, 1.403, 1.415,
- 1.461, 1.439, 1.419, 1.404, 1.392, 1.384, 1.379, 1.376, 1.373, 1.372, 1.374, 1.375, 1.379, 1.389, 1.401, 1.413,
- 1.461, 1.438, 1.419, 1.402, 1.389, 1.383, 1.377, 1.375, 1.373, 1.372, 1.372, 1.375, 1.381, 1.388, 1.401, 1.414,
- 1.462, 1.438, 1.419, 1.403, 1.391, 1.381, 1.377, 1.374, 1.373, 1.373, 1.374, 1.376, 1.381, 1.389, 1.401, 1.414,
- 1.462, 1.441, 1.423, 1.405, 1.392, 1.383, 1.377, 1.374, 1.373, 1.372, 1.373, 1.376, 1.382, 1.391, 1.402, 1.414,
- 1.465, 1.444, 1.424, 1.407, 1.393, 1.382, 1.378, 1.373, 1.369, 1.369, 1.372, 1.375, 1.381, 1.389, 1.402, 1.417,
- 1.469, 1.449, 1.427, 1.413, 1.396, 1.384, 1.381, 1.375, 1.371, 1.371, 1.373, 1.377, 1.385, 1.393, 1.407, 1.422,
- 1.474, 1.456, 1.436, 1.419, 1.407, 1.391, 1.383, 1.379, 1.377, 1.377, 1.378, 1.381, 1.391, 1.404, 1.422, 1.426
- ]
- },
- {
- "ct": 5000, "table":
- [
- 1.742, 1.721, 1.689, 1.661, 1.639, 1.623, 1.613, 1.609, 1.607, 1.606, 1.609, 1.617, 1.626, 1.641, 1.665, 1.681,
- 1.728, 1.703, 1.672, 1.645, 1.631, 1.614, 1.602, 1.599, 1.596, 1.597, 1.601, 1.608, 1.618, 1.631, 1.653, 1.671,
- 1.713, 1.691, 1.658, 1.635, 1.618, 1.606, 1.595, 1.591, 1.588, 1.588, 1.591, 1.601, 1.608, 1.624, 1.641, 1.658,
- 1.707, 1.681, 1.651, 1.627, 1.613, 1.599, 1.591, 1.585, 1.583, 1.584, 1.587, 1.591, 1.601, 1.615, 1.633, 1.655,
- 1.699, 1.672, 1.644, 1.622, 1.606, 1.593, 1.586, 1.581, 1.579, 1.581, 1.583, 1.587, 1.597, 1.611, 1.631, 1.652,
- 1.697, 1.665, 1.637, 1.617, 1.601, 1.589, 1.584, 1.579, 1.577, 1.578, 1.581, 1.585, 1.597, 1.607, 1.627, 1.652,
- 1.697, 1.662, 1.634, 1.613, 1.599, 1.591, 1.583, 1.578, 1.576, 1.576, 1.579, 1.586, 1.597, 1.607, 1.628, 1.653,
- 1.697, 1.662, 1.633, 1.613, 1.598, 1.589, 1.582, 1.578, 1.576, 1.577, 1.582, 1.589, 1.598, 1.611, 1.635, 1.655,
- 1.701, 1.666, 1.636, 1.616, 1.602, 1.589, 1.583, 1.578, 1.577, 1.581, 1.583, 1.591, 1.601, 1.617, 1.639, 1.659,
- 1.708, 1.671, 1.641, 1.618, 1.603, 1.591, 1.584, 1.581, 1.578, 1.581, 1.585, 1.594, 1.604, 1.622, 1.646, 1.666,
- 1.714, 1.681, 1.648, 1.622, 1.608, 1.599, 1.591, 1.584, 1.583, 1.584, 1.589, 1.599, 1.614, 1.629, 1.653, 1.673,
- 1.719, 1.691, 1.659, 1.631, 1.618, 1.606, 1.596, 1.591, 1.591, 1.593, 1.599, 1.608, 1.623, 1.642, 1.665, 1.681
- ]
- }
- ],
- "calibrations_Cb":
- [
- {
- "ct": 4000, "table":
- [
- 2.253, 2.267, 2.289, 2.317, 2.342, 2.359, 2.373, 2.381, 2.381, 2.378, 2.368, 2.361, 2.344, 2.337, 2.314, 2.301,
- 2.262, 2.284, 2.314, 2.335, 2.352, 2.371, 2.383, 2.391, 2.393, 2.391, 2.381, 2.368, 2.361, 2.342, 2.322, 2.308,
- 2.277, 2.303, 2.321, 2.346, 2.364, 2.381, 2.391, 2.395, 2.397, 2.397, 2.395, 2.381, 2.367, 2.354, 2.332, 2.321,
- 2.277, 2.304, 2.327, 2.349, 2.369, 2.388, 2.393, 2.396, 2.396, 2.398, 2.396, 2.391, 2.376, 2.359, 2.339, 2.328,
- 2.279, 2.311, 2.327, 2.354, 2.377, 2.389, 2.393, 2.397, 2.397, 2.398, 2.395, 2.393, 2.382, 2.363, 2.344, 2.332,
- 2.282, 2.311, 2.329, 2.354, 2.377, 2.386, 2.396, 2.396, 2.395, 2.396, 2.397, 2.394, 2.383, 2.367, 2.346, 2.333,
- 2.283, 2.314, 2.333, 2.353, 2.375, 2.389, 2.394, 2.395, 2.395, 2.395, 2.396, 2.394, 2.386, 2.368, 2.354, 2.336,
- 2.287, 2.309, 2.331, 2.352, 2.373, 2.386, 2.394, 2.395, 2.395, 2.396, 2.396, 2.394, 2.384, 2.371, 2.354, 2.339,
- 2.289, 2.307, 2.326, 2.347, 2.369, 2.385, 2.392, 2.397, 2.398, 2.398, 2.397, 2.392, 2.383, 2.367, 2.352, 2.337,
- 2.286, 2.303, 2.322, 2.342, 2.361, 2.379, 2.389, 2.394, 2.397, 2.398, 2.396, 2.389, 2.381, 2.366, 2.346, 2.332,
- 2.284, 2.291, 2.312, 2.329, 2.351, 2.372, 2.381, 2.389, 2.393, 2.394, 2.389, 2.385, 2.374, 2.362, 2.338, 2.325,
- 2.283, 2.288, 2.305, 2.319, 2.339, 2.365, 2.374, 2.381, 2.384, 2.386, 2.385, 2.379, 2.368, 2.342, 2.325, 2.318
- ]
- },
- {
- "ct": 5000, "table":
- [
- 1.897, 1.919, 1.941, 1.969, 1.989, 2.003, 2.014, 2.019, 2.019, 2.017, 2.014, 2.008, 1.999, 1.988, 1.968, 1.944,
- 1.914, 1.932, 1.957, 1.982, 1.998, 2.014, 2.023, 2.029, 2.031, 2.029, 2.022, 2.014, 2.006, 1.995, 1.976, 1.955,
- 1.925, 1.951, 1.974, 1.996, 2.013, 2.027, 2.035, 2.039, 2.039, 2.038, 2.035, 2.026, 2.015, 2.002, 1.984, 1.963,
- 1.932, 1.958, 1.986, 2.007, 2.024, 2.034, 2.041, 2.041, 2.045, 2.045, 2.042, 2.033, 2.023, 2.009, 1.995, 1.971,
- 1.942, 1.964, 1.994, 2.012, 2.029, 2.038, 2.043, 2.046, 2.047, 2.046, 2.045, 2.039, 2.029, 2.014, 1.997, 1.977,
- 1.946, 1.974, 1.999, 2.015, 2.031, 2.041, 2.046, 2.047, 2.048, 2.047, 2.044, 2.041, 2.031, 2.019, 1.999, 1.978,
- 1.948, 1.975, 2.002, 2.018, 2.031, 2.041, 2.046, 2.047, 2.048, 2.048, 2.045, 2.041, 2.029, 2.019, 1.998, 1.978,
- 1.948, 1.973, 2.002, 2.018, 2.029, 2.042, 2.045, 2.048, 2.048, 2.048, 2.044, 2.037, 2.027, 2.014, 1.993, 1.978,
- 1.945, 1.969, 1.998, 2.015, 2.028, 2.037, 2.045, 2.046, 2.047, 2.044, 2.039, 2.033, 2.022, 2.008, 1.989, 1.971,
- 1.939, 1.964, 1.991, 2.011, 2.024, 2.032, 2.036, 2.042, 2.042, 2.039, 2.035, 2.024, 2.012, 1.998, 1.977, 1.964,
- 1.932, 1.953, 1.981, 2.006, 2.016, 2.024, 2.028, 2.031, 2.034, 2.031, 2.024, 2.015, 2.005, 1.989, 1.966, 1.955,
- 1.928, 1.944, 1.973, 1.999, 2.007, 2.016, 2.019, 2.025, 2.026, 2.025, 2.017, 2.008, 1.997, 1.975, 1.958, 1.947
- ]
- }
- ],
- "luminance_lut":
- [
- 1.877, 1.597, 1.397, 1.269, 1.191, 1.131, 1.093, 1.078, 1.071, 1.069, 1.086, 1.135, 1.221, 1.331, 1.474, 1.704,
- 1.749, 1.506, 1.334, 1.229, 1.149, 1.088, 1.058, 1.053, 1.051, 1.046, 1.053, 1.091, 1.163, 1.259, 1.387, 1.587,
- 1.661, 1.451, 1.295, 1.195, 1.113, 1.061, 1.049, 1.048, 1.047, 1.049, 1.049, 1.066, 1.124, 1.211, 1.333, 1.511,
- 1.615, 1.411, 1.267, 1.165, 1.086, 1.052, 1.047, 1.047, 1.047, 1.049, 1.052, 1.056, 1.099, 1.181, 1.303, 1.471,
- 1.576, 1.385, 1.252, 1.144, 1.068, 1.049, 1.044, 1.044, 1.045, 1.049, 1.053, 1.054, 1.083, 1.163, 1.283, 1.447,
- 1.561, 1.373, 1.245, 1.135, 1.064, 1.049, 1.044, 1.044, 1.044, 1.046, 1.048, 1.054, 1.073, 1.153, 1.271, 1.432,
- 1.571, 1.377, 1.242, 1.137, 1.066, 1.055, 1.052, 1.051, 1.051, 1.049, 1.047, 1.048, 1.068, 1.148, 1.271, 1.427,
- 1.582, 1.396, 1.259, 1.156, 1.085, 1.068, 1.059, 1.054, 1.049, 1.045, 1.041, 1.043, 1.074, 1.157, 1.284, 1.444,
- 1.623, 1.428, 1.283, 1.178, 1.105, 1.074, 1.069, 1.063, 1.056, 1.048, 1.046, 1.051, 1.094, 1.182, 1.311, 1.473,
- 1.691, 1.471, 1.321, 1.213, 1.135, 1.088, 1.073, 1.069, 1.063, 1.059, 1.053, 1.071, 1.129, 1.222, 1.351, 1.521,
- 1.808, 1.543, 1.371, 1.253, 1.174, 1.118, 1.085, 1.072, 1.067, 1.064, 1.071, 1.106, 1.176, 1.274, 1.398, 1.582,
- 1.969, 1.666, 1.447, 1.316, 1.223, 1.166, 1.123, 1.094, 1.089, 1.097, 1.118, 1.163, 1.239, 1.336, 1.471, 1.681
- ],
- "sigma": 0.00218,
- "sigma_Cb": 0.00194
- },
- "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": 2900, "ccm":
- [
- 1.44924, -0.12935, -0.31989, -0.65839, 1.95441, -0.29602, 0.18344, -1.22282, 2.03938
- ]
- },
- {
- "ct": 3000, "ccm":
- [
- 1.38736, 0.07714, -0.46451, -0.59691, 1.84335, -0.24644, 0.10092, -1.30441, 2.20349
- ]
- },
- {
- "ct": 3600, "ccm":
- [
- 1.51261, -0.27921, -0.23339, -0.55129, 1.83241, -0.28111, 0.11649, -0.93195, 1.81546
- ]
- },
- {
- "ct": 4600, "ccm":
- [
- 1.47082, -0.18523, -0.28559, -0.48923, 1.95126, -0.46203, 0.07951, -0.83987, 1.76036
- ]
- },
- {
- "ct": 5800, "ccm":
- [
- 1.57294, -0.36229, -0.21065, -0.42272, 1.80305, -0.38032, 0.03671, -0.66862, 1.63191
- ]
- },
- {
- "ct": 8100, "ccm":
- [
- 1.58803, -0.09912, -0.48891, -0.42594, 2.22303, -0.79709, -0.00621, -0.90516, 1.91137
- ]
- }
- ]
- },
- "rpi.sharpen":
- {
- "threshold": 2.0,
- "strength": 0.5,
- "limit": 0.5
- }
-}
diff --git a/src/ipa/raspberrypi/data/uncalibrated.json b/src/ipa/raspberrypi/data/uncalibrated.json
deleted file mode 100644
index 16a01e94..00000000
--- a/src/ipa/raspberrypi/data/uncalibrated.json
+++ /dev/null
@@ -1,82 +0,0 @@
-{
- "rpi.black_level":
- {
- "black_level": 4096
- },
- "rpi.awb":
- {
- "use_derivatives": 0,
- "bayes": 0
- },
- "rpi.agc":
- {
- "metering_modes":
- {
- "centre-weighted": {
- "weights": [4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0]
- }
- },
- "exposure_modes":
- {
- "normal":
- {
- "shutter": [ 100, 15000, 30000, 60000, 120000 ],
- "gain": [ 1.0, 2.0, 3.0, 4.0, 6.0 ]
- }
- },
- "constraint_modes":
- {
- "normal":
- [
- { "bound": "LOWER", "q_lo": 0.98, "q_hi": 1.0, "y_target": [ 0, 0.4, 1000, 0.4 ] }
- ]
- },
- "y_target": [ 0, 0.16, 1000, 0.165, 10000, 0.17 ]
- },
- "rpi.ccm":
- {
- "ccms":
- [
- { "ct": 4000, "ccm": [ 2.0, -1.0, 0.0, -0.5, 2.0, -0.5, 0, -1.0, 2.0 ] }
- ]
- },
- "rpi.contrast":
- {
- "ce_enable": 0,
- "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
- ]
- }
-}
diff --git a/src/ipa/raspberrypi/md_parser.hpp b/src/ipa/raspberrypi/md_parser.hpp
deleted file mode 100644
index d32d0f54..00000000
--- a/src/ipa/raspberrypi/md_parser.hpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019, Raspberry Pi (Trading) Limited
- *
- * md_parser.hpp - image sensor metadata parser interface
- */
-#pragma once
-
-#include <initializer_list>
-#include <map>
-#include <optional>
-#include <stdint.h>
-
-#include <libcamera/base/span.h>
-
-/*
- * Camera metadata parser class. Usage as shown below.
- *
- * Setup:
- *
- * Usually the metadata parser will be made as part of the CamHelper class so
- * application code doesn't have to worry which kind to instantiate. But for
- * the sake of example let's suppose we're parsing imx219 metadata.
- *
- * MdParser *parser = new MdParserSmia({ expHiReg, expLoReg, gainReg });
- * parser->SetBitsPerPixel(bpp);
- * parser->SetLineLengthBytes(pitch);
- * parser->SetNumLines(2);
- *
- * Note 1: if you don't know how many lines there are, the size of the input
- * buffer is used as a limit instead.
- *
- * Note 2: if you don't know the line length, you can leave the line length unset
- * (or set to zero) and the parser will hunt for the line start instead.
- *
- * Then on every frame:
- *
- * RegisterMap registers;
- * if (parser->Parse(buffer, registers) != MdParser::OK)
- * much badness;
- * Metadata metadata;
- * CamHelper::PopulateMetadata(registers, metadata);
- *
- * (Note that the CamHelper class converts to/from exposure lines and time,
- * and gain_code / actual gain.)
- *
- * If you suspect your embedded data may have changed its layout, change any line
- * lengths, number of lines, bits per pixel etc. that are different, and
- * then:
- *
- * parser->Reset();
- *
- * before calling Parse again.
- */
-
-namespace RPiController {
-
-/* Abstract base class from which other metadata parsers are derived. */
-
-class MdParser
-{
-public:
- using RegisterMap = std::map<uint32_t, uint32_t>;
-
- /*
- * Parser status codes:
- * OK - success
- * NOTFOUND - value such as exposure or gain was not found
- * ERROR - all other errors
- */
- enum Status {
- OK = 0,
- NOTFOUND = 1,
- ERROR = 2
- };
-
- MdParser()
- : reset_(true), bits_per_pixel_(0), num_lines_(0), line_length_bytes_(0)
- {
- }
-
- virtual ~MdParser() = default;
-
- void Reset()
- {
- reset_ = true;
- }
-
- void SetBitsPerPixel(int bpp)
- {
- bits_per_pixel_ = bpp;
- }
-
- void SetNumLines(unsigned int num_lines)
- {
- num_lines_ = num_lines;
- }
-
- void SetLineLengthBytes(unsigned int num_bytes)
- {
- line_length_bytes_ = num_bytes;
- }
-
- virtual Status Parse(libcamera::Span<const uint8_t> buffer,
- RegisterMap &registers) = 0;
-
-protected:
- bool reset_;
- int bits_per_pixel_;
- unsigned int num_lines_;
- unsigned int line_length_bytes_;
-};
-
-/*
- * This isn't a full implementation of a metadata parser for SMIA sensors,
- * however, it does provide the findRegs function which will prove useful and
- * make it easier to implement parsers for other SMIA-like sensors (see
- * md_parser_imx219.cpp for an example).
- */
-
-class MdParserSmia final : public MdParser
-{
-public:
- MdParserSmia(std::initializer_list<uint32_t> registerList);
-
- MdParser::Status Parse(libcamera::Span<const uint8_t> buffer,
- RegisterMap &registers) override;
-
-private:
- /* Maps register address to offset in the buffer. */
- using OffsetMap = std::map<uint32_t, std::optional<uint32_t>>;
-
- /*
- * Note that error codes > 0 are regarded as non-fatal; codes < 0
- * indicate a bad data buffer. Status codes are:
- * PARSE_OK - found all registers, much happiness
- * MISSING_REGS - some registers found; should this be a hard error?
- * The remaining codes are all hard errors.
- */
- enum ParseStatus {
- PARSE_OK = 0,
- MISSING_REGS = 1,
- NO_LINE_START = -1,
- ILLEGAL_TAG = -2,
- BAD_DUMMY = -3,
- BAD_LINE_END = -4,
- BAD_PADDING = -5
- };
-
- ParseStatus findRegs(libcamera::Span<const uint8_t> buffer);
-
- OffsetMap offsets_;
-};
-
-} // namespace RPi
diff --git a/src/ipa/raspberrypi/md_parser_smia.cpp b/src/ipa/raspberrypi/md_parser_smia.cpp
deleted file mode 100644
index ea5eac41..00000000
--- a/src/ipa/raspberrypi/md_parser_smia.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019-2021, Raspberry Pi (Trading) Limited
- *
- * md_parser_smia.cpp - SMIA specification based embedded data parser
- */
-
-#include <libcamera/base/log.h>
-#include "md_parser.hpp"
-
-using namespace RPiController;
-using namespace libcamera;
-
-/*
- * This function goes through the embedded data to find the offsets (not
- * values!), in the data block, where the values of the given registers can
- * subsequently be found.
- *
- * Embedded data tag bytes, from Sony IMX219 datasheet but general to all SMIA
- * sensors, I think.
- */
-
-constexpr unsigned int LINE_START = 0x0a;
-constexpr unsigned int LINE_END_TAG = 0x07;
-constexpr unsigned int REG_HI_BITS = 0xaa;
-constexpr unsigned int REG_LOW_BITS = 0xa5;
-constexpr unsigned int REG_VALUE = 0x5a;
-constexpr unsigned int REG_SKIP = 0x55;
-
-MdParserSmia::MdParserSmia(std::initializer_list<uint32_t> registerList)
-{
- for (auto r : registerList)
- offsets_[r] = {};
-}
-
-MdParser::Status MdParserSmia::Parse(libcamera::Span<const uint8_t> buffer,
- RegisterMap &registers)
-{
- if (reset_) {
- /*
- * Search again through the metadata for all the registers
- * requested.
- */
- ASSERT(bits_per_pixel_);
-
- for (const auto &kv : offsets_)
- offsets_[kv.first] = {};
-
- ParseStatus ret = findRegs(buffer);
- /*
- * > 0 means "worked partially but parse again next time",
- * < 0 means "hard error".
- *
- * In either case, we retry parsing on the next frame.
- */
- if (ret != PARSE_OK)
- return ERROR;
-
- reset_ = false;
- }
-
- /* Populate the register values requested. */
- registers.clear();
- for (const auto &[reg, offset] : offsets_) {
- if (!offset) {
- reset_ = true;
- return NOTFOUND;
- }
- registers[reg] = buffer[offset.value()];
- }
-
- return OK;
-}
-
-MdParserSmia::ParseStatus MdParserSmia::findRegs(libcamera::Span<const uint8_t> buffer)
-{
- ASSERT(offsets_.size());
-
- if (buffer[0] != LINE_START)
- return NO_LINE_START;
-
- unsigned int current_offset = 1; /* after the LINE_START */
- unsigned int current_line_start = 0, current_line = 0;
- unsigned int reg_num = 0, regs_done = 0;
-
- while (1) {
- int tag = buffer[current_offset++];
-
- if ((bits_per_pixel_ == 10 &&
- (current_offset + 1 - current_line_start) % 5 == 0) ||
- (bits_per_pixel_ == 12 &&
- (current_offset + 1 - current_line_start) % 3 == 0)) {
- if (buffer[current_offset++] != REG_SKIP)
- return BAD_DUMMY;
- }
-
- int data_byte = buffer[current_offset++];
-
- if (tag == LINE_END_TAG) {
- if (data_byte != LINE_END_TAG)
- return BAD_LINE_END;
-
- if (num_lines_ && ++current_line == num_lines_)
- return MISSING_REGS;
-
- if (line_length_bytes_) {
- current_offset = current_line_start + line_length_bytes_;
-
- /* Require whole line to be in the buffer (if buffer size set). */
- if (buffer.size() &&
- current_offset + line_length_bytes_ > buffer.size())
- return MISSING_REGS;
-
- if (buffer[current_offset] != LINE_START)
- return NO_LINE_START;
- } else {
- /* allow a zero line length to mean "hunt for the next line" */
- while (current_offset < buffer.size() &&
- buffer[current_offset] != LINE_START)
- current_offset++;
-
- if (current_offset == buffer.size())
- return NO_LINE_START;
- }
-
- /* inc current_offset to after LINE_START */
- current_line_start = current_offset++;
- } else {
- if (tag == REG_HI_BITS)
- reg_num = (reg_num & 0xff) | (data_byte << 8);
- else if (tag == REG_LOW_BITS)
- reg_num = (reg_num & 0xff00) | data_byte;
- else if (tag == REG_SKIP)
- reg_num++;
- else if (tag == REG_VALUE) {
- auto reg = offsets_.find(reg_num);
-
- if (reg != offsets_.end()) {
- offsets_[reg_num] = current_offset - 1;
-
- if (++regs_done == offsets_.size())
- return PARSE_OK;
- }
- reg_num++;
- } else
- return ILLEGAL_TAG;
- }
- }
-}
diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build
deleted file mode 100644
index 32897e07..00000000
--- a/src/ipa/raspberrypi/meson.build
+++ /dev/null
@@ -1,66 +0,0 @@
-# SPDX-License-Identifier: CC0-1.0
-
-ipa_name = 'ipa_rpi'
-
-rpi_ipa_deps = [
- libcamera_private,
- dependency('boost'),
- libatomic,
-]
-
-rpi_ipa_includes = [
- ipa_includes,
- libipa_includes,
- include_directories('controller')
-]
-
-rpi_ipa_sources = files([
- 'raspberrypi.cpp',
- 'md_parser_smia.cpp',
- 'cam_helper.cpp',
- 'cam_helper_ov5647.cpp',
- 'cam_helper_imx219.cpp',
- 'cam_helper_imx290.cpp',
- 'cam_helper_imx296.cpp',
- 'cam_helper_imx477.cpp',
- 'cam_helper_imx519.cpp',
- 'cam_helper_ov9281.cpp',
- 'controller/controller.cpp',
- 'controller/histogram.cpp',
- 'controller/algorithm.cpp',
- 'controller/rpi/alsc.cpp',
- 'controller/rpi/awb.cpp',
- 'controller/rpi/sharpen.cpp',
- 'controller/rpi/black_level.cpp',
- 'controller/rpi/focus.cpp',
- 'controller/rpi/geq.cpp',
- 'controller/rpi/noise.cpp',
- 'controller/rpi/lux.cpp',
- 'controller/rpi/agc.cpp',
- 'controller/rpi/dpc.cpp',
- 'controller/rpi/ccm.cpp',
- 'controller/rpi/contrast.cpp',
- 'controller/rpi/sdn.cpp',
- 'controller/pwl.cpp',
- 'controller/device_status.cpp',
-])
-
-mod = shared_module(ipa_name,
- [rpi_ipa_sources, libcamera_generated_ipa_headers],
- name_prefix : '',
- include_directories : rpi_ipa_includes,
- dependencies : rpi_ipa_deps,
- link_with : libipa,
- install : true,
- install_dir : ipa_install_dir)
-
-if ipa_sign_module
- custom_target(ipa_name + '.so.sign',
- input : mod,
- output : ipa_name + '.so.sign',
- command : [ipa_sign, ipa_priv_key, '@INPUT@', '@OUTPUT@'],
- install : false,
- build_by_default : true)
-endif
-
-subdir('data')
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
deleted file mode 100644
index f8d37b87..00000000
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ /dev/null
@@ -1,1460 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (C) 2019-2021, Raspberry Pi (Trading) Ltd.
- *
- * rpi.cpp - Raspberry Pi Image Processing Algorithms
- */
-
-#include <algorithm>
-#include <array>
-#include <fcntl.h>
-#include <math.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/mman.h>
-
-#include <linux/bcm2835-isp.h>
-
-#include <libcamera/base/log.h>
-#include <libcamera/base/shared_fd.h>
-#include <libcamera/base/span.h>
-
-#include <libcamera/control_ids.h>
-#include <libcamera/controls.h>
-#include <libcamera/framebuffer.h>
-#include <libcamera/ipa/ipa_interface.h>
-#include <libcamera/ipa/ipa_module_info.h>
-#include <libcamera/ipa/raspberrypi_ipa_interface.h>
-#include <libcamera/request.h>
-
-#include "libcamera/internal/mapped_framebuffer.h"
-
-#include "agc_algorithm.hpp"
-#include "agc_status.h"
-#include "alsc_status.h"
-#include "awb_algorithm.hpp"
-#include "awb_status.h"
-#include "black_level_status.h"
-#include "cam_helper.hpp"
-#include "ccm_algorithm.hpp"
-#include "ccm_status.h"
-#include "contrast_algorithm.hpp"
-#include "contrast_status.h"
-#include "controller.hpp"
-#include "denoise_algorithm.hpp"
-#include "denoise_status.h"
-#include "dpc_status.h"
-#include "focus_status.h"
-#include "geq_status.h"
-#include "lux_status.h"
-#include "metadata.hpp"
-#include "noise_status.h"
-#include "sharpen_algorithm.hpp"
-#include "sharpen_status.h"
-
-namespace libcamera {
-
-using namespace std::literals::chrono_literals;
-using utils::Duration;
-
-/* Configure the sensor with these values initially. */
-constexpr double defaultAnalogueGain = 1.0;
-constexpr Duration defaultExposureTime = 20.0ms;
-constexpr Duration defaultMinFrameDuration = 1.0s / 30.0;
-constexpr Duration defaultMaxFrameDuration = 250.0s;
-
-/*
- * Determine the minimum allowable inter-frame duration to run the controller
- * algorithms. If the pipeline handler provider frames at a rate higher than this,
- * we rate-limit the controller Prepare() and Process() calls to lower than or
- * equal to this rate.
- */
-constexpr Duration controllerMinFrameDuration = 1.0s / 30.0;
-
-/* List of controls handled by the Raspberry Pi IPA */
-static const ControlInfoMap::Map ipaControls{
- { &controls::AeEnable, ControlInfo(false, true) },
- { &controls::ExposureTime, ControlInfo(0, 66666) },
- { &controls::AnalogueGain, ControlInfo(1.0f, 16.0f) },
- { &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) },
- { &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },
- { &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },
- { &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) },
- { &controls::AwbEnable, ControlInfo(false, true) },
- { &controls::ColourGains, ControlInfo(0.0f, 32.0f) },
- { &controls::AwbMode, ControlInfo(controls::AwbModeValues) },
- { &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },
- { &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },
- { &controls::Saturation, ControlInfo(0.0f, 32.0f, 1.0f) },
- { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },
- { &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) },
- { &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
- { &controls::FrameDurationLimits, ControlInfo(INT64_C(33333), INT64_C(120000)) },
- { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }
-};
-
-LOG_DEFINE_CATEGORY(IPARPI)
-
-namespace ipa::RPi {
-
-class IPARPi : public IPARPiInterface
-{
-public:
- IPARPi()
- : controller_(), frameCount_(0), checkCount_(0), mistrustCount_(0),
- lastRunTimestamp_(0), lsTable_(nullptr), firstStart_(true)
- {
- }
-
- ~IPARPi()
- {
- if (lsTable_)
- munmap(lsTable_, MaxLsGridSize);
- }
-
- int init(const IPASettings &settings, IPAInitResult *result) override;
- void start(const ControlList &controls, StartConfig *startConfig) override;
- void stop() override {}
-
- int configure(const IPACameraSensorInfo &sensorInfo,
- const std::map<unsigned int, IPAStream> &streamConfig,
- const std::map<unsigned int, ControlInfoMap> &entityControls,
- const IPAConfig &data,
- ControlList *controls, IPAConfigResult *result) override;
- void mapBuffers(const std::vector<IPABuffer> &buffers) override;
- void unmapBuffers(const std::vector<unsigned int> &ids) override;
- void signalStatReady(const uint32_t bufferId) override;
- void signalQueueRequest(const ControlList &controls) override;
- void signalIspPrepare(const ISPConfig &data) override;
-
-private:
- void setMode(const IPACameraSensorInfo &sensorInfo);
- bool validateSensorControls();
- bool validateIspControls();
- void queueRequest(const ControlList &controls);
- void returnEmbeddedBuffer(unsigned int bufferId);
- void prepareISP(const ISPConfig &data);
- void reportMetadata();
- void fillDeviceStatus(const ControlList &sensorControls);
- void processStats(unsigned int bufferId);
- void applyFrameDurations(Duration minFrameDuration, Duration maxFrameDuration);
- void applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls);
- void applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls);
- void applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls);
- void applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls);
- void applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls);
- void applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls);
- void applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls);
- void applyDenoise(const struct DenoiseStatus *denoiseStatus, ControlList &ctrls);
- void applySharpen(const struct SharpenStatus *sharpenStatus, ControlList &ctrls);
- void applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls);
- void applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls);
- void resampleTable(uint16_t dest[], double const src[12][16], int destW, int destH);
-
- std::map<unsigned int, MappedFrameBuffer> buffers_;
-
- ControlInfoMap sensorCtrls_;
- ControlInfoMap ispCtrls_;
- ControlList libcameraMetadata_;
-
- /* Camera sensor params. */
- CameraMode mode_;
-
- /* Raspberry Pi controller specific defines. */
- std::unique_ptr<RPiController::CamHelper> helper_;
- RPiController::Controller controller_;
- RPiController::Metadata rpiMetadata_;
-
- /*
- * We count frames to decide if the frame must be hidden (e.g. from
- * display) or mistrusted (i.e. not given to the control algos).
- */
- uint64_t frameCount_;
-
- /* For checking the sequencing of Prepare/Process calls. */
- uint64_t checkCount_;
-
- /* How many frames we should avoid running control algos on. */
- unsigned int mistrustCount_;
-
- /* Number of frames that need to be dropped on startup. */
- unsigned int dropFrameCount_;
-
- /* Frame timestamp for the last run of the controller. */
- uint64_t lastRunTimestamp_;
-
- /* Do we run a Controller::process() for this frame? */
- bool processPending_;
-
- /* LS table allocation passed in from the pipeline handler. */
- SharedFD lsTableHandle_;
- void *lsTable_;
-
- /* Distinguish the first camera start from others. */
- bool firstStart_;
-
- /* Frame duration (1/fps) limits. */
- Duration minFrameDuration_;
- Duration maxFrameDuration_;
-
- /* Maximum gain code for the sensor. */
- uint32_t maxSensorGainCode_;
-};
-
-int IPARPi::init(const IPASettings &settings, IPAInitResult *result)
-{
- /*
- * Load the "helper" for this sensor. This tells us all the device specific stuff
- * that the kernel driver doesn't. We only do this the first time; we don't need
- * to re-parse the metadata after a simple mode-switch for no reason.
- */
- helper_ = std::unique_ptr<RPiController::CamHelper>(RPiController::CamHelper::Create(settings.sensorModel));
- if (!helper_) {
- LOG(IPARPI, Error) << "Could not create camera helper for "
- << settings.sensorModel;
- return -EINVAL;
- }
-
- /*
- * Pass out the sensor config to the pipeline handler in order
- * to setup the staggered writer class.
- */
- int gainDelay, exposureDelay, vblankDelay, sensorMetadata;
- helper_->GetDelays(exposureDelay, gainDelay, vblankDelay);
- sensorMetadata = helper_->SensorEmbeddedDataPresent();
-
- result->sensorConfig.gainDelay = gainDelay;
- result->sensorConfig.exposureDelay = exposureDelay;
- result->sensorConfig.vblankDelay = vblankDelay;
- result->sensorConfig.sensorMetadata = sensorMetadata;
-
- /* Load the tuning file for this sensor. */
- controller_.Read(settings.configurationFile.c_str());
- controller_.Initialise();
-
- /* Return the controls handled by the IPA */
- ControlInfoMap::Map ctrlMap = ipaControls;
- result->controlInfo = ControlInfoMap(std::move(ctrlMap), controls::controls);
-
- return 0;
-}
-
-void IPARPi::start(const ControlList &controls, StartConfig *startConfig)
-{
- RPiController::Metadata metadata;
-
- ASSERT(startConfig);
- if (!controls.empty()) {
- /* We have been given some controls to action before start. */
- queueRequest(controls);
- }
-
- controller_.SwitchMode(mode_, &metadata);
-
- /* SwitchMode may supply updated exposure/gain values to use. */
- AgcStatus agcStatus;
- agcStatus.shutter_time = 0.0s;
- agcStatus.analogue_gain = 0.0;
-
- metadata.Get("agc.status", agcStatus);
- if (agcStatus.shutter_time && agcStatus.analogue_gain) {
- ControlList ctrls(sensorCtrls_);
- applyAGC(&agcStatus, ctrls);
- startConfig->controls = std::move(ctrls);
- }
-
- /*
- * Initialise frame counts, and decide how many frames must be hidden or
- * "mistrusted", which depends on whether this is a startup from cold,
- * or merely a mode switch in a running system.
- */
- frameCount_ = 0;
- checkCount_ = 0;
- if (firstStart_) {
- dropFrameCount_ = helper_->HideFramesStartup();
- mistrustCount_ = helper_->MistrustFramesStartup();
-
- /*
- * Query the AGC/AWB for how many frames they may take to
- * converge sufficiently. Where these numbers are non-zero
- * we must allow for the frames with bad statistics
- * (mistrustCount_) that they won't see. But if zero (i.e.
- * no convergence necessary), no frames need to be dropped.
- */
- unsigned int agcConvergenceFrames = 0;
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- if (agc) {
- agcConvergenceFrames = agc->GetConvergenceFrames();
- if (agcConvergenceFrames)
- agcConvergenceFrames += mistrustCount_;
- }
-
- unsigned int awbConvergenceFrames = 0;
- RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
- controller_.GetAlgorithm("awb"));
- if (awb) {
- awbConvergenceFrames = awb->GetConvergenceFrames();
- if (awbConvergenceFrames)
- awbConvergenceFrames += mistrustCount_;
- }
-
- dropFrameCount_ = std::max({ dropFrameCount_, agcConvergenceFrames, awbConvergenceFrames });
- LOG(IPARPI, Debug) << "Drop " << dropFrameCount_ << " frames on startup";
- } else {
- dropFrameCount_ = helper_->HideFramesModeSwitch();
- mistrustCount_ = helper_->MistrustFramesModeSwitch();
- }
-
- startConfig->dropFrameCount = dropFrameCount_;
- const Duration maxSensorFrameDuration = mode_.max_frame_length * mode_.line_length;
- startConfig->maxSensorFrameLengthMs = maxSensorFrameDuration.get<std::milli>();
-
- firstStart_ = false;
- lastRunTimestamp_ = 0;
-}
-
-void IPARPi::setMode(const IPACameraSensorInfo &sensorInfo)
-{
- mode_.bitdepth = sensorInfo.bitsPerPixel;
- mode_.width = sensorInfo.outputSize.width;
- mode_.height = sensorInfo.outputSize.height;
- mode_.sensor_width = sensorInfo.activeAreaSize.width;
- mode_.sensor_height = sensorInfo.activeAreaSize.height;
- mode_.crop_x = sensorInfo.analogCrop.x;
- mode_.crop_y = sensorInfo.analogCrop.y;
-
- /*
- * Calculate scaling parameters. The scale_[xy] factors are determined
- * by the ratio between the crop rectangle size and the output size.
- */
- mode_.scale_x = sensorInfo.analogCrop.width / sensorInfo.outputSize.width;
- mode_.scale_y = sensorInfo.analogCrop.height / sensorInfo.outputSize.height;
-
- /*
- * We're not told by the pipeline handler how scaling is split between
- * binning and digital scaling. For now, as a heuristic, assume that
- * downscaling up to 2 is achieved through binning, and that any
- * additional scaling is achieved through digital scaling.
- *
- * \todo Get the pipeline handle to provide the full data
- */
- mode_.bin_x = std::min(2, static_cast<int>(mode_.scale_x));
- mode_.bin_y = std::min(2, static_cast<int>(mode_.scale_y));
-
- /* The noise factor is the square root of the total binning factor. */
- mode_.noise_factor = sqrt(mode_.bin_x * mode_.bin_y);
-
- /*
- * Calculate the line length as the ratio between the line length in
- * pixels and the pixel rate.
- */
- mode_.line_length = sensorInfo.lineLength * (1.0s / sensorInfo.pixelRate);
-
- /*
- * Set the frame length limits for the mode to ensure exposure and
- * framerate calculations are clipped appropriately.
- */
- mode_.min_frame_length = sensorInfo.minFrameLength;
- mode_.max_frame_length = sensorInfo.maxFrameLength;
-
- /*
- * Some sensors may have different sensitivities in different modes;
- * the CamHelper will know the correct value.
- */
- mode_.sensitivity = helper_->GetModeSensitivity(mode_);
-}
-
-int IPARPi::configure(const IPACameraSensorInfo &sensorInfo,
- [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig,
- const std::map<unsigned int, ControlInfoMap> &entityControls,
- const IPAConfig &ipaConfig,
- ControlList *controls, IPAConfigResult *result)
-{
- if (entityControls.size() != 2) {
- LOG(IPARPI, Error) << "No ISP or sensor controls found.";
- return -1;
- }
-
- sensorCtrls_ = entityControls.at(0);
- ispCtrls_ = entityControls.at(1);
-
- if (!validateSensorControls()) {
- LOG(IPARPI, Error) << "Sensor control validation failed.";
- return -1;
- }
-
- if (!validateIspControls()) {
- LOG(IPARPI, Error) << "ISP control validation failed.";
- return -1;
- }
-
- maxSensorGainCode_ = sensorCtrls_.at(V4L2_CID_ANALOGUE_GAIN).max().get<int32_t>();
-
- /* Setup a metadata ControlList to output metadata. */
- libcameraMetadata_ = ControlList(controls::controls);
-
- /* Re-assemble camera mode using the sensor info. */
- setMode(sensorInfo);
-
- mode_.transform = static_cast<libcamera::Transform>(ipaConfig.transform);
-
- /* Store the lens shading table pointer and handle if available. */
- if (ipaConfig.lsTableHandle.isValid()) {
- /* Remove any previous table, if there was one. */
- if (lsTable_) {
- munmap(lsTable_, MaxLsGridSize);
- lsTable_ = nullptr;
- }
-
- /* Map the LS table buffer into user space. */
- lsTableHandle_ = std::move(ipaConfig.lsTableHandle);
- if (lsTableHandle_.isValid()) {
- lsTable_ = mmap(nullptr, MaxLsGridSize, PROT_READ | PROT_WRITE,
- MAP_SHARED, lsTableHandle_.get(), 0);
-
- if (lsTable_ == MAP_FAILED) {
- LOG(IPARPI, Error) << "dmaHeap mmap failure for LS table.";
- lsTable_ = nullptr;
- }
- }
- }
-
- /* Pass the camera mode to the CamHelper to setup algorithms. */
- helper_->SetCameraMode(mode_);
-
- /*
- * Initialise this ControlList correctly, even if empty, in case the IPA is
- * running is isolation mode (passing the ControlList through the IPC layer).
- */
- ControlList ctrls(sensorCtrls_);
-
- /* The pipeline handler passes out the mode's sensitivity. */
- result->modeSensitivity = mode_.sensitivity;
-
- if (firstStart_) {
- /* Supply initial values for frame durations. */
- applyFrameDurations(defaultMinFrameDuration, defaultMaxFrameDuration);
-
- /* Supply initial values for gain and exposure. */
- AgcStatus agcStatus;
- agcStatus.shutter_time = defaultExposureTime;
- agcStatus.analogue_gain = defaultAnalogueGain;
- applyAGC(&agcStatus, ctrls);
- }
-
- ASSERT(controls);
- *controls = std::move(ctrls);
-
- /*
- * Apply the correct limits to the exposure, gain and frame duration controls
- * based on the current sensor mode.
- */
- ControlInfoMap::Map ctrlMap = ipaControls;
- const Duration minSensorFrameDuration = mode_.min_frame_length * mode_.line_length;
- const Duration maxSensorFrameDuration = mode_.max_frame_length * mode_.line_length;
- ctrlMap[&controls::FrameDurationLimits] =
- ControlInfo(static_cast<int64_t>(minSensorFrameDuration.get<std::micro>()),
- static_cast<int64_t>(maxSensorFrameDuration.get<std::micro>()));
-
- ctrlMap[&controls::AnalogueGain] =
- ControlInfo(1.0f, static_cast<float>(helper_->Gain(maxSensorGainCode_)));
-
- /*
- * Calculate the max exposure limit from the frame duration limit as V4L2
- * will limit the maximum control value based on the current VBLANK value.
- */
- Duration maxShutter = Duration::max();
- helper_->GetVBlanking(maxShutter, minSensorFrameDuration, maxSensorFrameDuration);
- const uint32_t exposureMin = sensorCtrls_.at(V4L2_CID_EXPOSURE).min().get<int32_t>();
-
- ctrlMap[&controls::ExposureTime] =
- ControlInfo(static_cast<int32_t>(helper_->Exposure(exposureMin).get<std::micro>()),
- static_cast<int32_t>(maxShutter.get<std::micro>()));
-
- result->controlInfo = ControlInfoMap(std::move(ctrlMap), controls::controls);
- return 0;
-}
-
-void IPARPi::mapBuffers(const std::vector<IPABuffer> &buffers)
-{
- for (const IPABuffer &buffer : buffers) {
- const FrameBuffer fb(buffer.planes);
- buffers_.emplace(buffer.id,
- MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));
- }
-}
-
-void IPARPi::unmapBuffers(const std::vector<unsigned int> &ids)
-{
- for (unsigned int id : ids) {
- auto it = buffers_.find(id);
- if (it == buffers_.end())
- continue;
-
- buffers_.erase(id);
- }
-}
-
-void IPARPi::signalStatReady(uint32_t bufferId)
-{
- if (++checkCount_ != frameCount_) /* assert here? */
- LOG(IPARPI, Error) << "WARNING: Prepare/Process mismatch!!!";
- if (processPending_ && frameCount_ > mistrustCount_)
- processStats(bufferId);
-
- reportMetadata();
-
- statsMetadataComplete.emit(bufferId & MaskID, libcameraMetadata_);
-}
-
-void IPARPi::signalQueueRequest(const ControlList &controls)
-{
- queueRequest(controls);
-}
-
-void IPARPi::signalIspPrepare(const ISPConfig &data)
-{
- /*
- * At start-up, or after a mode-switch, we may want to
- * avoid running the control algos for a few frames in case
- * they are "unreliable".
- */
- prepareISP(data);
- frameCount_++;
-
- /* Ready to push the input buffer into the ISP. */
- runIsp.emit(data.bayerBufferId & MaskID);
-}
-
-void IPARPi::reportMetadata()
-{
- std::unique_lock<RPiController::Metadata> lock(rpiMetadata_);
-
- /*
- * Certain information about the current frame and how it will be
- * processed can be extracted and placed into the libcamera metadata
- * buffer, where an application could query it.
- */
- DeviceStatus *deviceStatus = rpiMetadata_.GetLocked<DeviceStatus>("device.status");
- if (deviceStatus) {
- libcameraMetadata_.set(controls::ExposureTime,
- deviceStatus->shutter_speed.get<std::micro>());
- libcameraMetadata_.set(controls::AnalogueGain, deviceStatus->analogue_gain);
- libcameraMetadata_.set(controls::FrameDuration,
- helper_->Exposure(deviceStatus->frame_length).get<std::micro>());
- if (deviceStatus->sensor_temperature)
- libcameraMetadata_.set(controls::SensorTemperature, *deviceStatus->sensor_temperature);
- }
-
- AgcStatus *agcStatus = rpiMetadata_.GetLocked<AgcStatus>("agc.status");
- if (agcStatus) {
- libcameraMetadata_.set(controls::AeLocked, agcStatus->locked);
- libcameraMetadata_.set(controls::DigitalGain, agcStatus->digital_gain);
- }
-
- LuxStatus *luxStatus = rpiMetadata_.GetLocked<LuxStatus>("lux.status");
- if (luxStatus)
- libcameraMetadata_.set(controls::Lux, luxStatus->lux);
-
- AwbStatus *awbStatus = rpiMetadata_.GetLocked<AwbStatus>("awb.status");
- if (awbStatus) {
- libcameraMetadata_.set(controls::ColourGains, { static_cast<float>(awbStatus->gain_r),
- static_cast<float>(awbStatus->gain_b) });
- libcameraMetadata_.set(controls::ColourTemperature, awbStatus->temperature_K);
- }
-
- BlackLevelStatus *blackLevelStatus = rpiMetadata_.GetLocked<BlackLevelStatus>("black_level.status");
- if (blackLevelStatus)
- libcameraMetadata_.set(controls::SensorBlackLevels,
- { static_cast<int32_t>(blackLevelStatus->black_level_r),
- static_cast<int32_t>(blackLevelStatus->black_level_g),
- static_cast<int32_t>(blackLevelStatus->black_level_g),
- static_cast<int32_t>(blackLevelStatus->black_level_b) });
-
- FocusStatus *focusStatus = rpiMetadata_.GetLocked<FocusStatus>("focus.status");
- if (focusStatus && focusStatus->num == 12) {
- /*
- * We get a 4x3 grid of regions by default. Calculate the average
- * FoM over the central two positions to give an overall scene FoM.
- * This can change later if it is not deemed suitable.
- */
- int32_t focusFoM = (focusStatus->focus_measures[5] + focusStatus->focus_measures[6]) / 2;
- libcameraMetadata_.set(controls::FocusFoM, focusFoM);
- }
-
- CcmStatus *ccmStatus = rpiMetadata_.GetLocked<CcmStatus>("ccm.status");
- if (ccmStatus) {
- float m[9];
- for (unsigned int i = 0; i < 9; i++)
- m[i] = ccmStatus->matrix[i];
- libcameraMetadata_.set(controls::ColourCorrectionMatrix, m);
- }
-}
-
-bool IPARPi::validateSensorControls()
-{
- static const uint32_t ctrls[] = {
- V4L2_CID_ANALOGUE_GAIN,
- V4L2_CID_EXPOSURE,
- V4L2_CID_VBLANK,
- };
-
- for (auto c : ctrls) {
- if (sensorCtrls_.find(c) == sensorCtrls_.end()) {
- LOG(IPARPI, Error) << "Unable to find sensor control "
- << utils::hex(c);
- return false;
- }
- }
-
- return true;
-}
-
-bool IPARPi::validateIspControls()
-{
- static const uint32_t ctrls[] = {
- V4L2_CID_RED_BALANCE,
- V4L2_CID_BLUE_BALANCE,
- V4L2_CID_DIGITAL_GAIN,
- V4L2_CID_USER_BCM2835_ISP_CC_MATRIX,
- V4L2_CID_USER_BCM2835_ISP_GAMMA,
- V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL,
- V4L2_CID_USER_BCM2835_ISP_GEQ,
- V4L2_CID_USER_BCM2835_ISP_DENOISE,
- V4L2_CID_USER_BCM2835_ISP_SHARPEN,
- V4L2_CID_USER_BCM2835_ISP_DPC,
- V4L2_CID_USER_BCM2835_ISP_LENS_SHADING,
- V4L2_CID_USER_BCM2835_ISP_CDN,
- };
-
- for (auto c : ctrls) {
- if (ispCtrls_.find(c) == ispCtrls_.end()) {
- LOG(IPARPI, Error) << "Unable to find ISP control "
- << utils::hex(c);
- return false;
- }
- }
-
- return true;
-}
-
-/*
- * Converting between enums (used in the libcamera API) and the names that
- * we use to identify different modes. Unfortunately, the conversion tables
- * must be kept up-to-date by hand.
- */
-static const std::map<int32_t, std::string> MeteringModeTable = {
- { controls::MeteringCentreWeighted, "centre-weighted" },
- { controls::MeteringSpot, "spot" },
- { controls::MeteringMatrix, "matrix" },
- { controls::MeteringCustom, "custom" },
-};
-
-static const std::map<int32_t, std::string> ConstraintModeTable = {
- { controls::ConstraintNormal, "normal" },
- { controls::ConstraintHighlight, "highlight" },
- { controls::ConstraintCustom, "custom" },
-};
-
-static const std::map<int32_t, std::string> ExposureModeTable = {
- { controls::ExposureNormal, "normal" },
- { controls::ExposureShort, "short" },
- { controls::ExposureLong, "long" },
- { controls::ExposureCustom, "custom" },
-};
-
-static const std::map<int32_t, std::string> AwbModeTable = {
- { controls::AwbAuto, "auto" },
- { controls::AwbIncandescent, "incandescent" },
- { controls::AwbTungsten, "tungsten" },
- { controls::AwbFluorescent, "fluorescent" },
- { controls::AwbIndoor, "indoor" },
- { controls::AwbDaylight, "daylight" },
- { controls::AwbCloudy, "cloudy" },
- { controls::AwbCustom, "custom" },
-};
-
-static const std::map<int32_t, RPiController::DenoiseMode> DenoiseModeTable = {
- { controls::draft::NoiseReductionModeOff, RPiController::DenoiseMode::Off },
- { controls::draft::NoiseReductionModeFast, RPiController::DenoiseMode::ColourFast },
- { controls::draft::NoiseReductionModeHighQuality, RPiController::DenoiseMode::ColourHighQuality },
- { controls::draft::NoiseReductionModeMinimal, RPiController::DenoiseMode::ColourOff },
- { controls::draft::NoiseReductionModeZSL, RPiController::DenoiseMode::ColourHighQuality },
-};
-
-void IPARPi::queueRequest(const ControlList &controls)
-{
- /* Clear the return metadata buffer. */
- libcameraMetadata_.clear();
-
- for (auto const &ctrl : controls) {
- LOG(IPARPI, Debug) << "Request ctrl: "
- << controls::controls.at(ctrl.first)->name()
- << " = " << ctrl.second.toString();
-
- switch (ctrl.first) {
- case controls::AE_ENABLE: {
- RPiController::Algorithm *agc = controller_.GetAlgorithm("agc");
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set AE_ENABLE - no AGC algorithm";
- break;
- }
-
- if (ctrl.second.get<bool>() == false)
- agc->Pause();
- else
- agc->Resume();
-
- libcameraMetadata_.set(controls::AeEnable, ctrl.second.get<bool>());
- break;
- }
-
- case controls::EXPOSURE_TIME: {
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set EXPOSURE_TIME - no AGC algorithm";
- break;
- }
-
- /* The control provides units of microseconds. */
- agc->SetFixedShutter(ctrl.second.get<int32_t>() * 1.0us);
-
- libcameraMetadata_.set(controls::ExposureTime, ctrl.second.get<int32_t>());
- break;
- }
-
- case controls::ANALOGUE_GAIN: {
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set ANALOGUE_GAIN - no AGC algorithm";
- break;
- }
-
- agc->SetFixedAnalogueGain(ctrl.second.get<float>());
-
- libcameraMetadata_.set(controls::AnalogueGain,
- ctrl.second.get<float>());
- break;
- }
-
- case controls::AE_METERING_MODE: {
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set AE_METERING_MODE - no AGC algorithm";
- break;
- }
-
- int32_t idx = ctrl.second.get<int32_t>();
- if (MeteringModeTable.count(idx)) {
- agc->SetMeteringMode(MeteringModeTable.at(idx));
- libcameraMetadata_.set(controls::AeMeteringMode, idx);
- } else {
- LOG(IPARPI, Error) << "Metering mode " << idx
- << " not recognised";
- }
- break;
- }
-
- case controls::AE_CONSTRAINT_MODE: {
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set AE_CONSTRAINT_MODE - no AGC algorithm";
- break;
- }
-
- int32_t idx = ctrl.second.get<int32_t>();
- if (ConstraintModeTable.count(idx)) {
- agc->SetConstraintMode(ConstraintModeTable.at(idx));
- libcameraMetadata_.set(controls::AeConstraintMode, idx);
- } else {
- LOG(IPARPI, Error) << "Constraint mode " << idx
- << " not recognised";
- }
- break;
- }
-
- case controls::AE_EXPOSURE_MODE: {
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set AE_EXPOSURE_MODE - no AGC algorithm";
- break;
- }
-
- int32_t idx = ctrl.second.get<int32_t>();
- if (ExposureModeTable.count(idx)) {
- agc->SetExposureMode(ExposureModeTable.at(idx));
- libcameraMetadata_.set(controls::AeExposureMode, idx);
- } else {
- LOG(IPARPI, Error) << "Exposure mode " << idx
- << " not recognised";
- }
- break;
- }
-
- case controls::EXPOSURE_VALUE: {
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- if (!agc) {
- LOG(IPARPI, Warning)
- << "Could not set EXPOSURE_VALUE - no AGC algorithm";
- break;
- }
-
- /*
- * The SetEv() function takes in a direct exposure multiplier.
- * So convert to 2^EV
- */
- double ev = pow(2.0, ctrl.second.get<float>());
- agc->SetEv(ev);
- libcameraMetadata_.set(controls::ExposureValue,
- ctrl.second.get<float>());
- break;
- }
-
- case controls::AWB_ENABLE: {
- RPiController::Algorithm *awb = controller_.GetAlgorithm("awb");
- if (!awb) {
- LOG(IPARPI, Warning)
- << "Could not set AWB_ENABLE - no AWB algorithm";
- break;
- }
-
- if (ctrl.second.get<bool>() == false)
- awb->Pause();
- else
- awb->Resume();
-
- libcameraMetadata_.set(controls::AwbEnable,
- ctrl.second.get<bool>());
- break;
- }
-
- case controls::AWB_MODE: {
- RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
- controller_.GetAlgorithm("awb"));
- if (!awb) {
- LOG(IPARPI, Warning)
- << "Could not set AWB_MODE - no AWB algorithm";
- break;
- }
-
- int32_t idx = ctrl.second.get<int32_t>();
- if (AwbModeTable.count(idx)) {
- awb->SetMode(AwbModeTable.at(idx));
- libcameraMetadata_.set(controls::AwbMode, idx);
- } else {
- LOG(IPARPI, Error) << "AWB mode " << idx
- << " not recognised";
- }
- break;
- }
-
- case controls::COLOUR_GAINS: {
- auto gains = ctrl.second.get<Span<const float>>();
- RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
- controller_.GetAlgorithm("awb"));
- if (!awb) {
- LOG(IPARPI, Warning)
- << "Could not set COLOUR_GAINS - no AWB algorithm";
- break;
- }
-
- awb->SetManualGains(gains[0], gains[1]);
- if (gains[0] != 0.0f && gains[1] != 0.0f)
- /* A gain of 0.0f will switch back to auto mode. */
- libcameraMetadata_.set(controls::ColourGains,
- { gains[0], gains[1] });
- break;
- }
-
- case controls::BRIGHTNESS: {
- RPiController::ContrastAlgorithm *contrast = dynamic_cast<RPiController::ContrastAlgorithm *>(
- controller_.GetAlgorithm("contrast"));
- if (!contrast) {
- LOG(IPARPI, Warning)
- << "Could not set BRIGHTNESS - no contrast algorithm";
- break;
- }
-
- contrast->SetBrightness(ctrl.second.get<float>() * 65536);
- libcameraMetadata_.set(controls::Brightness,
- ctrl.second.get<float>());
- break;
- }
-
- case controls::CONTRAST: {
- RPiController::ContrastAlgorithm *contrast = dynamic_cast<RPiController::ContrastAlgorithm *>(
- controller_.GetAlgorithm("contrast"));
- if (!contrast) {
- LOG(IPARPI, Warning)
- << "Could not set CONTRAST - no contrast algorithm";
- break;
- }
-
- contrast->SetContrast(ctrl.second.get<float>());
- libcameraMetadata_.set(controls::Contrast,
- ctrl.second.get<float>());
- break;
- }
-
- case controls::SATURATION: {
- RPiController::CcmAlgorithm *ccm = dynamic_cast<RPiController::CcmAlgorithm *>(
- controller_.GetAlgorithm("ccm"));
- if (!ccm) {
- LOG(IPARPI, Warning)
- << "Could not set SATURATION - no ccm algorithm";
- break;
- }
-
- ccm->SetSaturation(ctrl.second.get<float>());
- libcameraMetadata_.set(controls::Saturation,
- ctrl.second.get<float>());
- break;
- }
-
- case controls::SHARPNESS: {
- RPiController::SharpenAlgorithm *sharpen = dynamic_cast<RPiController::SharpenAlgorithm *>(
- controller_.GetAlgorithm("sharpen"));
- if (!sharpen) {
- LOG(IPARPI, Warning)
- << "Could not set SHARPNESS - no sharpen algorithm";
- break;
- }
-
- sharpen->SetStrength(ctrl.second.get<float>());
- libcameraMetadata_.set(controls::Sharpness,
- ctrl.second.get<float>());
- break;
- }
-
- case controls::SCALER_CROP: {
- /* We do nothing with this, but should avoid the warning below. */
- break;
- }
-
- case controls::FRAME_DURATION_LIMITS: {
- auto frameDurations = ctrl.second.get<Span<const int64_t>>();
- applyFrameDurations(frameDurations[0] * 1.0us, frameDurations[1] * 1.0us);
- break;
- }
-
- case controls::NOISE_REDUCTION_MODE: {
- RPiController::DenoiseAlgorithm *sdn = dynamic_cast<RPiController::DenoiseAlgorithm *>(
- controller_.GetAlgorithm("SDN"));
- if (!sdn) {
- LOG(IPARPI, Warning)
- << "Could not set NOISE_REDUCTION_MODE - no SDN algorithm";
- break;
- }
-
- int32_t idx = ctrl.second.get<int32_t>();
- auto mode = DenoiseModeTable.find(idx);
- if (mode != DenoiseModeTable.end()) {
- sdn->SetMode(mode->second);
-
- /*
- * \todo If the colour denoise is not going to run due to an
- * analysis image resolution or format mismatch, we should
- * report the status correctly in the metadata.
- */
- libcameraMetadata_.set(controls::draft::NoiseReductionMode, idx);
- } else {
- LOG(IPARPI, Error) << "Noise reduction mode " << idx
- << " not recognised";
- }
- break;
- }
-
- default:
- LOG(IPARPI, Warning)
- << "Ctrl " << controls::controls.at(ctrl.first)->name()
- << " is not handled.";
- break;
- }
- }
-}
-
-void IPARPi::returnEmbeddedBuffer(unsigned int bufferId)
-{
- embeddedComplete.emit(bufferId & MaskID);
-}
-
-void IPARPi::prepareISP(const ISPConfig &data)
-{
- int64_t frameTimestamp = data.controls.get(controls::SensorTimestamp);
- RPiController::Metadata lastMetadata;
- Span<uint8_t> embeddedBuffer;
-
- lastMetadata = std::move(rpiMetadata_);
- fillDeviceStatus(data.controls);
-
- if (data.embeddedBufferPresent) {
- /*
- * Pipeline handler has supplied us with an embedded data buffer,
- * we must pass it to the CamHelper for parsing.
- */
- auto it = buffers_.find(data.embeddedBufferId);
- ASSERT(it != buffers_.end());
- embeddedBuffer = it->second.planes()[0];
- }
-
- /*
- * This may overwrite the DeviceStatus using values from the sensor
- * metadata, and may also do additional custom processing.
- */
- helper_->Prepare(embeddedBuffer, rpiMetadata_);
-
- /* Done with embedded data now, return to pipeline handler asap. */
- if (data.embeddedBufferPresent)
- returnEmbeddedBuffer(data.embeddedBufferId);
-
- /* Allow a 10% margin on the comparison below. */
- Duration delta = (frameTimestamp - lastRunTimestamp_) * 1.0ns;
- if (lastRunTimestamp_ && frameCount_ > dropFrameCount_ &&
- delta < controllerMinFrameDuration * 0.9) {
- /*
- * Ensure we merge the previous frame's metadata with the current
- * frame. This will not overwrite exposure/gain values for the
- * current frame, or any other bits of metadata that were added
- * in helper_->Prepare().
- */
- rpiMetadata_.Merge(lastMetadata);
- processPending_ = false;
- return;
- }
-
- lastRunTimestamp_ = frameTimestamp;
- processPending_ = true;
-
- ControlList ctrls(ispCtrls_);
-
- controller_.Prepare(&rpiMetadata_);
-
- /* Lock the metadata buffer to avoid constant locks/unlocks. */
- std::unique_lock<RPiController::Metadata> lock(rpiMetadata_);
-
- AwbStatus *awbStatus = rpiMetadata_.GetLocked<AwbStatus>("awb.status");
- if (awbStatus)
- applyAWB(awbStatus, ctrls);
-
- CcmStatus *ccmStatus = rpiMetadata_.GetLocked<CcmStatus>("ccm.status");
- if (ccmStatus)
- applyCCM(ccmStatus, ctrls);
-
- AgcStatus *dgStatus = rpiMetadata_.GetLocked<AgcStatus>("agc.status");
- if (dgStatus)
- applyDG(dgStatus, ctrls);
-
- AlscStatus *lsStatus = rpiMetadata_.GetLocked<AlscStatus>("alsc.status");
- if (lsStatus)
- applyLS(lsStatus, ctrls);
-
- ContrastStatus *contrastStatus = rpiMetadata_.GetLocked<ContrastStatus>("contrast.status");
- if (contrastStatus)
- applyGamma(contrastStatus, ctrls);
-
- BlackLevelStatus *blackLevelStatus = rpiMetadata_.GetLocked<BlackLevelStatus>("black_level.status");
- if (blackLevelStatus)
- applyBlackLevel(blackLevelStatus, ctrls);
-
- GeqStatus *geqStatus = rpiMetadata_.GetLocked<GeqStatus>("geq.status");
- if (geqStatus)
- applyGEQ(geqStatus, ctrls);
-
- DenoiseStatus *denoiseStatus = rpiMetadata_.GetLocked<DenoiseStatus>("denoise.status");
- if (denoiseStatus)
- applyDenoise(denoiseStatus, ctrls);
-
- SharpenStatus *sharpenStatus = rpiMetadata_.GetLocked<SharpenStatus>("sharpen.status");
- if (sharpenStatus)
- applySharpen(sharpenStatus, ctrls);
-
- DpcStatus *dpcStatus = rpiMetadata_.GetLocked<DpcStatus>("dpc.status");
- if (dpcStatus)
- applyDPC(dpcStatus, ctrls);
-
- if (!ctrls.empty())
- setIspControls.emit(ctrls);
-}
-
-void IPARPi::fillDeviceStatus(const ControlList &sensorControls)
-{
- DeviceStatus deviceStatus = {};
-
- int32_t exposureLines = sensorControls.get(V4L2_CID_EXPOSURE).get<int32_t>();
- int32_t gainCode = sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>();
- int32_t vblank = sensorControls.get(V4L2_CID_VBLANK).get<int32_t>();
-
- deviceStatus.shutter_speed = helper_->Exposure(exposureLines);
- deviceStatus.analogue_gain = helper_->Gain(gainCode);
- deviceStatus.frame_length = mode_.height + vblank;
-
- LOG(IPARPI, Debug) << "Metadata - " << deviceStatus;
-
- rpiMetadata_.Set("device.status", deviceStatus);
-}
-
-void IPARPi::processStats(unsigned int bufferId)
-{
- auto it = buffers_.find(bufferId);
- if (it == buffers_.end()) {
- LOG(IPARPI, Error) << "Could not find stats buffer!";
- return;
- }
-
- Span<uint8_t> mem = it->second.planes()[0];
- bcm2835_isp_stats *stats = reinterpret_cast<bcm2835_isp_stats *>(mem.data());
- RPiController::StatisticsPtr statistics = std::make_shared<bcm2835_isp_stats>(*stats);
- helper_->Process(statistics, rpiMetadata_);
- controller_.Process(statistics, &rpiMetadata_);
-
- struct AgcStatus agcStatus;
- if (rpiMetadata_.Get("agc.status", agcStatus) == 0) {
- ControlList ctrls(sensorCtrls_);
- applyAGC(&agcStatus, ctrls);
-
- setDelayedControls.emit(ctrls);
- }
-}
-
-void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls)
-{
- LOG(IPARPI, Debug) << "Applying WB R: " << awbStatus->gain_r << " B: "
- << awbStatus->gain_b;
-
- ctrls.set(V4L2_CID_RED_BALANCE,
- static_cast<int32_t>(awbStatus->gain_r * 1000));
- ctrls.set(V4L2_CID_BLUE_BALANCE,
- static_cast<int32_t>(awbStatus->gain_b * 1000));
-}
-
-void IPARPi::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDuration)
-{
- const Duration minSensorFrameDuration = mode_.min_frame_length * mode_.line_length;
- const Duration maxSensorFrameDuration = mode_.max_frame_length * mode_.line_length;
-
- /*
- * This will only be applied once AGC recalculations occur.
- * The values may be clamped based on the sensor mode capabilities as well.
- */
- minFrameDuration_ = minFrameDuration ? minFrameDuration : defaultMaxFrameDuration;
- maxFrameDuration_ = maxFrameDuration ? maxFrameDuration : defaultMinFrameDuration;
- minFrameDuration_ = std::clamp(minFrameDuration_,
- minSensorFrameDuration, maxSensorFrameDuration);
- maxFrameDuration_ = std::clamp(maxFrameDuration_,
- minSensorFrameDuration, maxSensorFrameDuration);
- maxFrameDuration_ = std::max(maxFrameDuration_, minFrameDuration_);
-
- /* Return the validated limits via metadata. */
- libcameraMetadata_.set(controls::FrameDurationLimits,
- { static_cast<int64_t>(minFrameDuration_.get<std::micro>()),
- static_cast<int64_t>(maxFrameDuration_.get<std::micro>()) });
-
- /*
- * Calculate the maximum exposure time possible for the AGC to use.
- * GetVBlanking() will update maxShutter with the largest exposure
- * value possible.
- */
- Duration maxShutter = Duration::max();
- helper_->GetVBlanking(maxShutter, minFrameDuration_, maxFrameDuration_);
-
- RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
- controller_.GetAlgorithm("agc"));
- agc->SetMaxShutter(maxShutter);
-}
-
-void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
-{
- int32_t gainCode = helper_->GainCode(agcStatus->analogue_gain);
-
- /*
- * Ensure anything larger than the max gain code will not be passed to
- * DelayedControls. The AGC will correctly handle a lower gain returned
- * by the sensor, provided it knows the actual gain used.
- */
- gainCode = std::min<int32_t>(gainCode, maxSensorGainCode_);
-
- /* GetVBlanking might clip exposure time to the fps limits. */
- Duration exposure = agcStatus->shutter_time;
- int32_t vblanking = helper_->GetVBlanking(exposure, minFrameDuration_, maxFrameDuration_);
- int32_t exposureLines = helper_->ExposureLines(exposure);
-
- LOG(IPARPI, Debug) << "Applying AGC Exposure: " << exposure
- << " (Shutter lines: " << exposureLines << ", AGC requested "
- << agcStatus->shutter_time << ") Gain: "
- << agcStatus->analogue_gain << " (Gain Code: "
- << gainCode << ")";
-
- /*
- * Due to the behavior of V4L2, the current value of VBLANK could clip the
- * exposure time without us knowing. The next time though this function should
- * clip exposure correctly.
- */
- ctrls.set(V4L2_CID_VBLANK, vblanking);
- ctrls.set(V4L2_CID_EXPOSURE, exposureLines);
- ctrls.set(V4L2_CID_ANALOGUE_GAIN, gainCode);
-}
-
-void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls)
-{
- ctrls.set(V4L2_CID_DIGITAL_GAIN,
- static_cast<int32_t>(dgStatus->digital_gain * 1000));
-}
-
-void IPARPi::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls)
-{
- bcm2835_isp_custom_ccm ccm;
-
- for (int i = 0; i < 9; i++) {
- ccm.ccm.ccm[i / 3][i % 3].den = 1000;
- ccm.ccm.ccm[i / 3][i % 3].num = 1000 * ccmStatus->matrix[i];
- }
-
- ccm.enabled = 1;
- ccm.ccm.offsets[0] = ccm.ccm.offsets[1] = ccm.ccm.offsets[2] = 0;
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&ccm),
- sizeof(ccm) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_CC_MATRIX, c);
-}
-
-void IPARPi::applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls)
-{
- struct bcm2835_isp_gamma gamma;
-
- gamma.enabled = 1;
- for (int i = 0; i < CONTRAST_NUM_POINTS; i++) {
- gamma.x[i] = contrastStatus->points[i].x;
- gamma.y[i] = contrastStatus->points[i].y;
- }
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&gamma),
- sizeof(gamma) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_GAMMA, c);
-}
-
-void IPARPi::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls)
-{
- bcm2835_isp_black_level blackLevel;
-
- blackLevel.enabled = 1;
- blackLevel.black_level_r = blackLevelStatus->black_level_r;
- blackLevel.black_level_g = blackLevelStatus->black_level_g;
- blackLevel.black_level_b = blackLevelStatus->black_level_b;
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&blackLevel),
- sizeof(blackLevel) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL, c);
-}
-
-void IPARPi::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls)
-{
- bcm2835_isp_geq geq;
-
- geq.enabled = 1;
- geq.offset = geqStatus->offset;
- geq.slope.den = 1000;
- geq.slope.num = 1000 * geqStatus->slope;
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&geq),
- sizeof(geq) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_GEQ, c);
-}
-
-void IPARPi::applyDenoise(const struct DenoiseStatus *denoiseStatus, ControlList &ctrls)
-{
- using RPiController::DenoiseMode;
-
- bcm2835_isp_denoise denoise;
- DenoiseMode mode = static_cast<DenoiseMode>(denoiseStatus->mode);
-
- denoise.enabled = mode != DenoiseMode::Off;
- denoise.constant = denoiseStatus->noise_constant;
- denoise.slope.num = 1000 * denoiseStatus->noise_slope;
- denoise.slope.den = 1000;
- denoise.strength.num = 1000 * denoiseStatus->strength;
- denoise.strength.den = 1000;
-
- /* Set the CDN mode to match the SDN operating mode. */
- bcm2835_isp_cdn cdn;
- switch (mode) {
- case DenoiseMode::ColourFast:
- cdn.enabled = 1;
- cdn.mode = CDN_MODE_FAST;
- break;
- case DenoiseMode::ColourHighQuality:
- cdn.enabled = 1;
- cdn.mode = CDN_MODE_HIGH_QUALITY;
- break;
- default:
- cdn.enabled = 0;
- }
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&denoise),
- sizeof(denoise) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_DENOISE, c);
-
- c = ControlValue(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&cdn),
- sizeof(cdn) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_CDN, c);
-}
-
-void IPARPi::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList &ctrls)
-{
- bcm2835_isp_sharpen sharpen;
-
- sharpen.enabled = 1;
- sharpen.threshold.num = 1000 * sharpenStatus->threshold;
- sharpen.threshold.den = 1000;
- sharpen.strength.num = 1000 * sharpenStatus->strength;
- sharpen.strength.den = 1000;
- sharpen.limit.num = 1000 * sharpenStatus->limit;
- sharpen.limit.den = 1000;
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&sharpen),
- sizeof(sharpen) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_SHARPEN, c);
-}
-
-void IPARPi::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls)
-{
- bcm2835_isp_dpc dpc;
-
- dpc.enabled = 1;
- dpc.strength = dpcStatus->strength;
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&dpc),
- sizeof(dpc) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_DPC, c);
-}
-
-void IPARPi::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls)
-{
- /*
- * Program lens shading tables into pipeline.
- * Choose smallest cell size that won't exceed 63x48 cells.
- */
- const int cellSizes[] = { 16, 32, 64, 128, 256 };
- unsigned int numCells = std::size(cellSizes);
- unsigned int i, w, h, cellSize;
- for (i = 0; i < numCells; i++) {
- cellSize = cellSizes[i];
- w = (mode_.width + cellSize - 1) / cellSize;
- h = (mode_.height + cellSize - 1) / cellSize;
- if (w < 64 && h <= 48)
- break;
- }
-
- if (i == numCells) {
- LOG(IPARPI, Error) << "Cannot find cell size";
- return;
- }
-
- /* We're going to supply corner sampled tables, 16 bit samples. */
- w++, h++;
- bcm2835_isp_lens_shading ls = {
- .enabled = 1,
- .grid_cell_size = cellSize,
- .grid_width = w,
- .grid_stride = w,
- .grid_height = h,
- /* .dmabuf will be filled in by pipeline handler. */
- .dmabuf = 0,
- .ref_transform = 0,
- .corner_sampled = 1,
- .gain_format = GAIN_FORMAT_U4P10
- };
-
- if (!lsTable_ || w * h * 4 * sizeof(uint16_t) > MaxLsGridSize) {
- LOG(IPARPI, Error) << "Do not have a correctly allocate lens shading table!";
- return;
- }
-
- if (lsStatus) {
- /* Format will be u4.10 */
- uint16_t *grid = static_cast<uint16_t *>(lsTable_);
-
- resampleTable(grid, lsStatus->r, w, h);
- resampleTable(grid + w * h, lsStatus->g, w, h);
- std::memcpy(grid + 2 * w * h, grid + w * h, w * h * sizeof(uint16_t));
- resampleTable(grid + 3 * w * h, lsStatus->b, w, h);
- }
-
- ControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&ls),
- sizeof(ls) });
- ctrls.set(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING, c);
-}
-
-/*
- * Resamples a 16x12 table with central sampling to destW x destH with corner
- * sampling.
- */
-void IPARPi::resampleTable(uint16_t dest[], double const src[12][16],
- int destW, int destH)
-{
- /*
- * Precalculate and cache the x sampling locations and phases to
- * save recomputing them on every row.
- */
- assert(destW > 1 && destH > 1 && destW <= 64);
- int xLo[64], xHi[64];
- double xf[64];
- double x = -0.5, xInc = 16.0 / (destW - 1);
- for (int i = 0; i < destW; i++, x += xInc) {
- xLo[i] = floor(x);
- xf[i] = x - xLo[i];
- xHi[i] = xLo[i] < 15 ? xLo[i] + 1 : 15;
- xLo[i] = xLo[i] > 0 ? xLo[i] : 0;
- }
-
- /* Now march over the output table generating the new values. */
- double y = -0.5, yInc = 12.0 / (destH - 1);
- for (int j = 0; j < destH; j++, y += yInc) {
- int yLo = floor(y);
- double yf = y - yLo;
- int yHi = yLo < 11 ? yLo + 1 : 11;
- yLo = yLo > 0 ? yLo : 0;
- double const *rowAbove = src[yLo];
- double const *rowBelow = src[yHi];
- for (int i = 0; i < destW; i++) {
- double above = rowAbove[xLo[i]] * (1 - xf[i]) + rowAbove[xHi[i]] * xf[i];
- double below = rowBelow[xLo[i]] * (1 - xf[i]) + rowBelow[xHi[i]] * xf[i];
- int result = floor(1024 * (above * (1 - yf) + below * yf) + .5);
- *(dest++) = result > 16383 ? 16383 : result; /* want u4.10 */
- }
- }
-}
-
-} /* namespace ipa::RPi */
-
-/*
- * External IPA module interface
- */
-extern "C" {
-const struct IPAModuleInfo ipaModuleInfo = {
- IPA_MODULE_API_VERSION,
- 1,
- "PipelineHandlerRPi",
- "raspberrypi",
-};
-
-IPAInterface *ipaCreate()
-{
- return new ipa::RPi::IPARPi();
-}
-
-} /* extern "C" */
-
-} /* namespace libcamera */