diff options
Diffstat (limited to 'src/ipa/rpi/controller/rpi/agc_channel.h')
-rw-r--r-- | src/ipa/rpi/controller/rpi/agc_channel.h | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h new file mode 100644 index 00000000..aca79ef2 --- /dev/null +++ b/src/ipa/rpi/controller/rpi/agc_channel.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2023, Raspberry Pi Ltd + * + * agc_channel.h - AGC/AEC control algorithm + */ +#pragma once + +#include <map> +#include <string> +#include <vector> + +#include <libcamera/base/utils.h> + +#include "../agc_status.h" +#include "../awb_status.h" +#include "../controller.h" +#include "../pwl.h" + +/* This is our implementation of AGC. */ + +namespace RPiController { + +struct AgcMeteringMode { + std::vector<double> weights; + int read(const libcamera::YamlObject ¶ms); +}; + +struct AgcExposureMode { + std::vector<libcamera::utils::Duration> shutter; + std::vector<double> gain; + int read(const libcamera::YamlObject ¶ms); +}; + +struct AgcConstraint { + enum class Bound { LOWER = 0, + UPPER = 1 }; + Bound bound; + double qLo; + double qHi; + Pwl yTarget; + int read(const libcamera::YamlObject ¶ms); +}; + +typedef std::vector<AgcConstraint> AgcConstraintMode; + +struct AgcConfig { + int read(const libcamera::YamlObject ¶ms); + std::map<std::string, AgcMeteringMode> meteringModes; + std::map<std::string, AgcExposureMode> exposureModes; + std::map<std::string, AgcConstraintMode> constraintModes; + Pwl yTarget; + double speed; + uint16_t startupFrames; + unsigned int convergenceFrames; + double maxChange; + double minChange; + double fastReduceThreshold; + double speedUpThreshold; + std::string defaultMeteringMode; + std::string defaultExposureMode; + std::string defaultConstraintMode; + double baseEv; + libcamera::utils::Duration defaultExposureTime; + double defaultAnalogueGain; +}; + +class AgcChannel +{ +public: + AgcChannel(); + int read(const libcamera::YamlObject ¶ms, + const Controller::HardwareConfig &hardwareConfig); + unsigned int getConvergenceFrames() const; + std::vector<double> const &getWeights() const; + void setEv(double ev); + void setFlickerPeriod(libcamera::utils::Duration flickerPeriod); + void setMaxShutter(libcamera::utils::Duration maxShutter); + void setFixedShutter(libcamera::utils::Duration fixedShutter); + void setFixedAnalogueGain(double fixedAnalogueGain); + void setMeteringMode(std::string const &meteringModeName); + void setExposureMode(std::string const &exposureModeName); + void setConstraintMode(std::string const &contraintModeName); + void enableAuto(); + void disableAuto(); + void switchMode(CameraMode const &cameraMode, Metadata *metadata); + void prepare(Metadata *imageMetadata); + void process(StatisticsPtr &stats, Metadata *imageMetadata); + +private: + bool updateLockStatus(DeviceStatus const &deviceStatus); + AgcConfig config_; + void housekeepConfig(); + void fetchCurrentExposure(Metadata *imageMetadata); + void fetchAwbStatus(Metadata *imageMetadata); + void computeGain(StatisticsPtr &statistics, Metadata *imageMetadata, + double &gain, double &targetY); + void computeTargetExposure(double gain); + void filterExposure(); + bool applyDigitalGain(double gain, double targetY); + void divideUpExposure(); + void writeAndFinish(Metadata *imageMetadata, bool desaturate); + libcamera::utils::Duration limitShutter(libcamera::utils::Duration shutter); + double limitGain(double gain) const; + AgcMeteringMode *meteringMode_; + AgcExposureMode *exposureMode_; + AgcConstraintMode *constraintMode_; + CameraMode mode_; + uint64_t frameCount_; + AwbStatus awb_; + struct ExposureValues { + ExposureValues(); + + libcamera::utils::Duration shutter; + double analogueGain; + libcamera::utils::Duration totalExposure; + libcamera::utils::Duration totalExposureNoDG; /* 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 lockCount_; + DeviceStatus lastDeviceStatus_; + libcamera::utils::Duration lastTargetExposure_; + /* Below here the "settings" that applications can change. */ + std::string meteringModeName_; + std::string exposureModeName_; + std::string constraintModeName_; + double ev_; + libcamera::utils::Duration flickerPeriod_; + libcamera::utils::Duration maxShutter_; + libcamera::utils::Duration fixedShutter_; + double fixedAnalogueGain_; +}; + +} /* namespace RPiController */ |