[3/3] ipa: rkisp1: cproc: Provide a Hue control
diff mbox series

Message ID 20250624171223.2181226-4-kieran.bingham@ideasonboard.com
State New
Headers show
Series
  • rkisp1: cproc - Metadata and Hue developments
Related show

Commit Message

Kieran Bingham June 24, 2025, 5:12 p.m. UTC
From: "van Veen, Stephan" <stephan.vanveen@karlstorz.com>

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

This is implemented as a phase shift of the chrominance values between
-90 and +87.188 degrees.

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

Signed-off-by: van Veen, Stephan <stephan.vanveen@karlstorz.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/ipa/rkisp1/algorithms/cproc.cpp | 31 ++++++++++++++++++++++-------
 src/ipa/rkisp1/ipa_context.h        |  2 ++
 2 files changed, 26 insertions(+), 7 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp
index 9213ee49b374..217c1ee2b039 100644
--- a/src/ipa/rkisp1/algorithms/cproc.cpp
+++ b/src/ipa/rkisp1/algorithms/cproc.cpp
@@ -27,8 +27,8 @@  namespace ipa::rkisp1::algorithms {
  * \brief RkISP1 Color Processing control
  *
  * The ColorProcessing algorithm is responsible for applying brightness,
- * contrast and saturation corrections. The values are directly provided
- * through requests by the corresponding controls.
+ * contrast, hue and saturation corrections. The values are directly
+ * provided through requests by the corresponding controls.
  */
 
 LOG_DEFINE_CATEGORY(RkISP1CProc)
@@ -37,14 +37,15 @@  namespace {
 
 constexpr float kDefaultBrightness = 0.0f;
 constexpr float kDefaultContrast = 1.0f;
+constexpr float kDefaultHue = 0.0f;
 constexpr float kDefaultSaturation = 1.0f;
 
-int convertBrightness(const float v)
+int convertBrightnessOrHue(const float v)
 {
 	return std::clamp<int>(std::lround(v * 128), -128, 127);
 }
 
-float convertBrightness(const int v)
+float convertBrightnessOrHue(const int v)
 {
 	return static_cast<float>(v) / 128.0f;
 }
@@ -71,6 +72,7 @@  int ColorProcessing::init(IPAContext &context,
 
 	cmap[&controls::Brightness] = ControlInfo(-1.0f, 0.993f, kDefaultBrightness);
 	cmap[&controls::Contrast] = ControlInfo(0.0f, 1.993f, kDefaultContrast);
+	cmap[&controls::Hue] = ControlInfo(-1.0f, 0.993f, kDefaultHue);
 	cmap[&controls::Saturation] = ControlInfo(0.0f, 1.993f, kDefaultSaturation);
 
 	return 0;
@@ -84,8 +86,9 @@  int ColorProcessing::configure(IPAContext &context,
 {
 	auto &cproc = context.activeState.cproc;
 
-	cproc.brightness = convertBrightness(kDefaultBrightness);
+	cproc.brightness = convertBrightnessOrHue(kDefaultBrightness);
 	cproc.contrast = convertContrastOrSaturation(kDefaultContrast);
+	cproc.hue = convertBrightnessOrHue(kDefaultHue);
 	cproc.saturation = convertContrastOrSaturation(kDefaultSaturation);
 
 	return 0;
@@ -107,7 +110,7 @@  void ColorProcessing::queueRequest(IPAContext &context,
 
 	const auto &brightness = controls.get(controls::Brightness);
 	if (brightness) {
-		int value = convertBrightness(*brightness);
+		int value = convertBrightnessOrHue(*brightness);
 		if (cproc.brightness != value) {
 			cproc.brightness = value;
 			update = true;
@@ -127,6 +130,17 @@  void ColorProcessing::queueRequest(IPAContext &context,
 		LOG(RkISP1CProc, Debug) << "Set contrast to " << value;
 	}
 
+	const auto &hue = controls.get(controls::Hue);
+	if (hue) {
+		int value = convertBrightnessOrHue(*hue);
+		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) {
 		int value = convertContrastOrSaturation(*saturation);
@@ -140,6 +154,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;
 }
@@ -160,6 +175,7 @@  void ColorProcessing::prepare([[maybe_unused]] IPAContext &context,
 	config.setEnabled(true);
 	config->brightness = frameContext.cproc.brightness;
 	config->contrast = frameContext.cproc.contrast;
+	config->hue = frameContext.cproc.hue;
 	config->sat = frameContext.cproc.saturation;
 }
 
@@ -170,8 +186,9 @@  void ColorProcessing::process([[maybe_unused]] IPAContext &context, [[maybe_unus
 			      IPAFrameContext &frameContext, [[maybe_unused]] const rkisp1_stat_buffer *stats,
 			      ControlList &metadata)
 {
-	metadata.set(controls::Brightness, convertBrightness(frameContext.cproc.brightness));
+	metadata.set(controls::Brightness, convertBrightnessOrHue(frameContext.cproc.brightness));
 	metadata.set(controls::Contrast, convertContrastOrSaturation(frameContext.cproc.contrast));
+	metadata.set(controls::Hue, convertBrightnessOrHue(frameContext.cproc.hue));
 	metadata.set(controls::Saturation, convertContrastOrSaturation(frameContext.cproc.saturation));
 }
 
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index f0d504215d34..54234ea3acc4 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -108,6 +108,7 @@  struct IPAActiveState {
 	struct {
 		int8_t brightness;
 		uint8_t contrast;
+		int8_t hue;
 		uint8_t saturation;
 	} cproc;
 
@@ -152,6 +153,7 @@  struct IPAFrameContext : public FrameContext {
 	struct {
 		int8_t brightness;
 		uint8_t contrast;
+		int8_t hue;
 		uint8_t saturation;
 		bool update;
 	} cproc;