| Message ID | 20260816204259.2845517-2-opensource@inspiredexperts.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
Hi James, On Sun, Aug 16, 2026 at 02:42:57PM -0600, James Alexander wrote: > Simple IPA tuning files can enable Adjust, but they cannot choose the > starting gamma, contrast or saturation. That leaves sensor-specific tuning > unable to set useful defaults without application controls. > > Read optional values from the Adjust section, clamp them to the existing > control ranges and use them as both control defaults and initial state. Existing > tuning files keep the current defaults. > > Build-tested against libcamera base b8910c9a4961 and hardware-tested as part of > the complete patch set on the target HP Spectre. > > Signed-off-by: James Alexander <opensource@inspiredexperts.com> I think this is not too different from what an HW ISP does: you specify a gamma value in tuning file, and eventually override it with controls at run-time. This makes sense to me: Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> But I would like someone that knows about softisp to give a look here. Thanks j > --- > diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp > index 8bf39c4..be29127 100644 > --- a/src/ipa/simple/algorithms/adjust.cpp > +++ b/src/ipa/simple/algorithms/adjust.cpp > @@ -24,24 +24,38 @@ constexpr float kDefaultSaturation = 1.0f; > > LOG_DEFINE_CATEGORY(IPASoftAdjust) > > -int Adjust::init(IPAContext &context, [[maybe_unused]] const ValueNode &tuningData) > +int Adjust::init(IPAContext &context, const ValueNode &tuningData) > { > + auto gamma = tuningData["gamma"].get<float>(); > + if (gamma.has_value()) > + defaultGamma_ = std::clamp(gamma.value(), 0.1f, 10.0f); > + > + auto contrast = tuningData["contrast"].get<float>(); > + if (contrast.has_value()) > + defaultContrast_ = std::clamp(contrast.value(), 0.0f, 2.0f); > + > + auto saturation = tuningData["saturation"].get<float>(); > + if (saturation.has_value()) > + defaultSaturation_ = std::clamp(saturation.value(), 0.0f, 2.0f); > + > context.ctrlMap[&controls::Gamma] = > - ControlInfo(0.1f, 10.0f, kDefaultGamma); > + ControlInfo(0.1f, 10.0f, defaultGamma_); > context.ctrlMap[&controls::Contrast] = > - ControlInfo(0.0f, 2.0f, kDefaultContrast); > + ControlInfo(0.0f, 2.0f, defaultContrast_); > if (context.ccmEnabled) > context.ctrlMap[&controls::Saturation] = > - ControlInfo(0.0f, 2.0f, kDefaultSaturation); > + ControlInfo(0.0f, 2.0f, defaultSaturation_); > return 0; > } > > int Adjust::configure(IPAContext &context, > [[maybe_unused]] const IPAConfigInfo &configInfo) > { > - context.activeState.knobs.gamma = kDefaultGamma; > - context.activeState.knobs.contrast = std::optional<float>(); > + context.activeState.knobs.gamma = defaultGamma_; > + context.activeState.knobs.contrast = defaultContrast_; > context.activeState.knobs.saturation = std::optional<float>(); > + if (context.ccmEnabled) > + context.activeState.knobs.saturation = defaultSaturation_; > > return 0; > } > diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h > index 49c1f26..1968b7c 100644 > --- a/src/ipa/simple/algorithms/adjust.h > +++ b/src/ipa/simple/algorithms/adjust.h > @@ -7,6 +7,8 @@ > > #pragma once > > +#include <optional> > + > #include "libcamera/internal/matrix.h" > > #include <libipa/interpolator.h> > @@ -43,6 +45,10 @@ public: > > private: > void applySaturation(Matrix<float, 3, 3> &ccm, float saturation); > + > + float defaultGamma_ = kDefaultGamma; > + float defaultContrast_ = 1.0f; > + float defaultSaturation_ = 1.0f; > }; > > } /* namespace ipa::soft::algorithms */ > -- > 2.46.0
Quoting Jacopo Mondi (2026-08-18 11:26:42) > Hi James, > > On Sun, Aug 16, 2026 at 02:42:57PM -0600, James Alexander wrote: > > Simple IPA tuning files can enable Adjust, but they cannot choose the > > starting gamma, contrast or saturation. That leaves sensor-specific tuning > > unable to set useful defaults without application controls. > > > > Read optional values from the Adjust section, clamp them to the existing > > control ranges and use them as both control defaults and initial state. Existing > > tuning files keep the current defaults. > > > > Build-tested against libcamera base b8910c9a4961 and hardware-tested as part of > > the complete patch set on the target HP Spectre. > > > > Signed-off-by: James Alexander <opensource@inspiredexperts.com> > > I think this is not too different from what an HW ISP does: you > specify a gamma value in tuning file, and eventually override it > with controls at run-time. > > This makes sense to me: > Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> > > But I would like someone that knows about softisp to give a look here. Should this also convert to the common implementation thought to ensure consistent behaviour? Dan has done the IPU3: - https://patchwork.libcamera.org/patch/27069/ > > Thanks > j > > > --- > > diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp > > index 8bf39c4..be29127 100644 > > --- a/src/ipa/simple/algorithms/adjust.cpp > > +++ b/src/ipa/simple/algorithms/adjust.cpp > > @@ -24,24 +24,38 @@ constexpr float kDefaultSaturation = 1.0f; > > > > LOG_DEFINE_CATEGORY(IPASoftAdjust) > > > > -int Adjust::init(IPAContext &context, [[maybe_unused]] const ValueNode &tuningData) > > +int Adjust::init(IPAContext &context, const ValueNode &tuningData) > > { > > + auto gamma = tuningData["gamma"].get<float>(); > > + if (gamma.has_value()) > > + defaultGamma_ = std::clamp(gamma.value(), 0.1f, 10.0f); > > + > > + auto contrast = tuningData["contrast"].get<float>(); > > + if (contrast.has_value()) > > + defaultContrast_ = std::clamp(contrast.value(), 0.0f, 2.0f); > > + > > + auto saturation = tuningData["saturation"].get<float>(); > > + if (saturation.has_value()) > > + defaultSaturation_ = std::clamp(saturation.value(), 0.0f, 2.0f); > > + > > context.ctrlMap[&controls::Gamma] = > > - ControlInfo(0.1f, 10.0f, kDefaultGamma); > > + ControlInfo(0.1f, 10.0f, defaultGamma_); > > context.ctrlMap[&controls::Contrast] = > > - ControlInfo(0.0f, 2.0f, kDefaultContrast); > > + ControlInfo(0.0f, 2.0f, defaultContrast_); > > if (context.ccmEnabled) > > context.ctrlMap[&controls::Saturation] = > > - ControlInfo(0.0f, 2.0f, kDefaultSaturation); > > + ControlInfo(0.0f, 2.0f, defaultSaturation_); > > return 0; > > } > > > > int Adjust::configure(IPAContext &context, > > [[maybe_unused]] const IPAConfigInfo &configInfo) > > { > > - context.activeState.knobs.gamma = kDefaultGamma; > > - context.activeState.knobs.contrast = std::optional<float>(); > > + context.activeState.knobs.gamma = defaultGamma_; > > + context.activeState.knobs.contrast = defaultContrast_; > > context.activeState.knobs.saturation = std::optional<float>(); > > + if (context.ccmEnabled) > > + context.activeState.knobs.saturation = defaultSaturation_; > > > > return 0; > > } > > diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h > > index 49c1f26..1968b7c 100644 > > --- a/src/ipa/simple/algorithms/adjust.h > > +++ b/src/ipa/simple/algorithms/adjust.h > > @@ -7,6 +7,8 @@ > > > > #pragma once > > > > +#include <optional> > > + > > #include "libcamera/internal/matrix.h" > > > > #include <libipa/interpolator.h> > > @@ -43,6 +45,10 @@ public: > > > > private: > > void applySaturation(Matrix<float, 3, 3> &ccm, float saturation); > > + > > + float defaultGamma_ = kDefaultGamma; > > + float defaultContrast_ = 1.0f; > > + float defaultSaturation_ = 1.0f; > > }; > > > > } /* namespace ipa::soft::algorithms */ > > -- > > 2.46.0
diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp index 8bf39c4..be29127 100644 --- a/src/ipa/simple/algorithms/adjust.cpp +++ b/src/ipa/simple/algorithms/adjust.cpp @@ -24,24 +24,38 @@ constexpr float kDefaultSaturation = 1.0f; LOG_DEFINE_CATEGORY(IPASoftAdjust) -int Adjust::init(IPAContext &context, [[maybe_unused]] const ValueNode &tuningData) +int Adjust::init(IPAContext &context, const ValueNode &tuningData) { + auto gamma = tuningData["gamma"].get<float>(); + if (gamma.has_value()) + defaultGamma_ = std::clamp(gamma.value(), 0.1f, 10.0f); + + auto contrast = tuningData["contrast"].get<float>(); + if (contrast.has_value()) + defaultContrast_ = std::clamp(contrast.value(), 0.0f, 2.0f); + + auto saturation = tuningData["saturation"].get<float>(); + if (saturation.has_value()) + defaultSaturation_ = std::clamp(saturation.value(), 0.0f, 2.0f); + context.ctrlMap[&controls::Gamma] = - ControlInfo(0.1f, 10.0f, kDefaultGamma); + ControlInfo(0.1f, 10.0f, defaultGamma_); context.ctrlMap[&controls::Contrast] = - ControlInfo(0.0f, 2.0f, kDefaultContrast); + ControlInfo(0.0f, 2.0f, defaultContrast_); if (context.ccmEnabled) context.ctrlMap[&controls::Saturation] = - ControlInfo(0.0f, 2.0f, kDefaultSaturation); + ControlInfo(0.0f, 2.0f, defaultSaturation_); return 0; } int Adjust::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { - context.activeState.knobs.gamma = kDefaultGamma; - context.activeState.knobs.contrast = std::optional<float>(); + context.activeState.knobs.gamma = defaultGamma_; + context.activeState.knobs.contrast = defaultContrast_; context.activeState.knobs.saturation = std::optional<float>(); + if (context.ccmEnabled) + context.activeState.knobs.saturation = defaultSaturation_; return 0; } diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h index 49c1f26..1968b7c 100644 --- a/src/ipa/simple/algorithms/adjust.h +++ b/src/ipa/simple/algorithms/adjust.h @@ -7,6 +7,8 @@ #pragma once +#include <optional> + #include "libcamera/internal/matrix.h" #include <libipa/interpolator.h> @@ -43,6 +45,10 @@ public: private: void applySaturation(Matrix<float, 3, 3> &ccm, float saturation); + + float defaultGamma_ = kDefaultGamma; + float defaultContrast_ = 1.0f; + float defaultSaturation_ = 1.0f; }; } /* namespace ipa::soft::algorithms */
Simple IPA tuning files can enable Adjust, but they cannot choose the starting gamma, contrast or saturation. That leaves sensor-specific tuning unable to set useful defaults without application controls. Read optional values from the Adjust section, clamp them to the existing control ranges and use them as both control defaults and initial state. Existing tuning files keep the current defaults. Build-tested against libcamera base b8910c9a4961 and hardware-tested as part of the complete patch set on the target HP Spectre. Signed-off-by: James Alexander <opensource@inspiredexperts.com> ---