Camera2: Add color correction test
Change-Id: I1838193b4b3f2fed146d27af02fc17804f730810
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 e6c2984..fb7eef4 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -21,10 +21,12 @@
import android.graphics.Point;
import android.graphics.Rect;
+import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.Face;
+import android.hardware.camera2.Rational;
import android.hardware.camera2.Size;
import android.hardware.camera2.CameraMetadata.Key;
import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureListener;
@@ -73,6 +75,8 @@
0.5333f, 0.7569f, 0.6000f, 0.7977f, 0.6667f, 0.8360f, 0.7333f, 0.8721f,
0.8000f, 0.9063f, 0.8667f, 0.9389f, 0.9333f, 0.9701f, 1.0000f, 1.0000f
};
+ private final Rational ZERO_R = new Rational(0, 1);
+ private final Rational ONE_R = new Rational(1, 1);
@Override
protected void setUp() throws Exception {
@@ -332,9 +336,113 @@
}
}
+ /**
+ * Test color correction modes and controls.
+ */
+ public void testColorCorrectionControl() throws Exception {
+ for (String id : mCameraIds) {
+ try {
+ openDevice(id);
+
+ colorCorrectionTestByCamera();
+ } finally {
+ closeDevice();
+ }
+ }
+ }
+
// TODO: add 3A state machine test.
/**
+ * Test color correction controls.
+ *
+ * <p>Test different color correction modes. For TRANSFORM_MATRIX, only test
+ * the unit gain and identity transform.</p>
+ */
+ private void colorCorrectionTestByCamera() throws Exception {
+ CaptureRequest request;
+ CaptureResult result;
+ Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
+ updatePreviewSurface(maxPreviewSz);
+ CaptureRequest.Builder manualRequestBuilder = createRequestForPreview();
+ CaptureRequest.Builder previewRequestBuilder = createRequestForPreview();
+ SimpleCaptureListener listener = new SimpleCaptureListener();
+
+ startPreview(previewRequestBuilder, maxPreviewSz, listener);
+
+ // Default preview result should give valid color correction metadata.
+ result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+ validateColorCorrectionResult(result);
+
+ // TRANSFORM_MATRIX mode
+ // Only test unit gain and identity transform
+ float[] UNIT_GAIN = {1.0f, 1.0f, 1.0f, 1.0f};
+ Rational[] IDENTITY_TRANSFORM = {
+ ONE_R, ZERO_R, ZERO_R,
+ ZERO_R, ONE_R, ZERO_R,
+ ZERO_R, ZERO_R, ONE_R
+ };
+ manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
+ manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE,
+ CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
+ manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, UNIT_GAIN);
+ manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_TRANSFORM, IDENTITY_TRANSFORM);
+ request = manualRequestBuilder.build();
+ mCamera.capture(request, listener, mHandler);
+ result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
+ float[] gains = result.get(CaptureResult.COLOR_CORRECTION_GAINS);
+ Rational[] transform = result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM);
+ validateColorCorrectionResult(result);
+ mCollector.expectEquals("Color correction gain result/request mismatch",
+ CameraTestUtils.toObject(UNIT_GAIN), CameraTestUtils.toObject(gains));
+ mCollector.expectEquals("Color correction gain result/request mismatch",
+ IDENTITY_TRANSFORM, transform);
+
+ // FAST mode
+ manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
+ manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE,
+ CaptureRequest.COLOR_CORRECTION_MODE_FAST);
+ request = manualRequestBuilder.build();
+ mCamera.capture(request, listener, mHandler);
+ result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
+ validateColorCorrectionResult(result);
+
+ // HIGH_QUALITY mode
+ manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
+ manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE,
+ CaptureRequest.COLOR_CORRECTION_MODE_FAST);
+ request = manualRequestBuilder.build();
+ mCamera.capture(request, listener, mHandler);
+ result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
+ validateColorCorrectionResult(result);
+ }
+
+ private void validateColorCorrectionResult(CaptureResult result) {
+ float[] ZERO_GAINS = {0, 0, 0, 0};
+ final int TRANSFORM_SIZE = 9;
+ Rational[] zeroTransform = new Rational[TRANSFORM_SIZE];
+ Arrays.fill(zeroTransform, ZERO_R);
+
+ float[] resultGain;
+ if ((resultGain = mCollector.expectKeyValueNotNull(result,
+ CaptureResult.COLOR_CORRECTION_GAINS)) != null) {
+ mCollector.expectEquals("Color correction gain size in incorrect",
+ ZERO_GAINS.length, resultGain.length);
+ mCollector.expectKeyValueNotEquals(result,
+ CaptureResult.COLOR_CORRECTION_GAINS, ZERO_GAINS);
+ }
+
+ Rational[] resultTransform;
+ if ((resultTransform = mCollector.expectKeyValueNotNull(result,
+ CaptureResult.COLOR_CORRECTION_TRANSFORM)) != null) {
+ mCollector.expectEquals("Color correction transform size is incorrect",
+ zeroTransform.length, resultTransform.length);
+ mCollector.expectKeyValueNotEquals(result,
+ CaptureResult.COLOR_CORRECTION_TRANSFORM, zeroTransform);
+ }
+ }
+
+ /**
* Test flash mode control by AE mode.
* <p>
* Only allow AE mode ON or OFF, because other AE mode could run into conflict with
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java
index c1c1d3e..56bce1c 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java
@@ -19,6 +19,7 @@
import android.hardware.camera2.CameraMetadata.Key;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureRequest.Builder;
+import android.hardware.camera2.CaptureResult;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Matcher;
@@ -282,6 +283,23 @@
}
/**
+ * Check if the key value is not null and return the value.
+ *
+ * @param result The {@link CaptureResult} to get the key from.
+ * @param key The {@link CaptureResult} key to be checked.
+ * @return The value of the key.
+ */
+ public <T> T expectKeyValueNotNull(CaptureResult result, Key<T> key) {
+
+ T value = result.get(key);
+ if (value == null) {
+ addMessage("Key " + key.getName() + " shouldn't be null");
+ }
+
+ return value;
+ }
+
+ /**
* Check if the key is non-null and the value is not equal to target.
*
* @param request The The {@link CaptureRequest#Builder} to get the key from.
@@ -303,6 +321,27 @@
}
/**
+ * Check if the key is non-null and the value is not equal to target.
+ *
+ * @param result The The {@link CaptureResult} to get the key from.
+ * @param key The {@link CaptureResult} key to be checked.
+ * @param expected The expected value of the CaptureResult key.
+ */
+ public <T> void expectKeyValueNotEquals(CaptureResult result, Key<T> key, T expected) {
+ if (result == null || key == null || expected == null) {
+ throw new IllegalArgumentException("result, key and target shouldn't be null");
+ }
+
+ T value;
+ if ((value = expectKeyValueNotNull(result, key)) == null) {
+ return;
+ }
+
+ String reason = "Key " + key.getName() + " shouldn't have value " + value.toString();
+ checkThat(reason, value, CoreMatchers.not(expected));
+ }
+
+ /**
* Check if the key is non-null and the value is equal to target.
*
* <p>Only check non-null if the target is null.</p>
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index 79402ac..7e09ee0 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -180,6 +180,11 @@
* @throws CameraAccessException When create capture request from camera fails
*/
protected CaptureRequest.Builder createRequestForPreview() throws CameraAccessException {
+ if (mPreviewSurface == null) {
+ throw new IllegalStateException(
+ "Preview surface is not set yet, call updatePreviewSurface or startPreview"
+ + "first to set the preview surface properly.");
+ }
CaptureRequest.Builder requestBuilder =
mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
requestBuilder.addTarget(mPreviewSurface);