diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 320e7b3119..3ca0b8ea84 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -7670,6 +7670,24 @@ typedef enum acamera_metadata_enum_acamera_request_available_capabilities {
*
ACAMERA_LENS_POSE_REFERENCE
* ACAMERA_LENS_DISTORTION
*
+ * The field of view of all non-RAW physical streams must be the same or as close as
+ * possible to that of non-RAW logical streams. If the requested FOV is outside of the
+ * range supported by the physical camera, the physical stream for that physical camera
+ * will use either the maximum or minimum scaler crop region, depending on which one is
+ * closer to the requested FOV. For example, for a logical camera with wide-tele lens
+ * configuration where the wide lens is the default, if the logical camera's crop region
+ * is set to maximum, the physical stream for the tele lens will be configured to its
+ * maximum crop region. On the other hand, if the logical camera has a normal-wide lens
+ * configuration where the normal lens is the default, when the logical camera's crop
+ * region is set to maximum, the FOV of the logical streams will be that of the normal
+ * lens. The FOV of the physical streams for the wide lens will be the same as the
+ * logical stream, by making the crop region smaller than its active array size to
+ * compensate for the smaller focal length.
+ * Even if the underlying physical cameras have different RAW characteristics (such as
+ * size or CFA pattern), a logical camera can still advertise RAW capability. In this
+ * case, when the application configures a RAW stream, the camera device will make sure
+ * the active physical camera will remain active to ensure consistent RAW output
+ * behavior, and not switch to other physical cameras.
* To maintain backward compatibility, the capture request and result metadata tags
* required for basic camera functionalities will be solely based on the
* logical camera capabiltity. Other request and result metadata tags, on the other
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index bc0dafefd5..54c26b13cf 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -132,13 +132,24 @@ status_t Camera3Device::initialize(sp manager, const Stri
bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
if (isLogical) {
for (auto& physicalId : physicalCameraIds) {
- res = manager->getCameraCharacteristics(physicalId, &mPhysicalDeviceInfoMap[physicalId]);
+ res = manager->getCameraCharacteristics(
+ physicalId, &mPhysicalDeviceInfoMap[physicalId]);
if (res != OK) {
SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
physicalId.c_str(), strerror(-res), res);
session->close();
return res;
}
+
+ if (DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId])) {
+ mDistortionMappers[physicalId].setupStaticInfo(mPhysicalDeviceInfoMap[physicalId]);
+ if (res != OK) {
+ SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
+ "correction", physicalId.c_str());
+ session->close();
+ return res;
+ }
+ }
}
}
@@ -308,7 +319,7 @@ status_t Camera3Device::initializeCommonLocked() {
}
if (DistortionMapper::isDistortionSupported(mDeviceInfo)) {
- res = mDistortionMapper.setupStaticInfo(mDeviceInfo);
+ res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
if (res != OK) {
SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
return res;
@@ -3503,12 +3514,27 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata,
}
// Fix up some result metadata to account for HAL-level distortion correction
- status_t res = mDistortionMapper.correctCaptureResult(&captureResult.mMetadata);
+ status_t res =
+ mDistortionMappers[mId.c_str()].correctCaptureResult(&captureResult.mMetadata);
if (res != OK) {
SET_ERR("Unable to correct capture result metadata for frame %d: %s (%d)",
frameNumber, strerror(res), res);
return;
}
+ for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
+ String8 cameraId8(physicalMetadata.mPhysicalCameraId);
+ if (mDistortionMappers.find(cameraId8.c_str()) == mDistortionMappers.end()) {
+ continue;
+ }
+ res = mDistortionMappers[cameraId8.c_str()].correctCaptureResult(
+ &physicalMetadata.mPhysicalCameraMetadata);
+ if (res != OK) {
+ SET_ERR("Unable to correct physical capture result metadata for frame %d: %s (%d)",
+ frameNumber, strerror(res), res);
+ return;
+ }
+ }
+
// Fix up result metadata for monochrome camera.
res = fixupMonochromeTags(mDeviceInfo, captureResult.mMetadata);
if (res != OK) {
@@ -5481,13 +5507,21 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
// Correct metadata regions for distortion correction if enabled
sp parent = mParent.promote();
if (parent != nullptr) {
- res = parent->mDistortionMapper.correctCaptureRequest(
- &(captureRequest->mSettingsList.begin()->metadata));
- if (res != OK) {
- SET_ERR("RequestThread: Unable to correct capture requests "
- "for lens distortion for request %d: %s (%d)",
- halRequest->frame_number, strerror(-res), res);
- return INVALID_OPERATION;
+ List::iterator it;
+ for (it = captureRequest->mSettingsList.begin();
+ it != captureRequest->mSettingsList.end(); it++) {
+ if (parent->mDistortionMappers.find(it->cameraId) ==
+ parent->mDistortionMappers.end()) {
+ continue;
+ }
+ res = parent->mDistortionMappers[it->cameraId].correctCaptureRequest(
+ &(it->metadata));
+ if (res != OK) {
+ SET_ERR("RequestThread: Unable to correct capture requests "
+ "for lens distortion for request %d: %s (%d)",
+ halRequest->frame_number, strerror(-res), res);
+ return INVALID_OPERATION;
+ }
}
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index d3bb21228a..f8245df821 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1250,8 +1250,10 @@ class Camera3Device :
/**
* Distortion correction support
*/
-
- camera3::DistortionMapper mDistortionMapper;
+ // Map from camera IDs to its corresponding distortion mapper. Only contains
+ // 1 ID if the device isn't a logical multi-camera. Otherwise contains both
+ // logical camera and its physical subcameras.
+ std::unordered_map mDistortionMappers;
// Debug tracker for metadata tag value changes
// - Enabled with the -m option to dumpsys, such as