libcamera: ipa: simple: Make gamma adjustable
The gamma value is fixed in software ISP. Let's make it adjustable, similarly to contrast and saturation, and report it in metadata. Reviewed-by: Robert Mader <robert.mader@collabora.com> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
committed by
Kieran Bingham
parent
e8e2bd39f9
commit
0f01a68086
@@ -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());
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user