mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-14 16:09:51 +03:00
ipa: rkisp1: Add GammaOutCorrection algorithm
Add a gamma algorithm for the rkisp1. It defaults to a gamma of 2.2 which closely resembles sRGB. No seperate sRGB mode was implemented because the pwl that models the gamma curve is so coarse that there is basically no difference between srgb and gamma=2.2. The default can be overridden within the tuning file or set at runtime using the gamma control. The gamma algorithm is not enabled by default. This will be done in future tuning file updates. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
parent
acfd602767
commit
eb41f63694
5 changed files with 225 additions and 0 deletions
153
src/ipa/rkisp1/algorithms/goc.cpp
Normal file
153
src/ipa/rkisp1/algorithms/goc.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2024, Ideas On Board
|
||||
*
|
||||
* RkISP1 Gamma out control
|
||||
*/
|
||||
#include "goc.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <libcamera/base/log.h>
|
||||
#include <libcamera/base/utils.h>
|
||||
|
||||
#include <libcamera/control_ids.h>
|
||||
|
||||
#include "libcamera/internal/yaml_parser.h"
|
||||
|
||||
#include "linux/rkisp1-config.h"
|
||||
|
||||
/**
|
||||
* \file goc.h
|
||||
*/
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
namespace ipa::rkisp1::algorithms {
|
||||
|
||||
/**
|
||||
* \class GammaOutCorrection
|
||||
* \brief RkISP1 Gamma out correction
|
||||
*
|
||||
* This algorithm implements the gamma out curve for the RkISP1.
|
||||
* It defaults to a gamma value of 2.2
|
||||
* As gamma is internally represented as a piecewise linear function with only
|
||||
* 17 knots, the difference between gamma=2.2 and sRGB gamma is minimal.
|
||||
* Therefore sRGB gamma was not implemented as special case.
|
||||
*
|
||||
* Useful links:
|
||||
* https://www.cambridgeincolour.com/tutorials/gamma-correction.htm
|
||||
* https://en.wikipedia.org/wiki/SRGB
|
||||
*/
|
||||
|
||||
LOG_DEFINE_CATEGORY(RkISP1Gamma)
|
||||
|
||||
const float kDefaultGamma = 2.2f;
|
||||
|
||||
/**
|
||||
* \copydoc libcamera::ipa::Algorithm::init
|
||||
*/
|
||||
int GammaOutCorrection::init([[maybe_unused]] IPAContext &context,
|
||||
[[maybe_unused]] const YamlObject &tuningData)
|
||||
{
|
||||
if (context.hw->numGammaOutSamples !=
|
||||
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10) {
|
||||
LOG(RkISP1Gamma, Error)
|
||||
<< "Gamma is not implemented for RkISP1 V12";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
defaultGamma_ = tuningData["gamma"].get<double>(kDefaultGamma);
|
||||
context.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, defaultGamma_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure the Gamma given a configInfo
|
||||
* \param[in] context The shared IPA context
|
||||
* \param[in] configInfo The IPA configuration data
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int GammaOutCorrection::configure(IPAContext &context,
|
||||
[[maybe_unused]] const IPACameraSensorInfo &configInfo)
|
||||
{
|
||||
context.activeState.goc.gamma = defaultGamma_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \copydoc libcamera::ipa::Algorithm::queueRequest
|
||||
*/
|
||||
void GammaOutCorrection::queueRequest([[maybe_unused]] IPAContext &context,
|
||||
[[maybe_unused]] const uint32_t frame,
|
||||
IPAFrameContext &frameContext,
|
||||
const ControlList &controls)
|
||||
{
|
||||
if (frame == 0)
|
||||
frameContext.goc.update = true;
|
||||
|
||||
const auto &gamma = controls.get(controls::Gamma);
|
||||
if (gamma) {
|
||||
context.activeState.goc.gamma = *gamma;
|
||||
frameContext.goc.update = true;
|
||||
LOG(RkISP1Gamma, Debug) << "Set gamma to " << *gamma;
|
||||
}
|
||||
|
||||
frameContext.goc.gamma = context.activeState.goc.gamma;
|
||||
}
|
||||
|
||||
/**
|
||||
* \copydoc libcamera::ipa::Algorithm::prepare
|
||||
*/
|
||||
void GammaOutCorrection::prepare([[maybe_unused]] IPAContext &context,
|
||||
[[maybe_unused]] const uint32_t frame,
|
||||
[[maybe_unused]] IPAFrameContext &frameContext,
|
||||
rkisp1_params_cfg *params)
|
||||
{
|
||||
ASSERT(context.hw->numGammaOutSamples ==
|
||||
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);
|
||||
|
||||
/*
|
||||
* The logarithmic segments as specified in the reference.
|
||||
* Plus an additional 0 to make the loop easier
|
||||
*/
|
||||
std::array<unsigned, RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10> segments = {
|
||||
64, 64, 64, 64, 128, 128, 128, 128, 256,
|
||||
256, 256, 512, 512, 512, 512, 512, 0
|
||||
};
|
||||
auto gamma_y = params->others.goc_config.gamma_y;
|
||||
|
||||
if (!frameContext.goc.update)
|
||||
return;
|
||||
|
||||
unsigned x = 0;
|
||||
for (const auto [i, size] : utils::enumerate(segments)) {
|
||||
gamma_y[i] = std::pow(x / 4096.0, 1.0 / frameContext.goc.gamma) * 1023.0;
|
||||
x += size;
|
||||
}
|
||||
|
||||
params->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;
|
||||
params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;
|
||||
params->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;
|
||||
params->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;
|
||||
}
|
||||
|
||||
/**
|
||||
* \copydoc libcamera::ipa::Algorithm::process
|
||||
*/
|
||||
void GammaOutCorrection::process([[maybe_unused]] IPAContext &context,
|
||||
[[maybe_unused]] const uint32_t frame,
|
||||
IPAFrameContext &frameContext,
|
||||
[[maybe_unused]] const rkisp1_stat_buffer *stats,
|
||||
ControlList &metadata)
|
||||
{
|
||||
metadata.set(controls::Gamma, frameContext.goc.gamma);
|
||||
}
|
||||
|
||||
REGISTER_IPA_ALGORITHM(GammaOutCorrection, "GammaOutCorrection")
|
||||
|
||||
} /* namespace ipa::rkisp1::algorithms */
|
||||
|
||||
} /* namespace libcamera */
|
Loading…
Add table
Add a link
Reference in a new issue