[PATCH v4 3/3] ipa: rkisp1: Add GammaOutCorrection algorithm
Stefan Klug
stefan.klug at ideasonboard.com
Thu Jun 6 08:25:05 CEST 2024
Hi,
I missed the changelog on this one. So here it goes...
On Wed, Jun 05, 2024 at 11:53:51AM +0200, Stefan Klug wrote:
> 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 at ideasonboard.com>
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> ---
v3 -> v4:
- Changed structure in IPAActiveState and IPAFrameContext to be in line with
the other algorithms.
- Changed the logic to check if hw needs updating to a bool inside frameContext
to be in line with the other algorithms
v2 -> v3:
- Squashed with patch 1/4 from previous series
- Renamed from Gamma to GammaOutCorrection
- Read default gamma value from tuning file
- Some stylistic fixes from review
> src/ipa/rkisp1/algorithms/goc.cpp | 153 ++++++++++++++++++++++++++
> src/ipa/rkisp1/algorithms/goc.h | 42 +++++++
> src/ipa/rkisp1/algorithms/meson.build | 1 +
> src/ipa/rkisp1/ipa_context.h | 9 ++
> 4 files changed, 205 insertions(+)
> create mode 100644 src/ipa/rkisp1/algorithms/goc.cpp
> create mode 100644 src/ipa/rkisp1/algorithms/goc.h
>
> diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp
> new file mode 100644
> index 000000000000..ab634c1c9709
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/goc.cpp
> @@ -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;
> + }
> +
> + context.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, kDefaultGamma);
> + defaultGamma_ = tuningData["gamma"].get<double>(kDefaultGamma);
> +
> + 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 */
> diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h
> new file mode 100644
> index 000000000000..3be8e500be67
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/goc.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2024, Ideas On Board
> + *
> + * RkISP1 Gamma out control
> + */
> +
> +#pragma once
> +
> +#include "algorithm.h"
> +
> +namespace libcamera {
> +
> +namespace ipa::rkisp1::algorithms {
> +
> +class GammaOutCorrection : public Algorithm
> +{
> +public:
> + GammaOutCorrection() = default;
> + ~GammaOutCorrection() = default;
> +
> + int init(IPAContext &context, const YamlObject &tuningData) override;
> + int configure(IPAContext &context,
> + const IPACameraSensorInfo &configInfo) override;
> + void queueRequest(IPAContext &context,
> + const uint32_t frame,
> + IPAFrameContext &frameContext,
> + const ControlList &controls) override;
> + void prepare(IPAContext &context, const uint32_t frame,
> + IPAFrameContext &frameContext,
> + rkisp1_params_cfg *params) override;
> + void process(IPAContext &context, const uint32_t frame,
> + IPAFrameContext &frameContext,
> + const rkisp1_stat_buffer *stats,
> + ControlList &metadata) override;
> +
> +private:
> + double defaultGamma_;
> +};
> +
> +} /* namespace ipa::rkisp1::algorithms */
> +} /* namespace libcamera */
> diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build
> index 93a483292753..6ee71a9b5da3 100644
> --- a/src/ipa/rkisp1/algorithms/meson.build
> +++ b/src/ipa/rkisp1/algorithms/meson.build
> @@ -8,6 +8,7 @@ rkisp1_ipa_algorithms = files([
> 'dpcc.cpp',
> 'dpf.cpp',
> 'filter.cpp',
> + 'goc.cpp',
> 'gsl.cpp',
> 'lsc.cpp',
> ])
> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
> index bd02a7a24fdd..f261e42fc2fd 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -104,6 +104,10 @@ struct IPAActiveState {
> uint8_t denoise;
> uint8_t sharpness;
> } filter;
> +
> + struct {
> + double gamma;
> + } goc;
> };
>
> struct IPAFrameContext : public FrameContext {
> @@ -146,6 +150,11 @@ struct IPAFrameContext : public FrameContext {
> uint32_t exposure;
> double gain;
> } sensor;
> +
> + struct {
> + double gamma;
> + bool update;
> + } goc;
> };
>
> struct IPAContext {
> --
> 2.43.0
>
More information about the libcamera-devel
mailing list