[libcamera-devel,2/2] android: Plumb hot pixel mode
diff mbox series

Message ID 20211221053304.2704780-3-paul.elder@ideasonboard.com
State New
Delegated to: Paul Elder
Headers show
Series
  • android: Hot pixel correction
Related show

Commit Message

Paul Elder Dec. 21, 2021, 5:33 a.m. UTC
Plumb hot pixel mode:
- add check for hardware level FULL
- static metadata: report the available modes, enable the keys
- request, result: convert between libcamera control and android control
- add to templates

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
---
 src/android/camera_capabilities.cpp | 55 +++++++++++++++++++++++++++++
 src/android/camera_device.cpp       | 46 ++++++++++++++++++++++++
 2 files changed, 101 insertions(+)

Patch
diff mbox series

diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
index 2ce465aa..c52b22be 100644
--- a/src/android/camera_capabilities.cpp
+++ b/src/android/camera_capabilities.cpp
@@ -492,6 +492,12 @@  void CameraCapabilities::computeHwLevel(
 		hwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
 	}
 
+	found = availableResultKeys_.count(ANDROID_HOT_PIXEL_MODE);
+	if (!found) {
+		LOG(HAL, Info) << noFull << "missing hot pixel mode";
+		hwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
+	}
+
 	hwLevel_ = hwLevel;
 }
 
@@ -1132,6 +1138,37 @@  int CameraCapabilities::initializeStaticMetadata()
 	staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
 				  availableStabilizationModes);
 
+	std::vector<uint8_t> availableHotPixelModes;
+	const auto &hotPixelInfo = controlsInfo.find(&controls::draft::HotPixelMode);
+	if (hotPixelInfo != controlsInfo.end()) {
+		for (const auto &value : hotPixelInfo->second.values()) {
+			uint8_t mode;
+			switch (value.get<int32_t>()) {
+			case controls::draft::HotPixelModeOff:
+				mode = ANDROID_HOT_PIXEL_MODE_OFF;
+				break;
+			case controls::draft::HotPixelModeFast:
+				mode = ANDROID_HOT_PIXEL_MODE_FAST;
+				break;
+			case controls::draft::HotPixelModeHighQuality:
+				mode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
+				break;
+			default:
+				LOG(HAL, Error) << "Unknown hot pixel mode";
+				continue;
+			}
+
+			availableHotPixelModes.push_back(mode);
+		}
+
+		staticMetadata_->addEntry(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+					  availableHotPixelModes);
+
+		availableCharacteristicsKeys_.insert(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES);
+		availableRequestKeys_.insert(ANDROID_HOT_PIXEL_MODE);
+		availableResultKeys_.insert(ANDROID_HOT_PIXEL_MODE);
+	}
+
 	/*
 	 * \todo Inspect the camera capabilities to report the available
 	 * AWB modes. Default to AUTO as CTS tests require it.
@@ -1995,6 +2032,12 @@  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplatePreview() con
 		requestTemplate->addEntry(ANDROID_TONEMAP_MODE, tonemapMode);
 	}
 
+	if (staticMetadata_->entryContains<uint8_t>(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+						    ANDROID_HOT_PIXEL_MODE_FAST)) {
+		uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
+		requestTemplate->addEntry(ANDROID_HOT_PIXEL_MODE, hotPixelMode);
+	}
+
 	return requestTemplate;
 }
 
@@ -2029,6 +2072,12 @@  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateStill() const
 		stillTemplate->appendEntry(ANDROID_TONEMAP_MODE, tonemapMode);
 	}
 
+	if (staticMetadata_->entryContains<uint8_t>(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+						    ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY)) {
+		uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
+		stillTemplate->appendEntry(ANDROID_HOT_PIXEL_MODE, hotPixelMode);
+	}
+
 	return stillTemplate;
 }
 
@@ -2058,6 +2107,12 @@  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateVideo() const
 		previewTemplate->appendEntry(ANDROID_TONEMAP_MODE, tonemapMode);
 	}
 
+	if (staticMetadata_->entryContains<uint8_t>(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+						    ANDROID_HOT_PIXEL_MODE_FAST)) {
+		uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
+		previewTemplate->appendEntry(ANDROID_HOT_PIXEL_MODE, hotPixelMode);
+	}
+
 	/*
 	 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
 	 * has been assembled as {{min, max} {max, max}}.
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 7cffb4b1..7cab878c 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -973,6 +973,27 @@  int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
 		}
 	}
 
+	if (settings.getEntry(ANDROID_HOT_PIXEL_MODE, &entry)) {
+		const int32_t data = static_cast<int32_t>(*entry.data.u8);
+		int32_t hotPixelMode;
+		switch (data) {
+		case ANDROID_HOT_PIXEL_MODE_OFF:
+			hotPixelMode = controls::draft::HotPixelModeOff;
+			break;
+		case ANDROID_HOT_PIXEL_MODE_FAST:
+			hotPixelMode = controls::draft::HotPixelModeFast;
+			break;
+		case ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY:
+			hotPixelMode = controls::draft::HotPixelModeHighQuality;
+			break;
+		default:
+			LOG(HAL, Error) << "Unknown hot pixel mode: " << data;
+			return -EINVAL;
+		}
+
+		controls.set(controls::draft::HotPixelMode, hotPixelMode);
+	}
+
 	if (settings.getEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &entry)) {
 		const int32_t data = static_cast<int32_t>(*entry.data.u8);
 		int32_t statsLensShadingMode;
@@ -1793,6 +1814,31 @@  CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons
 		resultMetadata->addEntry(ANDROID_EDGE_MODE, descriptor.edgeMode_);
 	}
 
+	if (metadata.contains(controls::draft::HotPixelMode)) {
+		bool valid;
+		switch (metadata.get(controls::draft::HotPixelMode)) {
+		case controls::draft::HotPixelModeOff:
+			value = ANDROID_HOT_PIXEL_MODE_OFF;
+			valid = true;
+			break;
+		case controls::draft::HotPixelModeFast:
+			value = ANDROID_HOT_PIXEL_MODE_FAST;
+			valid = true;
+			break;
+		case controls::draft::HotPixelModeHighQuality:
+			value = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
+			valid = true;
+			break;
+		default:
+			LOG(HAL, Error) << "Invalid hot pixel mode";
+			valid = false;
+		}
+
+		/* Can be null on non-FULL */
+		if (valid)
+			resultMetadata->addEntry(ANDROID_HOT_PIXEL_MODE, value);
+	}
+
 	if (metadata.contains(controls::ScalerCrop)) {
 		Rectangle crop = metadata.get(controls::ScalerCrop);
 		int32_t cropRect[] = {