ipa: rkisp1: cproc: Provide a Hue control

The RKISP1 supports a configurable Hue as part of the colour processing
unit (cproc).

Implement the new control converting to the hardware scale accordingly
and report the applied control in the completed request metadata.

This is implemented as a phase shift of the chrominance values between
-90 and +87.188 degrees according to the datasheet however the type
itself would imply that this is a range between -90 and 89.2969.

Moreover, the hardware applies the inverse phase shift to the operation
expected and documented by libcamera, so we apply a negative scale when
converting the libcamera control to the Q<1,7> type, resulting in a
range of -89.2969 to +90.0 degrees control.

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Kieran Bingham
2026-02-19 15:05:10 +00:00
parent da967ed63d
commit 6c181ac5a7
2 changed files with 31 additions and 0 deletions
+28
View File
@@ -37,8 +37,15 @@ namespace {
constexpr float kDefaultBrightness = 0.0f;
constexpr float kDefaultContrast = 1.0f;
constexpr float kDefaultHue = 0.0f;
constexpr float kDefaultSaturation = 1.0f;
/*
* The Hue scale is negated as the hardware performs the opposite phase shift
* to what is expected and defined from the libcamera Hue control value.
*/
constexpr float kHueScale = -90.0f;
} /* namespace */
/**
@@ -53,6 +60,11 @@ int ColorProcessing::init(IPAContext &context,
cmap[&controls::Contrast] = ControlInfo(0.0f, 1.993f, kDefaultContrast);
cmap[&controls::Saturation] = ControlInfo(0.0f, 1.993f, kDefaultSaturation);
/* Hue adjustment is negated by kHueScale, min/max are swapped */
cmap[&controls::Hue] = ControlInfo(HueQ::TraitsType::max * kHueScale,
HueQ::TraitsType::min * kHueScale,
kDefaultHue);
return 0;
}
@@ -66,6 +78,7 @@ int ColorProcessing::configure(IPAContext &context,
cproc.brightness = BrightnessQ(kDefaultBrightness);
cproc.contrast = ContrastQ(kDefaultContrast);
cproc.hue = HueQ(kDefaultHue);
cproc.saturation = SaturationQ(kDefaultSaturation);
return 0;
@@ -107,6 +120,18 @@ void ColorProcessing::queueRequest(IPAContext &context,
LOG(RkISP1CProc, Debug) << "Set contrast to " << value;
}
const auto &hue = controls.get(controls::Hue);
if (hue) {
/* Scale the Hue from ]-90, +90] */
HueQ value = *hue / kHueScale;
if (cproc.hue != value) {
cproc.hue = value;
update = true;
}
LOG(RkISP1CProc, Debug) << "Set hue to " << value;
}
const auto saturation = controls.get(controls::Saturation);
if (saturation) {
SaturationQ value = *saturation;
@@ -120,6 +145,7 @@ void ColorProcessing::queueRequest(IPAContext &context,
frameContext.cproc.brightness = cproc.brightness;
frameContext.cproc.contrast = cproc.contrast;
frameContext.cproc.hue = cproc.hue;
frameContext.cproc.saturation = cproc.saturation;
frameContext.cproc.update = update;
}
@@ -140,6 +166,7 @@ void ColorProcessing::prepare([[maybe_unused]] IPAContext &context,
config.setEnabled(true);
config->brightness = frameContext.cproc.brightness.quantized();
config->contrast = frameContext.cproc.contrast.quantized();
config->hue = frameContext.cproc.hue.quantized();
config->sat = frameContext.cproc.saturation.quantized();
}
@@ -154,6 +181,7 @@ void ColorProcessing::process([[maybe_unused]] IPAContext &context,
{
metadata.set(controls::Brightness, frameContext.cproc.brightness.value());
metadata.set(controls::Contrast, frameContext.cproc.contrast.value());
metadata.set(controls::Hue, frameContext.cproc.hue.value() * kHueScale);
metadata.set(controls::Saturation, frameContext.cproc.saturation.value());
}
+3
View File
@@ -36,6 +36,7 @@ namespace ipa::rkisp1 {
/* Fixed point types used by CPROC */
using BrightnessQ = Q<1, 7>;
using ContrastQ = UQ<1, 7>;
using HueQ = Q<1, 7>;
using SaturationQ = UQ<1, 7>;
struct IPAHwSettings {
@@ -119,6 +120,7 @@ struct IPAActiveState {
struct {
BrightnessQ brightness;
ContrastQ contrast;
HueQ hue;
SaturationQ saturation;
} cproc;
@@ -181,6 +183,7 @@ struct IPAFrameContext : public FrameContext {
struct {
BrightnessQ brightness;
ContrastQ contrast;
HueQ hue;
SaturationQ saturation;
bool update;