[libcamera-devel] [PATCH v2 4/5] ipa: rpi: agc: Add AgcChannelConstraint class
David Plowman
david.plowman at raspberrypi.com
Wed Aug 23 14:09:14 CEST 2023
A channel constraint is somewhat similar to the upper/lower bound
constraints that we use elsewhere, but these constraints apply between
multiple AGC channels. For example, it lets you say things like "don't
let the channel 1 total exposure be more than 8x that of channel 0",
and so on. By using both an upper and lower bound constraint, you
could fix one AGC channel always to be a fixed ratio of another.
Also read a vector of them (if present) when loading the tuning file.
Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
Reviewed-by: Naushir Patuck <naush at raspberrypi.com>
---
src/ipa/rpi/controller/rpi/agc_channel.cpp | 42 ++++++++++++++++++++++
src/ipa/rpi/controller/rpi/agc_channel.h | 10 ++++++
2 files changed, 52 insertions(+)
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
index ddec611f..44198c2c 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
+++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
@@ -173,6 +173,42 @@ readConstraintModes(std::map<std::string, AgcConstraintMode> &constraintModes,
return { 0, first };
}
+int AgcChannelConstraint::read(const libcamera::YamlObject ¶ms)
+{
+ std::string boundString = params["bound"].get<std::string>("");
+ transform(boundString.begin(), boundString.end(),
+ boundString.begin(), ::toupper);
+ if (boundString != "UPPER" && boundString != "LOWER") {
+ LOG(RPiAgc, Error) << "AGC channelconstraint type should be UPPER or LOWER";
+ return -EINVAL;
+ }
+ bound = boundString == "UPPER" ? Bound::UPPER : Bound::LOWER;
+
+ auto value = params["factor"].get<double>();
+ if (!value)
+ return -EINVAL;
+ factor = *value;
+
+ return 0;
+}
+
+static int readChannelConstraints(std::vector<AgcChannelConstraint> &channelConstraints,
+ const libcamera::YamlObject ¶ms)
+{
+ int ret = 0;
+
+ for (const auto &p : params.asList()) {
+ AgcChannelConstraint constraint;
+ ret = constraint.read(p);
+ if (ret)
+ return ret;
+
+ channelConstraints.push_back(constraint);
+ }
+
+ return ret;
+}
+
int AgcConfig::read(const libcamera::YamlObject ¶ms)
{
LOG(RPiAgc, Debug) << "AgcConfig";
@@ -191,6 +227,12 @@ int AgcConfig::read(const libcamera::YamlObject ¶ms)
if (ret)
return ret;
+ if (params.contains("channel_constraints")) {
+ ret = readChannelConstraints(channelConstraints, params["channel_constraints"]);
+ if (ret)
+ return ret;
+ }
+
ret = yTarget.read(params["y_target"]);
if (ret)
return ret;
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h
index 0e3d44b0..446125ef 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.h
+++ b/src/ipa/rpi/controller/rpi/agc_channel.h
@@ -42,11 +42,21 @@ struct AgcConstraint {
typedef std::vector<AgcConstraint> AgcConstraintMode;
+struct AgcChannelConstraint {
+ enum class Bound { LOWER = 0,
+ UPPER = 1 };
+ Bound bound;
+ unsigned int channel;
+ double factor;
+ int read(const libcamera::YamlObject ¶ms);
+};
+
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;
+ std::vector<AgcChannelConstraint> channelConstraints;
Pwl yTarget;
double speed;
uint16_t startupFrames;
--
2.30.2
More information about the libcamera-devel
mailing list