| Message ID | 20260122161935.208562-10-mzamazal@redhat.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
Reviewed-by: Robert Mader <robert.mader@collabora.com> On 22.01.26 17:19, Milan Zamazal wrote: > The gamma value is fixed in software ISP. Let's make it adjustable, > similarly to contrast and saturation, and report it in metadata. > > Signed-off-by: Milan Zamazal <mzamazal@redhat.com> > --- > src/ipa/simple/algorithms/adjust.cpp | 12 ++++++++++++ > src/ipa/simple/algorithms/adjust.h | 4 +++- > src/ipa/simple/algorithms/lut.cpp | 11 ++++++----- > src/ipa/simple/ipa_context.h | 6 ++++-- > 4 files changed, 25 insertions(+), 8 deletions(-) > > diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp > index 27ae2a53a..a067f7b84 100644 > --- a/src/ipa/simple/algorithms/adjust.cpp > +++ b/src/ipa/simple/algorithms/adjust.cpp > @@ -23,6 +23,7 @@ LOG_DEFINE_CATEGORY(IPASoftAdjust) > > int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) > { > + context.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, kDefaultGamma); > context.ctrlMap[&controls::Contrast] = ControlInfo(0.0f, 2.0f, 1.0f); > if (context.ccmEnabled) > context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f); > @@ -32,6 +33,7 @@ int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningD > int Adjust::configure(IPAContext &context, > [[maybe_unused]] const IPAConfigInfo &configInfo) > { > + context.activeState.knobs.gamma = kDefaultGamma; > context.activeState.knobs.contrast = std::optional<double>(); > context.activeState.knobs.saturation = std::optional<double>(); > > @@ -43,6 +45,12 @@ void Adjust::queueRequest(typename Module::Context &context, > [[maybe_unused]] typename Module::FrameContext &frameContext, > const ControlList &controls) > { > + const auto &gamma = controls.get(controls::Gamma); > + if (gamma.has_value()) { > + context.activeState.knobs.gamma = gamma.value(); > + LOG(IPASoftAdjust, Debug) << "Setting gamma to " << gamma.value(); > + } > + > const auto &contrast = controls.get(controls::Contrast); > if (contrast.has_value()) { > context.activeState.knobs.contrast = contrast; > @@ -83,6 +91,7 @@ void Adjust::prepare(IPAContext &context, > IPAFrameContext &frameContext, > [[maybe_unused]] DebayerParams *params) > { > + frameContext.gamma = context.activeState.knobs.gamma; > frameContext.contrast = context.activeState.knobs.contrast; > > if (!context.ccmEnabled) > @@ -105,6 +114,9 @@ void Adjust::process([[maybe_unused]] IPAContext &context, > [[maybe_unused]] const SwIspStats *stats, > ControlList &metadata) > { > + const auto &gamma = frameContext.gamma; > + metadata.set(controls::Gamma, gamma); > + > const auto &contrast = frameContext.contrast; > if (contrast) > metadata.set(controls::Contrast, contrast.value()); > diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h > index c4baa2503..7644138ff 100644 > --- a/src/ipa/simple/algorithms/adjust.h > +++ b/src/ipa/simple/algorithms/adjust.h > @@ -1,6 +1,6 @@ > /* SPDX-License-Identifier: LGPL-2.1-or-later */ > /* > - * Copyright (C) 2024-2025, Red Hat Inc. > + * Copyright (C) 2024-2026, Red Hat Inc. > * > * Color correction matrix > */ > @@ -19,6 +19,8 @@ namespace libcamera { > > namespace ipa::soft::algorithms { > > +constexpr float kDefaultGamma = 2.2f; > + > class Adjust : public Algorithm > { > public: > diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp > index 3a00bf4ee..9740f8c8d 100644 > --- a/src/ipa/simple/algorithms/lut.cpp > +++ b/src/ipa/simple/algorithms/lut.cpp > @@ -18,6 +18,8 @@ > > #include "simple/ipa_context.h" > > +#include "adjust.h" > + > namespace libcamera { > > LOG_DEFINE_CATEGORY(IPASoftLut) > @@ -27,8 +29,6 @@ namespace ipa::soft::algorithms { > int Lut::configure(IPAContext &context, > [[maybe_unused]] const IPAConfigInfo &configInfo) > { > - /* Gamma value is fixed */ > - context.configuration.gamma = 1.0 / 2.2; > updateGammaTable(context); > > return 0; > @@ -37,6 +37,7 @@ int Lut::configure(IPAContext &context, > void Lut::updateGammaTable(IPAContext &context) > { > const auto blackLevel = context.activeState.blc.level; > + const auto gamma = 1.0 / context.activeState.knobs.gamma; > const auto contrast = context.activeState.knobs.contrast.value_or(1.0); > /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ > double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); > @@ -52,8 +53,7 @@ void Lut::updateGammaTable(IPAContext &context) > normalized = 0.5 * std::pow(normalized / 0.5, contrastExp); > else > normalized = 1.0 - 0.5 * std::pow((1.0 - normalized) / 0.5, contrastExp); > - gammaTable[i] = UINT8_MAX * > - std::pow(normalized, context.configuration.gamma); > + gammaTable[i] = UINT8_MAX * std::pow(normalized, gamma); > } > /* > * Due to CCM operations, the table lookup may reach indices below the black > @@ -65,6 +65,7 @@ void Lut::updateGammaTable(IPAContext &context) > gammaTable[blackIndex]); > } > > + context.activeState.gamma.gamma = gamma; > context.activeState.gamma.blackLevel = blackLevel; > context.activeState.gamma.contrastExp = contrastExp; > } > @@ -131,7 +132,7 @@ void Lut::prepare(IPAContext &context, > context.activeState.matrixChanged = false; > } > > - params->gamma = context.configuration.gamma; > + params->gamma = context.activeState.gamma.gamma; > params->contrastExp = context.activeState.gamma.contrastExp; > } > > diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h > index a3ff3d038..eeade9d35 100644 > --- a/src/ipa/simple/ipa_context.h > +++ b/src/ipa/simple/ipa_context.h > @@ -1,6 +1,6 @@ > /* SPDX-License-Identifier: LGPL-2.1-or-later */ > /* > - * Copyright (C) 2024-2025 Red Hat, Inc. > + * Copyright (C) 2024-2026 Red Hat, Inc. > * > * Simple pipeline IPA Context > */ > @@ -25,7 +25,6 @@ namespace libcamera { > namespace ipa::soft { > > struct IPASessionConfiguration { > - float gamma; > struct { > int32_t exposureMin, exposureMax; > double againMin, againMax, again10, againMinStep; > @@ -58,6 +57,7 @@ struct IPAActiveState { > struct { > std::array<double, kGammaLookupSize> gammaTable; > uint8_t blackLevel; > + float gamma; > double contrast; > double contrastExp; > } gamma; > @@ -66,6 +66,7 @@ struct IPAActiveState { > bool matrixChanged = false; > > struct { > + float gamma; > /* 0..2 range, 1.0 = normal */ > std::optional<double> contrast; > std::optional<float> saturation; > @@ -85,6 +86,7 @@ struct IPAFrameContext : public FrameContext { > double blue; > } gains; > > + float gamma; > std::optional<double> contrast; > std::optional<float> saturation; > };
2026. 01. 22. 17:19 keltezéssel, Milan Zamazal írta: > The gamma value is fixed in software ISP. Let's make it adjustable, > similarly to contrast and saturation, and report it in metadata. > > Signed-off-by: Milan Zamazal <mzamazal@redhat.com> > --- Seems fine to me. Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > src/ipa/simple/algorithms/adjust.cpp | 12 ++++++++++++ > src/ipa/simple/algorithms/adjust.h | 4 +++- > src/ipa/simple/algorithms/lut.cpp | 11 ++++++----- > src/ipa/simple/ipa_context.h | 6 ++++-- > 4 files changed, 25 insertions(+), 8 deletions(-) > > diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp > index 27ae2a53a..a067f7b84 100644 > --- a/src/ipa/simple/algorithms/adjust.cpp > +++ b/src/ipa/simple/algorithms/adjust.cpp > @@ -23,6 +23,7 @@ LOG_DEFINE_CATEGORY(IPASoftAdjust) > > int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) > { > + context.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, kDefaultGamma); > context.ctrlMap[&controls::Contrast] = ControlInfo(0.0f, 2.0f, 1.0f); > if (context.ccmEnabled) > context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f); > @@ -32,6 +33,7 @@ int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningD > int Adjust::configure(IPAContext &context, > [[maybe_unused]] const IPAConfigInfo &configInfo) > { > + context.activeState.knobs.gamma = kDefaultGamma; > context.activeState.knobs.contrast = std::optional<double>(); > context.activeState.knobs.saturation = std::optional<double>(); > > @@ -43,6 +45,12 @@ void Adjust::queueRequest(typename Module::Context &context, > [[maybe_unused]] typename Module::FrameContext &frameContext, > const ControlList &controls) > { > + const auto &gamma = controls.get(controls::Gamma); > + if (gamma.has_value()) { > + context.activeState.knobs.gamma = gamma.value(); > + LOG(IPASoftAdjust, Debug) << "Setting gamma to " << gamma.value(); > + } > + > const auto &contrast = controls.get(controls::Contrast); > if (contrast.has_value()) { > context.activeState.knobs.contrast = contrast; > @@ -83,6 +91,7 @@ void Adjust::prepare(IPAContext &context, > IPAFrameContext &frameContext, > [[maybe_unused]] DebayerParams *params) > { > + frameContext.gamma = context.activeState.knobs.gamma; > frameContext.contrast = context.activeState.knobs.contrast; > > if (!context.ccmEnabled) > @@ -105,6 +114,9 @@ void Adjust::process([[maybe_unused]] IPAContext &context, > [[maybe_unused]] const SwIspStats *stats, > ControlList &metadata) > { > + const auto &gamma = frameContext.gamma; > + metadata.set(controls::Gamma, gamma); > + > const auto &contrast = frameContext.contrast; > if (contrast) > metadata.set(controls::Contrast, contrast.value()); > diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h > index c4baa2503..7644138ff 100644 > --- a/src/ipa/simple/algorithms/adjust.h > +++ b/src/ipa/simple/algorithms/adjust.h > @@ -1,6 +1,6 @@ > /* SPDX-License-Identifier: LGPL-2.1-or-later */ > /* > - * Copyright (C) 2024-2025, Red Hat Inc. > + * Copyright (C) 2024-2026, Red Hat Inc. > * > * Color correction matrix > */ > @@ -19,6 +19,8 @@ namespace libcamera { > > namespace ipa::soft::algorithms { > > +constexpr float kDefaultGamma = 2.2f; > + > class Adjust : public Algorithm > { > public: > diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp > index 3a00bf4ee..9740f8c8d 100644 > --- a/src/ipa/simple/algorithms/lut.cpp > +++ b/src/ipa/simple/algorithms/lut.cpp > @@ -18,6 +18,8 @@ > > #include "simple/ipa_context.h" > > +#include "adjust.h" > + > namespace libcamera { > > LOG_DEFINE_CATEGORY(IPASoftLut) > @@ -27,8 +29,6 @@ namespace ipa::soft::algorithms { > int Lut::configure(IPAContext &context, > [[maybe_unused]] const IPAConfigInfo &configInfo) > { > - /* Gamma value is fixed */ > - context.configuration.gamma = 1.0 / 2.2; > updateGammaTable(context); > > return 0; > @@ -37,6 +37,7 @@ int Lut::configure(IPAContext &context, > void Lut::updateGammaTable(IPAContext &context) > { > const auto blackLevel = context.activeState.blc.level; > + const auto gamma = 1.0 / context.activeState.knobs.gamma; > const auto contrast = context.activeState.knobs.contrast.value_or(1.0); > /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ > double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); > @@ -52,8 +53,7 @@ void Lut::updateGammaTable(IPAContext &context) > normalized = 0.5 * std::pow(normalized / 0.5, contrastExp); > else > normalized = 1.0 - 0.5 * std::pow((1.0 - normalized) / 0.5, contrastExp); > - gammaTable[i] = UINT8_MAX * > - std::pow(normalized, context.configuration.gamma); > + gammaTable[i] = UINT8_MAX * std::pow(normalized, gamma); > } > /* > * Due to CCM operations, the table lookup may reach indices below the black > @@ -65,6 +65,7 @@ void Lut::updateGammaTable(IPAContext &context) > gammaTable[blackIndex]); > } > > + context.activeState.gamma.gamma = gamma; > context.activeState.gamma.blackLevel = blackLevel; > context.activeState.gamma.contrastExp = contrastExp; > } > @@ -131,7 +132,7 @@ void Lut::prepare(IPAContext &context, > context.activeState.matrixChanged = false; > } > > - params->gamma = context.configuration.gamma; > + params->gamma = context.activeState.gamma.gamma; > params->contrastExp = context.activeState.gamma.contrastExp; > } > > diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h > index a3ff3d038..eeade9d35 100644 > --- a/src/ipa/simple/ipa_context.h > +++ b/src/ipa/simple/ipa_context.h > @@ -1,6 +1,6 @@ > /* SPDX-License-Identifier: LGPL-2.1-or-later */ > /* > - * Copyright (C) 2024-2025 Red Hat, Inc. > + * Copyright (C) 2024-2026 Red Hat, Inc. > * > * Simple pipeline IPA Context > */ > @@ -25,7 +25,6 @@ namespace libcamera { > namespace ipa::soft { > > struct IPASessionConfiguration { > - float gamma; > struct { > int32_t exposureMin, exposureMax; > double againMin, againMax, again10, againMinStep; > @@ -58,6 +57,7 @@ struct IPAActiveState { > struct { > std::array<double, kGammaLookupSize> gammaTable; > uint8_t blackLevel; > + float gamma; > double contrast; > double contrastExp; > } gamma; > @@ -66,6 +66,7 @@ struct IPAActiveState { > bool matrixChanged = false; > > struct { > + float gamma; > /* 0..2 range, 1.0 = normal */ > std::optional<double> contrast; > std::optional<float> saturation; > @@ -85,6 +86,7 @@ struct IPAFrameContext : public FrameContext { > double blue; > } gains; > > + float gamma; > std::optional<double> contrast; > std::optional<float> saturation; > };
diff --git a/src/ipa/simple/algorithms/adjust.cpp b/src/ipa/simple/algorithms/adjust.cpp index 27ae2a53a..a067f7b84 100644 --- a/src/ipa/simple/algorithms/adjust.cpp +++ b/src/ipa/simple/algorithms/adjust.cpp @@ -23,6 +23,7 @@ LOG_DEFINE_CATEGORY(IPASoftAdjust) int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) { + context.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, kDefaultGamma); context.ctrlMap[&controls::Contrast] = ControlInfo(0.0f, 2.0f, 1.0f); if (context.ccmEnabled) context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f); @@ -32,6 +33,7 @@ int Adjust::init(IPAContext &context, [[maybe_unused]] const YamlObject &tuningD int Adjust::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { + context.activeState.knobs.gamma = kDefaultGamma; context.activeState.knobs.contrast = std::optional<double>(); context.activeState.knobs.saturation = std::optional<double>(); @@ -43,6 +45,12 @@ void Adjust::queueRequest(typename Module::Context &context, [[maybe_unused]] typename Module::FrameContext &frameContext, const ControlList &controls) { + const auto &gamma = controls.get(controls::Gamma); + if (gamma.has_value()) { + context.activeState.knobs.gamma = gamma.value(); + LOG(IPASoftAdjust, Debug) << "Setting gamma to " << gamma.value(); + } + const auto &contrast = controls.get(controls::Contrast); if (contrast.has_value()) { context.activeState.knobs.contrast = contrast; @@ -83,6 +91,7 @@ void Adjust::prepare(IPAContext &context, IPAFrameContext &frameContext, [[maybe_unused]] DebayerParams *params) { + frameContext.gamma = context.activeState.knobs.gamma; frameContext.contrast = context.activeState.knobs.contrast; if (!context.ccmEnabled) @@ -105,6 +114,9 @@ void Adjust::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const SwIspStats *stats, ControlList &metadata) { + const auto &gamma = frameContext.gamma; + metadata.set(controls::Gamma, gamma); + const auto &contrast = frameContext.contrast; if (contrast) metadata.set(controls::Contrast, contrast.value()); diff --git a/src/ipa/simple/algorithms/adjust.h b/src/ipa/simple/algorithms/adjust.h index c4baa2503..7644138ff 100644 --- a/src/ipa/simple/algorithms/adjust.h +++ b/src/ipa/simple/algorithms/adjust.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2024-2025, Red Hat Inc. + * Copyright (C) 2024-2026, Red Hat Inc. * * Color correction matrix */ @@ -19,6 +19,8 @@ namespace libcamera { namespace ipa::soft::algorithms { +constexpr float kDefaultGamma = 2.2f; + class Adjust : public Algorithm { public: diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index 3a00bf4ee..9740f8c8d 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -18,6 +18,8 @@ #include "simple/ipa_context.h" +#include "adjust.h" + namespace libcamera { LOG_DEFINE_CATEGORY(IPASoftLut) @@ -27,8 +29,6 @@ namespace ipa::soft::algorithms { int Lut::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { - /* Gamma value is fixed */ - context.configuration.gamma = 1.0 / 2.2; updateGammaTable(context); return 0; @@ -37,6 +37,7 @@ int Lut::configure(IPAContext &context, void Lut::updateGammaTable(IPAContext &context) { const auto blackLevel = context.activeState.blc.level; + const auto gamma = 1.0 / context.activeState.knobs.gamma; const auto contrast = context.activeState.knobs.contrast.value_or(1.0); /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); @@ -52,8 +53,7 @@ void Lut::updateGammaTable(IPAContext &context) normalized = 0.5 * std::pow(normalized / 0.5, contrastExp); else normalized = 1.0 - 0.5 * std::pow((1.0 - normalized) / 0.5, contrastExp); - gammaTable[i] = UINT8_MAX * - std::pow(normalized, context.configuration.gamma); + gammaTable[i] = UINT8_MAX * std::pow(normalized, gamma); } /* * Due to CCM operations, the table lookup may reach indices below the black @@ -65,6 +65,7 @@ void Lut::updateGammaTable(IPAContext &context) gammaTable[blackIndex]); } + context.activeState.gamma.gamma = gamma; context.activeState.gamma.blackLevel = blackLevel; context.activeState.gamma.contrastExp = contrastExp; } @@ -131,7 +132,7 @@ void Lut::prepare(IPAContext &context, context.activeState.matrixChanged = false; } - params->gamma = context.configuration.gamma; + params->gamma = context.activeState.gamma.gamma; params->contrastExp = context.activeState.gamma.contrastExp; } diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index a3ff3d038..eeade9d35 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2024-2025 Red Hat, Inc. + * Copyright (C) 2024-2026 Red Hat, Inc. * * Simple pipeline IPA Context */ @@ -25,7 +25,6 @@ namespace libcamera { namespace ipa::soft { struct IPASessionConfiguration { - float gamma; struct { int32_t exposureMin, exposureMax; double againMin, againMax, again10, againMinStep; @@ -58,6 +57,7 @@ struct IPAActiveState { struct { std::array<double, kGammaLookupSize> gammaTable; uint8_t blackLevel; + float gamma; double contrast; double contrastExp; } gamma; @@ -66,6 +66,7 @@ struct IPAActiveState { bool matrixChanged = false; struct { + float gamma; /* 0..2 range, 1.0 = normal */ std::optional<double> contrast; std::optional<float> saturation; @@ -85,6 +86,7 @@ struct IPAFrameContext : public FrameContext { double blue; } gains; + float gamma; std::optional<double> contrast; std::optional<float> saturation; };
The gamma value is fixed in software ISP. Let's make it adjustable, similarly to contrast and saturation, and report it in metadata. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> --- src/ipa/simple/algorithms/adjust.cpp | 12 ++++++++++++ src/ipa/simple/algorithms/adjust.h | 4 +++- src/ipa/simple/algorithms/lut.cpp | 11 ++++++----- src/ipa/simple/ipa_context.h | 6 ++++-- 4 files changed, 25 insertions(+), 8 deletions(-)