@@ -295,6 +295,18 @@ bool CameraCapabilities::validateManualPostProcessingCapability()
return false;
}
+ /* From docs */
+ if (!staticMetadata_->entryContains<uint8_t>(ANDROID_SHADING_AVAILABLE_MODES,
+ ANDROID_SHADING_MODE_OFF) ||
+ !staticMetadata_->entryContains<uint8_t>(ANDROID_SHADING_AVAILABLE_MODES,
+ ANDROID_SHADING_MODE_FAST) ||
+ /* From CTS */
+ !staticMetadata_->entryContains<uint8_t>(ANDROID_SHADING_AVAILABLE_MODES,
+ ANDROID_SHADING_MODE_HIGH_QUALITY)) {
+ LOG(HAL, Info) << noMode << "missing shading modes off or fast or HQ";
+ return false;
+ }
+
/*
* \todo return true here after we satisfy all the requirements:
* https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
@@ -375,8 +387,12 @@ CameraCapabilities::computeCapabilities()
if (validateBurstCaptureCapability())
capabilities.insert(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
- if (rawStreamAvailable_)
+ if (rawStreamAvailable_ &&
+ staticMetadata_->entryContains<uint8_t>(
+ ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
+ ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON)) {
capabilities.insert(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
+ }
return capabilities;
}
@@ -437,6 +453,21 @@ void CameraCapabilities::computeHwLevel(
hwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
}
+ /*
+ * Shading mode and lens shading map mode are always available and
+ * don't need to be checked. We only need to check we support reporting
+ * the lens shading map.
+ *
+ * The lens shading map may have a null map with a zero size. It is
+ * valid, but will give android a null correction map.
+ * \todo Confirm that this is fine
+ */
+ found = availableResultKeys_.count(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
+ if (!found) {
+ LOG(HAL, Info) << noFull << "missing reportable lens shading map";
+ hwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
+ }
+
hwLevel_ = hwLevel;
}
@@ -871,7 +902,9 @@ int CameraCapabilities::initializeStaticMetadata()
ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
ANDROID_SENSOR_ORIENTATION,
+ ANDROID_SHADING_AVAILABLE_MODES,
ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
+ ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
ANDROID_SYNC_MAX_LATENCY,
};
@@ -903,7 +936,9 @@ int CameraCapabilities::initializeStaticMetadata()
ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
ANDROID_NOISE_REDUCTION_MODE,
ANDROID_SCALER_CROP_REGION,
- ANDROID_STATISTICS_FACE_DETECT_MODE
+ ANDROID_SHADING_MODE,
+ ANDROID_STATISTICS_FACE_DETECT_MODE,
+ ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
};
availableResultKeys_ = {
@@ -949,6 +984,7 @@ int CameraCapabilities::initializeStaticMetadata()
ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
ANDROID_SENSOR_TEST_PATTERN_MODE,
ANDROID_SENSOR_TIMESTAMP,
+ ANDROID_SHADING_MODE,
ANDROID_STATISTICS_FACE_DETECT_MODE,
ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
@@ -1361,7 +1397,25 @@ int CameraCapabilities::initializeStaticMetadata()
staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
maxFaceCount);
+ /* Lens shading */
{
+ /*
+ * Controls for requesting and reporting the lens shading map:
+ * static:
+ * - ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES
+ * - availability of requesting the lens shading map, always
+ * available
+ * request:
+ * - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE
+ * - request reporting of the lens shading map, always available
+ * result:
+ * - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE
+ * - result version of the above control
+ * - ANDROID_LENS_INFO_SHADING_MAP_SIZE
+ * - size of the lens shading map
+ * - ANDROID_STATISTICS_LENS_SHADING_MAP
+ * - the actual lens shading map
+ */
std::vector<uint8_t> data;
data.reserve(2);
const auto &infoMap = controlsInfo.find(&controls::StatsLensShadingMapMode);
@@ -1373,6 +1427,34 @@ int CameraCapabilities::initializeStaticMetadata()
}
staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
data);
+
+ const auto &mapSizeInfoMap = controlsInfo.find(&controls::StatsLensShadingMapSize);
+ if (mapSizeInfoMap != controlsInfo.end())
+ availableResultKeys_.insert(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
+
+ const auto &mapInfoMap = controlsInfo.find(&controls::StatsLensShadingMap);
+ if (mapInfoMap != controlsInfo.end())
+ availableResultKeys_.insert(ANDROID_STATISTICS_LENS_SHADING_MAP);
+
+ /*
+ * Controls for enabling/disabling lens shading:
+ * static:
+ * - ANDROID_SHADING_AVAILABLE_MODES
+ * - list of available lens shading modes, always available
+ * request and result:
+ * - ANDROID_SHADING_MODE
+ * - set/report the shading mode (off, fast, hq)
+ */
+ data.clear();
+ data.reserve(3);
+ const auto &shadingInfoMap = controlsInfo.find(&controls::LensShadingMode);
+ if (shadingInfoMap != controlsInfo.end()) {
+ for (const auto &value : shadingInfoMap->second.values())
+ data.push_back(value.get<int32_t>());
+ } else {
+ data.push_back(ANDROID_SHADING_MODE_OFF);
+ }
+ staticMetadata_->addEntry(ANDROID_SHADING_AVAILABLE_MODES, data);
}
/* Sync static metadata. */
@@ -1802,6 +1884,16 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplatePreview() con
requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
captureIntent);
+ uint8_t shadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+ requestTemplate->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+ shadingMapMode);
+
+ if (staticMetadata_->entryContains<uint8_t>(ANDROID_SHADING_AVAILABLE_MODES,
+ ANDROID_SHADING_MODE_FAST)) {
+ uint8_t shadingMode = ANDROID_SHADING_MODE_FAST;
+ requestTemplate->addEntry(ANDROID_SHADING_MODE, shadingMode);
+ }
+
return requestTemplate;
}
@@ -1817,6 +1909,12 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateStill() const
stillTemplate->appendEntry(ANDROID_EDGE_MODE, edgeMode);
}
+ if (staticMetadata_->entryContains<uint8_t>(ANDROID_SHADING_AVAILABLE_MODES,
+ ANDROID_SHADING_MODE_HIGH_QUALITY)) {
+ uint8_t shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
+ stillTemplate->appendEntry(ANDROID_SHADING_MODE, shadingMode);
+ }
+
if (staticMetadata_->entryContains<uint8_t>(
ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY)) {
@@ -973,6 +973,47 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
}
}
+ if (settings.getEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &entry)) {
+ const int32_t data = static_cast<int32_t>(*entry.data.u8);
+ int32_t statsLensShadingMode;
+ switch (data) {
+ case ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON:
+ statsLensShadingMode = controls::StatsLensShadingMapModeOn;
+ break;
+ case ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF:
+ statsLensShadingMode = controls::StatsLensShadingMapModeOff;
+ break;
+ default:
+ LOG(HAL, Error)
+ << "Unknown lens shading map mode: " << data;
+ return -EINVAL;
+ }
+
+ controls.set(controls::StatsLensShadingMapMode, statsLensShadingMode);
+ }
+
+ if (settings.getEntry(ANDROID_SHADING_MODE, &entry)) {
+ const int32_t data = static_cast<int32_t>(*entry.data.u8);
+ int32_t shadingMode;
+ switch (data) {
+ case ANDROID_SHADING_MODE_OFF:
+ shadingMode = controls::LensShadingModeOff;
+ break;
+ case ANDROID_SHADING_MODE_FAST:
+ shadingMode = controls::LensShadingModeFast;
+ break;
+ case ANDROID_SHADING_MODE_HIGH_QUALITY:
+ shadingMode = controls::LensShadingModeHighQuality;
+ break;
+ default:
+ LOG(HAL, Error)
+ << "Unknown shading mode: " << data;
+ return -EINVAL;
+ }
+
+ controls.set(controls::LensShadingMode, shadingMode);
+ }
+
return 0;
}
@@ -1613,10 +1654,6 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons
value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, value);
- value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
- resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
- value);
-
value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
resultMetadata->addEntry(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, value);
@@ -1720,6 +1757,61 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons
std::vector<float> focusRange = { 0.0f, 0.0f };
resultMetadata->addEntry(ANDROID_LENS_FOCUS_RANGE, focusRange);
+ value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+ if (metadata.contains(controls::StatsLensShadingMapMode)) {
+ switch (metadata.get(controls::StatsLensShadingMapMode)) {
+ case controls::StatsLensShadingMapModeOn:
+ value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON;
+ break;
+ case controls::StatsLensShadingMapModeOff:
+ value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+ break;
+ default:
+ LOG(HAL, Error) << "Invalid StatsLensShadingMapMode";
+ }
+ }
+ resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, value);
+
+ if (metadata.contains(controls::LensShadingMode)) {
+ bool valid;
+ switch (metadata.get(controls::LensShadingMode)) {
+ case controls::LensShadingModeOff:
+ value = ANDROID_SHADING_MODE_OFF;
+ valid = true;
+ break;
+ case controls::LensShadingModeFast:
+ value = ANDROID_SHADING_MODE_FAST;
+ valid = true;
+ break;
+ case controls::LensShadingModeHighQuality:
+ value = ANDROID_SHADING_MODE_HIGH_QUALITY;
+ valid = true;
+ break;
+ default:
+ LOG(HAL, Error) << "Invalid LensShadingMode";
+ valid = false;
+ }
+
+ /* Can be null on non-FULL */
+ if (valid)
+ resultMetadata->addEntry(ANDROID_SHADING_MODE, value);
+ }
+
+ if (metadata.contains(controls::StatsLensShadingMapSize)) {
+ Size size = metadata.get(controls::StatsLensShadingMapSize);
+ std::array<uint32_t, 2> mapSize = { size.width, size.height };
+ resultMetadata->addEntry(ANDROID_LENS_INFO_SHADING_MAP_SIZE, mapSize);
+
+ /* valid size and null map is fine, but not vice versa */
+ if (metadata.contains(controls::StatsLensShadingMap)) {
+ const Span<const float> map =
+ metadata.get(controls::StatsLensShadingMap);
+ std::vector<float> shadingMap(map.begin(), map.end());
+ resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP,
+ shadingMap);
+ }
+ }
+
/*
* Return the result metadata pack even is not valid: get() will return
* nullptr.
Plumb the controls related to lens shading: - request the lens shading map to be reported (and report the current mode) - report the lens shading map (size + map) - request and report enabling/disabling of lens shading - corresponding static metadata to report available modes Also add a check for the RAW capability, as being able to report the lens shading map is a requirement for it. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> --- src/android/camera_capabilities.cpp | 102 +++++++++++++++++++++++++++- src/android/camera_device.cpp | 100 +++++++++++++++++++++++++-- 2 files changed, 196 insertions(+), 6 deletions(-)