Message ID | 20230823120915.18621-5-david.plowman@raspberrypi.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi David On Wed, Aug 23, 2023 at 01:09:14PM +0100, David Plowman via libcamera-devel wrote: > 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", I haven't seen an example of a config file, can you make an example of how you would express the above with UPPER and LOWER ? > 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@raspberrypi.com> > Reviewed-by: Naushir Patuck <naush@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); would this allow "upper" and "UPPER" ? > + 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; Does this deserve an error message ? > + factor = *value; > + > + return 0; > +} > + > +static int readChannelConstraints(std::vector<AgcChannelConstraint> &channelConstraints, > + const libcamera::YamlObject ¶ms) > +{ > + int ret = 0; no need > + > + for (const auto &p : params.asList()) { > + AgcChannelConstraint constraint; > + ret = constraint.read(p); int ret = .. > + if (ret) > + return ret; > + > + channelConstraints.push_back(constraint); > + } > + > + return ret; and return 0 > +} > + > 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 >
Hi Jacopo Thanks for the review. On Wed, 30 Aug 2023 at 09:13, Jacopo Mondi <jacopo.mondi@ideasonboard.com> wrote: > > Hi David > > On Wed, Aug 23, 2023 at 01:09:14PM +0100, David Plowman via libcamera-devel wrote: > > 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", > > I haven't seen an example of a config file, can you make an example of > how you would express the above with UPPER and LOWER ? Yes, given that I'm not using this feature anywhere (though I expect other people may want to), then I should supply something. What would be most appropriate do you think, extending the commit message, comments in the source file or something different? > > > 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@raspberrypi.com> > > Reviewed-by: Naushir Patuck <naush@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); > > would this allow "upper" and "UPPER" ? Yes, or "Upper" or even "uPpEr" if you want! But failing just on account of the case doesn't seem very helpful. > > > + 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; > > Does this deserve an error message ? Good point, I think it should. > > > + factor = *value; > > + > > + return 0; > > +} > > + > > +static int readChannelConstraints(std::vector<AgcChannelConstraint> &channelConstraints, > > + const libcamera::YamlObject ¶ms) > > +{ > > + int ret = 0; > > no need > > > + > > + for (const auto &p : params.asList()) { > > + AgcChannelConstraint constraint; > > + ret = constraint.read(p); > > int ret = .. > > > + if (ret) > > + return ret; > > + > > + channelConstraints.push_back(constraint); > > + } > > + > > + return ret; > > and return 0 Yep, I can make those changes! Thanks David > > > +} > > + > > 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 > >
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;