| Message ID | 20260828140629.128831-2-dmanresa@gmail.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
Quoting D. Manresa (2026-08-28 15:06:29) > AwbAlgorithm clamps the computed white balance gains to a minimum of > 1.0. The floor reflects a common hardware limitation, as many AWB > engines cannot attenuate a colour channel, but it is applied even on > platforms whose gain range does go below 1.0, most notably the software > ISP which applies the gains in floating point during debayering. > > Some camera modules are calibrated with a white point that genuinely > requires attenuating a channel. The front OV5693 of the Microsoft > Surface Pro 7+ is one such module: the OEM calibration Microsoft ships > in the public Surface driver package (the Intel CPFF/.aiqb container > OV5693_MSHW0220_TGL.aiqb) stores per-illuminant sensor white points, > and decoding them yields a red gain of 0.87 at 2592 K (illuminant A). > With the floor in place the algorithm cannot reach the calibrated white > point under warm light, and the picture keeps a red cast that no tuning > can remove. > > Keep the 1.0 default and let the tuning file lower the limit with a new > optional "gainMin" property, clamped to the gain range of the platform > AWB engine. Platforms and sensors that do not opt in behave exactly as > before. > > An alternative would be to drop the floor entirely and trust the > platform gain range alone, but hardware IPA modules currently reuse > their gain register format (e.g. UQ2.8) as the algorithm limits, and > their pipelines may rely on gains never attenuating. An opt-in tuning > property keeps the default behaviour unchanged everywhere. > > Developed with the assistance of an AI tool (Claude) and verified on a > Surface Pro 7+ (software ISP, OEM-derived colour tuning) against the > Windows 11 rendition of the same scenes. > > Signed-off-by: D. Manresa <dmanresa@gmail.com> > --- > src/ipa/libipa/awb.cpp | 4 ++++ > src/ipa/libipa/awb.h | 14 +++++++++++++- > 2 files changed, 17 insertions(+), 1 deletion(-) > > diff --git a/src/ipa/libipa/awb.cpp b/src/ipa/libipa/awb.cpp > index da835bec0..b7f309298 100644 > --- a/src/ipa/libipa/awb.cpp > +++ b/src/ipa/libipa/awb.cpp > @@ -526,6 +526,10 @@ int AwbAlgorithmBase::parseModeConfigs(const ValueNode &tuningData, > * Minimum gain value used to clamp the AWB algorithm calculation results in the > * range supported by the platform AWB engine. > * > + * The minimum defaults to 1.0, as most ISPs cannot attenuate a colour channel. > + * On platforms that can, the "gainMin" tuning file property may lower the > + * limit, within the range supported by the platform AWB engine. > + * > * The min and max gain values are initialized by AwbAlgorithm::init(). > */ > > diff --git a/src/ipa/libipa/awb.h b/src/ipa/libipa/awb.h > index d35a85167..7fe2e5f06 100644 > --- a/src/ipa/libipa/awb.h > +++ b/src/ipa/libipa/awb.h > @@ -7,6 +7,7 @@ > > #pragma once > > +#include <algorithm> > #include <array> > #include <map> > #include <optional> > @@ -117,7 +118,18 @@ public: > { > AwbAlgorithmBase::init(tuningData); > > - gainMin_ = std::max(Q::TraitsType::min, 1.0f); > + /* > + * Gains are not allowed to go below 1.0 by default, as most > + * ISPs cannot attenuate a colour channel. Some camera I don't think it's because they can't. It's because they shouldn't ? I'd love to see a histogram from a RAW capture of the sensor. I think it would be very unexpected to really want to reduce a channel. -- Kieran > + * modules are however calibrated with a white point that > + * requires attenuating a channel, which platforms whose AWB > + * gains can go below 1.0 (such as the software ISP) are able > + * to apply. Let the tuning file lower the limit with the > + * "gainMin" property, within the platform's gain range. > + */ > + float gainMin = tuningData["gainMin"].get<float>(1.0f); > + gainMin_ = std::clamp(gainMin, Q::TraitsType::min, > + Q::TraitsType::max); > gainMax_ = Q::TraitsType::max; > > controls_[&controls::ColourGains] = > -- > 2.43.0 >
diff --git a/src/ipa/libipa/awb.cpp b/src/ipa/libipa/awb.cpp index da835bec0..b7f309298 100644 --- a/src/ipa/libipa/awb.cpp +++ b/src/ipa/libipa/awb.cpp @@ -526,6 +526,10 @@ int AwbAlgorithmBase::parseModeConfigs(const ValueNode &tuningData, * Minimum gain value used to clamp the AWB algorithm calculation results in the * range supported by the platform AWB engine. * + * The minimum defaults to 1.0, as most ISPs cannot attenuate a colour channel. + * On platforms that can, the "gainMin" tuning file property may lower the + * limit, within the range supported by the platform AWB engine. + * * The min and max gain values are initialized by AwbAlgorithm::init(). */ diff --git a/src/ipa/libipa/awb.h b/src/ipa/libipa/awb.h index d35a85167..7fe2e5f06 100644 --- a/src/ipa/libipa/awb.h +++ b/src/ipa/libipa/awb.h @@ -7,6 +7,7 @@ #pragma once +#include <algorithm> #include <array> #include <map> #include <optional> @@ -117,7 +118,18 @@ public: { AwbAlgorithmBase::init(tuningData); - gainMin_ = std::max(Q::TraitsType::min, 1.0f); + /* + * Gains are not allowed to go below 1.0 by default, as most + * ISPs cannot attenuate a colour channel. Some camera + * modules are however calibrated with a white point that + * requires attenuating a channel, which platforms whose AWB + * gains can go below 1.0 (such as the software ISP) are able + * to apply. Let the tuning file lower the limit with the + * "gainMin" property, within the platform's gain range. + */ + float gainMin = tuningData["gainMin"].get<float>(1.0f); + gainMin_ = std::clamp(gainMin, Q::TraitsType::min, + Q::TraitsType::max); gainMax_ = Q::TraitsType::max; controls_[&controls::ColourGains] =
AwbAlgorithm clamps the computed white balance gains to a minimum of 1.0. The floor reflects a common hardware limitation, as many AWB engines cannot attenuate a colour channel, but it is applied even on platforms whose gain range does go below 1.0, most notably the software ISP which applies the gains in floating point during debayering. Some camera modules are calibrated with a white point that genuinely requires attenuating a channel. The front OV5693 of the Microsoft Surface Pro 7+ is one such module: the OEM calibration Microsoft ships in the public Surface driver package (the Intel CPFF/.aiqb container OV5693_MSHW0220_TGL.aiqb) stores per-illuminant sensor white points, and decoding them yields a red gain of 0.87 at 2592 K (illuminant A). With the floor in place the algorithm cannot reach the calibrated white point under warm light, and the picture keeps a red cast that no tuning can remove. Keep the 1.0 default and let the tuning file lower the limit with a new optional "gainMin" property, clamped to the gain range of the platform AWB engine. Platforms and sensors that do not opt in behave exactly as before. An alternative would be to drop the floor entirely and trust the platform gain range alone, but hardware IPA modules currently reuse their gain register format (e.g. UQ2.8) as the algorithm limits, and their pipelines may rely on gains never attenuating. An opt-in tuning property keeps the default behaviour unchanged everywhere. Developed with the assistance of an AI tool (Claude) and verified on a Surface Pro 7+ (software ISP, OEM-derived colour tuning) against the Windows 11 rendition of the same scenes. Signed-off-by: D. Manresa <dmanresa@gmail.com> --- src/ipa/libipa/awb.cpp | 4 ++++ src/ipa/libipa/awb.h | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)