CameraITS: Add physical camera metadata support
- Serialize physical camera metadata for logical multi-camera if physical
camera is requested.
- Update CTS test to use getPhysicalResultMetadata call
- Remove redundant request and static metadata from captureResults.
Test: Run hacked test_yuv_plus_raw to stream physical streams
Bug: 66697407
Change-Id: I8fdfd9992fc988de59f84a84f3cb99383abf1a01
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index 3e3cc02..7a20877 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -756,6 +756,7 @@
"rawStats":[], "dng":[], "jpeg":[]}
yuv_bufs = {size:[] for size in yuv_sizes}
mds = []
+ physical_mds = []
widths = None
heights = None
while nbufs < ncap*nsurf or len(mds) < ncap:
@@ -772,6 +773,7 @@
nbufs += 1
elif jsonObj['tag'] == 'captureResults':
mds.append(jsonObj['objValue']['captureResult'])
+ physical_mds.append(jsonObj['objValue']['physicalResults'])
outputs = jsonObj['objValue']['outputs']
widths = [out['width'] for out in outputs]
heights = [out['height'] for out in outputs]
@@ -791,7 +793,13 @@
obj["width"] = widths[j]
obj["height"] = heights[j]
obj["format"] = fmt
- obj["metadata"] = mds[i]
+ if j in physical_cam_ids:
+ for physical_md in physical_mds[i]:
+ if physical_cam_ids[j] in physical_md:
+ obj["metadata"] = physical_md[physical_cam_ids[j]]
+ break
+ else:
+ obj["metadata"] = mds[i]
if j in physical_cam_ids:
obj["data"] = physical_buffers[physical_cam_ids[j]][i]
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 8677941..6b8e9b2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -86,8 +86,10 @@
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
@@ -211,6 +213,9 @@
private HandlerThread mSensorThread = null;
private Handler mSensorHandler = null;
+ private static final int SERIALIZER_SURFACES_ID = 2;
+ private static final int SERIALIZER_PHYSICAL_METADATA_ID = 3;
+
public interface CaptureCallback {
void onCaptureAvailable(Image capture, String physicalCameraId);
}
@@ -420,9 +425,20 @@
jsonObj.put("captureResult", ItsSerializer.serialize(
(CaptureResult)obj));
} else if (obj instanceof JSONArray) {
- jsonObj.put("outputs", (JSONArray)obj);
+ if (tag == "captureResults") {
+ if (i == SERIALIZER_SURFACES_ID) {
+ jsonObj.put("outputs", (JSONArray)obj);
+ } else if (i == SERIALIZER_PHYSICAL_METADATA_ID) {
+ jsonObj.put("physicalResults", (JSONArray)obj);
+ } else {
+ throw new ItsException(
+ "Unsupported JSONArray for captureResults");
+ }
+ } else {
+ jsonObj.put("outputs", (JSONArray)obj);
+ }
} else {
- throw new ItsException("Invalid object received for serialiation");
+ throw new ItsException("Invalid object received for serialization");
}
}
if (tag == null) {
@@ -750,7 +766,7 @@
public void sendResponseCaptureResult(CameraCharacteristics props,
CaptureRequest request,
- CaptureResult result,
+ TotalCaptureResult result,
ImageReader[] readers)
throws ItsException {
try {
@@ -788,12 +804,19 @@
jsonSurfaces.put(jsonSurface);
}
- Object objs[] = new Object[5];
+ Map<String, CaptureResult> physicalMetadata =
+ result.getPhysicalCameraResults();
+ JSONArray jsonPhysicalMetadata = new JSONArray();
+ for (Map.Entry<String, CaptureResult> pair : physicalMetadata.entrySet()) {
+ JSONObject jsonOneMetadata = new JSONObject();
+ jsonOneMetadata.put(pair.getKey(), ItsSerializer.serialize(pair.getValue()));
+ jsonPhysicalMetadata.put(jsonOneMetadata);
+ }
+ Object objs[] = new Object[4];
objs[0] = "captureResults";
- objs[1] = props;
- objs[2] = request;
- objs[3] = result;
- objs[4] = jsonSurfaces;
+ objs[1] = result;
+ objs[SERIALIZER_SURFACES_ID] = jsonSurfaces;
+ objs[SERIALIZER_PHYSICAL_METADATA_ID] = jsonPhysicalMetadata;
mSerializerQueue.put(objs);
} catch (org.json.JSONException e) {
throw new ItsException("JSON error: ", e);
diff --git a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
index 05aa260..6621cef 100644
--- a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
@@ -52,6 +52,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import static org.mockito.Mockito.*;
@@ -505,18 +506,14 @@
CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
logicalTimestamps[i] = totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP);
}
- // Make sure that requesting a physical camera key for a logical stream request
- // throws exception.
- try {
- TotalCaptureResult totalCaptureResult =
- simpleResultListener.getTotalCaptureResult(
- CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
- long timestamp = totalCaptureResult.getPhysicalCameraKey(
- CaptureResult.SENSOR_TIMESTAMP, physicalCameraIds.get(0));
- fail("No exception for invalid physical camera Id for TotalCaptureResult");
- } catch (IllegalArgumentException e) {
- // expected
- }
+ // Make sure that a logical stream request wont' generate physical result metadata.
+ TotalCaptureResult totalCaptureResult =
+ simpleResultListener.getTotalCaptureResult(
+ CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+ Map<String, CaptureResult> physicalResults =
+ totalCaptureResult.getPhysicalCameraResults();
+ assertTrue("Logical stream request must not generate physical result metadata",
+ physicalResults.isEmpty());
double logicalAvgDurationMs = (logicalTimestamps[NUM_FRAMES_CHECKED-1] -
logicalTimestamps[0])/(NS_PER_MS*(NUM_FRAMES_CHECKED-1));
@@ -536,30 +533,28 @@
physicalTimestamps[i] = new long[NUM_FRAMES_CHECKED];
}
for (int i = 0; i < NUM_FRAMES_CHECKED; i++) {
- TotalCaptureResult totalCaptureResult =
+ TotalCaptureResult totalCaptureResultDual =
simpleResultListenerDual.getTotalCaptureResult(
CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
- logicalTimestamps2[i] = totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP);
+ logicalTimestamps2[i] = totalCaptureResultDual.get(CaptureResult.SENSOR_TIMESTAMP);
int index = 0;
+ Map<String, CaptureResult> physicalResultsDual =
+ totalCaptureResultDual.getPhysicalCameraResults();
for (String physicalId : physicalCameraIds) {
- physicalTimestamps[index][i] = totalCaptureResult.getPhysicalCameraKey(
- CaptureResult.SENSOR_TIMESTAMP, physicalId);
+ physicalTimestamps[index][i] = physicalResultsDual.get(physicalId).get(
+ CaptureResult.SENSOR_TIMESTAMP);
index++;
}
}
- // Make sure that requesting an invalid physical camera key throws exception.
- try {
- String invalidStringId = "InvalidCamera";
- TotalCaptureResult totalCaptureResult =
- simpleResultListener.getTotalCaptureResult(
- CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
- long timestamp = totalCaptureResult.getPhysicalCameraKey(
- CaptureResult.SENSOR_TIMESTAMP, invalidStringId);
- fail("No exception for invalid physical camera Id for TotalCaptureResult");
- } catch (IllegalArgumentException e) {
- // expected
- }
+ // Verify the size of the physical result metadata map
+ TotalCaptureResult totalCaptureResultDual =
+ simpleResultListenerDual.getTotalCaptureResult(
+ CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+ Map<String, CaptureResult> physicalResultsDual =
+ totalCaptureResultDual.getPhysicalCameraResults();
+ assertTrue("Stream request must generate 2 physical result metadata",
+ physicalResultsDual.size() == 2);
// Check timestamp monolithity for individual camera and across cameras
for (int i = 0; i < NUM_FRAMES_CHECKED-1; i++) {