Camera: Make sure metering regions are valid in capture result
- Make sure ZoomRatioMapper doesn't produce metering rectangles
with negative width/height
- If HAL or any framework component produces metering rectangles
with negative width/height, overwrite it to have 0 width/height.
Test: manual testing, cameraservice_test
Bug: 243985907
Change-Id: I04ca487c64f7db3e7ece209def2d1d03bc4a4238
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index f4e3fad..5d3da45 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -128,12 +128,41 @@
return res;
}
+void correctMeteringRegions(camera_metadata_t *meta) {
+ if (meta == nullptr) return;
+
+ uint32_t meteringRegionKeys[] = {
+ ANDROID_CONTROL_AE_REGIONS,
+ ANDROID_CONTROL_AWB_REGIONS,
+ ANDROID_CONTROL_AF_REGIONS };
+
+ for (uint32_t key : meteringRegionKeys) {
+ camera_metadata_entry_t entry;
+ int res = find_camera_metadata_entry(meta, key, &entry);
+ if (res != OK) continue;
+
+ for (size_t i = 0; i < entry.count; i += 5) {
+ if (entry.data.i32[0] > entry.data.i32[2]) {
+ ALOGW("%s: Invalid metering region (%d): left: %d, right: %d",
+ __FUNCTION__, key, entry.data.i32[0], entry.data.i32[2]);
+ entry.data.i32[2] = entry.data.i32[0];
+ }
+ if (entry.data.i32[1] > entry.data.i32[3]) {
+ ALOGW("%s: Invalid metering region (%d): top: %d, bottom: %d",
+ __FUNCTION__, key, entry.data.i32[1], entry.data.i32[3]);
+ entry.data.i32[3] = entry.data.i32[1];
+ }
+ }
+ }
+}
+
void insertResultLocked(CaptureOutputStates& states, CaptureResult *result, uint32_t frameNumber) {
if (result == nullptr) return;
camera_metadata_t *meta = const_cast<camera_metadata_t *>(
result->mMetadata.getAndLock());
set_camera_metadata_vendor_id(meta, states.vendorTagId);
+ correctMeteringRegions(meta);
result->mMetadata.unlock(meta);
if (result->mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
@@ -152,6 +181,7 @@
camera_metadata_t *pmeta = const_cast<camera_metadata_t *>(
physicalMetadata.mPhysicalCameraMetadata.getAndLock());
set_camera_metadata_vendor_id(pmeta, states.vendorTagId);
+ correctMeteringRegions(pmeta);
physicalMetadata.mPhysicalCameraMetadata.unlock(pmeta);
}