Camera2: Add shading mode test
Change-Id: I6f8b006064cde1bd740741851b260cf977b1e685
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 3131ba2..3dd9325 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -17,6 +17,7 @@
package android.hardware.camera2.cts;
import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static android.hardware.camera2.CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE;
import static android.hardware.camera2.CameraMetadata.*;
import android.hardware.camera2.CameraDevice;
@@ -26,6 +27,8 @@
import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
import android.util.Log;
+import java.util.Arrays;
+
/**
* <p>
* Basic test for camera CaptureRequest key controls.
@@ -42,6 +45,9 @@
private static final long WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
private static final long DEFAULT_EXP_TIME_NS = 30000000L; // 30ms
private static final int DEFAULT_SENSITIVITY = 100; // 10ms
+ private static final int RGGB_COLOR_CHANNEL_COUNT = 4;
+ private static final int MAX_SHADING_MAP_SIZE = 64 * 64 * RGGB_COLOR_CHANNEL_COUNT;
+ private static final int MIN_SHADING_MAP_SIZE = 1 * 1 * RGGB_COLOR_CHANNEL_COUNT;
@Override
protected void setUp() throws Exception {
@@ -53,6 +59,17 @@
super.tearDown();
}
+ /**
+ * Test black level lock when exposure value change.
+ * <p>
+ * When {@link CaptureRequest#BLACK_LEVEL_LOCK} is true in a request, the
+ * camera device should lock the black level. When the exposure values are changed,
+ * the camera may require reset black level Since changes to certain capture
+ * parameters (such as exposure time) may require resetting of black level
+ * compensation. However, the black level must remain locked after exposure
+ * value changes (when requests have lock ON).
+ * </p>
+ */
public void testBlackLevelLock() throws Exception {
for (int i = 0; i < mCameraIds.length; i++) {
try {
@@ -88,7 +105,70 @@
} finally {
closeDevice();
}
+ }
+ }
+ /**
+ * Basic lens shading map request test.
+ * <p>
+ * When {@link CaptureRequest#SHADING_MODE} is set to OFF, no lens shading correction will
+ * be applied by the camera device, and an identity lens shading map data
+ * will be provided if {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE} is ON.
+ * </p>
+ * <p>
+ * When {@link CaptureRequest#SHADING_MODE} is set to other modes, lens shading correction
+ * will be applied by the camera device. The lens shading map data can be
+ * requested by setting {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE} to ON.
+ * </p>
+ */
+ public void testLensShadingMap() throws Exception {
+ for (int i = 0; i < mCameraIds.length; i++) {
+ try {
+ openDevice(mCameraIds[i]);
+
+ if (!mStaticInfo.isHardwareLevelFull()) {
+ continue;
+ }
+
+ SimpleCaptureListener listener = new SimpleCaptureListener();
+ CaptureRequest.Builder requestBuilder =
+ mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+ // Shading map mode OFF, lensShadingMapMode ON, camera device
+ // should output unity maps.
+ requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_OFF);
+ requestBuilder.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
+ STATISTICS_LENS_SHADING_MAP_MODE_ON);
+
+ Size mapSz = mStaticInfo.getCharacteristics().get(LENS_INFO_SHADING_MAP_SIZE);
+ Size previewSz =
+ getMaxPreviewSize(mCamera.getId(), mCameraManager, PREVIEW_SIZE_BOUND);
+
+ startPreview(requestBuilder, previewSz, listener);
+
+ verifyShadingMap(listener, NUM_FRAMES_VERIFIED, mapSz, /*mapModeOn*/false);
+
+ // Shading map mode FAST, lensShadingMapMode ON, camera device
+ // should output valid maps.
+ requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_FAST);
+
+ startPreview(requestBuilder, previewSz, listener);
+
+ // Allow at most one lock OFF state as the exposure is changed once.
+ verifyShadingMap(listener, NUM_FRAMES_VERIFIED, mapSz, /*mapModeOn*/true);
+
+ // Shading map mode HIGH_QUALITY, lensShadingMapMode ON, camera device
+ // should output valid maps.
+ requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_HIGH_QUALITY);
+
+ startPreview(requestBuilder, previewSz, listener);
+
+ verifyShadingMap(listener, NUM_FRAMES_VERIFIED, mapSz, /*mapModeOn*/true);
+
+ stopPreview();
+ } finally {
+ closeDevice();
+ }
}
}
@@ -118,6 +198,46 @@
+ maxLockOffCnt + " for camera " + mCamera.getId(), noLockCnt <= maxLockOffCnt);
}
+ /**
+ * Verify shading map for different shading modes.
+ */
+ private void verifyShadingMap(SimpleCaptureListener listener, int numFramesVerified,
+ Size mapSize, boolean mapModeOn) throws Exception {
+ int numElementsInMap = mapSize.getWidth() * mapSize.getHeight() * RGGB_COLOR_CHANNEL_COUNT;
+ float[] unityMap = new float[numElementsInMap];
+ Arrays.fill(unityMap, 1.0f);
+
+ for (int i = 0; i < numFramesVerified; i++) {
+ CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+ float[] map = result.get(CaptureResult.STATISTICS_LENS_SHADING_MAP);
+ assertNotNull("Map must not be null", map);
+ assertTrue("Map size " + map.length + " must be " + numElementsInMap,
+ map.length == numElementsInMap);
+ assertFalse(String.format(
+ "Map size %d should be less than %d", numElementsInMap, MAX_SHADING_MAP_SIZE),
+ numElementsInMap >= MAX_SHADING_MAP_SIZE);
+ assertFalse(String.format("Map size %d should be no less than %d", numElementsInMap,
+ MIN_SHADING_MAP_SIZE), numElementsInMap < MIN_SHADING_MAP_SIZE);
+
+ if (mapModeOn) {
+ // Map mode is ON, expect to receive a map with all element >= 1.0f
+
+ int badValueCnt = 0;
+ // Detect the bad values of the map data.
+ for (int j = 0; j < numElementsInMap; j++) {
+ if (Float.isNaN(map[j]) || map[j] < 1.0f) {
+ badValueCnt++;
+ }
+ }
+ assertEquals("Number of value in the map is " + badValueCnt + " out of "
+ + numElementsInMap, /*expected*/0, /*actual*/badValueCnt);
+ } else {
+ // Map mode is OFF, expect to receive a unity map.
+ assertTrue("Result map " + Arrays.toString(map) + " must be an unity map",
+ Arrays.equals(unityMap, map));
+ }
+ }
+ }
//----------------------------------------------------------------
//---------Below are common functions for all tests.--------------