Saturation control is added on top of the colour correction matrix. A method of saturation adjustment that can be fully integrated into the colour correction matrix is used. The control is available only if Ccm algorithm is enabled. The control uses 0.0-2.0 value range, with 1.0 being unmodified saturation, 0.0 full desaturation and 2.0 quite saturated. The saturation is adjusted by converting to Y'CbCr colour space, applying the saturation value on the colour axes, and converting back to RGB. ITU-R BT.601 conversion is used to convert between the colour spaces, for no particular reason. The colour correction matrix is applied before gamma and the given matrix is suitable for such a case. Alternatively, the transformation used in libcamera rpi ccm.cpp could be used. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
105 lines
1.8 KiB
C++
105 lines
1.8 KiB
C++
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/*
|
|
* Copyright (C) 2024-2025 Red Hat, Inc.
|
|
*
|
|
* Simple pipeline IPA Context
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <optional>
|
|
#include <stdint.h>
|
|
|
|
#include <libcamera/controls.h>
|
|
|
|
#include "libcamera/internal/matrix.h"
|
|
#include "libcamera/internal/vector.h"
|
|
|
|
#include <libipa/fc_queue.h>
|
|
|
|
#include "core_ipa_interface.h"
|
|
|
|
namespace libcamera {
|
|
|
|
namespace ipa::soft {
|
|
|
|
struct IPASessionConfiguration {
|
|
float gamma;
|
|
struct {
|
|
int32_t exposureMin, exposureMax;
|
|
double againMin, againMax, againMinStep;
|
|
utils::Duration lineDuration;
|
|
} agc;
|
|
struct {
|
|
std::optional<uint8_t> level;
|
|
} black;
|
|
};
|
|
|
|
struct IPAActiveState {
|
|
struct {
|
|
uint8_t level;
|
|
int32_t lastExposure;
|
|
double lastGain;
|
|
} blc;
|
|
|
|
struct {
|
|
RGB<float> gains;
|
|
unsigned int temperatureK;
|
|
} awb;
|
|
|
|
static constexpr unsigned int kGammaLookupSize = 1024;
|
|
struct {
|
|
std::array<double, kGammaLookupSize> gammaTable;
|
|
uint8_t blackLevel;
|
|
double contrast;
|
|
} gamma;
|
|
|
|
struct {
|
|
Matrix<float, 3, 3> ccm;
|
|
bool changed;
|
|
} ccm;
|
|
|
|
struct {
|
|
/* 0..2 range, 1.0 = normal */
|
|
std::optional<double> contrast;
|
|
std::optional<float> saturation;
|
|
} knobs;
|
|
};
|
|
|
|
struct IPAFrameContext : public FrameContext {
|
|
struct {
|
|
Matrix<float, 3, 3> ccm;
|
|
} ccm;
|
|
|
|
struct {
|
|
int32_t exposure;
|
|
double gain;
|
|
} sensor;
|
|
|
|
struct {
|
|
double red;
|
|
double blue;
|
|
} gains;
|
|
|
|
std::optional<double> contrast;
|
|
std::optional<float> saturation;
|
|
};
|
|
|
|
struct IPAContext {
|
|
IPAContext(unsigned int frameContextSize)
|
|
: frameContexts(frameContextSize)
|
|
{
|
|
}
|
|
|
|
IPACameraSensorInfo sensorInfo;
|
|
IPASessionConfiguration configuration;
|
|
IPAActiveState activeState;
|
|
FCQueue<IPAFrameContext> frameContexts;
|
|
ControlInfoMap::Map ctrlMap;
|
|
bool ccmEnabled = false;
|
|
};
|
|
|
|
} /* namespace ipa::soft */
|
|
|
|
} /* namespace libcamera */
|