Loading services/camera/libcameraservice/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,7 @@ cc_library_shared { "device3/Camera3OutputStreamInterface.cpp", "device3/Camera3OutputStreamInterface.cpp", "device3/Camera3OutputUtils.cpp", "device3/Camera3OutputUtils.cpp", "device3/Camera3DeviceInjectionMethods.cpp", "device3/Camera3DeviceInjectionMethods.cpp", "device3/UHRCropAndMeteringRegionMapper.cpp", "gui/RingBufferConsumer.cpp", "gui/RingBufferConsumer.cpp", "hidl/AidlCameraDeviceCallbacks.cpp", "hidl/AidlCameraDeviceCallbacks.cpp", "hidl/AidlCameraServiceListener.cpp", "hidl/AidlCameraServiceListener.cpp", Loading services/camera/libcameraservice/device3/Camera3Device.cpp +34 −1 Original line number Original line Diff line number Diff line Loading @@ -171,6 +171,13 @@ status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const Stri mZoomRatioMappers[physicalId] = ZoomRatioMapper( mZoomRatioMappers[physicalId] = ZoomRatioMapper( &mPhysicalDeviceInfoMap[physicalId], &mPhysicalDeviceInfoMap[physicalId], mSupportNativeZoomRatio, usePrecorrectArray); mSupportNativeZoomRatio, usePrecorrectArray); if (SessionConfigurationUtils::isUltraHighResolutionSensor( mPhysicalDeviceInfoMap[physicalId])) { mUHRCropAndMeteringRegionMappers[physicalId] = UHRCropAndMeteringRegionMapper(mPhysicalDeviceInfoMap[physicalId], usePrecorrectArray); } } } } } Loading Loading @@ -348,6 +355,11 @@ status_t Camera3Device::initializeCommonLocked() { mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo, mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo, mSupportNativeZoomRatio, usePrecorrectArray); mSupportNativeZoomRatio, usePrecorrectArray); if (SessionConfigurationUtils::isUltraHighResolutionSensor(mDeviceInfo)) { mUHRCropAndMeteringRegionMappers[mId.c_str()] = UHRCropAndMeteringRegionMapper(mDeviceInfo, usePrecorrectArray); } if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) { if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) { mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo); mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo); } } Loading Loading @@ -4815,10 +4827,31 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { } } { { // Correct metadata regions for distortion correction if enabled sp<Camera3Device> parent = mParent.promote(); sp<Camera3Device> parent = mParent.promote(); if (parent != nullptr) { if (parent != nullptr) { List<PhysicalCameraSettings>::iterator it; List<PhysicalCameraSettings>::iterator it; for (it = captureRequest->mSettingsList.begin(); it != captureRequest->mSettingsList.end(); it++) { if (parent->mUHRCropAndMeteringRegionMappers.find(it->cameraId) == parent->mUHRCropAndMeteringRegionMappers.end()) { continue; } if (!captureRequest->mUHRCropAndMeteringRegionsUpdated) { res = parent->mUHRCropAndMeteringRegionMappers[it->cameraId]. updateCaptureRequest(&(it->metadata)); if (res != OK) { SET_ERR("RequestThread: Unable to correct capture requests " "for scaler crop region and metering regions for request " "%d: %s (%d)", halRequest->frame_number, strerror(-res), res); return INVALID_OPERATION; } captureRequest->mUHRCropAndMeteringRegionsUpdated = true; } } // Correct metadata regions for distortion correction if enabled for (it = captureRequest->mSettingsList.begin(); for (it = captureRequest->mSettingsList.begin(); it != captureRequest->mSettingsList.end(); it++) { it != captureRequest->mSettingsList.end(); it++) { if (parent->mDistortionMappers.find(it->cameraId) == if (parent->mDistortionMappers.find(it->cameraId) == Loading services/camera/libcameraservice/device3/Camera3Device.h +10 −0 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,7 @@ #include "device3/DistortionMapper.h" #include "device3/DistortionMapper.h" #include "device3/ZoomRatioMapper.h" #include "device3/ZoomRatioMapper.h" #include "device3/RotateAndCropMapper.h" #include "device3/RotateAndCropMapper.h" #include "device3/UHRCropAndMeteringRegionMapper.h" #include "device3/InFlightRequest.h" #include "device3/InFlightRequest.h" #include "device3/Camera3OutputInterface.h" #include "device3/Camera3OutputInterface.h" #include "device3/Camera3OfflineSession.h" #include "device3/Camera3OfflineSession.h" Loading Loading @@ -589,6 +590,9 @@ class Camera3Device : bool mRotationAndCropUpdated = false; bool mRotationAndCropUpdated = false; // Whether this capture request's zoom ratio update has been done. // Whether this capture request's zoom ratio update has been done. bool mZoomRatioUpdated = false; bool mZoomRatioUpdated = false; // Whether this max resolution capture request's crop / metering region update has been // done. bool mUHRCropAndMeteringRegionsUpdated = false; }; }; typedef List<sp<CaptureRequest> > RequestList; typedef List<sp<CaptureRequest> > RequestList; Loading Loading @@ -1223,6 +1227,12 @@ class Camera3Device : */ */ std::unordered_map<std::string, camera3::ZoomRatioMapper> mZoomRatioMappers; std::unordered_map<std::string, camera3::ZoomRatioMapper> mZoomRatioMappers; /** * UHR request crop / metering region mapper support */ std::unordered_map<std::string, camera3::UHRCropAndMeteringRegionMapper> mUHRCropAndMeteringRegionMappers; /** /** * RotateAndCrop mapper support * RotateAndCrop mapper support */ */ Loading services/camera/libcameraservice/device3/UHRCropAndMeteringRegionMapper.cpp 0 → 100644 +168 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "Camera3-UHRCropAndMeteringRegionMapper" #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include <algorithm> #include <cmath> #include "device3/UHRCropAndMeteringRegionMapper.h" #include "utils/SessionConfigurationUtils.h" namespace android { namespace camera3 { // For Capture request // metering region -> {fwk private key for metering region set, true} static std::unordered_map<uint32_t, std::pair<uint32_t, uint32_t>> kMeteringRegionsToCorrect = { {ANDROID_CONTROL_AF_REGIONS, {ANDROID_CONTROL_AF_REGIONS_SET, ANDROID_CONTROL_AF_REGIONS_SET_TRUE}}, {ANDROID_CONTROL_AE_REGIONS, {ANDROID_CONTROL_AE_REGIONS_SET, ANDROID_CONTROL_AE_REGIONS_SET_TRUE}}, {ANDROID_CONTROL_AWB_REGIONS, {ANDROID_CONTROL_AWB_REGIONS_SET, ANDROID_CONTROL_AWB_REGIONS_SET_TRUE}} }; UHRCropAndMeteringRegionMapper::UHRCropAndMeteringRegionMapper(const CameraMetadata &deviceInfo, bool usePreCorrectedArray) { if (usePreCorrectedArray) { if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &mArrayWidth, &mArrayHeight)) { ALOGE("%s: Couldn't get pre correction active array size", __FUNCTION__); return; } if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, &mArrayWidthMaximumResolution, &mArrayHeightMaximumResolution)) { ALOGE("%s: Couldn't get maximum resolution pre correction active array size", __FUNCTION__); return; } } else { if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, &mArrayWidth, &mArrayHeight)) { ALOGE("%s: Couldn't get active array size", __FUNCTION__); return; } if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, &mArrayWidthMaximumResolution, &mArrayHeightMaximumResolution)) { ALOGE("%s: Couldn't get maximum resolution active array size", __FUNCTION__); return; } } mIsValid = true; ALOGV("%s: array size: %d x %d, full res array size: %d x %d,", __FUNCTION__, mArrayWidth, mArrayHeight, mArrayWidthMaximumResolution, mArrayHeightMaximumResolution); } void UHRCropAndMeteringRegionMapper::fixMeteringRegionsIfNeeded(CameraMetadata *request) { if (request == nullptr) { ALOGE("%s request is nullptr, can't fix crop region", __FUNCTION__); return; } for (const auto &entry : kMeteringRegionsToCorrect) { // Check if the metering region Set key is set to TRUE, we don't // need to correct the metering regions. camera_metadata_entry meteringRegionsSetEntry = request->find(entry.second.first); if (meteringRegionsSetEntry.count == 1 && meteringRegionsSetEntry.data.u8[0] == entry.second.second) { // metering region set by client, doesn't need to be fixed. continue; } camera_metadata_entry meteringRegionEntry = request->find(entry.first); if (meteringRegionEntry.count % 5 != 0) { ALOGE("%s: Metering region entry for tag %d does not have a valid number of entries, " "skipping", __FUNCTION__, (int)entry.first); continue; } for (size_t j = 0; j < meteringRegionEntry.count; j += 5) { int32_t *meteringRegionStart = meteringRegionEntry.data.i32 + j; meteringRegionStart[0] = 0; meteringRegionStart[1] = 0; meteringRegionStart[2] = mArrayWidthMaximumResolution; meteringRegionStart[3] = mArrayHeightMaximumResolution; } } } void UHRCropAndMeteringRegionMapper::fixCropRegionsIfNeeded(CameraMetadata *request) { if (request == nullptr) { ALOGE("%s request is nullptr, can't fix crop region", __FUNCTION__); return; } // Check if the scalerCropRegionSet key is set to TRUE, we don't // need to correct the crop region. camera_metadata_entry cropRegionSetEntry = request->find(ANDROID_SCALER_CROP_REGION_SET); if (cropRegionSetEntry.count == 1 && cropRegionSetEntry.data.u8[0] == ANDROID_SCALER_CROP_REGION_SET_TRUE) { // crop regions set by client, doesn't need to be fixed. return; } camera_metadata_entry_t cropRegionEntry = request->find(ANDROID_SCALER_CROP_REGION); if (cropRegionEntry.count == 4) { cropRegionEntry.data.i32[0] = 0; cropRegionEntry.data.i32[1] = 0; cropRegionEntry.data.i32[2] = mArrayWidthMaximumResolution; cropRegionEntry.data.i32[3] = mArrayHeightMaximumResolution; } } status_t UHRCropAndMeteringRegionMapper::updateCaptureRequest(CameraMetadata* request) { if (request == nullptr) { ALOGE("%s Invalid request, request is nullptr", __FUNCTION__); return BAD_VALUE; } if (!mIsValid) { ALOGE("%s UHRCropAndMeteringRegionMapper didn't initialize correctly", __FUNCTION__); return INVALID_OPERATION; } camera_metadata_entry sensorPixelModeEntry = request->find(ANDROID_SENSOR_PIXEL_MODE); // Check if this is max resolution capture, if not, we don't need to do // anything. if (sensorPixelModeEntry.count != 0) { int32_t sensorPixelMode = sensorPixelModeEntry.data.u8[0]; if (sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) { // Correction not needed for default mode requests. return OK; } } else { // sensor pixel mode not set -> default sensor pixel mode request, which // doesn't need correction. return OK; } fixCropRegionsIfNeeded(request); fixMeteringRegionsIfNeeded(request); return OK; } } // namespace camera3 } // namespace android services/camera/libcameraservice/device3/UHRCropAndMeteringRegionMapper.h 0 → 100644 +59 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SERVERS_UHRCROP_REGIONS_MAPPER_H #define ANDROID_SERVERS_UHRCROP_REGIONS_MAPPER_H #include <utils/Errors.h> #include <array> #include "camera/CameraMetadata.h" namespace android { namespace camera3 { /** * Utilities to transform SCALER_CROP_REGION and metering regions for ultra high * resolution sensors. */ class UHRCropAndMeteringRegionMapper { public: UHRCropAndMeteringRegionMapper() = default; UHRCropAndMeteringRegionMapper(const CameraMetadata &deviceInfo, bool usePreCorrectionArray); /** * Adjust capture request assuming rotate and crop AUTO is enabled */ status_t updateCaptureRequest(CameraMetadata *request); private: void fixCropRegionsIfNeeded(CameraMetadata *request); void fixMeteringRegionsIfNeeded(CameraMetadata *request); int32_t mArrayWidth = 0; int32_t mArrayHeight = 0; int32_t mArrayWidthMaximumResolution = 0; int32_t mArrayHeightMaximumResolution = 0; bool mIsValid = false; }; // class UHRCropAndMeteringRegionMapper } // namespace camera3 } // namespace android #endif Loading
services/camera/libcameraservice/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,7 @@ cc_library_shared { "device3/Camera3OutputStreamInterface.cpp", "device3/Camera3OutputStreamInterface.cpp", "device3/Camera3OutputUtils.cpp", "device3/Camera3OutputUtils.cpp", "device3/Camera3DeviceInjectionMethods.cpp", "device3/Camera3DeviceInjectionMethods.cpp", "device3/UHRCropAndMeteringRegionMapper.cpp", "gui/RingBufferConsumer.cpp", "gui/RingBufferConsumer.cpp", "hidl/AidlCameraDeviceCallbacks.cpp", "hidl/AidlCameraDeviceCallbacks.cpp", "hidl/AidlCameraServiceListener.cpp", "hidl/AidlCameraServiceListener.cpp", Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +34 −1 Original line number Original line Diff line number Diff line Loading @@ -171,6 +171,13 @@ status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const Stri mZoomRatioMappers[physicalId] = ZoomRatioMapper( mZoomRatioMappers[physicalId] = ZoomRatioMapper( &mPhysicalDeviceInfoMap[physicalId], &mPhysicalDeviceInfoMap[physicalId], mSupportNativeZoomRatio, usePrecorrectArray); mSupportNativeZoomRatio, usePrecorrectArray); if (SessionConfigurationUtils::isUltraHighResolutionSensor( mPhysicalDeviceInfoMap[physicalId])) { mUHRCropAndMeteringRegionMappers[physicalId] = UHRCropAndMeteringRegionMapper(mPhysicalDeviceInfoMap[physicalId], usePrecorrectArray); } } } } } Loading Loading @@ -348,6 +355,11 @@ status_t Camera3Device::initializeCommonLocked() { mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo, mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo, mSupportNativeZoomRatio, usePrecorrectArray); mSupportNativeZoomRatio, usePrecorrectArray); if (SessionConfigurationUtils::isUltraHighResolutionSensor(mDeviceInfo)) { mUHRCropAndMeteringRegionMappers[mId.c_str()] = UHRCropAndMeteringRegionMapper(mDeviceInfo, usePrecorrectArray); } if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) { if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) { mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo); mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo); } } Loading Loading @@ -4815,10 +4827,31 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { } } { { // Correct metadata regions for distortion correction if enabled sp<Camera3Device> parent = mParent.promote(); sp<Camera3Device> parent = mParent.promote(); if (parent != nullptr) { if (parent != nullptr) { List<PhysicalCameraSettings>::iterator it; List<PhysicalCameraSettings>::iterator it; for (it = captureRequest->mSettingsList.begin(); it != captureRequest->mSettingsList.end(); it++) { if (parent->mUHRCropAndMeteringRegionMappers.find(it->cameraId) == parent->mUHRCropAndMeteringRegionMappers.end()) { continue; } if (!captureRequest->mUHRCropAndMeteringRegionsUpdated) { res = parent->mUHRCropAndMeteringRegionMappers[it->cameraId]. updateCaptureRequest(&(it->metadata)); if (res != OK) { SET_ERR("RequestThread: Unable to correct capture requests " "for scaler crop region and metering regions for request " "%d: %s (%d)", halRequest->frame_number, strerror(-res), res); return INVALID_OPERATION; } captureRequest->mUHRCropAndMeteringRegionsUpdated = true; } } // Correct metadata regions for distortion correction if enabled for (it = captureRequest->mSettingsList.begin(); for (it = captureRequest->mSettingsList.begin(); it != captureRequest->mSettingsList.end(); it++) { it != captureRequest->mSettingsList.end(); it++) { if (parent->mDistortionMappers.find(it->cameraId) == if (parent->mDistortionMappers.find(it->cameraId) == Loading
services/camera/libcameraservice/device3/Camera3Device.h +10 −0 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,7 @@ #include "device3/DistortionMapper.h" #include "device3/DistortionMapper.h" #include "device3/ZoomRatioMapper.h" #include "device3/ZoomRatioMapper.h" #include "device3/RotateAndCropMapper.h" #include "device3/RotateAndCropMapper.h" #include "device3/UHRCropAndMeteringRegionMapper.h" #include "device3/InFlightRequest.h" #include "device3/InFlightRequest.h" #include "device3/Camera3OutputInterface.h" #include "device3/Camera3OutputInterface.h" #include "device3/Camera3OfflineSession.h" #include "device3/Camera3OfflineSession.h" Loading Loading @@ -589,6 +590,9 @@ class Camera3Device : bool mRotationAndCropUpdated = false; bool mRotationAndCropUpdated = false; // Whether this capture request's zoom ratio update has been done. // Whether this capture request's zoom ratio update has been done. bool mZoomRatioUpdated = false; bool mZoomRatioUpdated = false; // Whether this max resolution capture request's crop / metering region update has been // done. bool mUHRCropAndMeteringRegionsUpdated = false; }; }; typedef List<sp<CaptureRequest> > RequestList; typedef List<sp<CaptureRequest> > RequestList; Loading Loading @@ -1223,6 +1227,12 @@ class Camera3Device : */ */ std::unordered_map<std::string, camera3::ZoomRatioMapper> mZoomRatioMappers; std::unordered_map<std::string, camera3::ZoomRatioMapper> mZoomRatioMappers; /** * UHR request crop / metering region mapper support */ std::unordered_map<std::string, camera3::UHRCropAndMeteringRegionMapper> mUHRCropAndMeteringRegionMappers; /** /** * RotateAndCrop mapper support * RotateAndCrop mapper support */ */ Loading
services/camera/libcameraservice/device3/UHRCropAndMeteringRegionMapper.cpp 0 → 100644 +168 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "Camera3-UHRCropAndMeteringRegionMapper" #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include <algorithm> #include <cmath> #include "device3/UHRCropAndMeteringRegionMapper.h" #include "utils/SessionConfigurationUtils.h" namespace android { namespace camera3 { // For Capture request // metering region -> {fwk private key for metering region set, true} static std::unordered_map<uint32_t, std::pair<uint32_t, uint32_t>> kMeteringRegionsToCorrect = { {ANDROID_CONTROL_AF_REGIONS, {ANDROID_CONTROL_AF_REGIONS_SET, ANDROID_CONTROL_AF_REGIONS_SET_TRUE}}, {ANDROID_CONTROL_AE_REGIONS, {ANDROID_CONTROL_AE_REGIONS_SET, ANDROID_CONTROL_AE_REGIONS_SET_TRUE}}, {ANDROID_CONTROL_AWB_REGIONS, {ANDROID_CONTROL_AWB_REGIONS_SET, ANDROID_CONTROL_AWB_REGIONS_SET_TRUE}} }; UHRCropAndMeteringRegionMapper::UHRCropAndMeteringRegionMapper(const CameraMetadata &deviceInfo, bool usePreCorrectedArray) { if (usePreCorrectedArray) { if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &mArrayWidth, &mArrayHeight)) { ALOGE("%s: Couldn't get pre correction active array size", __FUNCTION__); return; } if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, &mArrayWidthMaximumResolution, &mArrayHeightMaximumResolution)) { ALOGE("%s: Couldn't get maximum resolution pre correction active array size", __FUNCTION__); return; } } else { if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, &mArrayWidth, &mArrayHeight)) { ALOGE("%s: Couldn't get active array size", __FUNCTION__); return; } if (!SessionConfigurationUtils::getArrayWidthAndHeight(&deviceInfo, ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, &mArrayWidthMaximumResolution, &mArrayHeightMaximumResolution)) { ALOGE("%s: Couldn't get maximum resolution active array size", __FUNCTION__); return; } } mIsValid = true; ALOGV("%s: array size: %d x %d, full res array size: %d x %d,", __FUNCTION__, mArrayWidth, mArrayHeight, mArrayWidthMaximumResolution, mArrayHeightMaximumResolution); } void UHRCropAndMeteringRegionMapper::fixMeteringRegionsIfNeeded(CameraMetadata *request) { if (request == nullptr) { ALOGE("%s request is nullptr, can't fix crop region", __FUNCTION__); return; } for (const auto &entry : kMeteringRegionsToCorrect) { // Check if the metering region Set key is set to TRUE, we don't // need to correct the metering regions. camera_metadata_entry meteringRegionsSetEntry = request->find(entry.second.first); if (meteringRegionsSetEntry.count == 1 && meteringRegionsSetEntry.data.u8[0] == entry.second.second) { // metering region set by client, doesn't need to be fixed. continue; } camera_metadata_entry meteringRegionEntry = request->find(entry.first); if (meteringRegionEntry.count % 5 != 0) { ALOGE("%s: Metering region entry for tag %d does not have a valid number of entries, " "skipping", __FUNCTION__, (int)entry.first); continue; } for (size_t j = 0; j < meteringRegionEntry.count; j += 5) { int32_t *meteringRegionStart = meteringRegionEntry.data.i32 + j; meteringRegionStart[0] = 0; meteringRegionStart[1] = 0; meteringRegionStart[2] = mArrayWidthMaximumResolution; meteringRegionStart[3] = mArrayHeightMaximumResolution; } } } void UHRCropAndMeteringRegionMapper::fixCropRegionsIfNeeded(CameraMetadata *request) { if (request == nullptr) { ALOGE("%s request is nullptr, can't fix crop region", __FUNCTION__); return; } // Check if the scalerCropRegionSet key is set to TRUE, we don't // need to correct the crop region. camera_metadata_entry cropRegionSetEntry = request->find(ANDROID_SCALER_CROP_REGION_SET); if (cropRegionSetEntry.count == 1 && cropRegionSetEntry.data.u8[0] == ANDROID_SCALER_CROP_REGION_SET_TRUE) { // crop regions set by client, doesn't need to be fixed. return; } camera_metadata_entry_t cropRegionEntry = request->find(ANDROID_SCALER_CROP_REGION); if (cropRegionEntry.count == 4) { cropRegionEntry.data.i32[0] = 0; cropRegionEntry.data.i32[1] = 0; cropRegionEntry.data.i32[2] = mArrayWidthMaximumResolution; cropRegionEntry.data.i32[3] = mArrayHeightMaximumResolution; } } status_t UHRCropAndMeteringRegionMapper::updateCaptureRequest(CameraMetadata* request) { if (request == nullptr) { ALOGE("%s Invalid request, request is nullptr", __FUNCTION__); return BAD_VALUE; } if (!mIsValid) { ALOGE("%s UHRCropAndMeteringRegionMapper didn't initialize correctly", __FUNCTION__); return INVALID_OPERATION; } camera_metadata_entry sensorPixelModeEntry = request->find(ANDROID_SENSOR_PIXEL_MODE); // Check if this is max resolution capture, if not, we don't need to do // anything. if (sensorPixelModeEntry.count != 0) { int32_t sensorPixelMode = sensorPixelModeEntry.data.u8[0]; if (sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) { // Correction not needed for default mode requests. return OK; } } else { // sensor pixel mode not set -> default sensor pixel mode request, which // doesn't need correction. return OK; } fixCropRegionsIfNeeded(request); fixMeteringRegionsIfNeeded(request); return OK; } } // namespace camera3 } // namespace android
services/camera/libcameraservice/device3/UHRCropAndMeteringRegionMapper.h 0 → 100644 +59 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SERVERS_UHRCROP_REGIONS_MAPPER_H #define ANDROID_SERVERS_UHRCROP_REGIONS_MAPPER_H #include <utils/Errors.h> #include <array> #include "camera/CameraMetadata.h" namespace android { namespace camera3 { /** * Utilities to transform SCALER_CROP_REGION and metering regions for ultra high * resolution sensors. */ class UHRCropAndMeteringRegionMapper { public: UHRCropAndMeteringRegionMapper() = default; UHRCropAndMeteringRegionMapper(const CameraMetadata &deviceInfo, bool usePreCorrectionArray); /** * Adjust capture request assuming rotate and crop AUTO is enabled */ status_t updateCaptureRequest(CameraMetadata *request); private: void fixCropRegionsIfNeeded(CameraMetadata *request); void fixMeteringRegionsIfNeeded(CameraMetadata *request); int32_t mArrayWidth = 0; int32_t mArrayHeight = 0; int32_t mArrayWidthMaximumResolution = 0; int32_t mArrayHeightMaximumResolution = 0; bool mIsValid = false; }; // class UHRCropAndMeteringRegionMapper } // namespace camera3 } // namespace android #endif