@@ -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 = std::optional<double>();
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;
+ LOG(IPASoftAdjust, Debug) << "Setting gamma to " << gamma.value();
+ }
+
const auto &contrast = controls.get(controls::Contrast);
if (contrast.has_value()) {
context.activeState.knobs.contrast = contrast;
@@ -19,6 +19,8 @@ namespace libcamera {
namespace ipa::soft::algorithms {
+const float kDefaultGamma = 2.2f;
+
class Adjust : public Algorithm
{
public:
@@ -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 = 0.5;
updateGammaTable(context);
return 0;
@@ -39,6 +39,8 @@ void Lut::updateGammaTable(IPAContext &context)
auto &gammaTable = context.activeState.gamma.gammaTable;
const auto blackLevel = context.activeState.blc.level;
const unsigned int blackIndex = blackLevel * gammaTable.size() / 256;
+ const auto gamma =
+ 1.0 / context.activeState.knobs.gamma.value_or(kDefaultGamma);
const auto contrast = context.activeState.knobs.contrast.value_or(1.0);
const float divisor = gammaTable.size() - blackIndex - 1.0;
@@ -52,7 +54,7 @@ void Lut::updateGammaTable(IPAContext &context)
else
normalized = 1.0 - 0.5 * std::pow((1.0 - normalized) / 0.5, contrastExp);
gammaTable[i] = UINT8_MAX *
- std::pow(normalized, context.configuration.gamma);
+ std::pow(normalized, gamma);
}
/*
* Due to CCM operations, the table lookup may reach indices below the black
@@ -63,6 +65,7 @@ void Lut::updateGammaTable(IPAContext &context)
std::fill(gammaTable.begin(), gammaTable.begin() + blackIndex,
gammaTable[blackIndex]);
+ context.activeState.gamma.gamma = gamma;
context.activeState.gamma.blackLevel = blackLevel;
context.activeState.gamma.contrast = contrast;
}
@@ -57,6 +57,7 @@ struct IPAActiveState {
struct {
std::array<double, kGammaLookupSize> gammaTable;
uint8_t blackLevel;
+ float gamma;
double contrast;
} gamma;
@@ -65,6 +66,7 @@ struct IPAActiveState {
bool matrixChanged = false;
struct {
+ std::optional<float> gamma;
/* 0..2 range, 1.0 = normal */
std::optional<double> contrast;
std::optional<float> saturation;
@@ -84,6 +86,7 @@ struct IPAFrameContext : public FrameContext {
double blue;
} gains;
+ std::optional<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. The default gamma value is changed from 1/2.0 to a more common value 1/2.2, which is used in GPU ISP. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> --- src/ipa/simple/algorithms/adjust.cpp | 8 ++++++++ src/ipa/simple/algorithms/adjust.h | 2 ++ src/ipa/simple/algorithms/lut.cpp | 9 ++++++--- src/ipa/simple/ipa_context.h | 3 +++ 4 files changed, 19 insertions(+), 3 deletions(-)