diff options
author | Shuzhen Wang <shuzhenwang@google.com> | 2023-11-28 17:09:16 +0000 |
---|---|---|
committer | Shuzhen Wang <shuzhenwang@google.com> | 2023-12-15 02:14:56 +0000 |
commit | 3fe0eff4282d50aa9c798e04dab1aae545fc1f95 (patch) | |
tree | d8f93e711248144ba55a27f5abbd6d7e90af0306 | |
parent | e0be63de6bde41af23c060ceca400c02a1782a40 (diff) | |
download | camera-3fe0eff4282d50aa9c798e04dab1aae545fc1f95.tar.gz |
EmulatedCamera: Enable session configuration query
Really enable session configuration query for Cuttlefish HAL.
Test: Run Camera CTS test on Cuttlefish and Pixel
Bug: 298033056
Change-Id: I1cb513599ee28f988d692d849f63c66489a906f5
21 files changed, 2796 insertions, 2531 deletions
diff --git a/common/hal/aidl_service/aidl_camera_device.cc b/common/hal/aidl_service/aidl_camera_device.cc index a086897..4c4ea84 100644 --- a/common/hal/aidl_service/aidl_camera_device.cc +++ b/common/hal/aidl_service/aidl_camera_device.cc @@ -163,23 +163,48 @@ ScopedAStatus AidlCameraDevice::getTorchStrengthLevel(int32_t* strength_level) { } ScopedAStatus AidlCameraDevice::constructDefaultRequestSettings( - RequestTemplate /*requestTemplate*/, CameraMetadata* requestSettings) { - if (requestSettings == nullptr) { + RequestTemplate type, CameraMetadata* request_settings) { + if (request_settings == nullptr) { return ScopedAStatus::fromServiceSpecificError( static_cast<int32_t>(Status::ILLEGAL_ARGUMENT)); } - return ScopedAStatus::fromServiceSpecificError( - static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED)); -} -ScopedAStatus AidlCameraDevice::isStreamCombinationWithSettingsSupported( - const StreamConfiguration& /*streamConfiguration*/, bool* supported) { - if (supported == nullptr) { - return ScopedAStatus::fromServiceSpecificError( + request_settings->metadata.clear(); + + google_camera_hal::RequestTemplate hal_type; + status_t res = aidl_utils::ConvertToHalTemplateType(type, &hal_type); + if (res != OK) { + return ndk::ScopedAStatus::fromServiceSpecificError( static_cast<int32_t>(Status::ILLEGAL_ARGUMENT)); } - return ScopedAStatus::fromServiceSpecificError( - static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED)); + + std::unique_ptr<HalCameraMetadata> settings; + res = google_camera_device_->ConstructDefaultRequestSettings(hal_type, + &settings); + if (res != OK) { + ALOGE("%s: Getting camera characteristics for camera %u failed: %s(%d)", + __FUNCTION__, camera_id_, strerror(-res), res); + return ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(Status::INTERNAL_ERROR)); + } + if (settings == nullptr) { + ALOGE("%s: Default request settings for camera %u is nullptr.", + __FUNCTION__, camera_id_); + return ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(Status::INTERNAL_ERROR)); + } + + uint32_t metadata_size = settings->GetCameraMetadataSize(); + uint8_t* chars_p = (uint8_t*)settings->GetRawCameraMetadata(); + request_settings->metadata.assign(chars_p, chars_p + metadata_size); + + return ScopedAStatus::ok(); +} + +ScopedAStatus AidlCameraDevice::isStreamCombinationWithSettingsSupported( + const StreamConfiguration& streamConfiguration, bool* supported) { + return isStreamCombinationSupportedInternal(streamConfiguration, supported, + /*checkSettings*/ true); } ScopedAStatus AidlCameraDevice::getSessionCharacteristics( @@ -284,6 +309,12 @@ binder_status_t AidlCameraDevice::dump(int fd, const char** /*args*/, ScopedAStatus AidlCameraDevice::isStreamCombinationSupported( const StreamConfiguration& streams, bool* supported) { + return isStreamCombinationSupportedInternal(streams, supported, + /*checkSettings*/ false); +} + +ScopedAStatus AidlCameraDevice::isStreamCombinationSupportedInternal( + const StreamConfiguration& streams, bool* supported, bool checkSettings) { if (supported == nullptr) { return ScopedAStatus::fromServiceSpecificError( static_cast<int32_t>(Status::ILLEGAL_ARGUMENT)); @@ -296,8 +327,8 @@ ScopedAStatus AidlCameraDevice::isStreamCombinationSupported( return ScopedAStatus::fromServiceSpecificError( static_cast<int32_t>(Status::INTERNAL_ERROR)); } - *supported = - google_camera_device_->IsStreamCombinationSupported(stream_config); + *supported = google_camera_device_->IsStreamCombinationSupported( + stream_config, checkSettings); return ScopedAStatus::ok(); } diff --git a/common/hal/aidl_service/aidl_camera_device.h b/common/hal/aidl_service/aidl_camera_device.h index ccfaea2..060a421 100644 --- a/common/hal/aidl_service/aidl_camera_device.h +++ b/common/hal/aidl_service/aidl_camera_device.h @@ -88,7 +88,7 @@ class AidlCameraDevice : public BnCameraDevice { ScopedAStatus getTorchStrengthLevel(int32_t* strength_level) override; ScopedAStatus constructDefaultRequestSettings( - RequestTemplate requestTemplate, CameraMetadata* requestSettings) override; + RequestTemplate type, CameraMetadata* request_settings) override; ScopedAStatus isStreamCombinationWithSettingsSupported( const StreamConfiguration& streamConfiguration, bool* supported) override; @@ -106,6 +106,10 @@ class AidlCameraDevice : public BnCameraDevice { std::unique_ptr<CameraDevice> google_camera_device_; uint32_t camera_id_ = 0; std::shared_ptr<AidlProfiler> aidl_profiler_; + + ScopedAStatus isStreamCombinationSupportedInternal( + const StreamConfiguration& streamConfiguration, bool* supported, + bool checkSettings); }; } // namespace implementation diff --git a/common/hal/common/hal_types.h b/common/hal/common/hal_types.h index 380d2fb..8dcf789 100644 --- a/common/hal/common/hal_types.h +++ b/common/hal/common/hal_types.h @@ -250,6 +250,12 @@ enum class RequestTemplate : uint32_t { kVendorTemplateStart = 0x40000000, }; +static constexpr size_t kTemplateCount = + static_cast<size_t>(RequestTemplate::kManual) + 1; + +typedef std::array<std::unique_ptr<HalCameraMetadata>, kTemplateCount> + DefaultRequestsType; + // See the definition of // ::android::hardware::camera::device::V3_2::MsgType enum class MessageType : uint32_t { diff --git a/common/hal/google_camera_hal/camera_device.cc b/common/hal/google_camera_hal/camera_device.cc index 55c3a41..c10ede0 100644 --- a/common/hal/google_camera_hal/camera_device.cc +++ b/common/hal/google_camera_hal/camera_device.cc @@ -240,6 +240,13 @@ status_t CameraDevice::GetTorchStrengthLevel(int32_t& torch_strength) const { return res; } +status_t CameraDevice::ConstructDefaultRequestSettings( + RequestTemplate type, std::unique_ptr<HalCameraMetadata>* request_settings) { + ATRACE_CALL(); + return camera_device_hwl_->ConstructDefaultRequestSettings(type, + request_settings); +} + status_t CameraDevice::DumpState(int fd) { ATRACE_CALL(); return camera_device_hwl_->DumpState(fd); @@ -278,10 +285,21 @@ status_t CameraDevice::CreateCameraDeviceSession( } bool CameraDevice::IsStreamCombinationSupported( - const StreamConfiguration& stream_config) { + const StreamConfiguration& stream_config, bool check_settings) { if (!utils::IsStreamUseCaseSupported(stream_config, stream_use_cases_)) { return false; } + if (check_settings && stream_config.session_params == nullptr) { + ALOGE("%s: session_params must not be null if check_settings is true", + __FUNCTION__); + return false; + } + if (!check_settings && stream_config.session_params != nullptr && + stream_config.session_params->GetEntryCount() > 0) { + ALOGW("%s: session parameters is not empty but check_settings is false", + __FUNCTION__); + return false; + } bool supported = camera_device_hwl_->IsStreamCombinationSupported(stream_config); diff --git a/common/hal/google_camera_hal/camera_device.h b/common/hal/google_camera_hal/camera_device.h index 80245f1..dfcb4d7 100644 --- a/common/hal/google_camera_hal/camera_device.h +++ b/common/hal/google_camera_hal/camera_device.h @@ -69,6 +69,11 @@ class CameraDevice { // Get the flash unit strength level of this camera device. status_t GetTorchStrengthLevel(int32_t& torch_strength) const; + // Construct default request settings + status_t ConstructDefaultRequestSettings( + RequestTemplate type, + std::unique_ptr<HalCameraMetadata>* request_settings); + // Create a CameraDeviceSession to handle capture requests. This method will // return ALREADY_EXISTS if previous session has not been destroyed. // Created CameraDeviceSession remain valid even after this CameraDevice @@ -86,7 +91,8 @@ class CameraDevice { // Query whether a particular logical and physical streams combination are // supported. stream_config contains the stream configurations. - bool IsStreamCombinationSupported(const StreamConfiguration& stream_config); + bool IsStreamCombinationSupported(const StreamConfiguration& stream_config, + bool check_settings); status_t LoadExternalCaptureSession(); diff --git a/common/hal/hwl_interface/camera_device_hwl.h b/common/hal/hwl_interface/camera_device_hwl.h index 8bd8ead..18efeb8 100644 --- a/common/hal/hwl_interface/camera_device_hwl.h +++ b/common/hal/hwl_interface/camera_device_hwl.h @@ -69,6 +69,11 @@ class CameraDeviceHwl { return UNKNOWN_TRANSACTION; } + // Construct default request settings + virtual status_t ConstructDefaultRequestSettings( + RequestTemplate type, + std::unique_ptr<HalCameraMetadata>* request_settings) = 0; + // Dump the camera device states in fd, using dprintf() or write(). virtual status_t DumpState(int fd) = 0; @@ -97,4 +102,4 @@ class CameraDeviceHwl { } // namespace google_camera_hal } // namespace android -#endif // HARDWARE_GOOGLE_CAMERA_HAL_HWL_INTERFACE_CAMERA_DEVICE_HWL_H_
\ No newline at end of file +#endif // HARDWARE_GOOGLE_CAMERA_HAL_HWL_INTERFACE_CAMERA_DEVICE_HWL_H_ diff --git a/common/hal/tests/mock_device_hwl.h b/common/hal/tests/mock_device_hwl.h index f36015b..a71bcff 100644 --- a/common/hal/tests/mock_device_hwl.h +++ b/common/hal/tests/mock_device_hwl.h @@ -97,6 +97,12 @@ class MockDeviceHwl : public CameraDeviceHwl { return OK; } + status_t ConstructDefaultRequestSettings( + RequestTemplate /*type*/, + std::unique_ptr<HalCameraMetadata>* /*request_settings*/) { + return OK; + } + // Dump the camera device states in fd, using dprintf() or write(). status_t DumpState(int fd) { if (fd < 0) { diff --git a/devices/EmulatedCamera/hwl/Android.bp b/devices/EmulatedCamera/hwl/Android.bp index b452a70..62edc35 100644 --- a/devices/EmulatedCamera/hwl/Android.bp +++ b/devices/EmulatedCamera/hwl/Android.bp @@ -9,6 +9,7 @@ cc_defaults { proprietary: true, srcs: [ "EmulatedCameraProviderHWLImpl.cpp", + "EmulatedCameraDeviceInfo.cpp", "EmulatedCameraDeviceHWLImpl.cpp", "EmulatedCameraDeviceSessionHWLImpl.cpp", "EmulatedLogicalRequestState.cpp", diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp index 75a55af..bbb0427 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp @@ -102,6 +102,15 @@ status_t EmulatedCameraDeviceHwlImpl::Initialize() { default_torch_strength_level_ = GetDefaultTorchStrengthLevel(); maximum_torch_strength_level_ = GetMaximumTorchStrengthLevel(); + + device_info_ = EmulatedCameraDeviceInfo::Create( + HalCameraMetadata::Clone(static_metadata_.get())); + if (device_info_ == nullptr) { + ALOGE("%s: Unable to create device info for camera %d", __FUNCTION__, + camera_id_); + return NO_INIT; + } + return OK; } @@ -194,6 +203,29 @@ status_t EmulatedCameraDeviceHwlImpl::GetTorchStrengthLevel(int32_t& torch_stren return OK; } +status_t EmulatedCameraDeviceHwlImpl::ConstructDefaultRequestSettings( + RequestTemplate type, std::unique_ptr<HalCameraMetadata>* request_settings) { + if (request_settings == nullptr) { + ALOGE("%s requestSettings is nullptr", __FUNCTION__); + return BAD_VALUE; + } + + auto idx = static_cast<size_t>(type); + if (idx >= kTemplateCount) { + ALOGE("%s: Unexpected request type: %d", __FUNCTION__, type); + return BAD_VALUE; + } + + if (device_info_->default_requests_[idx].get() == nullptr) { + ALOGE("%s: Unsupported request type: %d", __FUNCTION__, type); + return BAD_VALUE; + } + + *request_settings = HalCameraMetadata::Clone( + device_info_->default_requests_[idx]->GetRawCameraMetadata()); + return OK; +} + status_t EmulatedCameraDeviceHwlImpl::DumpState(int /*fd*/) { return OK; } @@ -206,11 +238,11 @@ status_t EmulatedCameraDeviceHwlImpl::CreateCameraDeviceSessionHwl( return BAD_VALUE; } - std::unique_ptr<HalCameraMetadata> meta = - HalCameraMetadata::Clone(static_metadata_.get()); + std::unique_ptr<EmulatedCameraDeviceInfo> deviceInfo = + EmulatedCameraDeviceInfo::Clone(*device_info_); *session = EmulatedCameraDeviceSessionHwlImpl::Create( - camera_id_, std::move(meta), ClonePhysicalDeviceMap(physical_device_map_), - torch_state_); + camera_id_, std::move(deviceInfo), + ClonePhysicalDeviceMap(physical_device_map_), torch_state_); if (*session == nullptr) { ALOGE("%s: Cannot create EmulatedCameraDeviceSessionHWlImpl.", __FUNCTION__); return BAD_VALUE; diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h index 08c6ba3..fa58400 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h @@ -20,6 +20,7 @@ #include <camera_device_hwl.h> #include <hal_types.h> +#include "EmulatedCameraDeviceInfo.h" #include "EmulatedSensor.h" #include "EmulatedTorchState.h" #include "utils/HWLUtils.h" @@ -32,6 +33,8 @@ using google_camera_hal::CameraDeviceHwl; using google_camera_hal::CameraDeviceSessionHwl; using google_camera_hal::CameraResourceCost; using google_camera_hal::HalCameraMetadata; +using google_camera_hal::kTemplateCount; +using google_camera_hal::RequestTemplate; using google_camera_hal::StreamConfiguration; using google_camera_hal::TorchMode; @@ -62,6 +65,10 @@ class EmulatedCameraDeviceHwlImpl : public CameraDeviceHwl { status_t GetTorchStrengthLevel(int32_t& torch_strength) const override; + status_t ConstructDefaultRequestSettings( + RequestTemplate type, + std::unique_ptr<HalCameraMetadata>* request_settings) override; + status_t DumpState(int fd) override; status_t CreateCameraDeviceSessionHwl( @@ -87,6 +94,7 @@ class EmulatedCameraDeviceHwlImpl : public CameraDeviceHwl { const uint32_t camera_id_ = 0; std::unique_ptr<HalCameraMetadata> static_metadata_; + std::unique_ptr<EmulatedCameraDeviceInfo> device_info_; std::unique_ptr<StreamConfigurationMap> stream_configuration_map_; std::unique_ptr<StreamConfigurationMap> stream_configuration_map_max_resolution_; PhysicalStreamConfigurationMap physical_stream_configuration_map_; diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceInfo.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceInfo.cpp new file mode 100644 index 0000000..5b73c8c --- /dev/null +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceInfo.cpp @@ -0,0 +1,2004 @@ +/* + * Copyright (C) 2023 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 "EmulatedCameraDeviceInfo" +#define ATRACE_TAG ATRACE_TAG_CAMERA + +#include "EmulatedCameraDeviceInfo.h" + +#include <inttypes.h> +#include <log/log.h> + +namespace android { + +const std::set<uint8_t> EmulatedCameraDeviceInfo::kSupportedCapabilites = { + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES}; + +const std::set<uint8_t> EmulatedCameraDeviceInfo::kSupportedHWLevels = { + ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED, + ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL, + ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3, +}; + +const std::vector<int64_t> EmulatedCameraDeviceInfo::kSupportedUseCases = { + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL, + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL}; + +std::unique_ptr<EmulatedCameraDeviceInfo> EmulatedCameraDeviceInfo::Create( + std::unique_ptr<HalCameraMetadata> static_metadata) { + auto deviceInfo = std::make_unique<EmulatedCameraDeviceInfo>(); + if (deviceInfo == nullptr) { + ALOGE("%s: Creating EmulatedCameraDeviceInfo failed.", __FUNCTION__); + return nullptr; + } + + status_t res = deviceInfo->Initialize(std::move(static_metadata)); + if (res != OK) { + ALOGE("%s: Failed to initialize EmulatedCameraDeviceInfo: %s(%d)", + __FUNCTION__, strerror(-res), res); + return nullptr; + } + + return deviceInfo; +} + +std::unique_ptr<EmulatedCameraDeviceInfo> EmulatedCameraDeviceInfo::Clone( + const EmulatedCameraDeviceInfo& other) { + std::unique_ptr<HalCameraMetadata> static_metadata = + HalCameraMetadata::Clone(other.static_metadata_.get()); + + return EmulatedCameraDeviceInfo::Create(std::move(static_metadata)); +} + +status_t EmulatedCameraDeviceInfo::InitializeSensorDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = + static_metadata_->Get(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, &entry); + if ((ret == OK) && (entry.count == 2)) { + sensor_sensitivity_range_ = + std::make_pair(entry.data.i32[0], entry.data.i32[1]); + } else if (!supports_manual_sensor_) { + sensor_sensitivity_range_ = + std::make_pair(EmulatedSensor::kSupportedSensitivityRange[0], + EmulatedSensor::kSupportedSensitivityRange[1]); + } else { + ALOGE("%s: Manual sensor devices must advertise sensor sensitivity range!", + __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, &entry); + if ((ret == OK) && (entry.count == 2)) { + sensor_exposure_time_range_ = + std::make_pair(entry.data.i64[0], entry.data.i64[1]); + } else if (!supports_manual_sensor_) { + sensor_exposure_time_range_ = + std::make_pair(EmulatedSensor::kSupportedExposureTimeRange[0], + EmulatedSensor::kSupportedExposureTimeRange[1]); + } else { + ALOGE( + "%s: Manual sensor devices must advertise sensor exposure time range!", + __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &entry); + if ((ret == OK) && (entry.count == 1)) { + sensor_max_frame_duration_ = entry.data.i64[0]; + } else if (!supports_manual_sensor_) { + sensor_max_frame_duration_ = EmulatedSensor::kSupportedFrameDurationRange[1]; + } else { + ALOGE("%s: Manual sensor devices must advertise sensor max frame duration!", + __FUNCTION__); + return BAD_VALUE; + } + + if (supports_manual_sensor_) { + if (available_requests_.find(ANDROID_SENSOR_SENSITIVITY) == + available_requests_.end()) { + ALOGE( + "%s: Sensor sensitivity must be configurable on manual sensor " + "devices!", + __FUNCTION__); + return BAD_VALUE; + } + + if (available_requests_.find(ANDROID_SENSOR_EXPOSURE_TIME) == + available_requests_.end()) { + ALOGE( + "%s: Sensor exposure time must be configurable on manual sensor " + "devices!", + __FUNCTION__); + return BAD_VALUE; + } + + if (available_requests_.find(ANDROID_SENSOR_FRAME_DURATION) == + available_requests_.end()) { + ALOGE( + "%s: Sensor frame duration must be configurable on manual sensor " + "devices!", + __FUNCTION__); + return BAD_VALUE; + } + } + + report_rolling_shutter_skew_ = + available_results_.find(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW) != + available_results_.end(); + report_sensitivity_ = available_results_.find(ANDROID_SENSOR_SENSITIVITY) != + available_results_.end(); + report_exposure_time_ = + available_results_.find(ANDROID_SENSOR_EXPOSURE_TIME) != + available_results_.end(); + report_frame_duration_ = + available_results_.find(ANDROID_SENSOR_FRAME_DURATION) != + available_results_.end(); + report_neutral_color_point_ = + available_results_.find(ANDROID_SENSOR_NEUTRAL_COLOR_POINT) != + available_results_.end(); + report_green_split_ = available_results_.find(ANDROID_SENSOR_GREEN_SPLIT) != + available_results_.end(); + report_noise_profile_ = + available_results_.find(ANDROID_SENSOR_NOISE_PROFILE) != + available_results_.end(); + + if (is_raw_capable_ && !report_green_split_) { + ALOGE("%s: RAW capable devices must be able to report the noise profile!", + __FUNCTION__); + return BAD_VALUE; + } + + if (is_raw_capable_ && !report_neutral_color_point_) { + ALOGE( + "%s: RAW capable devices must be able to report the neutral color " + "point!", + __FUNCTION__); + return BAD_VALUE; + } + + if (is_raw_capable_ && !report_green_split_) { + ALOGE("%s: RAW capable devices must be able to report the green split!", + __FUNCTION__); + return BAD_VALUE; + } + if (available_results_.find(ANDROID_SENSOR_TIMESTAMP) == + available_results_.end()) { + ALOGE("%s: Sensor timestamp must always be part of the results!", + __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, + &entry); + if (ret == OK) { + available_test_pattern_modes_.insert(entry.data.i32, + entry.data.i32 + entry.count); + } else { + ALOGE("%s: No available test pattern modes!", __FUNCTION__); + return BAD_VALUE; + } + + sensor_exposure_time_ = GetClosestValue(EmulatedSensor::kDefaultExposureTime, + sensor_exposure_time_range_.first, + sensor_exposure_time_range_.second); + sensor_frame_duration_ = + GetClosestValue(EmulatedSensor::kDefaultFrameDuration, + EmulatedSensor::kSupportedFrameDurationRange[0], + sensor_max_frame_duration_); + sensor_sensitivity_ = GetClosestValue(EmulatedSensor::kDefaultSensitivity, + sensor_sensitivity_range_.first, + sensor_sensitivity_range_.second); + + bool off_test_pattern_mode_supported = + available_test_pattern_modes_.find(ANDROID_SENSOR_TEST_PATTERN_MODE_OFF) != + available_test_pattern_modes_.end(); + int32_t test_pattern_mode = (off_test_pattern_mode_supported) + ? ANDROID_SENSOR_TEST_PATTERN_MODE_OFF + : *available_test_pattern_modes_.begin(); + int32_t test_pattern_data[4] = {0, 0, 0, 0}; + + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + default_requests_[idx]->Set(ANDROID_SENSOR_EXPOSURE_TIME, + &sensor_exposure_time_, 1); + default_requests_[idx]->Set(ANDROID_SENSOR_FRAME_DURATION, + &sensor_frame_duration_, 1); + default_requests_[idx]->Set(ANDROID_SENSOR_SENSITIVITY, + &sensor_sensitivity_, 1); + default_requests_[idx]->Set(ANDROID_SENSOR_TEST_PATTERN_MODE, + &test_pattern_mode, 1); + default_requests_[idx]->Set(ANDROID_SENSOR_TEST_PATTERN_DATA, + test_pattern_data, 4); + } + + return OK; +} + +status_t EmulatedCameraDeviceInfo::InitializeStatisticsDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get( + ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, &entry); + if (ret == OK) { + available_face_detect_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available face detect modes!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get( + ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, &entry); + if (ret == OK) { + available_lens_shading_map_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available lens shading modes!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get( + ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, &entry); + if (ret == OK) { + available_hot_pixel_map_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else if (is_raw_capable_) { + ALOGE("%s: RAW capable device must support hot pixel map modes!", + __FUNCTION__); + return BAD_VALUE; + } else { + available_hot_pixel_map_modes_.emplace( + ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF); + } + + bool hot_pixel_mode_off_supported = + available_hot_pixel_map_modes_.find( + ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF) != + available_hot_pixel_map_modes_.end(); + bool face_detect_mode_off_supported = + available_face_detect_modes_.find( + ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) != + available_face_detect_modes_.end(); + bool lens_shading_map_mode_off_supported = + available_lens_shading_map_modes_.find( + ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON) != + available_lens_shading_map_modes_.end(); + bool lens_shading_map_mode_on_supported = + available_lens_shading_map_modes_.find( + ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON) != + available_lens_shading_map_modes_.end(); + if (is_raw_capable_ && !lens_shading_map_mode_on_supported) { + ALOGE("%s: RAW capable device must support lens shading map reporting!", + __FUNCTION__); + return BAD_VALUE; + } + + if (lens_shading_map_mode_on_supported && + (available_results_.find(ANDROID_STATISTICS_LENS_SHADING_MAP) == + available_results_.end())) { + ALOGE( + "%s: Lens shading map reporting available but corresponding result key " + "is absent!", + __FUNCTION__); + return BAD_VALUE; + } + + if (lens_shading_map_mode_on_supported && + ((shading_map_size_[0] == 0) || (shading_map_size_[1] == 0))) { + ALOGE( + "%s: Lens shading map reporting available but without valid shading " + "map size!", + __FUNCTION__); + return BAD_VALUE; + } + + report_lens_intrinsics_samples_ = + (available_results_.find(ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES) != + available_results_.end()) && + (available_results_.find(ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS) != + available_results_.end()); + + report_scene_flicker_ = + available_results_.find(ANDROID_STATISTICS_SCENE_FLICKER) != + available_results_.end(); + + uint8_t face_detect_mode = face_detect_mode_off_supported + ? ANDROID_STATISTICS_FACE_DETECT_MODE_OFF + : *available_face_detect_modes_.begin(); + uint8_t hot_pixel_map_mode = hot_pixel_mode_off_supported + ? ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF + : *available_hot_pixel_map_modes_.begin(); + uint8_t lens_shading_map_mode = + lens_shading_map_mode_off_supported + ? ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF + : *available_lens_shading_map_modes_.begin(); + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + if ((static_cast<RequestTemplate>(idx) == RequestTemplate::kStillCapture) && + is_raw_capable_ && lens_shading_map_mode_on_supported) { + uint8_t lens_shading_map_on = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON; + default_requests_[idx]->Set(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, + &lens_shading_map_on, 1); + } else { + default_requests_[idx]->Set(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, + &lens_shading_map_mode, 1); + } + + default_requests_[idx]->Set(ANDROID_STATISTICS_FACE_DETECT_MODE, + &face_detect_mode, 1); + default_requests_[idx]->Set(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, + &hot_pixel_map_mode, 1); + } + + return InitializeBlackLevelDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeControlSceneDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = + static_metadata_->Get(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, &entry); + if (ret == OK) { + available_scenes_.insert(entry.data.u8, entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available scene modes!", __FUNCTION__); + return BAD_VALUE; + } + + if ((entry.count == 1) && + (entry.data.u8[0] == ANDROID_CONTROL_SCENE_MODE_DISABLED)) { + scenes_supported_ = false; + return OK; + } else { + scenes_supported_ = true; + } + + if (available_requests_.find(ANDROID_CONTROL_SCENE_MODE) == + available_requests_.end()) { + ALOGE("%s: Scene mode cannot be set!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_SCENE_MODE) == + available_results_.end()) { + ALOGE("%s: Scene mode cannot be reported!", __FUNCTION__); + return BAD_VALUE; + } + + camera_metadata_ro_entry_t overrides_entry; + ret = static_metadata_->Get(ANDROID_CONTROL_SCENE_MODE_OVERRIDES, + &overrides_entry); + if ((ret == OK) && ((overrides_entry.count / 3) == available_scenes_.size()) && + ((overrides_entry.count % 3) == 0)) { + for (size_t i = 0; i < entry.count; i++) { + SceneOverride scene(overrides_entry.data.u8[i * 3], + overrides_entry.data.u8[i * 3 + 1], + overrides_entry.data.u8[i * 3 + 2]); + if (available_ae_modes_.find(scene.ae_mode) == available_ae_modes_.end()) { + ALOGE("%s: AE scene mode override: %d not supported!", __FUNCTION__, + scene.ae_mode); + return BAD_VALUE; + } + if (available_awb_modes_.find(scene.awb_mode) == + available_awb_modes_.end()) { + ALOGE("%s: AWB scene mode override: %d not supported!", __FUNCTION__, + scene.awb_mode); + return BAD_VALUE; + } + if (available_af_modes_.find(scene.af_mode) == available_af_modes_.end()) { + ALOGE("%s: AF scene mode override: %d not supported!", __FUNCTION__, + scene.af_mode); + return BAD_VALUE; + } + scene_overrides_.emplace(entry.data.u8[i], scene); + } + } else { + ALOGE("%s: No available scene overrides!", __FUNCTION__); + return BAD_VALUE; + } + + return OK; +} + +status_t EmulatedCameraDeviceInfo::InitializeControlAFDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get(ANDROID_CONTROL_AF_AVAILABLE_MODES, &entry); + if (ret == OK) { + available_af_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available AF modes!", __FUNCTION__); + return BAD_VALUE; + } + // Off mode must always be present + if (available_af_modes_.find(ANDROID_CONTROL_AF_MODE_OFF) == + available_af_modes_.end()) { + ALOGE("%s: AF off control mode must always be present!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_requests_.find(ANDROID_CONTROL_AF_MODE) == + available_requests_.end()) { + ALOGE("%s: Clients must be able to set AF mode!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_requests_.find(ANDROID_CONTROL_AF_TRIGGER) == + available_requests_.end()) { + ALOGE("%s: Clients must be able to set AF trigger!", __FUNCTION__); + return BAD_VALUE; + } + if (available_results_.find(ANDROID_CONTROL_AF_TRIGGER) == + available_results_.end()) { + ALOGE("%s: AF trigger must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AF_MODE) == + available_results_.end()) { + ALOGE("%s: AF mode must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AF_STATE) == + available_results_.end()) { + ALOGE("%s: AF state must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + bool auto_mode_present = + available_af_modes_.find(ANDROID_CONTROL_AF_MODE_AUTO) != + available_af_modes_.end(); + bool picture_caf_mode_present = + available_af_modes_.find(ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE) != + available_af_modes_.end(); + bool video_caf_mode_present = + available_af_modes_.find(ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO) != + available_af_modes_.end(); + af_supported_ = auto_mode_present && (minimum_focus_distance_ > .0f); + picture_caf_supported_ = + picture_caf_mode_present && (minimum_focus_distance_ > .0f); + video_caf_supported_ = + video_caf_mode_present && (minimum_focus_distance_ > .0f); + + return OK; +} + +status_t EmulatedCameraDeviceInfo::InitializeControlAWBDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get(ANDROID_CONTROL_AWB_AVAILABLE_MODES, &entry); + if (ret == OK) { + available_awb_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available AWB modes!", __FUNCTION__); + return BAD_VALUE; + } + // Auto mode must always be present + if (available_awb_modes_.find(ANDROID_CONTROL_AWB_MODE_AUTO) == + available_awb_modes_.end()) { + ALOGE("%s: AWB auto control mode must always be present!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AWB_MODE) == + available_results_.end()) { + ALOGE("%s: AWB mode must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AWB_STATE) == + available_results_.end()) { + ALOGE("%s: AWB state must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &entry); + if ((ret == OK) && (entry.count == 1)) { + awb_lock_available_ = + entry.data.u8[0] == ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE; + } else { + ALOGV("%s: No available AWB lock!", __FUNCTION__); + awb_lock_available_ = false; + } + report_awb_lock_ = available_results_.find(ANDROID_CONTROL_AWB_LOCK) != + available_results_.end(); + + return OK; +} + +status_t EmulatedCameraDeviceInfo::InitializeBlackLevelDefaults() { + if (is_level_full_or_higher_) { + if (available_requests_.find(ANDROID_BLACK_LEVEL_LOCK) == + available_requests_.end()) { + ALOGE( + "%s: Full or above capable devices must be able to set the black " + "level lock!", + __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_BLACK_LEVEL_LOCK) == + available_results_.end()) { + ALOGE( + "%s: Full or above capable devices must be able to report the black " + "level lock!", + __FUNCTION__); + return BAD_VALUE; + } + + report_black_level_lock_ = true; + uint8_t blackLevelLock = ANDROID_BLACK_LEVEL_LOCK_OFF; + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + default_requests_[idx]->Set(ANDROID_BLACK_LEVEL_LOCK, &blackLevelLock, 1); + } + } + + return InitializeEdgeDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeControlAEDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get(ANDROID_CONTROL_AE_AVAILABLE_MODES, &entry); + if (ret == OK) { + available_ae_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available AE modes!", __FUNCTION__); + return BAD_VALUE; + } + // On mode must always be present + if (available_ae_modes_.find(ANDROID_CONTROL_AE_MODE_ON) == + available_ae_modes_.end()) { + ALOGE("%s: AE on control mode must always be present!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AE_MODE) == + available_results_.end()) { + ALOGE("%s: AE mode must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AE_STATE) == + available_results_.end()) { + ALOGE("%s: AE state must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &entry); + if ((ret == OK) && (entry.count == 1)) { + ae_lock_available_ = + entry.data.u8[0] == ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE; + } else { + ALOGV("%s: No available AE lock!", __FUNCTION__); + ae_lock_available_ = false; + } + report_ae_lock_ = available_results_.find(ANDROID_CONTROL_AE_LOCK) != + available_results_.end(); + + if (supports_manual_sensor_) { + if (!ae_lock_available_) { + ALOGE("%s: AE lock must always be available for manual sensors!", + __FUNCTION__); + return BAD_VALUE; + } + auto off_mode = available_control_modes_.find(ANDROID_CONTROL_MODE_OFF); + if (off_mode == available_control_modes_.end()) { + ALOGE("%s: Off control mode must always be present for manual sensors!", + __FUNCTION__); + return BAD_VALUE; + } + + off_mode = available_ae_modes_.find(ANDROID_CONTROL_AE_MODE_OFF); + if (off_mode == available_ae_modes_.end()) { + ALOGE( + "%s: AE off control mode must always be present for manual sensors!", + __FUNCTION__); + return BAD_VALUE; + } + } + + if (available_requests_.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) == + available_requests_.end()) { + ALOGE("%s: Clients must be able to set AE pre-capture trigger!", + __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) == + available_results_.end()) { + ALOGE("%s: AE pre-capture trigger must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, + &entry); + if (ret == OK) { + available_antibanding_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available antibanding modes!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_CONTROL_AE_COMPENSATION_RANGE, &entry); + if ((ret == OK) && (entry.count == 2)) { + exposure_compensation_range_[0] = entry.data.i32[0]; + exposure_compensation_range_[1] = entry.data.i32[1]; + } else { + ALOGE("%s: No available exposure compensation range!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_CONTROL_AE_COMPENSATION_STEP, &entry); + if ((ret == OK) && (entry.count == 1)) { + exposure_compensation_step_ = entry.data.r[0]; + } else { + ALOGE("%s: No available exposure compensation step!", __FUNCTION__); + return BAD_VALUE; + } + + bool ae_comp_requests = + available_requests_.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION) != + available_requests_.end(); + bool ae_comp_results = + available_results_.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION) != + available_results_.end(); + exposure_compensation_supported_ = + ((exposure_compensation_range_[0] < 0) && + (exposure_compensation_range_[1] > 0) && + (exposure_compensation_step_.denominator > 0) && + (exposure_compensation_step_.numerator > 0)) && + ae_comp_results && ae_comp_requests; + + return OK; +} + +status_t EmulatedCameraDeviceInfo::InitializeMeteringRegionDefault( + uint32_t tag, int32_t* region /*out*/) { + if (region == nullptr) { + return BAD_VALUE; + } + if (available_requests_.find(tag) == available_requests_.end()) { + ALOGE("%s: %d metering region configuration must be supported!", + __FUNCTION__, tag); + return BAD_VALUE; + } + if (available_results_.find(tag) == available_results_.end()) { + ALOGE("%s: %d metering region must be reported!", __FUNCTION__, tag); + return BAD_VALUE; + } + + region[0] = scaler_crop_region_default_[0]; + region[1] = scaler_crop_region_default_[1]; + region[2] = scaler_crop_region_default_[2]; + region[3] = scaler_crop_region_default_[3]; + region[4] = 0; + + return OK; +} + +status_t EmulatedCameraDeviceInfo::InitializeControlDefaults() { + camera_metadata_ro_entry_t entry; + int32_t metering_area[5] = {0}; // (top, left, width, height, wight) + auto ret = static_metadata_->Get(ANDROID_CONTROL_AVAILABLE_MODES, &entry); + if (ret == OK) { + available_control_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available control modes!", __FUNCTION__); + return BAD_VALUE; + } + + available_sensor_pixel_modes_.insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT); + + if (SupportsCapability( + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR)) { + available_sensor_pixel_modes_.insert( + ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION); + } + + // Auto mode must always be present + if (available_control_modes_.find(ANDROID_CONTROL_MODE_AUTO) == + available_control_modes_.end()) { + ALOGE("%s: Auto control modes must always be present!", __FUNCTION__); + return BAD_VALUE; + } + + // Capture intent must always be user configurable + if (available_requests_.find(ANDROID_CONTROL_CAPTURE_INTENT) == + available_requests_.end()) { + ALOGE("%s: Clients must be able to set the capture intent!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, + &entry); + if ((ret == OK) && ((entry.count % 2) == 0)) { + available_fps_ranges_.reserve(entry.count / 2); + for (size_t i = 0; i < entry.count; i += 2) { + FPSRange range(entry.data.i32[i], entry.data.i32[i + 1]); + if (range.min_fps > range.max_fps) { + ALOGE("%s: Minimum framerate: %d bigger than maximum framerate: %d", + __FUNCTION__, range.min_fps, range.max_fps); + return BAD_VALUE; + } + if ((range.max_fps >= kMinimumStreamingFPS) && + (range.max_fps == range.min_fps) && (ae_target_fps_.max_fps == 0)) { + ae_target_fps_ = range; + } + available_fps_ranges_.push_back(range); + } + } else { + ALOGE("%s: No available framerate ranges!", __FUNCTION__); + return BAD_VALUE; + } + + if (ae_target_fps_.max_fps == 0) { + ALOGE("%s: No minimum streaming capable framerate range available!", + __FUNCTION__); + return BAD_VALUE; + } + + if (available_requests_.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE) == + available_requests_.end()) { + ALOGE("%s: Clients must be able to set the target framerate range!", + __FUNCTION__); + return BAD_VALUE; + } + + if (available_results_.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE) == + available_results_.end()) { + ALOGE("%s: Target framerate must be reported!", __FUNCTION__); + return BAD_VALUE; + } + + report_extended_scene_mode_ = + available_results_.find(ANDROID_CONTROL_EXTENDED_SCENE_MODE) != + available_results_.end(); + + if (is_backward_compatible_) { + ret = static_metadata_->Get(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, + &entry); + if (ret == OK) { + post_raw_boost_ = entry.data.i32[0]; + } else { + ALOGW("%s: No available post RAW boost! Setting default!", __FUNCTION__); + post_raw_boost_ = 100; + } + report_post_raw_boost_ = + available_results_.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST) != + available_results_.end(); + + ret = static_metadata_->Get(ANDROID_CONTROL_AVAILABLE_EFFECTS, &entry); + if ((ret == OK) && (entry.count > 0)) { + available_effects_.insert(entry.data.u8, entry.data.u8 + entry.count); + if (available_effects_.find(ANDROID_CONTROL_EFFECT_MODE_OFF) == + available_effects_.end()) { + ALOGE("%s: Off color effect mode not supported!", __FUNCTION__); + return BAD_VALUE; + } + } else { + ALOGE("%s: No available effects!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get( + ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, &entry); + if ((ret == OK) && (entry.count > 0)) { + available_vstab_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + if (available_vstab_modes_.find( + ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF) == + available_vstab_modes_.end()) { + ALOGE("%s: Off video stabilization mode not supported!", __FUNCTION__); + return BAD_VALUE; + } + if (available_vstab_modes_.find( + ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON) != + available_vstab_modes_.end()) { + vstab_available_ = true; + } + } else { + ALOGE("%s: No available video stabilization modes!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, + &entry); + if ((ret == OK) && (entry.count > 0)) { + if (entry.count != 1) { + ALOGE("%s: Invalid max digital zoom capability!", __FUNCTION__); + return BAD_VALUE; + } + max_zoom_ = entry.data.f[0]; + } else { + ALOGE("%s: No available max digital zoom", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry); + if ((ret == OK) && (entry.count > 0)) { + if (entry.count != 2) { + ALOGE("%s: Invalid zoom ratio range capability!", __FUNCTION__); + return BAD_VALUE; + } + + if (entry.data.f[1] != max_zoom_) { + ALOGE("%s: Max zoom ratio must be equal to max digital zoom", + __FUNCTION__); + return BAD_VALUE; + } + + if (entry.data.f[1] < entry.data.f[0]) { + ALOGE("%s: Max zoom ratio must be larger than min zoom ratio", + __FUNCTION__); + return BAD_VALUE; + } + + // Validity check request and result keys + if (available_requests_.find(ANDROID_CONTROL_ZOOM_RATIO) == + available_requests_.end()) { + ALOGE("%s: Zoom ratio tag must be available in available request keys", + __FUNCTION__); + return BAD_VALUE; + } + if (available_results_.find(ANDROID_CONTROL_ZOOM_RATIO) == + available_results_.end()) { + ALOGE("%s: Zoom ratio tag must be available in available result keys", + __FUNCTION__); + return BAD_VALUE; + } + + zoom_ratio_supported_ = true; + min_zoom_ = entry.data.f[0]; + } + + ret = static_metadata_->Get( + ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES, &entry); + if ((ret == OK) && (entry.count > 0)) { + if (entry.count % 3 != 0) { + ALOGE("%s: Invalid bokeh capabilities!", __FUNCTION__); + return BAD_VALUE; + } + + camera_metadata_ro_entry_t zoom_ratio_ranges_entry; + ret = static_metadata_->Get( + ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES, + &zoom_ratio_ranges_entry); + if (ret != OK || + zoom_ratio_ranges_entry.count / 2 != entry.count / 3 - 1) { + ALOGE("%s: Invalid bokeh mode zoom ratio ranges.", __FUNCTION__); + return BAD_VALUE; + } + + // Validity check request and characteristics keys + if (available_requests_.find(ANDROID_CONTROL_EXTENDED_SCENE_MODE) == + available_requests_.end()) { + ALOGE("%s: Extended scene mode must be configurable for this device", + __FUNCTION__); + return BAD_VALUE; + } + if (available_characteristics_.find( + ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES) == + available_characteristics_.end() || + available_characteristics_.find( + ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES) == + available_characteristics_.end()) { + ALOGE( + "%s: ExtendedSceneMode maxSizes and zoomRatioRanges " + "characteristics keys must " + "be available", + __FUNCTION__); + return BAD_VALUE; + } + + // Derive available bokeh caps. + StreamConfigurationMap stream_configuration_map(*static_metadata_); + std::set<StreamSize> yuv_sizes = stream_configuration_map.GetOutputSizes( + HAL_PIXEL_FORMAT_YCBCR_420_888); + bool has_extended_scene_mode_off = false; + for (size_t i = 0, j = 0; i < entry.count; i += 3) { + int32_t mode = entry.data.i32[i]; + int32_t max_width = entry.data.i32[i + 1]; + int32_t max_height = entry.data.i32[i + 2]; + float min_zoom_ratio, max_zoom_ratio; + + if (mode < ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED || + (mode > ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS && + mode < ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START)) { + ALOGE("%s: Invalid extended scene mode %d", __FUNCTION__, mode); + return BAD_VALUE; + } + + if (mode == ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED) { + has_extended_scene_mode_off = true; + if (max_width != 0 || max_height != 0) { + ALOGE( + "%s: Invalid max width or height for " + "EXTENDED_SCENE_MODE_DISABLED", + __FUNCTION__); + return BAD_VALUE; + } + min_zoom_ratio = min_zoom_; + max_zoom_ratio = max_zoom_; + } else if (yuv_sizes.find({max_width, max_height}) == yuv_sizes.end()) { + ALOGE("%s: Invalid max width or height for extended scene mode %d", + __FUNCTION__, mode); + return BAD_VALUE; + } else { + min_zoom_ratio = zoom_ratio_ranges_entry.data.f[j]; + max_zoom_ratio = zoom_ratio_ranges_entry.data.f[j + 1]; + j += 2; + } + + ExtendedSceneModeCapability cap(mode, max_width, max_height, + min_zoom_ratio, max_zoom_ratio); + available_extended_scene_mode_caps_.push_back(cap); + } + if (!has_extended_scene_mode_off) { + ALOGE("%s: Off extended scene mode not supported!", __FUNCTION__); + return BAD_VALUE; + } + } + + ret = static_metadata_->Get(ANDROID_CONTROL_MAX_REGIONS, &entry); + if ((ret == OK) && (entry.count == 3)) { + max_ae_regions_ = entry.data.i32[0]; + max_awb_regions_ = entry.data.i32[1]; + max_af_regions_ = entry.data.i32[2]; + } else { + ALOGE( + "%s: Metering regions must be available for backward compatible " + "devices!", + __FUNCTION__); + return BAD_VALUE; + } + + if ((is_level_full_or_higher_) && + ((max_ae_regions_ == 0) || (max_af_regions_ == 0))) { + ALOGE( + "%s: Full and higher level cameras must support at AF and AE " + "metering regions", + __FUNCTION__); + return BAD_VALUE; + } + + if (max_ae_regions_ > 0) { + ret = InitializeMeteringRegionDefault(ANDROID_CONTROL_AE_REGIONS, + ae_metering_region_); + if (ret != OK) { + return ret; + } + } + + if (max_awb_regions_ > 0) { + ret = InitializeMeteringRegionDefault(ANDROID_CONTROL_AWB_REGIONS, + awb_metering_region_); + if (ret != OK) { + return ret; + } + } + + if (max_af_regions_ > 0) { + ret = InitializeMeteringRegionDefault(ANDROID_CONTROL_AF_REGIONS, + af_metering_region_); + if (ret != OK) { + return ret; + } + } + + ret = InitializeControlAEDefaults(); + if (ret != OK) { + return ret; + } + + ret = InitializeControlAWBDefaults(); + if (ret != OK) { + return ret; + } + + ret = InitializeControlAFDefaults(); + if (ret != OK) { + return ret; + } + + ret = InitializeControlSceneDefaults(); + if (ret != OK) { + return ret; + } + } + + for (size_t idx = 0; idx < kTemplateCount; idx++) { + auto template_idx = static_cast<RequestTemplate>(idx); + if (default_requests_[idx].get() == nullptr) { + continue; + } + + uint8_t intent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM; + uint8_t control_mode, ae_mode, awb_mode, af_mode, scene_mode, vstab_mode; + control_mode = ANDROID_CONTROL_MODE_AUTO; + ae_mode = ANDROID_CONTROL_AE_MODE_ON; + awb_mode = ANDROID_CONTROL_AWB_MODE_AUTO; + af_mode = af_supported_ ? ANDROID_CONTROL_AF_MODE_AUTO + : ANDROID_CONTROL_AF_MODE_OFF; + scene_mode = ANDROID_CONTROL_SCENE_MODE_DISABLED; + vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; + uint8_t effect_mode = ANDROID_CONTROL_EFFECT_MODE_OFF; + uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF; + uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF; + int32_t ae_target_fps[] = {ae_target_fps_.min_fps, ae_target_fps_.max_fps}; + float zoom_ratio = 1.0f; + switch (template_idx) { + case RequestTemplate::kManual: + intent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL; + control_mode = ANDROID_CONTROL_MODE_OFF; + ae_mode = ANDROID_CONTROL_AE_MODE_OFF; + awb_mode = ANDROID_CONTROL_AWB_MODE_OFF; + af_mode = ANDROID_CONTROL_AF_MODE_OFF; + break; + case RequestTemplate::kZeroShutterLag: + intent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG; + if (picture_caf_supported_) { + af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; + } + break; + case RequestTemplate::kPreview: + intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; + if (picture_caf_supported_) { + af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; + } + break; + case RequestTemplate::kStillCapture: + intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; + if (picture_caf_supported_) { + af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; + } + break; + case RequestTemplate::kVideoRecord: + intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; + if (video_caf_supported_) { + af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; + } + if (vstab_available_) { + vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON; + } + break; + case RequestTemplate::kVideoSnapshot: + intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; + if (video_caf_supported_) { + af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; + } + if (vstab_available_) { + vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON; + } + break; + default: + // Noop + break; + } + + if (intent != ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM) { + default_requests_[idx]->Set(ANDROID_CONTROL_CAPTURE_INTENT, &intent, 1); + default_requests_[idx]->Set(ANDROID_CONTROL_MODE, &control_mode, 1); + default_requests_[idx]->Set(ANDROID_CONTROL_AE_MODE, &ae_mode, 1); + default_requests_[idx]->Set(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, + ae_target_fps, ARRAY_SIZE(ae_target_fps)); + default_requests_[idx]->Set(ANDROID_CONTROL_AWB_MODE, &awb_mode, 1); + default_requests_[idx]->Set(ANDROID_CONTROL_AF_MODE, &af_mode, 1); + if (is_backward_compatible_) { + default_requests_[idx]->Set(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, + &post_raw_boost_, 1); + if (vstab_available_) { + default_requests_[idx]->Set(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, + &vstab_mode, 1); + } + if (ae_lock_available_) { + default_requests_[idx]->Set(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1); + } + if (awb_lock_available_) { + default_requests_[idx]->Set(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1); + } + if (scenes_supported_) { + default_requests_[idx]->Set(ANDROID_CONTROL_SCENE_MODE, &scene_mode, + 1); + } + if (max_ae_regions_ > 0) { + default_requests_[idx]->Set(ANDROID_CONTROL_AE_REGIONS, metering_area, + ARRAY_SIZE(metering_area)); + } + if (max_awb_regions_ > 0) { + default_requests_[idx]->Set(ANDROID_CONTROL_AWB_REGIONS, + metering_area, ARRAY_SIZE(metering_area)); + } + if (max_af_regions_ > 0) { + default_requests_[idx]->Set(ANDROID_CONTROL_AF_REGIONS, metering_area, + ARRAY_SIZE(metering_area)); + } + if (exposure_compensation_supported_) { + default_requests_[idx]->Set(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, + &exposure_compensation_, 1); + } + if (zoom_ratio_supported_) { + default_requests_[idx]->Set(ANDROID_CONTROL_ZOOM_RATIO, &zoom_ratio, + 1); + } + bool is_auto_antbanding_supported = + available_antibanding_modes_.find( + ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO) != + available_antibanding_modes_.end(); + uint8_t antibanding_mode = is_auto_antbanding_supported + ? ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO + : *available_antibanding_modes_.begin(); + default_requests_[idx]->Set(ANDROID_CONTROL_AE_ANTIBANDING_MODE, + &antibanding_mode, 1); + default_requests_[idx]->Set(ANDROID_CONTROL_EFFECT_MODE, &effect_mode, + 1); + uint8_t ae_trigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + default_requests_[idx]->Set(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, + &ae_trigger, 1); + uint8_t af_trigger = ANDROID_CONTROL_AF_TRIGGER_IDLE; + default_requests_[idx]->Set(ANDROID_CONTROL_AF_TRIGGER, &af_trigger, 1); + } + } + + int32_t settings_override = ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF; + default_requests_[idx]->Set(ANDROID_CONTROL_SETTINGS_OVERRIDE, + &settings_override, 1); + } + + return InitializeHotPixelDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeTonemapDefaults() { + if (is_backward_compatible_) { + camera_metadata_ro_entry_t entry; + auto ret = + static_metadata_->Get(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES, &entry); + if (ret == OK) { + available_tonemap_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available tonemap modes!", __FUNCTION__); + return BAD_VALUE; + } + + if ((is_level_full_or_higher_) && (available_tonemap_modes_.size() < 3)) { + ALOGE( + "%s: Full and higher level cameras must support at least three or " + "more tonemap modes", + __FUNCTION__); + return BAD_VALUE; + } + + bool fast_mode_supported = + available_tonemap_modes_.find(ANDROID_TONEMAP_MODE_FAST) != + available_tonemap_modes_.end(); + bool hq_mode_supported = + available_tonemap_modes_.find(ANDROID_TONEMAP_MODE_HIGH_QUALITY) != + available_tonemap_modes_.end(); + uint8_t tonemap_mode = *available_tonemap_modes_.begin(); + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + switch (static_cast<RequestTemplate>(idx)) { + case RequestTemplate::kVideoRecord: // Pass-through + case RequestTemplate::kPreview: + if (fast_mode_supported) { + tonemap_mode = ANDROID_TONEMAP_MODE_FAST; + } + break; + case RequestTemplate::kVideoSnapshot: // Pass-through + case RequestTemplate::kStillCapture: + if (hq_mode_supported) { + tonemap_mode = ANDROID_TONEMAP_MODE_HIGH_QUALITY; + } + break; + default: + // Noop + break; + } + + default_requests_[idx]->Set(ANDROID_TONEMAP_MODE, &tonemap_mode, 1); + default_requests_[idx]->Set( + ANDROID_TONEMAP_CURVE_RED, EmulatedSensor::kDefaultToneMapCurveRed, + ARRAY_SIZE(EmulatedSensor::kDefaultToneMapCurveRed)); + default_requests_[idx]->Set( + ANDROID_TONEMAP_CURVE_GREEN, EmulatedSensor::kDefaultToneMapCurveGreen, + ARRAY_SIZE(EmulatedSensor::kDefaultToneMapCurveGreen)); + default_requests_[idx]->Set( + ANDROID_TONEMAP_CURVE_BLUE, EmulatedSensor::kDefaultToneMapCurveBlue, + ARRAY_SIZE(EmulatedSensor::kDefaultToneMapCurveBlue)); + } + } + + return InitializeStatisticsDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeEdgeDefaults() { + if (is_backward_compatible_) { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get(ANDROID_EDGE_AVAILABLE_EDGE_MODES, &entry); + if (ret == OK) { + available_edge_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available edge modes!", __FUNCTION__); + return BAD_VALUE; + } + + report_edge_mode_ = + available_results_.find(ANDROID_EDGE_MODE) != available_results_.end(); + bool is_fast_mode_supported = + available_edge_modes_.find(ANDROID_EDGE_MODE_FAST) != + available_edge_modes_.end(); + bool is_hq_mode_supported = + available_edge_modes_.find(ANDROID_EDGE_MODE_HIGH_QUALITY) != + available_edge_modes_.end(); + bool is_zsl_mode_supported = + available_edge_modes_.find(ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG) != + available_edge_modes_.end(); + uint8_t edge_mode = *available_ae_modes_.begin(); + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + switch (static_cast<RequestTemplate>(idx)) { + case RequestTemplate::kVideoRecord: // Pass-through + case RequestTemplate::kPreview: + if (is_fast_mode_supported) { + edge_mode = ANDROID_EDGE_MODE_FAST; + } + break; + case RequestTemplate::kVideoSnapshot: // Pass-through + case RequestTemplate::kStillCapture: + if (is_hq_mode_supported) { + edge_mode = ANDROID_EDGE_MODE_HIGH_QUALITY; + } + break; + case RequestTemplate::kZeroShutterLag: + if (is_zsl_mode_supported) { + edge_mode = ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG; + } + break; + default: + // Noop + break; + } + + default_requests_[idx]->Set(ANDROID_EDGE_MODE, &edge_mode, 1); + } + } + + return InitializeShadingDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeColorCorrectionDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get( + ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, &entry); + if (ret == OK) { + available_color_aberration_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else if (supports_manual_post_processing_) { + ALOGE( + "%s: Devices capable of manual post-processing must support color " + "abberation!", + __FUNCTION__); + return BAD_VALUE; + } + + if (!available_color_aberration_modes_.empty()) { + bool is_fast_mode_supported = + available_color_aberration_modes_.find( + ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST) != + available_color_aberration_modes_.end(); + bool is_hq_mode_supported = + available_color_aberration_modes_.find( + ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY) != + available_color_aberration_modes_.end(); + uint8_t color_aberration = *available_color_aberration_modes_.begin(); + uint8_t color_correction_mode = ANDROID_COLOR_CORRECTION_MODE_FAST; + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + switch (static_cast<RequestTemplate>(idx)) { + case RequestTemplate::kVideoRecord: // Pass-through + case RequestTemplate::kPreview: + if (is_fast_mode_supported) { + color_aberration = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST; + } + break; + case RequestTemplate::kVideoSnapshot: // Pass-through + case RequestTemplate::kStillCapture: + if (is_hq_mode_supported) { + color_aberration = + ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY; + } + break; + default: + // Noop + break; + } + + default_requests_[idx]->Set(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, + &color_aberration, 1); + if (is_backward_compatible_) { + default_requests_[idx]->Set(ANDROID_COLOR_CORRECTION_MODE, + &color_correction_mode, 1); + default_requests_[idx]->Set( + ANDROID_COLOR_CORRECTION_TRANSFORM, + EmulatedSensor::kDefaultColorTransform, + ARRAY_SIZE(EmulatedSensor::kDefaultColorTransform)); + default_requests_[idx]->Set( + ANDROID_COLOR_CORRECTION_GAINS, + EmulatedSensor::kDefaultColorCorrectionGains, + ARRAY_SIZE(EmulatedSensor::kDefaultColorCorrectionGains)); + } + } + } + + return InitializeSensorDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeScalerDefaults() { + if (is_backward_compatible_) { + camera_metadata_ro_entry_t entry; + auto ret = + static_metadata_->Get(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, &entry); + if ((ret == OK) && (entry.count == 4)) { + scaler_crop_region_default_[0] = entry.data.i32[0]; + scaler_crop_region_default_[1] = entry.data.i32[1]; + scaler_crop_region_default_[2] = entry.data.i32[2]; + scaler_crop_region_default_[3] = entry.data.i32[3]; + } else { + ALOGE("%s: Sensor pixel array size is not available!", __FUNCTION__); + return BAD_VALUE; + } + + if (SupportsCapability( + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR)) { + ret = static_metadata_->Get( + ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, &entry); + if ((ret == OK) && (entry.count == 4)) { + scaler_crop_region_max_resolution_[0] = entry.data.i32[0]; + scaler_crop_region_max_resolution_[1] = entry.data.i32[1]; + scaler_crop_region_max_resolution_[2] = entry.data.i32[2]; + scaler_crop_region_max_resolution_[3] = entry.data.i32[3]; + } else { + ALOGE( + "%s: Sensor pixel array size maximum resolution is not available!", + __FUNCTION__); + return BAD_VALUE; + } + } + + if (available_requests_.find(ANDROID_SCALER_CROP_REGION) == + available_requests_.end()) { + ALOGE( + "%s: Backward compatible devices must support scaler crop " + "configuration!", + __FUNCTION__); + return BAD_VALUE; + } + if (available_results_.find(ANDROID_SCALER_CROP_REGION) == + available_results_.end()) { + ALOGE("%s: Scaler crop must reported on backward compatible devices!", + __FUNCTION__); + return BAD_VALUE; + } + if (available_requests_.find( + ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION) != + available_results_.end()) { + report_active_sensor_crop_ = true; + } + ret = static_metadata_->Get(ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES, + &entry); + if ((ret == OK) && (entry.count > 0)) { + // Listing rotate and crop, so need to make sure it's consistently reported + if (available_requests_.find(ANDROID_SCALER_ROTATE_AND_CROP) == + available_requests_.end()) { + ALOGE( + "%s: Rotate and crop must be listed in request keys if supported!", + __FUNCTION__); + return BAD_VALUE; + } + if (available_results_.find(ANDROID_SCALER_ROTATE_AND_CROP) == + available_results_.end()) { + ALOGE("%s: Rotate and crop must be listed in result keys if supported!", + __FUNCTION__); + return BAD_VALUE; + } + if (available_characteristics_.find( + ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES) == + available_characteristics_.end()) { + ALOGE( + "%s: Rotate and crop must be listed in characteristics keys if " + "supported!", + __FUNCTION__); + return BAD_VALUE; + } + report_rotate_and_crop_ = true; + for (size_t i = 0; i < entry.count; i++) { + if (entry.data.u8[i] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) { + rotate_and_crop_ = ANDROID_SCALER_ROTATE_AND_CROP_AUTO; + } + available_rotate_crop_modes_.insert(entry.data.u8[i]); + } + } + + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + default_requests_[idx]->Set(ANDROID_SCALER_CROP_REGION, + scaler_crop_region_default_, + ARRAY_SIZE(scaler_crop_region_default_)); + if (report_rotate_and_crop_) { + default_requests_[idx]->Set(ANDROID_SCALER_ROTATE_AND_CROP, + &rotate_and_crop_, 1); + } + } + } + + return InitializeControlDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeShadingDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get(ANDROID_SHADING_AVAILABLE_MODES, &entry); + if (ret == OK) { + available_shading_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available lens shading modes!", __FUNCTION__); + return BAD_VALUE; + } + + if (supports_manual_post_processing_ && + (available_shading_modes_.size() < 2)) { + ALOGE( + "%s: Devices capable of manual post-processing need to support at " + "least " + "two" + " lens shading modes!", + __FUNCTION__); + return BAD_VALUE; + } + + bool is_fast_mode_supported = + available_shading_modes_.find(ANDROID_SHADING_MODE_FAST) != + available_shading_modes_.end(); + bool is_hq_mode_supported = + available_shading_modes_.find(ANDROID_SHADING_MODE_HIGH_QUALITY) != + available_shading_modes_.end(); + uint8_t shading_mode = *available_shading_modes_.begin(); + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + switch (static_cast<RequestTemplate>(idx)) { + case RequestTemplate::kVideoRecord: // Pass-through + case RequestTemplate::kPreview: + if (is_fast_mode_supported) { + shading_mode = ANDROID_SHADING_MODE_FAST; + } + break; + case RequestTemplate::kVideoSnapshot: // Pass-through + case RequestTemplate::kStillCapture: + if (is_hq_mode_supported) { + shading_mode = ANDROID_SHADING_MODE_HIGH_QUALITY; + } + break; + default: + // Noop + break; + } + + default_requests_[idx]->Set(ANDROID_SHADING_MODE, &shading_mode, 1); + } + + return InitializeNoiseReductionDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeNoiseReductionDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get( + ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, &entry); + if (ret == OK) { + available_noise_reduction_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available noise reduction modes!", __FUNCTION__); + return BAD_VALUE; + } + + if ((is_level_full_or_higher_) && + (available_noise_reduction_modes_.size() < 2)) { + ALOGE( + "%s: Full and above device must support at least two noise reduction " + "modes!", + __FUNCTION__); + return BAD_VALUE; + } + + bool is_fast_mode_supported = + available_noise_reduction_modes_.find(ANDROID_NOISE_REDUCTION_MODE_FAST) != + available_noise_reduction_modes_.end(); + bool is_hq_mode_supported = available_noise_reduction_modes_.find( + ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY) != + available_noise_reduction_modes_.end(); + bool is_zsl_mode_supported = + available_noise_reduction_modes_.find( + ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG) != + available_noise_reduction_modes_.end(); + uint8_t noise_reduction_mode = *available_noise_reduction_modes_.begin(); + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + switch (static_cast<RequestTemplate>(idx)) { + case RequestTemplate::kVideoRecord: // Pass-through + case RequestTemplate::kVideoSnapshot: // Pass-through + case RequestTemplate::kPreview: + if (is_fast_mode_supported) { + noise_reduction_mode = ANDROID_NOISE_REDUCTION_MODE_FAST; + } + break; + case RequestTemplate::kStillCapture: + if (is_hq_mode_supported) { + noise_reduction_mode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY; + } + break; + case RequestTemplate::kZeroShutterLag: + if (is_zsl_mode_supported) { + noise_reduction_mode = ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG; + } + break; + default: + // Noop + break; + } + + default_requests_[idx]->Set(ANDROID_NOISE_REDUCTION_MODE, + &noise_reduction_mode, 1); + } + + return InitializeColorCorrectionDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeHotPixelDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES, + &entry); + if (ret == OK) { + available_hot_pixel_modes_.insert(entry.data.u8, + entry.data.u8 + entry.count); + } else { + ALOGE("%s: No available hotpixel modes!", __FUNCTION__); + return BAD_VALUE; + } + + if ((is_level_full_or_higher_) && (available_hot_pixel_modes_.size() < 2)) { + ALOGE( + "%s: Full and higher level cameras must support at least fast and hq " + "hotpixel modes", + __FUNCTION__); + return BAD_VALUE; + } + + bool fast_mode_supported = + available_hot_pixel_modes_.find(ANDROID_HOT_PIXEL_MODE_FAST) != + available_hot_pixel_modes_.end(); + bool hq_mode_supported = + available_hot_pixel_modes_.find(ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY) != + available_hot_pixel_modes_.end(); + uint8_t hotpixel_mode = *available_hot_pixel_modes_.begin(); + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + switch (static_cast<RequestTemplate>(idx)) { + case RequestTemplate::kVideoRecord: // Pass-through + case RequestTemplate::kPreview: + if (fast_mode_supported) { + hotpixel_mode = ANDROID_HOT_PIXEL_MODE_FAST; + } + break; + case RequestTemplate::kVideoSnapshot: // Pass-through + case RequestTemplate::kStillCapture: + if (hq_mode_supported) { + hotpixel_mode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY; + } + break; + default: + // Noop + break; + } + + default_requests_[idx]->Set(ANDROID_HOT_PIXEL_MODE, &hotpixel_mode, 1); + } + + return InitializeTonemapDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeFlashDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_AVAILABLE, &entry); + if ((ret == OK) && (entry.count == 1)) { + is_flash_supported_ = entry.data.u8[0]; + } else { + ALOGE("%s: No available flash info!", __FUNCTION__); + return BAD_VALUE; + } + + if (is_flash_supported_) { + flash_state_ = ANDROID_FLASH_STATE_READY; + } else { + flash_state_ = ANDROID_FLASH_STATE_UNAVAILABLE; + } + + uint8_t flash_mode = ANDROID_FLASH_MODE_OFF; + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + default_requests_[idx]->Set(ANDROID_FLASH_MODE, &flash_mode, 1); + } + + return InitializeScalerDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeLensDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = + static_metadata_->Get(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &entry); + if ((ret == OK) && (entry.count == 1)) { + minimum_focus_distance_ = entry.data.f[0]; + } else { + ALOGW("%s: No available minimum focus distance assuming fixed focus!", + __FUNCTION__); + minimum_focus_distance_ = .0f; + } + + ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &entry); + if ((ret == OK) && (entry.count > 0)) { + // TODO: add support for multiple apertures + aperture_ = entry.data.f[0]; + } else { + ALOGE("%s: No available aperture!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &entry); + if ((ret == OK) && (entry.count > 0)) { + focal_length_ = entry.data.f[0]; + } else { + ALOGE("%s: No available focal length!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_LENS_INFO_SHADING_MAP_SIZE, &entry); + if ((ret == OK) && (entry.count == 2)) { + shading_map_size_[0] = entry.data.i32[0]; + shading_map_size_[1] = entry.data.i32[1]; + } else if (is_raw_capable_) { + ALOGE("%s: No available shading map size!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, + &entry); + if ((ret == OK) && (entry.count > 0)) { + // TODO: add support for multiple filter densities + filter_density_ = entry.data.f[0]; + } else { + ALOGE("%s: No available filter density!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, + &entry); + if ((ret == OK) && (entry.count > 0)) { + // TODO: add support for multiple OIS modes + available_ois_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); + if (available_ois_modes_.find(ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF) == + available_ois_modes_.end()) { + ALOGE("%s: OIS off mode not supported!", __FUNCTION__); + return BAD_VALUE; + } + } else { + ALOGE("%s: No available OIS modes!", __FUNCTION__); + return BAD_VALUE; + } + + ret = static_metadata_->Get(ANDROID_LENS_POSE_ROTATION, &entry); + if ((ret == OK) && (entry.count == ARRAY_SIZE(pose_rotation_))) { + memcpy(pose_rotation_, entry.data.f, sizeof(pose_rotation_)); + } + ret = static_metadata_->Get(ANDROID_LENS_POSE_TRANSLATION, &entry); + if ((ret == OK) && (entry.count == ARRAY_SIZE(pose_translation_))) { + memcpy(pose_translation_, entry.data.f, sizeof(pose_translation_)); + } + ret = static_metadata_->Get(ANDROID_LENS_INTRINSIC_CALIBRATION, &entry); + if ((ret == OK) && (entry.count == ARRAY_SIZE(intrinsic_calibration_))) { + memcpy(intrinsic_calibration_, entry.data.f, sizeof(intrinsic_calibration_)); + } + + ret = static_metadata_->Get(ANDROID_LENS_DISTORTION, &entry); + if ((ret == OK) && (entry.count == ARRAY_SIZE(distortion_))) { + memcpy(distortion_, entry.data.f, sizeof(distortion_)); + } + + report_focus_distance_ = + available_results_.find(ANDROID_LENS_FOCUS_DISTANCE) != + available_results_.end(); + report_focus_range_ = available_results_.find(ANDROID_LENS_FOCUS_RANGE) != + available_results_.end(); + report_filter_density_ = + available_results_.find(ANDROID_LENS_FILTER_DENSITY) != + available_results_.end(); + report_ois_mode_ = + available_results_.find(ANDROID_LENS_OPTICAL_STABILIZATION_MODE) != + available_results_.end(); + report_pose_rotation_ = available_results_.find(ANDROID_LENS_POSE_ROTATION) != + available_results_.end(); + report_pose_translation_ = + available_results_.find(ANDROID_LENS_POSE_TRANSLATION) != + available_results_.end(); + report_intrinsic_calibration_ = + available_results_.find(ANDROID_LENS_INTRINSIC_CALIBRATION) != + available_results_.end(); + report_distortion_ = available_results_.find(ANDROID_LENS_DISTORTION) != + available_results_.end(); + + focus_distance_ = minimum_focus_distance_; + for (size_t idx = 0; idx < kTemplateCount; idx++) { + if (default_requests_[idx].get() == nullptr) { + continue; + } + + default_requests_[idx]->Set(ANDROID_LENS_APERTURE, &aperture_, 1); + default_requests_[idx]->Set(ANDROID_LENS_FOCAL_LENGTH, &focal_length_, 1); + default_requests_[idx]->Set(ANDROID_LENS_FOCUS_DISTANCE, &focus_distance_, + 1); + default_requests_[idx]->Set(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, + &ois_mode_, 1); + } + + return InitializeFlashDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeInfoDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = + static_metadata_->Get(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry); + if ((ret == OK) && (entry.count == 1)) { + if (kSupportedHWLevels.find(entry.data.u8[0]) == + kSupportedCapabilites.end()) { + ALOGE("%s: HW Level: %u not supported", __FUNCTION__, entry.data.u8[0]); + return BAD_VALUE; + } + } else { + ALOGE("%s: No available hardware level!", __FUNCTION__); + return BAD_VALUE; + } + + supported_hw_level_ = entry.data.u8[0]; + is_level_full_or_higher_ = + (supported_hw_level_ == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL) || + (supported_hw_level_ == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3); + + return InitializeReprocessDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeReprocessDefaults() { + if (supports_private_reprocessing_ || supports_yuv_reprocessing_ || + supports_remosaic_reprocessing_) { + StreamConfigurationMap config_map(*static_metadata_); + if (!config_map.SupportsReprocessing()) { + ALOGE( + "%s: Reprocess capability present but InputOutput format map is " + "absent!", + __FUNCTION__); + return BAD_VALUE; + } + + auto input_formats = config_map.GetInputFormats(); + for (const auto& input_format : input_formats) { + auto output_formats = + config_map.GetValidOutputFormatsForInput(input_format); + for (const auto& output_format : output_formats) { + if (!EmulatedSensor::IsReprocessPathSupported( + EmulatedSensor::OverrideFormat( + input_format, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD), + EmulatedSensor::OverrideFormat( + output_format, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD))) { + ALOGE( + "%s: Input format: 0x%x to output format: 0x%x reprocess is" + " currently not supported!", + __FUNCTION__, input_format, output_format); + return BAD_VALUE; + } + } + } + } + + return InitializeLensDefaults(); +} + +status_t EmulatedCameraDeviceInfo::InitializeRequestDefaults() { + camera_metadata_ro_entry_t entry; + auto ret = + static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); + if ((ret == OK) && (entry.count > 0)) { + for (size_t i = 0; i < entry.count; i++) { + if (kSupportedCapabilites.find(entry.data.u8[i]) == + kSupportedCapabilites.end()) { + ALOGE("%s: Capability: %u not supported", __FUNCTION__, + entry.data.u8[i]); + return BAD_VALUE; + } + } + } else { + ALOGE("%s: No available capabilities!", __FUNCTION__); + return BAD_VALUE; + } + available_capabilities_.insert(entry.data.u8, entry.data.u8 + entry.count); + + ret = static_metadata_->Get(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry); + if ((ret == OK) && (entry.count == 1)) { + if (entry.data.u8[0] == 0) { + ALOGE("%s: Maximum request pipeline depth must have a non zero value!", + __FUNCTION__); + return BAD_VALUE; + } + } else { + ALOGE("%s: Maximum request pipeline depth absent!", __FUNCTION__); + return BAD_VALUE; + } + max_pipeline_depth_ = entry.data.u8[0]; + + ret = static_metadata_->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); + if ((ret == OK) && (entry.count == 1)) { + if (entry.data.i32[0] > 2) { + ALOGW("%s: Partial result count greater than 2 not supported!", + __FUNCTION__); + } + partial_result_count_ = entry.data.i32[0]; + } + + ret = static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, + &entry); + if ((ret != OK) || (entry.count == 0)) { + ALOGE("%s: No available characteristic keys!", __FUNCTION__); + return BAD_VALUE; + } + available_characteristics_.insert(entry.data.i32, + entry.data.i32 + entry.count); + + ret = static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry); + if ((ret != OK) || (entry.count == 0)) { + ALOGE("%s: No available result keys!", __FUNCTION__); + return BAD_VALUE; + } + available_results_.insert(entry.data.i32, entry.data.i32 + entry.count); + + ret = static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry); + if ((ret != OK) || (entry.count == 0)) { + ALOGE("%s: No available request keys!", __FUNCTION__); + return BAD_VALUE; + } + available_requests_.insert(entry.data.i32, entry.data.i32 + entry.count); + + supports_manual_sensor_ = + SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR); + supports_manual_post_processing_ = SupportsCapability( + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING); + supports_private_reprocessing_ = SupportsCapability( + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING); + supports_yuv_reprocessing_ = SupportsCapability( + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING); + supports_remosaic_reprocessing_ = SupportsCapability( + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING); + is_backward_compatible_ = SupportsCapability( + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE); + is_raw_capable_ = + SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW); + supports_stream_use_case_ = + SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE); + + if (supports_manual_sensor_) { + auto templateIdx = static_cast<size_t>(RequestTemplate::kManual); + default_requests_[templateIdx] = HalCameraMetadata::Create(1, 10); + } + + if (supports_stream_use_case_) { + ret = static_metadata_->Get(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, + &entry); + if (ret != OK) { + ALOGE("%s: No available stream use cases!", __FUNCTION__); + return BAD_VALUE; + } + for (int64_t useCase : kSupportedUseCases) { + if (std::find(entry.data.i64, entry.data.i64 + entry.count, useCase) == + entry.data.i64 + entry.count) { + ALOGE("%s: Mandatory stream use case %" PRId64 " not found!", + __FUNCTION__, useCase); + return BAD_VALUE; + } + } + } + + for (size_t templateIdx = 0; templateIdx < kTemplateCount; templateIdx++) { + switch (static_cast<RequestTemplate>(templateIdx)) { + case RequestTemplate::kPreview: + case RequestTemplate::kStillCapture: + case RequestTemplate::kVideoRecord: + case RequestTemplate::kVideoSnapshot: + default_requests_[templateIdx] = HalCameraMetadata::Create(1, 10); + break; + default: + // Noop + break; + } + } + + if (supports_yuv_reprocessing_ || supports_private_reprocessing_) { + auto templateIdx = static_cast<size_t>(RequestTemplate::kZeroShutterLag); + default_requests_[templateIdx] = HalCameraMetadata::Create(1, 10); + } + + return InitializeInfoDefaults(); +} + +bool EmulatedCameraDeviceInfo::SupportsCapability(uint8_t cap) { + return available_capabilities_.find(cap) != available_capabilities_.end(); +} + +} // namespace android diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceInfo.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceInfo.h new file mode 100644 index 0000000..d203412 --- /dev/null +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceInfo.h @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2023 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 EMULATOR_CAMERA_HAL_HWL_CAMERA_DEVICE_INFO_H +#define EMULATOR_CAMERA_HAL_HWL_CAMERA_DEVICE_INFO_H + +#include <log/log.h> + +#include <memory> +#include <set> +#include <unordered_map> +#include <utility> +#include <vector> + +#include "hal_camera_metadata.h" +#include "hal_types.h" +#include "utils/HWLUtils.h" + +namespace android { + +using google_camera_hal::HalCameraMetadata; +using google_camera_hal::kTemplateCount; +using google_camera_hal::RequestTemplate; + +template <typename T> +T GetClosestValue(T val, T min, T max) { + if ((min > max) || ((val >= min) && (val <= max))) { + return val; + } else if (val > max) { + return max; + } else { + return min; + } +} + +struct EmulatedCameraDeviceInfo { + static std::unique_ptr<EmulatedCameraDeviceInfo> Create( + std::unique_ptr<HalCameraMetadata> static_metadata); + + static std::unique_ptr<EmulatedCameraDeviceInfo> Clone( + const EmulatedCameraDeviceInfo& other); + + std::unique_ptr<HalCameraMetadata> static_metadata_; + std::unique_ptr<HalCameraMetadata> default_requests_[kTemplateCount]; + + static const std::set<uint8_t> kSupportedCapabilites; + static const std::set<uint8_t> kSupportedHWLevels; + static const std::vector<int64_t> kSupportedUseCases; + + static const int32_t kMinimumStreamingFPS = 20; + + // android.blacklevel.* + bool report_black_level_lock_ = false; + uint8_t black_level_lock_ = ANDROID_BLACK_LEVEL_LOCK_ON; + + // android.colorcorrection.* + std::set<uint8_t> available_color_aberration_modes_; + + // android.edge.* + std::set<uint8_t> available_edge_modes_; + bool report_edge_mode_ = false; + + // android.shading.* + std::set<uint8_t> available_shading_modes_; + + // android.noiseReduction.* + std::set<uint8_t> available_noise_reduction_modes_; + + uint8_t partial_result_count_ = 1; + + // android.request.* + std::set<uint8_t> available_capabilities_; + std::set<int32_t> available_characteristics_; + std::set<int32_t> available_results_; + std::set<int32_t> available_requests_; + uint8_t max_pipeline_depth_ = 0; + bool supports_manual_sensor_ = false; + bool supports_manual_post_processing_ = false; + bool supports_remosaic_reprocessing_ = false; + bool supports_private_reprocessing_ = false; + bool supports_yuv_reprocessing_ = false; + bool is_backward_compatible_ = false; + bool is_raw_capable_ = false; + bool supports_stream_use_case_ = false; + + // android.info.* + bool is_level_full_or_higher_ = false; + // Set to true if the camera device has HW level FULL or LEVEL3 + uint8_t supported_hw_level_ = 0; + + // android.lens.* + float minimum_focus_distance_ = 0.f; + float aperture_ = 0.f; + float focal_length_ = 0.f; + float focus_distance_ = 0.f; + bool report_focus_distance_ = false; + uint8_t lens_state_ = ANDROID_LENS_STATE_STATIONARY; + bool report_focus_range_ = false; + float filter_density_ = 0.f; + bool report_filter_density_ = false; + std::set<uint8_t> available_ois_modes_; + uint8_t ois_mode_ = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; + bool report_ois_mode_ = false; + float pose_rotation_[4] = {.0f}; + float pose_translation_[3] = {.0f}; + float distortion_[5] = {.0f}; + float intrinsic_calibration_[5] = {.0f}; + bool report_pose_rotation_ = false; + bool report_pose_translation_ = false; + bool report_distortion_ = false; + bool report_intrinsic_calibration_ = false; + bool report_active_sensor_crop_ = false; + bool report_lens_intrinsics_samples_ = false; + int32_t shading_map_size_[2] = {0}; + + // android.control.* + struct SceneOverride { + uint8_t ae_mode, awb_mode, af_mode; + SceneOverride() + : ae_mode(ANDROID_CONTROL_AE_MODE_OFF), + awb_mode(ANDROID_CONTROL_AWB_MODE_OFF), + af_mode(ANDROID_CONTROL_AF_MODE_OFF) { + } + SceneOverride(uint8_t ae, uint8_t awb, uint8_t af) + : ae_mode(ae), awb_mode(awb), af_mode(af) { + } + }; + + struct FPSRange { + int32_t min_fps, max_fps; + FPSRange() : min_fps(-1), max_fps(-1) { + } + FPSRange(int32_t min, int32_t max) : min_fps(min), max_fps(max) { + } + }; + + struct ExtendedSceneModeCapability { + int32_t mode, max_width, max_height; + float min_zoom, max_zoom; + ExtendedSceneModeCapability() + : mode(ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED), + max_width(-1), + max_height(-1), + min_zoom(1.0f), + max_zoom(1.0f) { + } + ExtendedSceneModeCapability(int32_t m, int32_t w, int32_t h, float min_z, + float max_z) + : mode(m), max_width(w), max_height(h), min_zoom(min_z), max_zoom(max_z) { + } + }; + + std::set<uint8_t> available_control_modes_; + std::set<uint8_t> available_ae_modes_; + std::set<uint8_t> available_af_modes_; + std::set<uint8_t> available_awb_modes_; + std::set<uint8_t> available_scenes_; + std::set<uint8_t> available_antibanding_modes_; + std::set<uint8_t> available_effects_; + std::set<uint8_t> available_vstab_modes_; + std::set<uint8_t> available_sensor_pixel_modes_; + std::vector<ExtendedSceneModeCapability> available_extended_scene_mode_caps_; + std::unordered_map<uint8_t, SceneOverride> scene_overrides_; + std::vector<FPSRange> available_fps_ranges_; + int32_t exposure_compensation_range_[2] = {0, 0}; + float max_zoom_ = 1.0f; + bool zoom_ratio_supported_ = false; + float min_zoom_ = 1.0f; + camera_metadata_rational exposure_compensation_step_ = {0, 1}; + bool exposure_compensation_supported_ = false; + int32_t exposure_compensation_ = 0; + int32_t ae_metering_region_[5] = {0, 0, 0, 0, 0}; + int32_t awb_metering_region_[5] = {0, 0, 0, 0, 0}; + int32_t af_metering_region_[5] = {0, 0, 0, 0, 0}; + size_t max_ae_regions_ = 0; + size_t max_awb_regions_ = 0; + size_t max_af_regions_ = 0; + uint8_t control_mode_ = ANDROID_CONTROL_MODE_AUTO; + uint8_t sensor_pixel_mode_ = ANDROID_SENSOR_PIXEL_MODE_DEFAULT; + uint8_t scene_mode_ = ANDROID_CONTROL_SCENE_MODE_DISABLED; + uint8_t ae_mode_ = ANDROID_CONTROL_AE_MODE_ON; + uint8_t awb_mode_ = ANDROID_CONTROL_AWB_MODE_AUTO; + uint8_t af_mode_ = ANDROID_CONTROL_AF_MODE_AUTO; + uint8_t ae_lock_ = ANDROID_CONTROL_AE_LOCK_OFF; + uint8_t ae_state_ = ANDROID_CONTROL_AE_STATE_INACTIVE; + uint8_t awb_state_ = ANDROID_CONTROL_AWB_STATE_INACTIVE; + uint8_t awb_lock_ = ANDROID_CONTROL_AWB_LOCK_OFF; + uint8_t af_state_ = ANDROID_CONTROL_AF_STATE_INACTIVE; + uint8_t af_trigger_ = ANDROID_CONTROL_AF_TRIGGER_IDLE; + uint8_t ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + uint8_t autoframing_ = ANDROID_CONTROL_AUTOFRAMING_OFF; + FPSRange ae_target_fps_ = {0, 0}; + float zoom_ratio_ = 1.0f; + uint8_t extended_scene_mode_ = ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED; + bool ae_lock_available_ = false; + bool report_ae_lock_ = false; + bool scenes_supported_ = false; + bool vstab_available_ = false; + int32_t post_raw_boost_ = 100; + bool report_post_raw_boost_ = false; + bool awb_lock_available_ = false; + bool report_awb_lock_ = false; + bool af_supported_ = false; + bool picture_caf_supported_ = false; + bool video_caf_supported_ = false; + int32_t settings_override_ = ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF; + + // android.flash.* + bool is_flash_supported_ = false; + uint8_t flash_state_ = ANDROID_FLASH_STATE_UNAVAILABLE; + int32_t flash_strength_level_ = 1; + + // android.hotpixel.* + std::set<uint8_t> available_hot_pixel_modes_; + + // android.scaler.* + bool report_rotate_and_crop_ = false; + uint8_t rotate_and_crop_ = ANDROID_SCALER_ROTATE_AND_CROP_NONE; + int32_t scaler_crop_region_default_[4] = {0, 0, 0, 0}; + int32_t scaler_crop_region_max_resolution_[4] = {0, 0, 0, 0}; + std::set<uint8_t> available_rotate_crop_modes_; + + // android.sensor.* + std::pair<int32_t, int32_t> sensor_sensitivity_range_; + std::pair<nsecs_t, nsecs_t> sensor_exposure_time_range_; + nsecs_t sensor_max_frame_duration_ = + EmulatedSensor::kSupportedFrameDurationRange[1]; + nsecs_t sensor_exposure_time_ = EmulatedSensor::kDefaultExposureTime; + nsecs_t sensor_frame_duration_ = EmulatedSensor::kDefaultFrameDuration; + int32_t sensor_sensitivity_ = EmulatedSensor::kDefaultSensitivity; + bool report_frame_duration_ = false; + bool report_sensitivity_ = false; + bool report_exposure_time_ = false; + std::set<int32_t> available_test_pattern_modes_; + bool report_rolling_shutter_skew_ = false; + bool report_neutral_color_point_ = false; + bool report_green_split_ = false; + bool report_noise_profile_ = false; + bool report_extended_scene_mode_ = false; + uint32_t timestamp_source_ = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN; + + // android.statistics.* + uint8_t current_scene_flicker_ = ANDROID_STATISTICS_SCENE_FLICKER_NONE; + std::set<uint8_t> available_hot_pixel_map_modes_; + std::set<uint8_t> available_lens_shading_map_modes_; + std::set<uint8_t> available_face_detect_modes_; + bool report_scene_flicker_ = false; + + // android.tonemap.* + std::set<uint8_t> available_tonemap_modes_; + + private: + status_t Initialize(unique_ptr<HalCameraMetadata> staticMetadata) { + static_metadata_ = std::move(staticMetadata); + return InitializeRequestDefaults(); + } + + status_t InitializeRequestDefaults(); + status_t InitializeSensorDefaults(); + status_t InitializeFlashDefaults(); + status_t InitializeControlDefaults(); + status_t InitializeControlAEDefaults(); + status_t InitializeControlAWBDefaults(); + status_t InitializeControlAFDefaults(); + status_t InitializeControlSceneDefaults(); + status_t InitializeHotPixelDefaults(); + status_t InitializeStatisticsDefaults(); + status_t InitializeTonemapDefaults(); + status_t InitializeBlackLevelDefaults(); + status_t InitializeEdgeDefaults(); + status_t InitializeShadingDefaults(); + status_t InitializeNoiseReductionDefaults(); + status_t InitializeColorCorrectionDefaults(); + status_t InitializeScalerDefaults(); + status_t InitializeReprocessDefaults(); + status_t InitializeMeteringRegionDefault(uint32_t tag, + int32_t* region /*out*/); + status_t InitializeControlefaults(); + status_t InitializeInfoDefaults(); + status_t InitializeLensDefaults(); + + bool SupportsCapability(uint8_t cap); +}; + +} // namespace android + +#endif // EMULATOR_CAMERA_HAL_HWL_CAMERA_DEVICE_INFO_H diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp index 6ad921d..45e3daf 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp @@ -76,11 +76,11 @@ bool EmulatedCameraZoomRatioMapperHwlImpl::GetActiveArrayDimensionToBeUsed( std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl> EmulatedCameraDeviceSessionHwlImpl::Create( - uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + uint32_t camera_id, std::unique_ptr<EmulatedCameraDeviceInfo> device_info, PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state) { ATRACE_CALL(); - if (static_meta.get() == nullptr) { + if (device_info.get() == nullptr) { return nullptr; } @@ -93,7 +93,7 @@ EmulatedCameraDeviceSessionHwlImpl::Create( return nullptr; } - status_t res = session->Initialize(camera_id, std::move(static_meta)); + status_t res = session->Initialize(camera_id, std::move(device_info)); if (res != OK) { ALOGE("%s: Initializing EmulatedCameraDeviceSessionHwlImpl failed: %s(%d)", __FUNCTION__, strerror(-res), res); @@ -140,15 +140,17 @@ static std::pair<Dimension, Dimension> GetArrayDimensions( } status_t EmulatedCameraDeviceSessionHwlImpl::Initialize( - uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta) { + uint32_t camera_id, std::unique_ptr<EmulatedCameraDeviceInfo> device_info) { camera_id_ = camera_id; - static_metadata_ = std::move(static_meta); - stream_configuration_map_ = - std::make_unique<StreamConfigurationMap>(*static_metadata_); + device_info_ = std::move(device_info); + stream_configuration_map_ = std::make_unique<StreamConfigurationMap>( + *(device_info_->static_metadata_)); stream_configuration_map_max_resolution_ = - std::make_unique<StreamConfigurationMap>(*static_metadata_, true); + std::make_unique<StreamConfigurationMap>( + *(device_info_->static_metadata_), true); camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry); + auto ret = device_info_->static_metadata_->Get( + ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry); if (ret != OK) { ALOGE("%s: Unable to extract ANDROID_REQUEST_PIPELINE_MAX_DEPTH, %s (%d)", __FUNCTION__, strerror(-ret), ret); @@ -160,16 +162,17 @@ status_t EmulatedCameraDeviceSessionHwlImpl::Initialize( std::unordered_map<uint32_t, std::pair<Dimension, Dimension>> camera_ids_to_dimensions; camera_ids_to_dimensions[camera_id] = - GetArrayDimensions(camera_id, static_metadata_.get()); + GetArrayDimensions(camera_id, device_info_->static_metadata_.get()); - ret = GetSensorCharacteristics(static_metadata_.get(), &sensor_chars_); + ret = GetSensorCharacteristics(device_info_->static_metadata_.get(), + &sensor_chars_); if (ret != OK) { ALOGE("%s: Unable to extract sensor characteristics %s (%d)", __FUNCTION__, strerror(-ret), ret); return ret; } - ret = SupportsSessionHalBufManager(static_metadata_.get(), + ret = SupportsSessionHalBufManager(device_info_->static_metadata_.get(), &supports_session_hal_buf_manager_); if (ret != OK) { ALOGE("%s: Unable to get sensor hal buffer manager support %s (%d)", @@ -219,7 +222,7 @@ status_t EmulatedCameraDeviceSessionHwlImpl::InitializeRequestProcessor() { request_processor_->InitializeSensorQueue(request_processor_); return request_processor_->Initialize( - HalCameraMetadata::Clone(static_metadata_.get()), + EmulatedCameraDeviceInfo::Clone(*device_info_), ClonePhysicalDeviceMap(physical_device_map_)); } @@ -506,7 +509,8 @@ status_t EmulatedCameraDeviceSessionHwlImpl::GetCameraCharacteristics( return BAD_VALUE; } - (*characteristics) = HalCameraMetadata::Clone(static_metadata_.get()); + (*characteristics) = + HalCameraMetadata::Clone(device_info_->static_metadata_.get()); if (*characteristics == nullptr) { ALOGE("%s metadata clone failed", __FUNCTION__); diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h index 06c3609..8993b06 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h @@ -79,7 +79,7 @@ class EmulatedCameraZoomRatioMapperHwlImpl : public ZoomRatioMapperHwl { class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { public: static std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl> Create( - uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + uint32_t camera_id, std::unique_ptr<EmulatedCameraDeviceInfo> device_info, PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state); @@ -180,7 +180,7 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { private: status_t Initialize(uint32_t camera_id, - std::unique_ptr<HalCameraMetadata> static_meta); + std::unique_ptr<EmulatedCameraDeviceInfo> device_info); status_t InitializeRequestProcessor(); status_t CheckOutputFormatsForInput( @@ -205,7 +205,7 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { bool pipelines_built_ = false; bool has_raw_stream_ = false; bool supports_session_hal_buf_manager_ = false; - std::unique_ptr<HalCameraMetadata> static_metadata_; + std::unique_ptr<EmulatedCameraDeviceInfo> device_info_; std::vector<EmulatedPipeline> pipelines_; std::shared_ptr<EmulatedRequestProcessor> request_processor_; std::unique_ptr<StreamConfigurationMap> stream_configuration_map_; diff --git a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.cpp b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.cpp index cd3c136..b1d0faf 100644 --- a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.cpp @@ -35,11 +35,11 @@ EmulatedLogicalRequestState::~EmulatedLogicalRequestState() { } status_t EmulatedLogicalRequestState::Initialize( - std::unique_ptr<HalCameraMetadata> static_meta, + std::unique_ptr<EmulatedCameraDeviceInfo> device_info, PhysicalDeviceMapPtr physical_devices) { if ((physical_devices.get() != nullptr) && (!physical_devices->empty())) { zoom_ratio_physical_camera_info_ = GetZoomRatioPhysicalCameraInfo( - static_meta.get(), physical_devices.get()); + device_info->static_metadata_.get(), physical_devices.get()); physical_device_map_ = std::move(physical_devices); @@ -59,8 +59,9 @@ status_t EmulatedLogicalRequestState::Initialize( for (const auto& it : *physical_device_map_) { std::unique_ptr<EmulatedRequestState> physical_request_state = std::make_unique<EmulatedRequestState>(it.first); - auto ret = physical_request_state->Initialize( - HalCameraMetadata::Clone(it.second.second.get())); + auto ret = + physical_request_state->Initialize(EmulatedCameraDeviceInfo::Create( + HalCameraMetadata::Clone(it.second.second.get()))); if (ret != OK) { ALOGE("%s: Physical device: %u request state initialization failed!", __FUNCTION__, it.first); @@ -72,7 +73,7 @@ status_t EmulatedLogicalRequestState::Initialize( } } - return logical_request_state_->Initialize(std::move(static_meta)); + return logical_request_state_->Initialize(std::move(device_info)); } status_t EmulatedLogicalRequestState::GetDefaultRequest( diff --git a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h index 77f8955..0235f40 100644 --- a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h +++ b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h @@ -60,7 +60,7 @@ class EmulatedLogicalRequestState { EmulatedLogicalRequestState(uint32_t camera_id); virtual ~EmulatedLogicalRequestState(); - status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta, + status_t Initialize(std::unique_ptr<EmulatedCameraDeviceInfo> device_info, PhysicalDeviceMapPtr physical_device_map); status_t GetDefaultRequest( diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp index 536b423..d5a8510 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp @@ -544,10 +544,10 @@ void EmulatedRequestProcessor::RequestProcessorLoop() { } status_t EmulatedRequestProcessor::Initialize( - std::unique_ptr<HalCameraMetadata> static_meta, + std::unique_ptr<EmulatedCameraDeviceInfo> device_info, PhysicalDeviceMapPtr physical_devices) { std::lock_guard<std::mutex> lock(process_mutex_); - return request_state_->Initialize(std::move(static_meta), + return request_state_->Initialize(std::move(device_info), std::move(physical_devices)); } diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h index 0907fdb..4aeba20 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h +++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h @@ -78,7 +78,7 @@ class EmulatedRequestProcessor { status_t Flush(); - status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta, + status_t Initialize(std::unique_ptr<EmulatedCameraDeviceInfo> device_info, PhysicalDeviceMapPtr physical_devices); void InitializeSensorQueue(std::weak_ptr<EmulatedRequestProcessor> processor); diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp index ff6ed12..3a3a4b4 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp @@ -29,48 +29,6 @@ namespace android { using google_camera_hal::HwlPipelineResult; -const std::set<uint8_t> EmulatedRequestState::kSupportedCapabilites = { - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE, - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES}; - -const std::set<uint8_t> EmulatedRequestState::kSupportedHWLevels = { - ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED, - ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL, - ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3, -}; - -const std::vector<int64_t> EmulatedRequestState::kSupportedUseCases = { - ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT, - ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW, - ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE, - ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD, - ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL, - ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL}; - -template <typename T> -T GetClosestValue(T val, T min, T max) { - if ((min > max) || ((val >= min) && (val <= max))) { - return val; - } else if (val > max) { - return max; - } else { - return min; - } -} - status_t EmulatedRequestState::Update3AMeteringRegion( uint32_t tag, const HalCameraMetadata& settings, int32_t* region /*out*/) { if ((region == nullptr) || ((tag != ANDROID_CONTROL_AE_REGIONS) && @@ -106,8 +64,10 @@ status_t EmulatedRequestState::Update3AMeteringRegion( } status_t EmulatedRequestState::CompensateAE() { - if (!exposure_compensation_supported_) { - sensor_exposure_time_ = current_exposure_time_; + auto& info = *device_info_; + + if (!info.exposure_compensation_supported_) { + info.sensor_exposure_time_ = current_exposure_time_; return OK; } @@ -115,42 +75,45 @@ status_t EmulatedRequestState::CompensateAE() { auto ret = request_settings_->Get(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &entry); if ((ret == OK) && (entry.count == 1)) { - exposure_compensation_ = entry.data.i32[0]; + info.exposure_compensation_ = entry.data.i32[0]; } else { ALOGW("%s: AE compensation absent from request, re-using previous value!", __FUNCTION__); } float ae_compensation = ::powf( - 2, exposure_compensation_ * - ((static_cast<float>(exposure_compensation_step_.numerator) / - exposure_compensation_step_.denominator))); + 2, info.exposure_compensation_ * + ((static_cast<float>(info.exposure_compensation_step_.numerator) / + info.exposure_compensation_step_.denominator))); - sensor_exposure_time_ = GetClosestValue( + info.sensor_exposure_time_ = GetClosestValue( static_cast<nsecs_t>(ae_compensation * current_exposure_time_), - sensor_exposure_time_range_.first, sensor_exposure_time_range_.second); + info.sensor_exposure_time_range_.first, + info.sensor_exposure_time_range_.second); return OK; } status_t EmulatedRequestState::DoFakeAE() { + auto& info = *device_info_; + camera_metadata_ro_entry_t entry; auto ret = request_settings_->Get(ANDROID_CONTROL_AE_LOCK, &entry); if ((ret == OK) && (entry.count == 1)) { - ae_lock_ = entry.data.u8[0]; + info.ae_lock_ = entry.data.u8[0]; } else { - ae_lock_ = ANDROID_CONTROL_AE_LOCK_OFF; + info.ae_lock_ = ANDROID_CONTROL_AE_LOCK_OFF; } - if (ae_lock_ == ANDROID_CONTROL_AE_LOCK_ON) { - ae_state_ = ANDROID_CONTROL_AE_STATE_LOCKED; + if (info.ae_lock_ == ANDROID_CONTROL_AE_LOCK_ON) { + info.ae_state_ = ANDROID_CONTROL_AE_STATE_LOCKED; return OK; } - FPSRange fps_range; + EmulatedCameraDeviceInfo::FPSRange fps_range; ret = request_settings_->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry); if ((ret == OK) && (entry.count == 2)) { - for (const auto& it : available_fps_ranges_) { + for (const auto& it : info.available_fps_ranges_) { if ((it.min_fps == entry.data.i32[0]) && (it.max_fps == entry.data.i32[1])) { fps_range = {entry.data.i32[0], entry.data.i32[1]}; @@ -163,78 +126,79 @@ status_t EmulatedRequestState::DoFakeAE() { return BAD_VALUE; } } else { - fps_range = *available_fps_ranges_.begin(); + fps_range = *info.available_fps_ranges_.begin(); } ret = request_settings_->Get(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &entry); if ((ret == OK) && (entry.count == 1)) { - ae_trigger_ = entry.data.u8[0]; + info.ae_trigger_ = entry.data.u8[0]; } else { - ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + info.ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; } nsecs_t min_frame_duration = GetClosestValue(ms2ns(1000 / fps_range.max_fps), EmulatedSensor::kSupportedFrameDurationRange[0], - sensor_max_frame_duration_); + info.sensor_max_frame_duration_); nsecs_t max_frame_duration = GetClosestValue(ms2ns(1000 / fps_range.min_fps), EmulatedSensor::kSupportedFrameDurationRange[0], - sensor_max_frame_duration_); - sensor_frame_duration_ = (max_frame_duration + min_frame_duration) / 2; + info.sensor_max_frame_duration_); + info.sensor_frame_duration_ = (max_frame_duration + min_frame_duration) / 2; // Face priority mode usually changes the AE algorithm behavior by // using the regions of interest associated with detected faces. // Try to emulate this behavior by slightly increasing the target exposure // time compared to normal operation. - if (exposure_compensation_supported_) { + if (info.exposure_compensation_supported_) { float max_ae_compensation = ::powf( - 2, exposure_compensation_range_[1] * - ((static_cast<float>(exposure_compensation_step_.numerator) / - exposure_compensation_step_.denominator))); + 2, info.exposure_compensation_range_[1] * + ((static_cast<float>(info.exposure_compensation_step_.numerator) / + info.exposure_compensation_step_.denominator))); ae_target_exposure_time_ = GetClosestValue( - static_cast<nsecs_t>(sensor_frame_duration_ / max_ae_compensation), - sensor_exposure_time_range_.first, sensor_exposure_time_range_.second); - } else if (scene_mode_ == ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY) { + static_cast<nsecs_t>(info.sensor_frame_duration_ / max_ae_compensation), + info.sensor_exposure_time_range_.first, + info.sensor_exposure_time_range_.second); + } else if (info.scene_mode_ == ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY) { ae_target_exposure_time_ = GetClosestValue( - sensor_frame_duration_ / 4, sensor_exposure_time_range_.first, - sensor_exposure_time_range_.second); + info.sensor_frame_duration_ / 4, info.sensor_exposure_time_range_.first, + info.sensor_exposure_time_range_.second); } else { ae_target_exposure_time_ = GetClosestValue( - sensor_frame_duration_ / 5, sensor_exposure_time_range_.first, - sensor_exposure_time_range_.second); + info.sensor_frame_duration_ / 5, info.sensor_exposure_time_range_.first, + info.sensor_exposure_time_range_.second); } - if ((ae_trigger_ == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START) || - (ae_state_ == ANDROID_CONTROL_AE_STATE_PRECAPTURE)) { - if (ae_state_ != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { + if ((info.ae_trigger_ == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START) || + (info.ae_state_ == ANDROID_CONTROL_AE_STATE_PRECAPTURE)) { + if (info.ae_state_ != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { ae_frame_counter_ = 0; } - if (ae_trigger_ == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) { + if (info.ae_trigger_ == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) { // Done with precapture ae_frame_counter_ = 0; - ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; - ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL; + info.ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; + info.ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL; } else if ((ae_frame_counter_ > kAEPrecaptureMinFrames) && (abs(ae_target_exposure_time_ - current_exposure_time_) < ae_target_exposure_time_ / kAETargetThreshold)) { // Done with precapture ae_frame_counter_ = 0; - ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; - ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + info.ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; + info.ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; } else { // Converge some more current_exposure_time_ += (ae_target_exposure_time_ - current_exposure_time_) * kExposureTrackRate; ae_frame_counter_++; - ae_state_ = ANDROID_CONTROL_AE_STATE_PRECAPTURE; + info.ae_state_ = ANDROID_CONTROL_AE_STATE_PRECAPTURE; } } else { - switch (ae_state_) { + switch (info.ae_state_) { case ANDROID_CONTROL_AE_STATE_INACTIVE: - ae_state_ = ANDROID_CONTROL_AE_STATE_SEARCHING; + info.ae_state_ = ANDROID_CONTROL_AE_STATE_SEARCHING; break; case ANDROID_CONTROL_AE_STATE_CONVERGED: ae_frame_counter_++; @@ -245,9 +209,9 @@ status_t EmulatedRequestState::DoFakeAE() { ae_target_exposure_time_ = GetClosestValue(static_cast<nsecs_t>(ae_target_exposure_time_ * std::pow(2, exposure_step)), - sensor_exposure_time_range_.first, - sensor_exposure_time_range_.second); - ae_state_ = ANDROID_CONTROL_AE_STATE_SEARCHING; + info.sensor_exposure_time_range_.first, + info.sensor_exposure_time_range_.second); + info.ae_state_ = ANDROID_CONTROL_AE_STATE_SEARCHING; } break; case ANDROID_CONTROL_AE_STATE_SEARCHING: @@ -257,16 +221,16 @@ status_t EmulatedRequestState::DoFakeAE() { if (abs(ae_target_exposure_time_ - current_exposure_time_) < ae_target_exposure_time_ / kAETargetThreshold) { // Close enough - ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; + info.ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; ae_frame_counter_ = 0; } break; case ANDROID_CONTROL_AE_STATE_LOCKED: - ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; + info.ae_state_ = ANDROID_CONTROL_AE_STATE_CONVERGED; ae_frame_counter_ = 0; break; default: - ALOGE("%s: Unexpected AE state %d!", __FUNCTION__, ae_state_); + ALOGE("%s: Unexpected AE state %d!", __FUNCTION__, info.ae_state_); return INVALID_OPERATION; } } @@ -275,30 +239,33 @@ status_t EmulatedRequestState::DoFakeAE() { } status_t EmulatedRequestState::ProcessAWB() { - if (max_awb_regions_ > 0) { - auto ret = Update3AMeteringRegion(ANDROID_CONTROL_AWB_REGIONS, - *request_settings_, awb_metering_region_); + auto& info = *device_info_; + + if (info.max_awb_regions_ > 0) { + auto ret = + Update3AMeteringRegion(ANDROID_CONTROL_AWB_REGIONS, *request_settings_, + info.awb_metering_region_); if (ret != OK) { return ret; } } - if (((awb_mode_ == ANDROID_CONTROL_AWB_MODE_OFF) || - (control_mode_ == ANDROID_CONTROL_MODE_OFF)) && - supports_manual_post_processing_) { + if (((info.awb_mode_ == ANDROID_CONTROL_AWB_MODE_OFF) || + (info.control_mode_ == ANDROID_CONTROL_MODE_OFF)) && + info.supports_manual_post_processing_) { // TODO: Add actual manual support - } else if (is_backward_compatible_) { + } else if (info.is_backward_compatible_) { camera_metadata_ro_entry_t entry; auto ret = request_settings_->Get(ANDROID_CONTROL_AWB_LOCK, &entry); if ((ret == OK) && (entry.count == 1)) { - awb_lock_ = entry.data.u8[0]; + info.awb_lock_ = entry.data.u8[0]; } else { - awb_lock_ = ANDROID_CONTROL_AWB_LOCK_OFF; + info.awb_lock_ = ANDROID_CONTROL_AWB_LOCK_OFF; } - if (awb_lock_ == ANDROID_CONTROL_AWB_LOCK_ON) { - awb_state_ = ANDROID_CONTROL_AWB_STATE_LOCKED; + if (info.awb_lock_ == ANDROID_CONTROL_AWB_LOCK_ON) { + info.awb_state_ = ANDROID_CONTROL_AWB_STATE_LOCKED; } else { - awb_state_ = ANDROID_CONTROL_AWB_STATE_CONVERGED; + info.awb_state_ = ANDROID_CONTROL_AWB_STATE_CONVERGED; } } else { // No color output support no need for AWB @@ -308,39 +275,41 @@ status_t EmulatedRequestState::ProcessAWB() { } status_t EmulatedRequestState::ProcessAF() { + auto& info = *device_info_; camera_metadata_ro_entry entry; - if (max_af_regions_ > 0) { - auto ret = Update3AMeteringRegion(ANDROID_CONTROL_AF_REGIONS, - *request_settings_, af_metering_region_); + if (info.max_af_regions_ > 0) { + auto ret = + Update3AMeteringRegion(ANDROID_CONTROL_AF_REGIONS, *request_settings_, + info.af_metering_region_); if (ret != OK) { return ret; } } - if (af_mode_ == ANDROID_CONTROL_AF_MODE_OFF) { + if (info.af_mode_ == ANDROID_CONTROL_AF_MODE_OFF) { camera_metadata_ro_entry_t entry; auto ret = request_settings_->Get(ANDROID_LENS_FOCUS_DISTANCE, &entry); if ((ret == OK) && (entry.count == 1)) { if ((entry.data.f[0] >= 0.f) && - (entry.data.f[0] <= minimum_focus_distance_)) { - focus_distance_ = entry.data.f[0]; + (entry.data.f[0] <= info.minimum_focus_distance_)) { + info.focus_distance_ = entry.data.f[0]; } else { ALOGE( "%s: Unsupported focus distance, It should be within " "[%5.2f, %5.2f]", - __FUNCTION__, 0.f, minimum_focus_distance_); + __FUNCTION__, 0.f, info.minimum_focus_distance_); } } - af_state_ = ANDROID_CONTROL_AF_STATE_INACTIVE; + info.af_state_ = ANDROID_CONTROL_AF_STATE_INACTIVE; return OK; } auto ret = request_settings_->Get(ANDROID_CONTROL_AF_TRIGGER, &entry); if ((ret == OK) && (entry.count == 1)) { - af_trigger_ = entry.data.u8[0]; + info.af_trigger_ = entry.data.u8[0]; } else { - af_trigger_ = ANDROID_CONTROL_AF_TRIGGER_IDLE; + info.af_trigger_ = ANDROID_CONTROL_AF_TRIGGER_IDLE; } /** @@ -349,7 +318,7 @@ status_t EmulatedRequestState::ProcessAF() { */ bool af_trigger_start = false; - switch (af_trigger_) { + switch (info.af_trigger_) { case ANDROID_CONTROL_AF_TRIGGER_IDLE: break; case ANDROID_CONTROL_AF_TRIGGER_START: @@ -357,7 +326,7 @@ status_t EmulatedRequestState::ProcessAF() { break; case ANDROID_CONTROL_AF_TRIGGER_CANCEL: // Cancel trigger always transitions into INACTIVE - af_state_ = ANDROID_CONTROL_AF_STATE_INACTIVE; + info.af_state_ = ANDROID_CONTROL_AF_STATE_INACTIVE; // Stay in 'inactive' until at least next frame return OK; @@ -370,29 +339,29 @@ status_t EmulatedRequestState::ProcessAF() { // ANDROID_CONTROL_AF_MODE_MACRO, ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO, // ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE and no other modes like // ANDROID_CONTROL_AF_MODE_OFF or ANDROID_CONTROL_AF_MODE_EDOF - switch (af_state_) { + switch (info.af_state_) { case ANDROID_CONTROL_AF_STATE_INACTIVE: if (af_trigger_start) { - switch (af_mode_) { + switch (info.af_mode_) { case ANDROID_CONTROL_AF_MODE_AUTO: // fall-through case ANDROID_CONTROL_AF_MODE_MACRO: - af_state_ = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; + info.af_state_ = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; break; case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: // fall-through case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; break; } } else { // At least one frame stays in INACTIVE if (!af_mode_changed_) { - switch (af_mode_) { + switch (info.af_mode_) { case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: // fall-through case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - af_state_ = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN; + info.af_state_ = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN; break; } } @@ -407,9 +376,9 @@ status_t EmulatedRequestState::ProcessAF() { if (af_trigger_start) { // Randomly transition to focused or not focused if (rand_r(&rand_seed_) % 3) { - af_state_ = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; } else { - af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; } } /** @@ -420,7 +389,7 @@ status_t EmulatedRequestState::ProcessAF() { else { // Randomly transition to passive focus if (rand_r(&rand_seed_) % 3 == 0) { - af_state_ = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED; } } @@ -429,9 +398,9 @@ status_t EmulatedRequestState::ProcessAF() { if (af_trigger_start) { // Randomly transition to focused or not focused if (rand_r(&rand_seed_) % 3) { - af_state_ = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; } else { - af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; } } // TODO: initiate passive scan (PASSIVE_SCAN) @@ -441,18 +410,18 @@ status_t EmulatedRequestState::ProcessAF() { // Randomly transition to focused or not focused if (rand_r(&rand_seed_) % 3) { - af_state_ = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; } else { - af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; + info.af_state_ = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; } break; case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED: if (af_trigger_start) { - switch (af_mode_) { + switch (info.af_mode_) { case ANDROID_CONTROL_AF_MODE_AUTO: // fall-through case ANDROID_CONTROL_AF_MODE_MACRO: - af_state_ = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; + info.af_state_ = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; break; case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: // fall-through @@ -464,11 +433,11 @@ status_t EmulatedRequestState::ProcessAF() { break; case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: if (af_trigger_start) { - switch (af_mode_) { + switch (info.af_mode_) { case ANDROID_CONTROL_AF_MODE_AUTO: // fall-through case ANDROID_CONTROL_AF_MODE_MACRO: - af_state_ = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; + info.af_state_ = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; break; case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: // fall-through @@ -479,16 +448,18 @@ status_t EmulatedRequestState::ProcessAF() { } break; default: - ALOGE("%s: Bad af state %d", __FUNCTION__, af_state_); + ALOGE("%s: Bad af state %d", __FUNCTION__, info.af_state_); } return OK; } status_t EmulatedRequestState::ProcessAE() { - if (max_ae_regions_ > 0) { - auto ret = Update3AMeteringRegion(ANDROID_CONTROL_AE_REGIONS, - *request_settings_, ae_metering_region_); + auto& info = *device_info_; + if (info.max_ae_regions_ > 0) { + auto ret = + Update3AMeteringRegion(ANDROID_CONTROL_AE_REGIONS, *request_settings_, + info.ae_metering_region_); if (ret != OK) { ALOGE("%s: Failed updating the 3A metering regions: %d, (%s)", __FUNCTION__, ret, strerror(-ret)); @@ -498,7 +469,7 @@ status_t EmulatedRequestState::ProcessAE() { camera_metadata_ro_entry_t entry; bool auto_ae_mode = false; bool auto_ae_flash_mode = false; - switch (ae_mode_) { + switch (info.ae_mode_) { case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH: case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH: case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: @@ -507,22 +478,20 @@ status_t EmulatedRequestState::ProcessAE() { case ANDROID_CONTROL_AE_MODE_ON: auto_ae_mode = true; }; - if (((ae_mode_ == ANDROID_CONTROL_AE_MODE_OFF) || - (control_mode_ == ANDROID_CONTROL_MODE_OFF)) && - supports_manual_sensor_) { + if (((info.ae_mode_ == ANDROID_CONTROL_AE_MODE_OFF) || + (info.control_mode_ == ANDROID_CONTROL_MODE_OFF)) && + info.supports_manual_sensor_) { auto ret = request_settings_->Get(ANDROID_SENSOR_EXPOSURE_TIME, &entry); if ((ret == OK) && (entry.count == 1)) { - if ((entry.data.i64[0] >= sensor_exposure_time_range_.first) && - (entry.data.i64[0] <= sensor_exposure_time_range_.second)) { - sensor_exposure_time_ = entry.data.i64[0]; + if ((entry.data.i64[0] >= info.sensor_exposure_time_range_.first) && + (entry.data.i64[0] <= info.sensor_exposure_time_range_.second)) { + info.sensor_exposure_time_ = entry.data.i64[0]; } else { - ALOGE( - "%s: Sensor exposure time %" PRId64 - " not within supported range[%" PRId64 ", %" PRId64 "]", - __FUNCTION__, - entry.data.i64[0], - sensor_exposure_time_range_.first, - sensor_exposure_time_range_.second); + ALOGE("%s: Sensor exposure time %" PRId64 + " not within supported range[%" PRId64 ", %" PRId64 "]", + __FUNCTION__, entry.data.i64[0], + info.sensor_exposure_time_range_.first, + info.sensor_exposure_time_range_.second); // Use last valid value } } @@ -531,38 +500,37 @@ status_t EmulatedRequestState::ProcessAE() { if ((ret == OK) && (entry.count == 1)) { if ((entry.data.i64[0] >= EmulatedSensor::kSupportedFrameDurationRange[0]) && - (entry.data.i64[0] <= sensor_max_frame_duration_)) { - sensor_frame_duration_ = entry.data.i64[0]; + (entry.data.i64[0] <= info.sensor_max_frame_duration_)) { + info.sensor_frame_duration_ = entry.data.i64[0]; } else { - ALOGE( - "%s: Sensor frame duration %" PRId64 - " not within supported range[%" PRId64 ", %" PRId64 "]", - __FUNCTION__, entry.data.i64[0], - EmulatedSensor::kSupportedFrameDurationRange[0], - sensor_max_frame_duration_); + ALOGE("%s: Sensor frame duration %" PRId64 + " not within supported range[%" PRId64 ", %" PRId64 "]", + __FUNCTION__, entry.data.i64[0], + EmulatedSensor::kSupportedFrameDurationRange[0], + info.sensor_max_frame_duration_); // Use last valid value } } - if (sensor_frame_duration_ < sensor_exposure_time_) { - sensor_frame_duration_ = sensor_exposure_time_; + if (info.sensor_frame_duration_ < info.sensor_exposure_time_) { + info.sensor_frame_duration_ = info.sensor_exposure_time_; } ret = request_settings_->Get(ANDROID_SENSOR_SENSITIVITY, &entry); if ((ret == OK) && (entry.count == 1)) { - if ((entry.data.i32[0] >= sensor_sensitivity_range_.first) && - (entry.data.i32[0] <= sensor_sensitivity_range_.second)) { - sensor_sensitivity_ = entry.data.i32[0]; + if ((entry.data.i32[0] >= info.sensor_sensitivity_range_.first) && + (entry.data.i32[0] <= info.sensor_sensitivity_range_.second)) { + info.sensor_sensitivity_ = entry.data.i32[0]; } else { ALOGE("%s: Sensor sensitivity %d not within supported range[%d, %d]", __FUNCTION__, entry.data.i32[0], - sensor_sensitivity_range_.first, - sensor_sensitivity_range_.second); + info.sensor_sensitivity_range_.first, + info.sensor_sensitivity_range_.second); // Use last valid value } } - ae_state_ = ANDROID_CONTROL_AE_STATE_INACTIVE; - } else if (is_backward_compatible_ && auto_ae_mode) { + info.ae_state_ = ANDROID_CONTROL_AE_STATE_INACTIVE; + } else if (info.is_backward_compatible_ && auto_ae_mode) { auto ret = DoFakeAE(); if (ret != OK) { ALOGE("%s: Failed fake AE: %d, (%s)", __FUNCTION__, ret, strerror(-ret)); @@ -580,8 +548,8 @@ status_t EmulatedRequestState::ProcessAE() { __FUNCTION__); } - if (is_flash_supported_) { - flash_state_ = ANDROID_FLASH_STATE_READY; + if (info.is_flash_supported_) { + info.flash_state_ = ANDROID_FLASH_STATE_READY; // Flash fires only if the request manually enables it (SINGLE/TORCH) // and the appropriate AE mode is set or during still capture with auto // flash AE modes. @@ -594,7 +562,7 @@ status_t EmulatedRequestState::ProcessAE() { } } if (manual_flash_mode && !auto_ae_flash_mode) { - flash_state_ = ANDROID_FLASH_STATE_FIRED; + info.flash_state_ = ANDROID_FLASH_STATE_FIRED; } else { bool is_still_capture = false; ret = request_settings_->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry); @@ -604,11 +572,11 @@ status_t EmulatedRequestState::ProcessAE() { } } if (is_still_capture && auto_ae_flash_mode) { - flash_state_ = ANDROID_FLASH_STATE_FIRED; + info.flash_state_ = ANDROID_FLASH_STATE_FIRED; } } } else { - flash_state_ = ANDROID_FLASH_STATE_UNAVAILABLE; + info.flash_state_ = ANDROID_FLASH_STATE_UNAVAILABLE; } return OK; @@ -618,6 +586,7 @@ status_t EmulatedRequestState::InitializeSensorSettings( std::unique_ptr<HalCameraMetadata> request_settings, uint32_t override_frame_number, EmulatedSensor::SensorSettings* sensor_settings /*out*/) { + auto& info = *device_info_; if ((sensor_settings == nullptr) || (request_settings.get() == nullptr)) { return BAD_VALUE; } @@ -627,9 +596,9 @@ status_t EmulatedRequestState::InitializeSensorSettings( camera_metadata_ro_entry_t entry; auto ret = request_settings_->Get(ANDROID_CONTROL_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_control_modes_.find(entry.data.u8[0]) != - available_control_modes_.end()) { - control_mode_ = entry.data.u8[0]; + if (info.available_control_modes_.find(entry.data.u8[0]) != + info.available_control_modes_.end()) { + info.control_mode_ = entry.data.u8[0]; } else { ALOGE("%s: Unsupported control mode!", __FUNCTION__); return BAD_VALUE; @@ -638,9 +607,9 @@ status_t EmulatedRequestState::InitializeSensorSettings( ret = request_settings_->Get(ANDROID_SENSOR_PIXEL_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_sensor_pixel_modes_.find(entry.data.u8[0]) != - available_sensor_pixel_modes_.end()) { - sensor_pixel_mode_ = entry.data.u8[0]; + if (info.available_sensor_pixel_modes_.find(entry.data.u8[0]) != + info.available_sensor_pixel_modes_.end()) { + info.sensor_pixel_mode_ = entry.data.u8[0]; } else { ALOGE("%s: Unsupported control sensor pixel mode!", __FUNCTION__); return BAD_VALUE; @@ -651,21 +620,22 @@ status_t EmulatedRequestState::InitializeSensorSettings( if ((ret == OK) && (entry.count == 1)) { // Disabled scene is not expected to be among the available scene list if ((entry.data.u8[0] == ANDROID_CONTROL_SCENE_MODE_DISABLED) || - (available_scenes_.find(entry.data.u8[0]) != available_scenes_.end())) { - scene_mode_ = entry.data.u8[0]; + (info.available_scenes_.find(entry.data.u8[0]) != + info.available_scenes_.end())) { + info.scene_mode_ = entry.data.u8[0]; } else { ALOGE("%s: Unsupported scene mode!", __FUNCTION__); return BAD_VALUE; } } - float min_zoom = min_zoom_, max_zoom = max_zoom_; + float min_zoom = info.min_zoom_, max_zoom = info.max_zoom_; ret = request_settings_->Get(ANDROID_CONTROL_EXTENDED_SCENE_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { bool extended_scene_mode_valid = false; - for (const auto& cap : available_extended_scene_mode_caps_) { + for (const auto& cap : info.available_extended_scene_mode_caps_) { if (cap.mode == entry.data.u8[0]) { - extended_scene_mode_ = entry.data.u8[0]; + info.extended_scene_mode_ = entry.data.u8[0]; min_zoom = cap.min_zoom; max_zoom = cap.max_zoom; extended_scene_mode_valid = true; @@ -677,21 +647,22 @@ status_t EmulatedRequestState::InitializeSensorSettings( entry.data.u8[0]); return BAD_VALUE; } - if (extended_scene_mode_ != ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED) { - scene_mode_ = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; + if (info.extended_scene_mode_ != + ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED) { + info.scene_mode_ = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; } } // Check zoom ratio range and override to supported range ret = request_settings_->Get(ANDROID_CONTROL_ZOOM_RATIO, &entry); if ((ret == OK) && (entry.count == 1)) { - zoom_ratio_ = std::min(std::max(entry.data.f[0], min_zoom), max_zoom); + info.zoom_ratio_ = std::min(std::max(entry.data.f[0], min_zoom), max_zoom); } // Check settings override ret = request_settings_->Get(ANDROID_CONTROL_SETTINGS_OVERRIDE, &entry); if ((ret == OK) && (entry.count == 1)) { - settings_override_ = entry.data.i32[0]; + info.settings_override_ = entry.data.i32[0]; } // Store settings override frame number @@ -702,9 +673,9 @@ status_t EmulatedRequestState::InitializeSensorSettings( // Check rotate_and_crop setting ret = request_settings_->Get(ANDROID_SCALER_ROTATE_AND_CROP, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_rotate_crop_modes_.find(entry.data.u8[0]) != - available_rotate_crop_modes_.end()) { - rotate_and_crop_ = entry.data.u8[0]; + if (info.available_rotate_crop_modes_.find(entry.data.u8[0]) != + info.available_rotate_crop_modes_.end()) { + info.rotate_and_crop_ = entry.data.u8[0]; } else { ALOGE("%s: Unsupported rotate and crop mode: %u", __FUNCTION__, entry.data.u8[0]); return BAD_VALUE; @@ -715,8 +686,8 @@ status_t EmulatedRequestState::InitializeSensorSettings( uint8_t vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; ret = request_settings_->Get(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_vstab_modes_.find(entry.data.u8[0]) != - available_vstab_modes_.end()) { + if (info.available_vstab_modes_.find(entry.data.u8[0]) != + info.available_vstab_modes_.end()) { vstab_mode = entry.data.u8[0]; } else { ALOGE("%s: Unsupported video stabilization mode: %u! Video stabilization will be disabled!", @@ -727,10 +698,10 @@ status_t EmulatedRequestState::InitializeSensorSettings( // Check autoframing ret = request_settings_->Get(ANDROID_CONTROL_AUTOFRAMING, &entry); if ((ret == OK) && (entry.count == 1)) { - autoframing_ = entry.data.i32[0]; - if (autoframing_ == ANDROID_CONTROL_AUTOFRAMING_ON) { + info.autoframing_ = entry.data.i32[0]; + if (info.autoframing_ == ANDROID_CONTROL_AUTOFRAMING_ON) { // Set zoom_ratio to be a hard-coded value to test autoframing. - zoom_ratio_ = 1.7f; + info.zoom_ratio_ = 1.7f; vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; } } @@ -738,23 +709,24 @@ status_t EmulatedRequestState::InitializeSensorSettings( // Check manual flash strength level ret = request_settings_->Get(ANDROID_FLASH_STRENGTH_LEVEL, &entry); if ((ret == OK) && (entry.count == 1)) { - flash_strength_level_ = entry.data.i32[0]; + info.flash_strength_level_ = entry.data.i32[0]; if (ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL > 1 && - ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL > 1 && is_flash_supported_) { + ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL > 1 && info.is_flash_supported_) { ALOGI("%s: Device supports manual flash strength control", __FUNCTION__); - flash_strength_level_ = entry.data.i32[0]; + info.flash_strength_level_ = entry.data.i32[0]; } else { - ALOGI("%s: Device does not support manual flash strength control", __FUNCTION__); - return BAD_VALUE; - } + ALOGI("%s: Device does not support manual flash strength control", + __FUNCTION__); + return BAD_VALUE; } + } // Check video stabilization parameter uint8_t edge_mode = ANDROID_EDGE_MODE_OFF; ret = request_settings_->Get(ANDROID_EDGE_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_edge_modes_.find(entry.data.u8[0]) != - available_edge_modes_.end()) { + if (info.available_edge_modes_.find(entry.data.u8[0]) != + info.available_edge_modes_.end()) { edge_mode = entry.data.u8[0]; } else { ALOGE("%s: Unsupported edge mode: %u", __FUNCTION__, entry.data.u8[0]); @@ -766,8 +738,8 @@ status_t EmulatedRequestState::InitializeSensorSettings( uint8_t test_pattern_mode = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; ret = request_settings_->Get(ANDROID_SENSOR_TEST_PATTERN_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_test_pattern_modes_.find(entry.data.u8[0]) != - available_test_pattern_modes_.end()) { + if (info.available_test_pattern_modes_.find(entry.data.u8[0]) != + info.available_test_pattern_modes_.end()) { test_pattern_mode = entry.data.u8[0]; } else { ALOGE("%s: Unsupported test pattern mode: %u", __FUNCTION__, @@ -790,14 +762,14 @@ status_t EmulatedRequestState::InitializeSensorSettings( // 3A modes are active in case the scene is disabled or set to face priority // or the control mode is not using scenes - if ((scene_mode_ == ANDROID_CONTROL_SCENE_MODE_DISABLED) || - (scene_mode_ == ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY) || - (control_mode_ != ANDROID_CONTROL_MODE_USE_SCENE_MODE)) { + if ((info.scene_mode_ == ANDROID_CONTROL_SCENE_MODE_DISABLED) || + (info.scene_mode_ == ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY) || + (info.control_mode_ != ANDROID_CONTROL_MODE_USE_SCENE_MODE)) { ret = request_settings_->Get(ANDROID_CONTROL_AE_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_ae_modes_.find(entry.data.u8[0]) != - available_ae_modes_.end()) { - ae_mode_ = entry.data.u8[0]; + if (info.available_ae_modes_.find(entry.data.u8[0]) != + info.available_ae_modes_.end()) { + info.ae_mode_ = entry.data.u8[0]; } else { ALOGE("%s: Unsupported AE mode! Using last valid mode!", __FUNCTION__); } @@ -805,9 +777,9 @@ status_t EmulatedRequestState::InitializeSensorSettings( ret = request_settings_->Get(ANDROID_CONTROL_AWB_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_awb_modes_.find(entry.data.u8[0]) != - available_awb_modes_.end()) { - awb_mode_ = entry.data.u8[0]; + if (info.available_awb_modes_.find(entry.data.u8[0]) != + info.available_awb_modes_.end()) { + info.awb_mode_ = entry.data.u8[0]; } else { ALOGE("%s: Unsupported AWB mode! Using last valid mode!", __FUNCTION__); } @@ -815,21 +787,21 @@ status_t EmulatedRequestState::InitializeSensorSettings( ret = request_settings_->Get(ANDROID_CONTROL_AF_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_af_modes_.find(entry.data.u8[0]) != - available_af_modes_.end()) { - af_mode_changed_ = af_mode_ != entry.data.u8[0]; - af_mode_ = entry.data.u8[0]; + if (info.available_af_modes_.find(entry.data.u8[0]) != + info.available_af_modes_.end()) { + af_mode_changed_ = info.af_mode_ != entry.data.u8[0]; + info.af_mode_ = entry.data.u8[0]; } else { ALOGE("%s: Unsupported AF mode! Using last valid mode!", __FUNCTION__); } } } else { - auto it = scene_overrides_.find(scene_mode_); - if (it != scene_overrides_.end()) { - ae_mode_ = it->second.ae_mode; - awb_mode_ = it->second.awb_mode; - af_mode_changed_ = af_mode_ != entry.data.u8[0]; - af_mode_ = it->second.af_mode; + auto it = info.scene_overrides_.find(info.scene_mode_); + if (it != info.scene_overrides_.end()) { + info.ae_mode_ = it->second.ae_mode; + info.awb_mode_ = it->second.awb_mode; + af_mode_changed_ = info.af_mode_ != entry.data.u8[0]; + info.af_mode_ = it->second.af_mode; } else { ALOGW( "%s: Current scene has no overrides! Using the currently active 3A " @@ -855,39 +827,39 @@ status_t EmulatedRequestState::InitializeSensorSettings( ret = request_settings_->Get(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &entry); if ((ret == OK) && (entry.count == 1)) { - if (available_lens_shading_map_modes_.find(entry.data.u8[0]) != - available_lens_shading_map_modes_.end()) { + if (info.available_lens_shading_map_modes_.find(entry.data.u8[0]) != + info.available_lens_shading_map_modes_.end()) { sensor_settings->lens_shading_map_mode = entry.data.u8[0]; } else { ALOGE("%s: Unsupported lens shading map mode!", __FUNCTION__); } } - ret = static_metadata_->Get(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, &entry); + ret = info.static_metadata_->Get(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, &entry); if ((ret == OK) && (entry.count == 1)) { if (entry.data.u8[0] == ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) { - timestamp_source_ = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME; + info.timestamp_source_ = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME; } else if (entry.data.u8[0] != ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN) { ALOGE("%s: Unsupported timestamp source", __FUNCTION__); } } - sensor_settings->exposure_time = sensor_exposure_time_; - sensor_settings->frame_duration = sensor_frame_duration_; - sensor_settings->gain = sensor_sensitivity_; - sensor_settings->report_neutral_color_point = report_neutral_color_point_; - sensor_settings->report_green_split = report_green_split_; - sensor_settings->report_noise_profile = report_noise_profile_; - sensor_settings->zoom_ratio = zoom_ratio_; - sensor_settings->report_rotate_and_crop = report_rotate_and_crop_; - sensor_settings->rotate_and_crop = rotate_and_crop_; - sensor_settings->report_video_stab = !available_vstab_modes_.empty(); + sensor_settings->exposure_time = info.sensor_exposure_time_; + sensor_settings->frame_duration = info.sensor_frame_duration_; + sensor_settings->gain = info.sensor_sensitivity_; + sensor_settings->report_neutral_color_point = info.report_neutral_color_point_; + sensor_settings->report_green_split = info.report_green_split_; + sensor_settings->report_noise_profile = info.report_noise_profile_; + sensor_settings->zoom_ratio = info.zoom_ratio_; + sensor_settings->report_rotate_and_crop = info.report_rotate_and_crop_; + sensor_settings->rotate_and_crop = info.rotate_and_crop_; + sensor_settings->report_video_stab = !info.available_vstab_modes_.empty(); sensor_settings->video_stab = vstab_mode; - sensor_settings->report_edge_mode = report_edge_mode_; + sensor_settings->report_edge_mode = info.report_edge_mode_; sensor_settings->edge_mode = edge_mode; - sensor_settings->sensor_pixel_mode = sensor_pixel_mode_; + sensor_settings->sensor_pixel_mode = info.sensor_pixel_mode_; sensor_settings->test_pattern_mode = test_pattern_mode; - sensor_settings->timestamp_source = timestamp_source_; + sensor_settings->timestamp_source = info.timestamp_source_; memcpy(sensor_settings->test_pattern_data, test_pattern_data, sizeof(sensor_settings->test_pattern_data)); @@ -896,11 +868,12 @@ status_t EmulatedRequestState::InitializeSensorSettings( uint32_t EmulatedRequestState::GetPartialResultCount(bool is_partial_result) { uint32_t res = 0; + auto& info = *device_info_; if (is_partial_result) { res = 1; } else { - res = partial_result_count ? partial_result_count : 1; + res = info.partial_result_count_ ? info.partial_result_count_ : 1; } return res; @@ -908,10 +881,11 @@ uint32_t EmulatedRequestState::GetPartialResultCount(bool is_partial_result) { std::unique_ptr<HwlPipelineResult> EmulatedRequestState::InitializePartialResult( uint32_t pipeline_id, uint32_t frame_number) { + auto& info = *device_info_; std::lock_guard<std::mutex> lock(request_state_mutex_); auto result = std::make_unique<HwlPipelineResult>(); - if (partial_result_count > 1) { + if (info.partial_result_count_ > 1) { result->camera_id = camera_id_; result->pipeline_id = pipeline_id; result->frame_number = frame_number; @@ -924,6 +898,7 @@ std::unique_ptr<HwlPipelineResult> EmulatedRequestState::InitializePartialResult std::unique_ptr<HwlPipelineResult> EmulatedRequestState::InitializeResult( uint32_t pipeline_id, uint32_t frame_number) { + auto& info = *device_info_; std::lock_guard<std::mutex> lock(request_state_mutex_); auto result = std::make_unique<HwlPipelineResult>(); result->camera_id = camera_id_; @@ -934,20 +909,20 @@ std::unique_ptr<HwlPipelineResult> EmulatedRequestState::InitializeResult( // Results supported on all emulated devices result->result_metadata->Set(ANDROID_REQUEST_PIPELINE_DEPTH, - &max_pipeline_depth_, 1); - result->result_metadata->Set(ANDROID_CONTROL_MODE, &control_mode_, 1); - result->result_metadata->Set(ANDROID_SENSOR_PIXEL_MODE, &sensor_pixel_mode_, - 1); - - result->result_metadata->Set(ANDROID_CONTROL_AF_MODE, &af_mode_, 1); - result->result_metadata->Set(ANDROID_CONTROL_AF_STATE, &af_state_, 1); - result->result_metadata->Set(ANDROID_CONTROL_AWB_MODE, &awb_mode_, 1); - result->result_metadata->Set(ANDROID_CONTROL_AWB_STATE, &awb_state_, 1); - result->result_metadata->Set(ANDROID_CONTROL_AE_MODE, &ae_mode_, 1); - result->result_metadata->Set(ANDROID_CONTROL_AE_STATE, &ae_state_, 1); + &info.max_pipeline_depth_, 1); + result->result_metadata->Set(ANDROID_CONTROL_MODE, &info.control_mode_, 1); + result->result_metadata->Set(ANDROID_SENSOR_PIXEL_MODE, + &info.sensor_pixel_mode_, 1); + + result->result_metadata->Set(ANDROID_CONTROL_AF_MODE, &info.af_mode_, 1); + result->result_metadata->Set(ANDROID_CONTROL_AF_STATE, &info.af_state_, 1); + result->result_metadata->Set(ANDROID_CONTROL_AWB_MODE, &info.awb_mode_, 1); + result->result_metadata->Set(ANDROID_CONTROL_AWB_STATE, &info.awb_state_, 1); + result->result_metadata->Set(ANDROID_CONTROL_AE_MODE, &info.ae_mode_, 1); + result->result_metadata->Set(ANDROID_CONTROL_AE_STATE, &info.ae_state_, 1); // If the overriding frame number isn't larger than current frame number, // use 0. - int32_t settings_override = settings_override_; + int32_t settings_override = info.settings_override_; uint32_t overriding_frame_number = settings_overriding_frame_number_; if (overriding_frame_number <= frame_number) { overriding_frame_number = frame_number; @@ -957,2074 +932,164 @@ std::unique_ptr<HwlPipelineResult> EmulatedRequestState::InitializeResult( &settings_override, 1); result->result_metadata->Set(ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER, (int32_t*)&overriding_frame_number, 1); - result->result_metadata->Set(ANDROID_CONTROL_AUTOFRAMING, &autoframing_, 1); + result->result_metadata->Set(ANDROID_CONTROL_AUTOFRAMING, &info.autoframing_, + 1); uint8_t autoframing_state = ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE; - if (autoframing_ == ANDROID_CONTROL_AUTOFRAMING_ON) { + if (info.autoframing_ == ANDROID_CONTROL_AUTOFRAMING_ON) { autoframing_state = ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED; } result->result_metadata->Set(ANDROID_CONTROL_AUTOFRAMING_STATE, &autoframing_state, 1); - int32_t fps_range[] = {ae_target_fps_.min_fps, ae_target_fps_.max_fps}; + int32_t fps_range[] = {info.ae_target_fps_.min_fps, + info.ae_target_fps_.max_fps}; result->result_metadata->Set(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, fps_range, ARRAY_SIZE(fps_range)); - result->result_metadata->Set(ANDROID_FLASH_STATE, &flash_state_, 1); - result->result_metadata->Set(ANDROID_LENS_STATE, &lens_state_, 1); + result->result_metadata->Set(ANDROID_FLASH_STATE, &info.flash_state_, 1); + result->result_metadata->Set(ANDROID_LENS_STATE, &info.lens_state_, 1); // Results depending on device capability and features - if (is_backward_compatible_) { + if (info.is_backward_compatible_) { result->result_metadata->Set(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, - &ae_trigger_, 1); - result->result_metadata->Set(ANDROID_CONTROL_AF_TRIGGER, &af_trigger_, 1); + &info.ae_trigger_, 1); + result->result_metadata->Set(ANDROID_CONTROL_AF_TRIGGER, &info.af_trigger_, + 1); uint8_t vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; result->result_metadata->Set(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstab_mode, 1); - if (exposure_compensation_supported_) { + if (info.exposure_compensation_supported_) { result->result_metadata->Set(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, - &exposure_compensation_, 1); + &info.exposure_compensation_, 1); } } - if (ae_lock_available_ && report_ae_lock_) { - result->result_metadata->Set(ANDROID_CONTROL_AE_LOCK, &ae_lock_, 1); + if (info.ae_lock_available_ && info.report_ae_lock_) { + result->result_metadata->Set(ANDROID_CONTROL_AE_LOCK, &info.ae_lock_, 1); } - if (awb_lock_available_ && report_awb_lock_) { - result->result_metadata->Set(ANDROID_CONTROL_AWB_LOCK, &awb_lock_, 1); + if (info.awb_lock_available_ && info.report_awb_lock_) { + result->result_metadata->Set(ANDROID_CONTROL_AWB_LOCK, &info.awb_lock_, 1); } - if (scenes_supported_) { - result->result_metadata->Set(ANDROID_CONTROL_SCENE_MODE, &scene_mode_, 1); + if (info.scenes_supported_) { + result->result_metadata->Set(ANDROID_CONTROL_SCENE_MODE, &info.scene_mode_, + 1); } - if (max_ae_regions_ > 0) { - result->result_metadata->Set(ANDROID_CONTROL_AE_REGIONS, ae_metering_region_, - ARRAY_SIZE(ae_metering_region_)); + if (info.max_ae_regions_ > 0) { + result->result_metadata->Set(ANDROID_CONTROL_AE_REGIONS, + info.ae_metering_region_, + ARRAY_SIZE(info.ae_metering_region_)); } - if (max_awb_regions_ > 0) { + if (info.max_awb_regions_ > 0) { result->result_metadata->Set(ANDROID_CONTROL_AWB_REGIONS, - awb_metering_region_, - ARRAY_SIZE(awb_metering_region_)); + info.awb_metering_region_, + ARRAY_SIZE(info.awb_metering_region_)); } - if (max_af_regions_ > 0) { - result->result_metadata->Set(ANDROID_CONTROL_AF_REGIONS, af_metering_region_, - ARRAY_SIZE(af_metering_region_)); + if (info.max_af_regions_ > 0) { + result->result_metadata->Set(ANDROID_CONTROL_AF_REGIONS, + info.af_metering_region_, + ARRAY_SIZE(info.af_metering_region_)); } - if (report_exposure_time_) { + if (info.report_exposure_time_) { result->result_metadata->Set(ANDROID_SENSOR_EXPOSURE_TIME, - &sensor_exposure_time_, 1); + &info.sensor_exposure_time_, 1); } else { result->result_metadata->Erase(ANDROID_SENSOR_EXPOSURE_TIME); } - if (report_frame_duration_) { + if (info.report_frame_duration_) { result->result_metadata->Set(ANDROID_SENSOR_FRAME_DURATION, - &sensor_frame_duration_, 1); + &info.sensor_frame_duration_, 1); } else { result->result_metadata->Erase(ANDROID_SENSOR_FRAME_DURATION); } - if (report_sensitivity_) { + if (info.report_sensitivity_) { result->result_metadata->Set(ANDROID_SENSOR_SENSITIVITY, - &sensor_sensitivity_, 1); + &info.sensor_sensitivity_, 1); } else { result->result_metadata->Erase(ANDROID_SENSOR_SENSITIVITY); } - if (report_rolling_shutter_skew_) { + if (info.report_rolling_shutter_skew_) { result->result_metadata->Set( ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, &EmulatedSensor::kSupportedFrameDurationRange[0], 1); } - if (report_post_raw_boost_) { + if (info.report_post_raw_boost_) { result->result_metadata->Set(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, - &post_raw_boost_, 1); + &info.post_raw_boost_, 1); } - if (report_focus_distance_) { - result->result_metadata->Set(ANDROID_LENS_FOCUS_DISTANCE, &focus_distance_, - 1); + if (info.report_focus_distance_) { + result->result_metadata->Set(ANDROID_LENS_FOCUS_DISTANCE, + &info.focus_distance_, 1); } - if (report_focus_range_) { + if (info.report_focus_range_) { float focus_range[2] = {}; - focus_range[0] = focus_distance_; + focus_range[0] = info.focus_distance_; result->result_metadata->Set(ANDROID_LENS_FOCUS_RANGE, focus_range, ARRAY_SIZE(focus_range)); } - if (report_filter_density_) { - result->result_metadata->Set(ANDROID_LENS_FILTER_DENSITY, &filter_density_, - 1); + if (info.report_filter_density_) { + result->result_metadata->Set(ANDROID_LENS_FILTER_DENSITY, + &info.filter_density_, 1); } - if (report_ois_mode_) { + if (info.report_ois_mode_) { result->result_metadata->Set(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, - &ois_mode_, 1); + &info.ois_mode_, 1); } - if (report_pose_rotation_) { - result->result_metadata->Set(ANDROID_LENS_POSE_ROTATION, pose_rotation_, - ARRAY_SIZE(pose_rotation_)); + if (info.report_pose_rotation_) { + result->result_metadata->Set(ANDROID_LENS_POSE_ROTATION, info.pose_rotation_, + ARRAY_SIZE(info.pose_rotation_)); } - if (report_pose_translation_) { + if (info.report_pose_translation_) { result->result_metadata->Set(ANDROID_LENS_POSE_TRANSLATION, - pose_translation_, - ARRAY_SIZE(pose_translation_)); + info.pose_translation_, + ARRAY_SIZE(info.pose_translation_)); } - if (report_intrinsic_calibration_) { + if (info.report_intrinsic_calibration_) { result->result_metadata->Set(ANDROID_LENS_INTRINSIC_CALIBRATION, - intrinsic_calibration_, - ARRAY_SIZE(intrinsic_calibration_)); + info.intrinsic_calibration_, + ARRAY_SIZE(info.intrinsic_calibration_)); } - if (report_lens_intrinsics_samples_) { + if (info.report_lens_intrinsics_samples_) { result->result_metadata->Set(ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES, - intrinsic_calibration_, - ARRAY_SIZE(intrinsic_calibration_)); + info.intrinsic_calibration_, + ARRAY_SIZE(info.intrinsic_calibration_)); } - if (report_distortion_) { - result->result_metadata->Set(ANDROID_LENS_DISTORTION, distortion_, - ARRAY_SIZE(distortion_)); + if (info.report_distortion_) { + result->result_metadata->Set(ANDROID_LENS_DISTORTION, info.distortion_, + ARRAY_SIZE(info.distortion_)); } - if (report_black_level_lock_) { - result->result_metadata->Set(ANDROID_BLACK_LEVEL_LOCK, &black_level_lock_, - 1); + if (info.report_black_level_lock_) { + result->result_metadata->Set(ANDROID_BLACK_LEVEL_LOCK, + &info.black_level_lock_, 1); } - if (report_scene_flicker_) { + if (info.report_scene_flicker_) { result->result_metadata->Set(ANDROID_STATISTICS_SCENE_FLICKER, - ¤t_scene_flicker_, 1); + &info.current_scene_flicker_, 1); } - if (zoom_ratio_supported_) { - result->result_metadata->Set(ANDROID_CONTROL_ZOOM_RATIO, &zoom_ratio_, 1); - int32_t* chosen_crop_region = scaler_crop_region_default_; - if (sensor_pixel_mode_ == ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) { - chosen_crop_region = scaler_crop_region_max_resolution_; + if (info.zoom_ratio_supported_) { + result->result_metadata->Set(ANDROID_CONTROL_ZOOM_RATIO, &info.zoom_ratio_, + 1); + int32_t* chosen_crop_region = info.scaler_crop_region_default_; + if (info.sensor_pixel_mode_ == ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) { + chosen_crop_region = info.scaler_crop_region_max_resolution_; } result->result_metadata->Set(ANDROID_SCALER_CROP_REGION, chosen_crop_region, - ARRAY_SIZE(scaler_crop_region_default_)); - if (report_active_sensor_crop_) { + ARRAY_SIZE(info.scaler_crop_region_default_)); + if (info.report_active_sensor_crop_) { result->result_metadata->Set( ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION, - chosen_crop_region, ARRAY_SIZE(scaler_crop_region_default_)); + chosen_crop_region, ARRAY_SIZE(info.scaler_crop_region_default_)); } } - if (report_extended_scene_mode_) { + if (info.report_extended_scene_mode_) { result->result_metadata->Set(ANDROID_CONTROL_EXTENDED_SCENE_MODE, - &extended_scene_mode_, 1); + &info.extended_scene_mode_, 1); } return result; } -bool EmulatedRequestState::SupportsCapability(uint8_t cap) { - return available_capabilities_.find(cap) != available_capabilities_.end(); -} - -status_t EmulatedRequestState::InitializeSensorDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = - static_metadata_->Get(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, &entry); - if ((ret == OK) && (entry.count == 2)) { - sensor_sensitivity_range_ = - std::make_pair(entry.data.i32[0], entry.data.i32[1]); - } else if (!supports_manual_sensor_) { - sensor_sensitivity_range_ = - std::make_pair(EmulatedSensor::kSupportedSensitivityRange[0], - EmulatedSensor::kSupportedSensitivityRange[1]); - } else { - ALOGE("%s: Manual sensor devices must advertise sensor sensitivity range!", - __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, &entry); - if ((ret == OK) && (entry.count == 2)) { - sensor_exposure_time_range_ = - std::make_pair(entry.data.i64[0], entry.data.i64[1]); - } else if (!supports_manual_sensor_) { - sensor_exposure_time_range_ = - std::make_pair(EmulatedSensor::kSupportedExposureTimeRange[0], - EmulatedSensor::kSupportedExposureTimeRange[1]); - } else { - ALOGE( - "%s: Manual sensor devices must advertise sensor exposure time range!", - __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &entry); - if ((ret == OK) && (entry.count == 1)) { - sensor_max_frame_duration_ = entry.data.i64[0]; - } else if (!supports_manual_sensor_) { - sensor_max_frame_duration_ = EmulatedSensor::kSupportedFrameDurationRange[1]; - } else { - ALOGE("%s: Manual sensor devices must advertise sensor max frame duration!", - __FUNCTION__); - return BAD_VALUE; - } - - if (supports_manual_sensor_) { - if (available_requests_.find(ANDROID_SENSOR_SENSITIVITY) == - available_requests_.end()) { - ALOGE( - "%s: Sensor sensitivity must be configurable on manual sensor " - "devices!", - __FUNCTION__); - return BAD_VALUE; - } - - if (available_requests_.find(ANDROID_SENSOR_EXPOSURE_TIME) == - available_requests_.end()) { - ALOGE( - "%s: Sensor exposure time must be configurable on manual sensor " - "devices!", - __FUNCTION__); - return BAD_VALUE; - } - - if (available_requests_.find(ANDROID_SENSOR_FRAME_DURATION) == - available_requests_.end()) { - ALOGE( - "%s: Sensor frame duration must be configurable on manual sensor " - "devices!", - __FUNCTION__); - return BAD_VALUE; - } - } - - report_rolling_shutter_skew_ = - available_results_.find(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW) != - available_results_.end(); - report_sensitivity_ = available_results_.find(ANDROID_SENSOR_SENSITIVITY) != - available_results_.end(); - report_exposure_time_ = - available_results_.find(ANDROID_SENSOR_EXPOSURE_TIME) != - available_results_.end(); - report_frame_duration_ = - available_results_.find(ANDROID_SENSOR_FRAME_DURATION) != - available_results_.end(); - report_neutral_color_point_ = - available_results_.find(ANDROID_SENSOR_NEUTRAL_COLOR_POINT) != - available_results_.end(); - report_green_split_ = available_results_.find(ANDROID_SENSOR_GREEN_SPLIT) != - available_results_.end(); - report_noise_profile_ = - available_results_.find(ANDROID_SENSOR_NOISE_PROFILE) != - available_results_.end(); - - if (is_raw_capable_ && !report_green_split_) { - ALOGE("%s: RAW capable devices must be able to report the noise profile!", - __FUNCTION__); - return BAD_VALUE; - } - - if (is_raw_capable_ && !report_neutral_color_point_) { - ALOGE( - "%s: RAW capable devices must be able to report the neutral color " - "point!", - __FUNCTION__); - return BAD_VALUE; - } - - if (is_raw_capable_ && !report_green_split_) { - ALOGE("%s: RAW capable devices must be able to report the green split!", - __FUNCTION__); - return BAD_VALUE; - } - if (available_results_.find(ANDROID_SENSOR_TIMESTAMP) == - available_results_.end()) { - ALOGE("%s: Sensor timestamp must always be part of the results!", - __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, - &entry); - if (ret == OK) { - available_test_pattern_modes_.insert(entry.data.i32, - entry.data.i32 + entry.count); - } else { - ALOGE("%s: No available test pattern modes!", __FUNCTION__); - return BAD_VALUE; - } - - sensor_exposure_time_ = GetClosestValue(EmulatedSensor::kDefaultExposureTime, - sensor_exposure_time_range_.first, - sensor_exposure_time_range_.second); - sensor_frame_duration_ = - GetClosestValue(EmulatedSensor::kDefaultFrameDuration, - EmulatedSensor::kSupportedFrameDurationRange[0], - sensor_max_frame_duration_); - sensor_sensitivity_ = GetClosestValue(EmulatedSensor::kDefaultSensitivity, - sensor_sensitivity_range_.first, - sensor_sensitivity_range_.second); - - bool off_test_pattern_mode_supported = - available_test_pattern_modes_.find(ANDROID_SENSOR_TEST_PATTERN_MODE_OFF) != - available_test_pattern_modes_.end(); - int32_t test_pattern_mode = (off_test_pattern_mode_supported) - ? ANDROID_SENSOR_TEST_PATTERN_MODE_OFF - : *available_test_pattern_modes_.begin(); - int32_t test_pattern_data[4] = {0, 0, 0, 0}; - - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - default_requests_[idx]->Set(ANDROID_SENSOR_EXPOSURE_TIME, - &sensor_exposure_time_, 1); - default_requests_[idx]->Set(ANDROID_SENSOR_FRAME_DURATION, - &sensor_frame_duration_, 1); - default_requests_[idx]->Set(ANDROID_SENSOR_SENSITIVITY, - &sensor_sensitivity_, 1); - default_requests_[idx]->Set(ANDROID_SENSOR_TEST_PATTERN_MODE, - &test_pattern_mode, 1); - default_requests_[idx]->Set(ANDROID_SENSOR_TEST_PATTERN_DATA, - test_pattern_data, 4); - } - - return OK; -} - -status_t EmulatedRequestState::InitializeStatisticsDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get( - ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, &entry); - if (ret == OK) { - available_face_detect_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available face detect modes!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get( - ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, &entry); - if (ret == OK) { - available_lens_shading_map_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available lens shading modes!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get( - ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, &entry); - if (ret == OK) { - available_hot_pixel_map_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else if (is_raw_capable_) { - ALOGE("%s: RAW capable device must support hot pixel map modes!", - __FUNCTION__); - return BAD_VALUE; - } else { - available_hot_pixel_map_modes_.emplace( - ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF); - } - - bool hot_pixel_mode_off_supported = - available_hot_pixel_map_modes_.find( - ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF) != - available_hot_pixel_map_modes_.end(); - bool face_detect_mode_off_supported = - available_face_detect_modes_.find( - ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) != - available_face_detect_modes_.end(); - bool lens_shading_map_mode_off_supported = - available_lens_shading_map_modes_.find( - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON) != - available_lens_shading_map_modes_.end(); - bool lens_shading_map_mode_on_supported = - available_lens_shading_map_modes_.find( - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON) != - available_lens_shading_map_modes_.end(); - if (is_raw_capable_ && !lens_shading_map_mode_on_supported) { - ALOGE("%s: RAW capable device must support lens shading map reporting!", - __FUNCTION__); - return BAD_VALUE; - } - - if (lens_shading_map_mode_on_supported && - (available_results_.find(ANDROID_STATISTICS_LENS_SHADING_MAP) == - available_results_.end())) { - ALOGE( - "%s: Lens shading map reporting available but corresponding result key " - "is absent!", - __FUNCTION__); - return BAD_VALUE; - } - - if (lens_shading_map_mode_on_supported && - ((shading_map_size_[0] == 0) || (shading_map_size_[1] == 0))) { - ALOGE( - "%s: Lens shading map reporting available but without valid shading " - "map size!", - __FUNCTION__); - return BAD_VALUE; - } - - report_lens_intrinsics_samples_ = - (available_results_.find(ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES) != - available_results_.end()) && - (available_results_.find(ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS) != - available_results_.end()); - report_scene_flicker_ = - available_results_.find(ANDROID_STATISTICS_SCENE_FLICKER) != - available_results_.end(); - - uint8_t face_detect_mode = face_detect_mode_off_supported - ? ANDROID_STATISTICS_FACE_DETECT_MODE_OFF - : *available_face_detect_modes_.begin(); - uint8_t hot_pixel_map_mode = hot_pixel_mode_off_supported - ? ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF - : *available_hot_pixel_map_modes_.begin(); - uint8_t lens_shading_map_mode = - lens_shading_map_mode_off_supported - ? ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF - : *available_lens_shading_map_modes_.begin(); - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - if ((static_cast<RequestTemplate>(idx) == RequestTemplate::kStillCapture) && - is_raw_capable_ && lens_shading_map_mode_on_supported) { - uint8_t lens_shading_map_on = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON; - default_requests_[idx]->Set(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, - &lens_shading_map_on, 1); - } else { - default_requests_[idx]->Set(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, - &lens_shading_map_mode, 1); - } - - default_requests_[idx]->Set(ANDROID_STATISTICS_FACE_DETECT_MODE, - &face_detect_mode, 1); - default_requests_[idx]->Set(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, - &hot_pixel_map_mode, 1); - } - - return InitializeBlackLevelDefaults(); -} - -status_t EmulatedRequestState::InitializeControlSceneDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = - static_metadata_->Get(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, &entry); - if (ret == OK) { - available_scenes_.insert(entry.data.u8, entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available scene modes!", __FUNCTION__); - return BAD_VALUE; - } - - if ((entry.count == 1) && - (entry.data.u8[0] == ANDROID_CONTROL_SCENE_MODE_DISABLED)) { - scenes_supported_ = false; - return OK; - } else { - scenes_supported_ = true; - } - - if (available_requests_.find(ANDROID_CONTROL_SCENE_MODE) == - available_requests_.end()) { - ALOGE("%s: Scene mode cannot be set!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_SCENE_MODE) == - available_results_.end()) { - ALOGE("%s: Scene mode cannot be reported!", __FUNCTION__); - return BAD_VALUE; - } - - camera_metadata_ro_entry_t overrides_entry; - ret = static_metadata_->Get(ANDROID_CONTROL_SCENE_MODE_OVERRIDES, - &overrides_entry); - if ((ret == OK) && ((overrides_entry.count / 3) == available_scenes_.size()) && - ((overrides_entry.count % 3) == 0)) { - for (size_t i = 0; i < entry.count; i++) { - SceneOverride scene(overrides_entry.data.u8[i*3], - overrides_entry.data.u8[i*3 + 1], - overrides_entry.data.u8[i*3 + 2]); - if (available_ae_modes_.find(scene.ae_mode) == available_ae_modes_.end()) { - ALOGE("%s: AE scene mode override: %d not supported!", __FUNCTION__, - scene.ae_mode); - return BAD_VALUE; - } - if (available_awb_modes_.find(scene.awb_mode) == - available_awb_modes_.end()) { - ALOGE("%s: AWB scene mode override: %d not supported!", __FUNCTION__, - scene.awb_mode); - return BAD_VALUE; - } - if (available_af_modes_.find(scene.af_mode) == available_af_modes_.end()) { - ALOGE("%s: AF scene mode override: %d not supported!", __FUNCTION__, - scene.af_mode); - return BAD_VALUE; - } - scene_overrides_.emplace(entry.data.u8[i], scene); - } - } else { - ALOGE("%s: No available scene overrides!", __FUNCTION__); - return BAD_VALUE; - } - - return OK; -} - -status_t EmulatedRequestState::InitializeControlAFDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_CONTROL_AF_AVAILABLE_MODES, &entry); - if (ret == OK) { - available_af_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available AF modes!", __FUNCTION__); - return BAD_VALUE; - } - // Off mode must always be present - if (available_af_modes_.find(ANDROID_CONTROL_AF_MODE_OFF) == - available_af_modes_.end()) { - ALOGE("%s: AF off control mode must always be present!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_requests_.find(ANDROID_CONTROL_AF_MODE) == - available_requests_.end()) { - ALOGE("%s: Clients must be able to set AF mode!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_requests_.find(ANDROID_CONTROL_AF_TRIGGER) == - available_requests_.end()) { - ALOGE("%s: Clients must be able to set AF trigger!", __FUNCTION__); - return BAD_VALUE; - } - if (available_results_.find(ANDROID_CONTROL_AF_TRIGGER) == - available_results_.end()) { - ALOGE("%s: AF trigger must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AF_MODE) == - available_results_.end()) { - ALOGE("%s: AF mode must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AF_STATE) == - available_results_.end()) { - ALOGE("%s: AF state must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - bool auto_mode_present = - available_af_modes_.find(ANDROID_CONTROL_AF_MODE_AUTO) != - available_af_modes_.end(); - bool picture_caf_mode_present = - available_af_modes_.find(ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE) != - available_af_modes_.end(); - bool video_caf_mode_present = - available_af_modes_.find(ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO) != - available_af_modes_.end(); - af_supported_ = auto_mode_present && (minimum_focus_distance_ > .0f); - picture_caf_supported_ = - picture_caf_mode_present && (minimum_focus_distance_ > .0f); - video_caf_supported_ = - video_caf_mode_present && (minimum_focus_distance_ > .0f); - - return OK; -} - -status_t EmulatedRequestState::InitializeControlAWBDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_CONTROL_AWB_AVAILABLE_MODES, &entry); - if (ret == OK) { - available_awb_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available AWB modes!", __FUNCTION__); - return BAD_VALUE; - } - // Auto mode must always be present - if (available_awb_modes_.find(ANDROID_CONTROL_AWB_MODE_AUTO) == - available_awb_modes_.end()) { - ALOGE("%s: AWB auto control mode must always be present!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AWB_MODE) == - available_results_.end()) { - ALOGE("%s: AWB mode must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AWB_STATE) == - available_results_.end()) { - ALOGE("%s: AWB state must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &entry); - if ((ret == OK) && (entry.count == 1)) { - awb_lock_available_ = - entry.data.u8[0] == ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE; - } else { - ALOGV("%s: No available AWB lock!", __FUNCTION__); - awb_lock_available_ = false; - } - report_awb_lock_ = available_results_.find(ANDROID_CONTROL_AWB_LOCK) != - available_results_.end(); - - return OK; -} - -status_t EmulatedRequestState::InitializeBlackLevelDefaults() { - if (is_level_full_or_higher_) { - if (available_requests_.find(ANDROID_BLACK_LEVEL_LOCK) == - available_requests_.end()) { - ALOGE( - "%s: Full or above capable devices must be able to set the black " - "level lock!", - __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_BLACK_LEVEL_LOCK) == - available_results_.end()) { - ALOGE( - "%s: Full or above capable devices must be able to report the black " - "level lock!", - __FUNCTION__); - return BAD_VALUE; - } - - report_black_level_lock_ = true; - uint8_t blackLevelLock = ANDROID_BLACK_LEVEL_LOCK_OFF; - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - default_requests_[idx]->Set(ANDROID_BLACK_LEVEL_LOCK, &blackLevelLock, 1); - } - } - - return InitializeEdgeDefaults(); -} - -status_t EmulatedRequestState::InitializeControlAEDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_CONTROL_AE_AVAILABLE_MODES, &entry); - if (ret == OK) { - available_ae_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available AE modes!", __FUNCTION__); - return BAD_VALUE; - } - // On mode must always be present - if (available_ae_modes_.find(ANDROID_CONTROL_AE_MODE_ON) == - available_ae_modes_.end()) { - ALOGE("%s: AE on control mode must always be present!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AE_MODE) == - available_results_.end()) { - ALOGE("%s: AE mode must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AE_STATE) == - available_results_.end()) { - ALOGE("%s: AE state must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &entry); - if ((ret == OK) && (entry.count == 1)) { - ae_lock_available_ = - entry.data.u8[0] == ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE; - } else { - ALOGV("%s: No available AE lock!", __FUNCTION__); - ae_lock_available_ = false; - } - report_ae_lock_ = available_results_.find(ANDROID_CONTROL_AE_LOCK) != - available_results_.end(); - - if (supports_manual_sensor_) { - if (!ae_lock_available_) { - ALOGE("%s: AE lock must always be available for manual sensors!", - __FUNCTION__); - return BAD_VALUE; - } - auto off_mode = available_control_modes_.find(ANDROID_CONTROL_MODE_OFF); - if (off_mode == available_control_modes_.end()) { - ALOGE("%s: Off control mode must always be present for manual sensors!", - __FUNCTION__); - return BAD_VALUE; - } - - off_mode = available_ae_modes_.find(ANDROID_CONTROL_AE_MODE_OFF); - if (off_mode == available_ae_modes_.end()) { - ALOGE( - "%s: AE off control mode must always be present for manual sensors!", - __FUNCTION__); - return BAD_VALUE; - } - } - - if (available_requests_.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) == - available_requests_.end()) { - ALOGE("%s: Clients must be able to set AE pre-capture trigger!", - __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) == - available_results_.end()) { - ALOGE("%s: AE pre-capture trigger must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, - &entry); - if (ret == OK) { - available_antibanding_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available antibanding modes!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_CONTROL_AE_COMPENSATION_RANGE, &entry); - if ((ret == OK) && (entry.count == 2)) { - exposure_compensation_range_[0] = entry.data.i32[0]; - exposure_compensation_range_[1] = entry.data.i32[1]; - } else { - ALOGE("%s: No available exposure compensation range!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_CONTROL_AE_COMPENSATION_STEP, &entry); - if ((ret == OK) && (entry.count == 1)) { - exposure_compensation_step_ = entry.data.r[0]; - } else { - ALOGE("%s: No available exposure compensation step!", __FUNCTION__); - return BAD_VALUE; - } - - bool ae_comp_requests = - available_requests_.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION) != - available_requests_.end(); - bool ae_comp_results = - available_results_.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION) != - available_results_.end(); - exposure_compensation_supported_ = - ((exposure_compensation_range_[0] < 0) && - (exposure_compensation_range_[1] > 0) && - (exposure_compensation_step_.denominator > 0) && - (exposure_compensation_step_.numerator > 0)) && - ae_comp_results && ae_comp_requests; - - return OK; -} - -status_t EmulatedRequestState::InitializeMeteringRegionDefault( - uint32_t tag, int32_t* region /*out*/) { - if (region == nullptr) { - return BAD_VALUE; - } - if (available_requests_.find(tag) == available_requests_.end()) { - ALOGE("%s: %d metering region configuration must be supported!", - __FUNCTION__, tag); - return BAD_VALUE; - } - if (available_results_.find(tag) == available_results_.end()) { - ALOGE("%s: %d metering region must be reported!", __FUNCTION__, tag); - return BAD_VALUE; - } - - region[0] = scaler_crop_region_default_[0]; - region[1] = scaler_crop_region_default_[1]; - region[2] = scaler_crop_region_default_[2]; - region[3] = scaler_crop_region_default_[3]; - region[4] = 0; - - return OK; -} - -status_t EmulatedRequestState::InitializeControlDefaults() { - camera_metadata_ro_entry_t entry; - int32_t metering_area[5] = {0}; // (top, left, width, height, wight) - auto ret = static_metadata_->Get(ANDROID_CONTROL_AVAILABLE_MODES, &entry); - if (ret == OK) { - available_control_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available control modes!", __FUNCTION__); - return BAD_VALUE; - } - - available_sensor_pixel_modes_.insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT); - - if (SupportsCapability( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR)) { - available_sensor_pixel_modes_.insert( - ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION); - } - - // Auto mode must always be present - if (available_control_modes_.find(ANDROID_CONTROL_MODE_AUTO) == - available_control_modes_.end()) { - ALOGE("%s: Auto control modes must always be present!", __FUNCTION__); - return BAD_VALUE; - } - - // Capture intent must always be user configurable - if (available_requests_.find(ANDROID_CONTROL_CAPTURE_INTENT) == - available_requests_.end()) { - ALOGE("%s: Clients must be able to set the capture intent!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, - &entry); - if ((ret == OK) && ((entry.count % 2) == 0)) { - available_fps_ranges_.reserve(entry.count / 2); - for (size_t i = 0; i < entry.count; i += 2) { - FPSRange range(entry.data.i32[i], entry.data.i32[i + 1]); - if (range.min_fps > range.max_fps) { - ALOGE("%s: Mininum framerate: %d bigger than maximum framerate: %d", - __FUNCTION__, range.min_fps, range.max_fps); - return BAD_VALUE; - } - if ((range.max_fps >= kMinimumStreamingFPS) && - (range.max_fps == range.min_fps) && (ae_target_fps_.max_fps == 0)) { - ae_target_fps_ = range; - } - available_fps_ranges_.push_back(range); - } - } else { - ALOGE("%s: No available framerate ranges!", __FUNCTION__); - return BAD_VALUE; - } - - if (ae_target_fps_.max_fps == 0) { - ALOGE("%s: No minimum streaming capable framerate range available!", - __FUNCTION__); - return BAD_VALUE; - } - - if (available_requests_.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE) == - available_requests_.end()) { - ALOGE("%s: Clients must be able to set the target framerate range!", - __FUNCTION__); - return BAD_VALUE; - } - - if (available_results_.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE) == - available_results_.end()) { - ALOGE("%s: Target framerate must be reported!", __FUNCTION__); - return BAD_VALUE; - } - - report_extended_scene_mode_ = - available_results_.find(ANDROID_CONTROL_EXTENDED_SCENE_MODE) != - available_results_.end(); - - if (is_backward_compatible_) { - ret = static_metadata_->Get(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, - &entry); - if (ret == OK) { - post_raw_boost_ = entry.data.i32[0]; - } else { - ALOGW("%s: No available post RAW boost! Setting default!", __FUNCTION__); - post_raw_boost_ = 100; - } - report_post_raw_boost_ = - available_results_.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST) != - available_results_.end(); - - ret = static_metadata_->Get(ANDROID_CONTROL_AVAILABLE_EFFECTS, &entry); - if ((ret == OK) && (entry.count > 0)) { - available_effects_.insert(entry.data.u8, entry.data.u8 + entry.count); - if (available_effects_.find(ANDROID_CONTROL_EFFECT_MODE_OFF) == - available_effects_.end()) { - ALOGE("%s: Off color effect mode not supported!", __FUNCTION__); - return BAD_VALUE; - } - } else { - ALOGE("%s: No available effects!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get( - ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, &entry); - if ((ret == OK) && (entry.count > 0)) { - available_vstab_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - if (available_vstab_modes_.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF) == - available_vstab_modes_.end()) { - ALOGE("%s: Off video stabilization mode not supported!", __FUNCTION__); - return BAD_VALUE; - } - if (available_vstab_modes_.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON) != - available_vstab_modes_.end()) { - vstab_available_ = true; - } - } else { - ALOGE("%s: No available video stabilization modes!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, - &entry); - if ((ret == OK) && (entry.count > 0)) { - if (entry.count != 1) { - ALOGE("%s: Invalid max digital zoom capability!", __FUNCTION__); - return BAD_VALUE; - } - max_zoom_ = entry.data.f[0]; - } else { - ALOGE("%s: No available max digital zoom", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry); - if ((ret == OK) && (entry.count > 0)) { - if (entry.count != 2) { - ALOGE("%s: Invalid zoom ratio range capability!", __FUNCTION__); - return BAD_VALUE; - } - - if (entry.data.f[1] != max_zoom_) { - ALOGE("%s: Max zoom ratio must be equal to max digital zoom", - __FUNCTION__); - return BAD_VALUE; - } - - if (entry.data.f[1] < entry.data.f[0]) { - ALOGE("%s: Max zoom ratio must be larger than min zoom ratio", - __FUNCTION__); - return BAD_VALUE; - } - - // Sanity check request and result keys - if (available_requests_.find(ANDROID_CONTROL_ZOOM_RATIO) == - available_requests_.end()) { - ALOGE("%s: Zoom ratio tag must be available in available request keys", - __FUNCTION__); - return BAD_VALUE; - } - if (available_results_.find(ANDROID_CONTROL_ZOOM_RATIO) == - available_results_.end()) { - ALOGE("%s: Zoom ratio tag must be available in available result keys", - __FUNCTION__); - return BAD_VALUE; - } - - zoom_ratio_supported_ = true; - min_zoom_ = entry.data.f[0]; - } - - ret = static_metadata_->Get( - ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES, &entry); - if ((ret == OK) && (entry.count > 0)) { - if (entry.count % 3 != 0) { - ALOGE("%s: Invalid bokeh capabilities!", __FUNCTION__); - return BAD_VALUE; - } - - camera_metadata_ro_entry_t zoom_ratio_ranges_entry; - ret = static_metadata_->Get( - ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES, - &zoom_ratio_ranges_entry); - if (ret != OK || - zoom_ratio_ranges_entry.count / 2 != entry.count / 3 - 1) { - ALOGE("%s: Invalid bokeh mode zoom ratio ranges.", __FUNCTION__); - return BAD_VALUE; - } - - // Sanity check request and characteristics keys - if (available_requests_.find(ANDROID_CONTROL_EXTENDED_SCENE_MODE) == - available_requests_.end()) { - ALOGE("%s: Extended scene mode must be configurable for this device", - __FUNCTION__); - return BAD_VALUE; - } - if (available_characteristics_.find( - ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES) == - available_characteristics_.end() || - available_characteristics_.find( - ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES) == - available_characteristics_.end()) { - ALOGE( - "%s: ExtendedSceneMode maxSizes and zoomRatioRanges " - "characteristics keys must " - "be available", - __FUNCTION__); - return BAD_VALUE; - } - - // Derive available bokeh caps. - StreamConfigurationMap stream_configuration_map(*static_metadata_); - std::set<StreamSize> yuv_sizes = stream_configuration_map.GetOutputSizes( - HAL_PIXEL_FORMAT_YCBCR_420_888); - bool has_extended_scene_mode_off = false; - for (size_t i = 0, j = 0; i < entry.count; i += 3) { - int32_t mode = entry.data.i32[i]; - int32_t max_width = entry.data.i32[i + 1]; - int32_t max_height = entry.data.i32[i + 2]; - float min_zoom_ratio, max_zoom_ratio; - - if (mode < ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED || - (mode > ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS && - mode < ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START)) { - ALOGE("%s: Invalid extended scene mode %d", __FUNCTION__, mode); - return BAD_VALUE; - } - - if (mode == ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED) { - has_extended_scene_mode_off = true; - if (max_width != 0 || max_height != 0) { - ALOGE( - "%s: Invalid max width or height for " - "EXTENDED_SCENE_MODE_DISABLED", - __FUNCTION__); - return BAD_VALUE; - } - min_zoom_ratio = min_zoom_; - max_zoom_ratio = max_zoom_; - } else if (yuv_sizes.find({max_width, max_height}) == yuv_sizes.end()) { - ALOGE("%s: Invalid max width or height for extended scene mode %d", - __FUNCTION__, mode); - return BAD_VALUE; - } else { - min_zoom_ratio = zoom_ratio_ranges_entry.data.f[j]; - max_zoom_ratio = zoom_ratio_ranges_entry.data.f[j + 1]; - j += 2; - } - - ExtendedSceneModeCapability cap(mode, max_width, max_height, - min_zoom_ratio, max_zoom_ratio); - available_extended_scene_mode_caps_.push_back(cap); - } - if (!has_extended_scene_mode_off) { - ALOGE("%s: Off extended scene mode not supported!", __FUNCTION__); - return BAD_VALUE; - } - } - - ret = static_metadata_->Get(ANDROID_CONTROL_MAX_REGIONS, &entry); - if ((ret == OK) && (entry.count == 3)) { - max_ae_regions_ = entry.data.i32[0]; - max_awb_regions_ = entry.data.i32[1]; - max_af_regions_ = entry.data.i32[2]; - } else { - ALOGE( - "%s: Metering regions must be available for backward compatible " - "devices!", - __FUNCTION__); - return BAD_VALUE; - } - - if ((is_level_full_or_higher_) && - ((max_ae_regions_ == 0) || (max_af_regions_ == 0))) { - ALOGE( - "%s: Full and higher level cameras must support at AF and AE " - "metering regions", - __FUNCTION__); - return BAD_VALUE; - } - - if (max_ae_regions_ > 0) { - ret = InitializeMeteringRegionDefault(ANDROID_CONTROL_AE_REGIONS, - ae_metering_region_); - if (ret != OK) { - return ret; - } - } - - if (max_awb_regions_ > 0) { - ret = InitializeMeteringRegionDefault(ANDROID_CONTROL_AWB_REGIONS, - awb_metering_region_); - if (ret != OK) { - return ret; - } - } - - if (max_af_regions_ > 0) { - ret = InitializeMeteringRegionDefault(ANDROID_CONTROL_AF_REGIONS, - af_metering_region_); - if (ret != OK) { - return ret; - } - } - - ret = InitializeControlAEDefaults(); - if (ret != OK) { - return ret; - } - - ret = InitializeControlAWBDefaults(); - if (ret != OK) { - return ret; - } - - ret = InitializeControlAFDefaults(); - if (ret != OK) { - return ret; - } - - ret = InitializeControlSceneDefaults(); - if (ret != OK) { - return ret; - } - } - - for (size_t idx = 0; idx < kTemplateCount; idx++) { - auto template_idx = static_cast<RequestTemplate>(idx); - if (default_requests_[idx].get() == nullptr) { - continue; - } - - uint8_t intent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM; - uint8_t control_mode, ae_mode, awb_mode, af_mode, scene_mode, vstab_mode; - control_mode = ANDROID_CONTROL_MODE_AUTO; - ae_mode = ANDROID_CONTROL_AE_MODE_ON; - awb_mode = ANDROID_CONTROL_AWB_MODE_AUTO; - af_mode = af_supported_ ? ANDROID_CONTROL_AF_MODE_AUTO - : ANDROID_CONTROL_AF_MODE_OFF; - scene_mode = ANDROID_CONTROL_SCENE_MODE_DISABLED; - vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; - uint8_t effect_mode = ANDROID_CONTROL_EFFECT_MODE_OFF; - uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF; - uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF; - int32_t ae_target_fps[] = {ae_target_fps_.min_fps, ae_target_fps_.max_fps}; - float zoom_ratio = 1.0f; - switch (template_idx) { - case RequestTemplate::kManual: - intent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL; - control_mode = ANDROID_CONTROL_MODE_OFF; - ae_mode = ANDROID_CONTROL_AE_MODE_OFF; - awb_mode = ANDROID_CONTROL_AWB_MODE_OFF; - af_mode = ANDROID_CONTROL_AF_MODE_OFF; - break; - case RequestTemplate::kZeroShutterLag: - intent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG; - if (picture_caf_supported_) { - af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; - } - break; - case RequestTemplate::kPreview: - intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; - if (picture_caf_supported_) { - af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; - } - break; - case RequestTemplate::kStillCapture: - intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; - if (picture_caf_supported_) { - af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; - } - break; - case RequestTemplate::kVideoRecord: - intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; - if (video_caf_supported_) { - af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; - } - if (vstab_available_) { - vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON; - } - break; - case RequestTemplate::kVideoSnapshot: - intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; - if (video_caf_supported_) { - af_mode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; - } - if (vstab_available_) { - vstab_mode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON; - } - break; - default: - // Noop - break; - } - - if (intent != ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM) { - default_requests_[idx]->Set(ANDROID_CONTROL_CAPTURE_INTENT, &intent, 1); - default_requests_[idx]->Set(ANDROID_CONTROL_MODE, &control_mode, 1); - default_requests_[idx]->Set(ANDROID_CONTROL_AE_MODE, &ae_mode, 1); - default_requests_[idx]->Set(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, - ae_target_fps, ARRAY_SIZE(ae_target_fps)); - default_requests_[idx]->Set(ANDROID_CONTROL_AWB_MODE, &awb_mode, 1); - default_requests_[idx]->Set(ANDROID_CONTROL_AF_MODE, &af_mode, 1); - if (is_backward_compatible_) { - default_requests_[idx]->Set(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, - &post_raw_boost_, 1); - if (vstab_available_) { - default_requests_[idx]->Set(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, - &vstab_mode, 1); - } - if (ae_lock_available_) { - default_requests_[idx]->Set(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1); - } - if (awb_lock_available_) { - default_requests_[idx]->Set(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1); - } - if (scenes_supported_) { - default_requests_[idx]->Set(ANDROID_CONTROL_SCENE_MODE, &scene_mode, - 1); - } - if (max_ae_regions_ > 0) { - default_requests_[idx]->Set(ANDROID_CONTROL_AE_REGIONS, metering_area, - ARRAY_SIZE(metering_area)); - } - if (max_awb_regions_ > 0) { - default_requests_[idx]->Set(ANDROID_CONTROL_AWB_REGIONS, - metering_area, ARRAY_SIZE(metering_area)); - } - if (max_af_regions_ > 0) { - default_requests_[idx]->Set(ANDROID_CONTROL_AF_REGIONS, metering_area, - ARRAY_SIZE(metering_area)); - } - if (exposure_compensation_supported_) { - default_requests_[idx]->Set(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, - &exposure_compensation_, 1); - } - if (zoom_ratio_supported_) { - default_requests_[idx]->Set(ANDROID_CONTROL_ZOOM_RATIO, &zoom_ratio, - 1); - } - bool is_auto_antbanding_supported = - available_antibanding_modes_.find( - ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO) != - available_antibanding_modes_.end(); - uint8_t antibanding_mode = is_auto_antbanding_supported - ? ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO - : *available_antibanding_modes_.begin(); - default_requests_[idx]->Set(ANDROID_CONTROL_AE_ANTIBANDING_MODE, - &antibanding_mode, 1); - default_requests_[idx]->Set(ANDROID_CONTROL_EFFECT_MODE, &effect_mode, - 1); - uint8_t ae_trigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; - default_requests_[idx]->Set(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, - &ae_trigger, 1); - uint8_t af_trigger = ANDROID_CONTROL_AF_TRIGGER_IDLE; - default_requests_[idx]->Set(ANDROID_CONTROL_AF_TRIGGER, &af_trigger, 1); - } - } - - int32_t settings_override = ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF; - default_requests_[idx]->Set(ANDROID_CONTROL_SETTINGS_OVERRIDE, - &settings_override, 1); - } - - return InitializeHotPixelDefaults(); -} - -status_t EmulatedRequestState::InitializeTonemapDefaults() { - if (is_backward_compatible_) { - camera_metadata_ro_entry_t entry; - auto ret = - static_metadata_->Get(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES, &entry); - if (ret == OK) { - available_tonemap_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available tonemap modes!", __FUNCTION__); - return BAD_VALUE; - } - - if ((is_level_full_or_higher_) && (available_tonemap_modes_.size() < 3)) { - ALOGE( - "%s: Full and higher level cameras must support at least three or " - "more tonemap modes", - __FUNCTION__); - return BAD_VALUE; - } - - bool fast_mode_supported = - available_tonemap_modes_.find(ANDROID_TONEMAP_MODE_FAST) != - available_tonemap_modes_.end(); - bool hq_mode_supported = - available_tonemap_modes_.find(ANDROID_TONEMAP_MODE_HIGH_QUALITY) != - available_tonemap_modes_.end(); - uint8_t tonemap_mode = *available_tonemap_modes_.begin(); - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - switch (static_cast<RequestTemplate>(idx)) { - case RequestTemplate::kVideoRecord: // Pass-through - case RequestTemplate::kPreview: - if (fast_mode_supported) { - tonemap_mode = ANDROID_TONEMAP_MODE_FAST; - } - break; - case RequestTemplate::kVideoSnapshot: // Pass-through - case RequestTemplate::kStillCapture: - if (hq_mode_supported) { - tonemap_mode = ANDROID_TONEMAP_MODE_HIGH_QUALITY; - } - break; - default: - // Noop - break; - } - - default_requests_[idx]->Set(ANDROID_TONEMAP_MODE, &tonemap_mode, 1); - default_requests_[idx]->Set( - ANDROID_TONEMAP_CURVE_RED, EmulatedSensor::kDefaultToneMapCurveRed, - ARRAY_SIZE(EmulatedSensor::kDefaultToneMapCurveRed)); - default_requests_[idx]->Set( - ANDROID_TONEMAP_CURVE_GREEN, EmulatedSensor::kDefaultToneMapCurveGreen, - ARRAY_SIZE(EmulatedSensor::kDefaultToneMapCurveGreen)); - default_requests_[idx]->Set( - ANDROID_TONEMAP_CURVE_BLUE, EmulatedSensor::kDefaultToneMapCurveBlue, - ARRAY_SIZE(EmulatedSensor::kDefaultToneMapCurveBlue)); - } - } - - return InitializeStatisticsDefaults(); -} - -status_t EmulatedRequestState::InitializeEdgeDefaults() { - if (is_backward_compatible_) { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_EDGE_AVAILABLE_EDGE_MODES, &entry); - if (ret == OK) { - available_edge_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available edge modes!", __FUNCTION__); - return BAD_VALUE; - } - - report_edge_mode_ = available_results_.find(ANDROID_EDGE_MODE) != available_results_.end(); - bool is_fast_mode_supported = - available_edge_modes_.find(ANDROID_EDGE_MODE_FAST) != - available_edge_modes_.end(); - bool is_hq_mode_supported = - available_edge_modes_.find(ANDROID_EDGE_MODE_HIGH_QUALITY) != - available_edge_modes_.end(); - bool is_zsl_mode_supported = - available_edge_modes_.find(ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG) != - available_edge_modes_.end(); - uint8_t edge_mode = *available_ae_modes_.begin(); - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - switch (static_cast<RequestTemplate>(idx)) { - case RequestTemplate::kVideoRecord: // Pass-through - case RequestTemplate::kPreview: - if (is_fast_mode_supported) { - edge_mode = ANDROID_EDGE_MODE_FAST; - } - break; - case RequestTemplate::kVideoSnapshot: // Pass-through - case RequestTemplate::kStillCapture: - if (is_hq_mode_supported) { - edge_mode = ANDROID_EDGE_MODE_HIGH_QUALITY; - } - break; - case RequestTemplate::kZeroShutterLag: - if (is_zsl_mode_supported) { - edge_mode = ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG; - } - break; - default: - // Noop - break; - } - - default_requests_[idx]->Set(ANDROID_EDGE_MODE, &edge_mode, 1); - } - } - - return InitializeShadingDefaults(); -} - -status_t EmulatedRequestState::InitializeColorCorrectionDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get( - ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, &entry); - if (ret == OK) { - available_color_aberration_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else if (supports_manual_post_processing_) { - ALOGE( - "%s: Devices capable of manual post-processing must support color " - "abberation!", - __FUNCTION__); - return BAD_VALUE; - } - - if (!available_color_aberration_modes_.empty()) { - bool is_fast_mode_supported = - available_color_aberration_modes_.find( - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST) != - available_color_aberration_modes_.end(); - bool is_hq_mode_supported = - available_color_aberration_modes_.find( - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY) != - available_color_aberration_modes_.end(); - uint8_t color_aberration = *available_color_aberration_modes_.begin(); - uint8_t color_correction_mode = ANDROID_COLOR_CORRECTION_MODE_FAST; - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - switch (static_cast<RequestTemplate>(idx)) { - case RequestTemplate::kVideoRecord: // Pass-through - case RequestTemplate::kPreview: - if (is_fast_mode_supported) { - color_aberration = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST; - } - break; - case RequestTemplate::kVideoSnapshot: // Pass-through - case RequestTemplate::kStillCapture: - if (is_hq_mode_supported) { - color_aberration = - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY; - } - break; - default: - // Noop - break; - } - - default_requests_[idx]->Set(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, - &color_aberration, 1); - if (is_backward_compatible_) { - default_requests_[idx]->Set(ANDROID_COLOR_CORRECTION_MODE, - &color_correction_mode, 1); - default_requests_[idx]->Set( - ANDROID_COLOR_CORRECTION_TRANSFORM, - EmulatedSensor::kDefaultColorTransform, - ARRAY_SIZE(EmulatedSensor::kDefaultColorTransform)); - default_requests_[idx]->Set( - ANDROID_COLOR_CORRECTION_GAINS, - EmulatedSensor::kDefaultColorCorrectionGains, - ARRAY_SIZE(EmulatedSensor::kDefaultColorCorrectionGains)); - } - } - } - - return InitializeSensorDefaults(); -} - -status_t EmulatedRequestState::InitializeScalerDefaults() { - if (is_backward_compatible_) { - camera_metadata_ro_entry_t entry; - auto ret = - static_metadata_->Get(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, &entry); - if ((ret == OK) && (entry.count == 4)) { - scaler_crop_region_default_[0] = entry.data.i32[0]; - scaler_crop_region_default_[1] = entry.data.i32[1]; - scaler_crop_region_default_[2] = entry.data.i32[2]; - scaler_crop_region_default_[3] = entry.data.i32[3]; - } else { - ALOGE("%s: Sensor pixel array size is not available!", __FUNCTION__); - return BAD_VALUE; - } - - if (SupportsCapability( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR)) { - ret = static_metadata_->Get( - ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, &entry); - if ((ret == OK) && (entry.count == 4)) { - scaler_crop_region_max_resolution_[0] = entry.data.i32[0]; - scaler_crop_region_max_resolution_[1] = entry.data.i32[1]; - scaler_crop_region_max_resolution_[2] = entry.data.i32[2]; - scaler_crop_region_max_resolution_[3] = entry.data.i32[3]; - } else { - ALOGE( - "%s: Sensor pixel array size maximum resolution is not available!", - __FUNCTION__); - return BAD_VALUE; - } - } - - if (available_requests_.find(ANDROID_SCALER_CROP_REGION) == - available_requests_.end()) { - ALOGE( - "%s: Backward compatible devices must support scaler crop " - "configuration!", - __FUNCTION__); - return BAD_VALUE; - } - if (available_results_.find(ANDROID_SCALER_CROP_REGION) == - available_results_.end()) { - ALOGE("%s: Scaler crop must reported on backward compatible devices!", - __FUNCTION__); - return BAD_VALUE; - } - - if (available_requests_.find( - ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION) != - available_results_.end()) { - report_active_sensor_crop_ = true; - } - ret = static_metadata_->Get(ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES, - &entry); - if ((ret == OK) && (entry.count > 0)) { - // Listing rotate and crop, so need to make sure it's consistently reported - if (available_requests_.find(ANDROID_SCALER_ROTATE_AND_CROP) == - available_requests_.end()) { - ALOGE( - "%s: Rotate and crop must be listed in request keys if supported!", - __FUNCTION__); - return BAD_VALUE; - } - if (available_results_.find(ANDROID_SCALER_ROTATE_AND_CROP) == - available_results_.end()) { - ALOGE("%s: Rotate and crop must be listed in result keys if supported!", - __FUNCTION__); - return BAD_VALUE; - } - if (available_characteristics_.find( - ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES) == - available_characteristics_.end()) { - ALOGE( - "%s: Rotate and crop must be listed in characteristics keys if " - "supported!", - __FUNCTION__); - return BAD_VALUE; - } - report_rotate_and_crop_ = true; - for (size_t i = 0; i < entry.count; i++) { - if (entry.data.u8[i] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) { - rotate_and_crop_ = ANDROID_SCALER_ROTATE_AND_CROP_AUTO; - } - available_rotate_crop_modes_.insert(entry.data.u8[i]); - } - } - - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - default_requests_[idx]->Set(ANDROID_SCALER_CROP_REGION, - scaler_crop_region_default_, - ARRAY_SIZE(scaler_crop_region_default_)); - if (report_rotate_and_crop_) { - default_requests_[idx]->Set(ANDROID_SCALER_ROTATE_AND_CROP, - &rotate_and_crop_, 1); - } - } - } - - return InitializeControlDefaults(); -} - -status_t EmulatedRequestState::InitializeShadingDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_SHADING_AVAILABLE_MODES, &entry); - if (ret == OK) { - available_shading_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available lens shading modes!", __FUNCTION__); - return BAD_VALUE; - } - - if (supports_manual_post_processing_ && - (available_shading_modes_.size() < 2)) { - ALOGE( - "%s: Devices capable of manual post-processing need to support at " - "least " - "two" - " lens shading modes!", - __FUNCTION__); - return BAD_VALUE; - } - - bool is_fast_mode_supported = - available_shading_modes_.find(ANDROID_SHADING_MODE_FAST) != - available_shading_modes_.end(); - bool is_hq_mode_supported = - available_shading_modes_.find(ANDROID_SHADING_MODE_HIGH_QUALITY) != - available_shading_modes_.end(); - uint8_t shading_mode = *available_shading_modes_.begin(); - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - switch (static_cast<RequestTemplate>(idx)) { - case RequestTemplate::kVideoRecord: // Pass-through - case RequestTemplate::kPreview: - if (is_fast_mode_supported) { - shading_mode = ANDROID_SHADING_MODE_FAST; - } - break; - case RequestTemplate::kVideoSnapshot: // Pass-through - case RequestTemplate::kStillCapture: - if (is_hq_mode_supported) { - shading_mode = ANDROID_SHADING_MODE_HIGH_QUALITY; - } - break; - default: - // Noop - break; - } - - default_requests_[idx]->Set(ANDROID_SHADING_MODE, &shading_mode, 1); - } - - return InitializeNoiseReductionDefaults(); -} - -status_t EmulatedRequestState::InitializeNoiseReductionDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get( - ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, &entry); - if (ret == OK) { - available_noise_reduction_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available noise reduction modes!", __FUNCTION__); - return BAD_VALUE; - } - - if ((is_level_full_or_higher_) && - (available_noise_reduction_modes_.size() < 2)) { - ALOGE( - "%s: Full and above device must support at least two noise reduction " - "modes!", - __FUNCTION__); - return BAD_VALUE; - } - - bool is_fast_mode_supported = - available_noise_reduction_modes_.find(ANDROID_NOISE_REDUCTION_MODE_FAST) != - available_noise_reduction_modes_.end(); - bool is_hq_mode_supported = available_noise_reduction_modes_.find( - ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY) != - available_noise_reduction_modes_.end(); - bool is_zsl_mode_supported = - available_noise_reduction_modes_.find( - ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG) != - available_noise_reduction_modes_.end(); - uint8_t noise_reduction_mode = *available_noise_reduction_modes_.begin(); - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - switch (static_cast<RequestTemplate>(idx)) { - case RequestTemplate::kVideoRecord: // Pass-through - case RequestTemplate::kVideoSnapshot: // Pass-through - case RequestTemplate::kPreview: - if (is_fast_mode_supported) { - noise_reduction_mode = ANDROID_NOISE_REDUCTION_MODE_FAST; - } - break; - case RequestTemplate::kStillCapture: - if (is_hq_mode_supported) { - noise_reduction_mode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY; - } - break; - case RequestTemplate::kZeroShutterLag: - if (is_zsl_mode_supported) { - noise_reduction_mode = ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG; - } - break; - default: - // Noop - break; - } - - default_requests_[idx]->Set(ANDROID_NOISE_REDUCTION_MODE, - &noise_reduction_mode, 1); - } - - return InitializeColorCorrectionDefaults(); -} - -status_t EmulatedRequestState::InitializeHotPixelDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES, - &entry); - if (ret == OK) { - available_hot_pixel_modes_.insert(entry.data.u8, - entry.data.u8 + entry.count); - } else { - ALOGE("%s: No available hotpixel modes!", __FUNCTION__); - return BAD_VALUE; - } - - if ((is_level_full_or_higher_) && (available_hot_pixel_modes_.size() < 2)) { - ALOGE( - "%s: Full and higher level cameras must support at least fast and hq " - "hotpixel modes", - __FUNCTION__); - return BAD_VALUE; - } - - bool fast_mode_supported = - available_hot_pixel_modes_.find(ANDROID_HOT_PIXEL_MODE_FAST) != - available_hot_pixel_modes_.end(); - bool hq_mode_supported = - available_hot_pixel_modes_.find(ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY) != - available_hot_pixel_modes_.end(); - uint8_t hotpixel_mode = *available_hot_pixel_modes_.begin(); - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - switch (static_cast<RequestTemplate>(idx)) { - case RequestTemplate::kVideoRecord: // Pass-through - case RequestTemplate::kPreview: - if (fast_mode_supported) { - hotpixel_mode = ANDROID_HOT_PIXEL_MODE_FAST; - } - break; - case RequestTemplate::kVideoSnapshot: // Pass-through - case RequestTemplate::kStillCapture: - if (hq_mode_supported) { - hotpixel_mode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY; - } - break; - default: - // Noop - break; - } - - default_requests_[idx]->Set(ANDROID_HOT_PIXEL_MODE, &hotpixel_mode, 1); - } - - return InitializeTonemapDefaults(); -} - -status_t EmulatedRequestState::InitializeFlashDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_AVAILABLE, &entry); - if ((ret == OK) && (entry.count == 1)) { - is_flash_supported_ = entry.data.u8[0]; - } else { - ALOGE("%s: No available flash info!", __FUNCTION__); - return BAD_VALUE; - } - - if (is_flash_supported_) { - flash_state_ = ANDROID_FLASH_STATE_READY; - } else { - flash_state_ = ANDROID_FLASH_STATE_UNAVAILABLE; - } - - uint8_t flash_mode = ANDROID_FLASH_MODE_OFF; - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - default_requests_[idx]->Set(ANDROID_FLASH_MODE, &flash_mode, 1); - } - - return InitializeScalerDefaults(); -} - -status_t EmulatedRequestState::InitializeLensDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = - static_metadata_->Get(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &entry); - if ((ret == OK) && (entry.count == 1)) { - minimum_focus_distance_ = entry.data.f[0]; - } else { - ALOGW("%s: No available minimum focus distance assuming fixed focus!", - __FUNCTION__); - minimum_focus_distance_ = .0f; - } - - ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &entry); - if ((ret == OK) && (entry.count > 0)) { - // TODO: add support for multiple apertures - aperture_ = entry.data.f[0]; - } else { - ALOGE("%s: No available aperture!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &entry); - if ((ret == OK) && (entry.count > 0)) { - focal_length_ = entry.data.f[0]; - } else { - ALOGE("%s: No available focal length!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_LENS_INFO_SHADING_MAP_SIZE, &entry); - if ((ret == OK) && (entry.count == 2)) { - shading_map_size_[0] = entry.data.i32[0]; - shading_map_size_[1] = entry.data.i32[1]; - } else if (is_raw_capable_) { - ALOGE("%s: No available shading map size!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, - &entry); - if ((ret == OK) && (entry.count > 0)) { - // TODO: add support for multiple filter densities - filter_density_ = entry.data.f[0]; - } else { - ALOGE("%s: No available filter density!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, - &entry); - if ((ret == OK) && (entry.count > 0)) { - // TODO: add support for multiple OIS modes - available_ois_modes_.insert(entry.data.u8, entry.data.u8 + entry.count); - if (available_ois_modes_.find(ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF) == - available_ois_modes_.end()) { - ALOGE("%s: OIS off mode not supported!", __FUNCTION__); - return BAD_VALUE; - } - } else { - ALOGE("%s: No available OIS modes!", __FUNCTION__); - return BAD_VALUE; - } - - ret = static_metadata_->Get(ANDROID_LENS_POSE_ROTATION, &entry); - if ((ret == OK) && (entry.count == ARRAY_SIZE(pose_rotation_))) { - memcpy(pose_rotation_, entry.data.f, sizeof(pose_rotation_)); - } - ret = static_metadata_->Get(ANDROID_LENS_POSE_TRANSLATION, &entry); - if ((ret == OK) && (entry.count == ARRAY_SIZE(pose_translation_))) { - memcpy(pose_translation_, entry.data.f, sizeof(pose_translation_)); - } - ret = static_metadata_->Get(ANDROID_LENS_INTRINSIC_CALIBRATION, &entry); - if ((ret == OK) && (entry.count == ARRAY_SIZE(intrinsic_calibration_))) { - memcpy(intrinsic_calibration_, entry.data.f, sizeof(intrinsic_calibration_)); - } - - ret = static_metadata_->Get(ANDROID_LENS_DISTORTION, &entry); - if ((ret == OK) && (entry.count == ARRAY_SIZE(distortion_))) { - memcpy(distortion_, entry.data.f, sizeof(distortion_)); - } - - report_focus_distance_ = - available_results_.find(ANDROID_LENS_FOCUS_DISTANCE) != - available_results_.end(); - report_focus_range_ = available_results_.find(ANDROID_LENS_FOCUS_RANGE) != - available_results_.end(); - report_filter_density_ = - available_results_.find(ANDROID_LENS_FILTER_DENSITY) != - available_results_.end(); - report_ois_mode_ = - available_results_.find(ANDROID_LENS_OPTICAL_STABILIZATION_MODE) != - available_results_.end(); - report_pose_rotation_ = available_results_.find(ANDROID_LENS_POSE_ROTATION) != - available_results_.end(); - report_pose_translation_ = - available_results_.find(ANDROID_LENS_POSE_TRANSLATION) != - available_results_.end(); - report_intrinsic_calibration_ = - available_results_.find(ANDROID_LENS_INTRINSIC_CALIBRATION) != - available_results_.end(); - report_distortion_ = available_results_.find(ANDROID_LENS_DISTORTION) != - available_results_.end(); - - focus_distance_ = minimum_focus_distance_; - for (size_t idx = 0; idx < kTemplateCount; idx++) { - if (default_requests_[idx].get() == nullptr) { - continue; - } - - default_requests_[idx]->Set(ANDROID_LENS_APERTURE, &aperture_, 1); - default_requests_[idx]->Set(ANDROID_LENS_FOCAL_LENGTH, &focal_length_, 1); - default_requests_[idx]->Set(ANDROID_LENS_FOCUS_DISTANCE, &focus_distance_, - 1); - default_requests_[idx]->Set(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, - &ois_mode_, 1); - } - - return InitializeFlashDefaults(); -} - -status_t EmulatedRequestState::InitializeInfoDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = - static_metadata_->Get(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry); - if ((ret == OK) && (entry.count == 1)) { - if (kSupportedHWLevels.find(entry.data.u8[0]) == - kSupportedCapabilites.end()) { - ALOGE("%s: HW Level: %u not supported", __FUNCTION__, entry.data.u8[0]); - return BAD_VALUE; - } - } else { - ALOGE("%s: No available hardware level!", __FUNCTION__); - return BAD_VALUE; - } - - supported_hw_level_ = entry.data.u8[0]; - is_level_full_or_higher_ = - (supported_hw_level_ == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL) || - (supported_hw_level_ == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3); - - return InitializeReprocessDefaults(); -} - -status_t EmulatedRequestState::InitializeReprocessDefaults() { - if (supports_private_reprocessing_ || supports_yuv_reprocessing_ || - supports_remosaic_reprocessing_) { - StreamConfigurationMap config_map(*static_metadata_); - if (!config_map.SupportsReprocessing()) { - ALOGE( - "%s: Reprocess capability present but InputOutput format map is " - "absent!", - __FUNCTION__); - return BAD_VALUE; - } - - auto input_formats = config_map.GetInputFormats(); - for (const auto& input_format : input_formats) { - auto output_formats = - config_map.GetValidOutputFormatsForInput(input_format); - for (const auto& output_format : output_formats) { - if (!EmulatedSensor::IsReprocessPathSupported( - EmulatedSensor::OverrideFormat( - input_format, - ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD), - EmulatedSensor::OverrideFormat( - output_format, - ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD))) { - ALOGE( - "%s: Input format: 0x%x to output format: 0x%x reprocess is" - " currently not supported!", - __FUNCTION__, input_format, output_format); - return BAD_VALUE; - } - } - } - } - - return InitializeLensDefaults(); -} - -status_t EmulatedRequestState::InitializeRequestDefaults() { - camera_metadata_ro_entry_t entry; - auto ret = - static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); - if ((ret == OK) && (entry.count > 0)) { - for (size_t i = 0; i < entry.count; i++) { - if (kSupportedCapabilites.find(entry.data.u8[i]) == - kSupportedCapabilites.end()) { - ALOGE("%s: Capability: %u not supported", __FUNCTION__, - entry.data.u8[i]); - return BAD_VALUE; - } - } - } else { - ALOGE("%s: No available capabilities!", __FUNCTION__); - return BAD_VALUE; - } - available_capabilities_.insert(entry.data.u8, entry.data.u8 + entry.count); - - ret = static_metadata_->Get(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry); - if ((ret == OK) && (entry.count == 1)) { - if (entry.data.u8[0] == 0) { - ALOGE("%s: Maximum request pipeline depth must have a non zero value!", - __FUNCTION__); - return BAD_VALUE; - } - } else { - ALOGE("%s: Maximum request pipeline depth absent!", __FUNCTION__); - return BAD_VALUE; - } - max_pipeline_depth_ = entry.data.u8[0]; - - ret = static_metadata_->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); - if ((ret == OK) && (entry.count == 1)) { - if (entry.data.i32[0] > 2) { - ALOGW("%s: Partial result count greater than 2 not supported!", - __FUNCTION__); - } - partial_result_count = entry.data.i32[0]; - } - - ret = static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, - &entry); - if ((ret != OK) || (entry.count == 0)) { - ALOGE("%s: No available characteristic keys!", __FUNCTION__); - return BAD_VALUE; - } - available_characteristics_.insert(entry.data.i32, - entry.data.i32 + entry.count); - - ret = static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry); - if ((ret != OK) || (entry.count == 0)) { - ALOGE("%s: No available result keys!", __FUNCTION__); - return BAD_VALUE; - } - available_results_.insert(entry.data.i32, entry.data.i32 + entry.count); - - ret = static_metadata_->Get(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry); - if ((ret != OK) || (entry.count == 0)) { - ALOGE("%s: No available request keys!", __FUNCTION__); - return BAD_VALUE; - } - available_requests_.insert(entry.data.i32, entry.data.i32 + entry.count); - - supports_manual_sensor_ = - SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR); - supports_manual_post_processing_ = SupportsCapability( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING); - supports_private_reprocessing_ = SupportsCapability( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING); - supports_yuv_reprocessing_ = SupportsCapability( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING); - supports_remosaic_reprocessing_ = SupportsCapability( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING); - is_backward_compatible_ = SupportsCapability( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE); - is_raw_capable_ = - SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW); - supports_stream_use_case_ = - SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE); - - if (supports_manual_sensor_) { - auto templateIdx = static_cast<size_t>(RequestTemplate::kManual); - default_requests_[templateIdx] = HalCameraMetadata::Create(1, 10); - } - - if (supports_stream_use_case_) { - ret = static_metadata_->Get(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, - &entry); - if (ret != OK) { - ALOGE("%s: No available stream use cases!", __FUNCTION__); - return BAD_VALUE; - } - for (int64_t useCase : kSupportedUseCases) { - if (std::find(entry.data.i64, entry.data.i64 + entry.count, useCase) == - entry.data.i64 + entry.count) { - ALOGE("%s: Mandatory stream use case %" PRId64 " not found!", - __FUNCTION__, useCase); - return BAD_VALUE; - } - } - } - - for (size_t templateIdx = 0; templateIdx < kTemplateCount; templateIdx++) { - switch (static_cast<RequestTemplate>(templateIdx)) { - case RequestTemplate::kPreview: - case RequestTemplate::kStillCapture: - case RequestTemplate::kVideoRecord: - case RequestTemplate::kVideoSnapshot: - default_requests_[templateIdx] = HalCameraMetadata::Create(1, 10); - break; - default: - // Noop - break; - } - } - - if (supports_yuv_reprocessing_ || supports_private_reprocessing_) { - auto templateIdx = static_cast<size_t>(RequestTemplate::kZeroShutterLag); - default_requests_[templateIdx] = HalCameraMetadata::Create(1, 10); - } - - return InitializeInfoDefaults(); -} - status_t EmulatedRequestState::Initialize( - std::unique_ptr<HalCameraMetadata> staticMeta) { + std::unique_ptr<EmulatedCameraDeviceInfo> deviceInfo) { std::lock_guard<std::mutex> lock(request_state_mutex_); - static_metadata_ = std::move(staticMeta); + device_info_ = std::move(deviceInfo); - return InitializeRequestDefaults(); + return OK; } status_t EmulatedRequestState::GetDefaultRequest( @@ -3041,13 +1106,13 @@ status_t EmulatedRequestState::GetDefaultRequest( return BAD_VALUE; } - if (default_requests_[idx].get() == nullptr) { + if (device_info_->default_requests_[idx].get() == nullptr) { ALOGE("%s: Unsupported request type: %d", __FUNCTION__, type); return BAD_VALUE; } - *default_settings = - HalCameraMetadata::Clone(default_requests_[idx]->GetRawCameraMetadata()); + *default_settings = HalCameraMetadata::Clone( + device_info_->default_requests_[idx]->GetRawCameraMetadata()); return OK; } diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.h b/devices/EmulatedCamera/hwl/EmulatedRequestState.h index 79ad968..4900635 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestState.h +++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.h @@ -20,6 +20,7 @@ #include <mutex> #include <unordered_map> +#include "EmulatedCameraDeviceInfo.h" #include "EmulatedSensor.h" #include "hwl_types.h" @@ -29,6 +30,7 @@ using google_camera_hal::HalCameraMetadata; using google_camera_hal::HalStream; using google_camera_hal::HwlPipelineCallback; using google_camera_hal::HwlPipelineRequest; +using google_camera_hal::kTemplateCount; using google_camera_hal::RequestTemplate; struct PendingRequest; @@ -40,7 +42,7 @@ class EmulatedRequestState { virtual ~EmulatedRequestState() { } - status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta); + status_t Initialize(std::unique_ptr<EmulatedCameraDeviceInfo> static_meta); status_t GetDefaultRequest( RequestTemplate type, @@ -59,32 +61,6 @@ class EmulatedRequestState { uint32_t GetPartialResultCount(bool is_partial_result); private: - bool SupportsCapability(uint8_t cap); - - status_t InitializeRequestDefaults(); - status_t InitializeSensorDefaults(); - status_t InitializeFlashDefaults(); - status_t InitializeControlDefaults(); - status_t InitializeControlAEDefaults(); - status_t InitializeControlAWBDefaults(); - status_t InitializeControlAFDefaults(); - status_t InitializeControlSceneDefaults(); - status_t InitializeHotPixelDefaults(); - status_t InitializeStatisticsDefaults(); - status_t InitializeTonemapDefaults(); - status_t InitializeBlackLevelDefaults(); - status_t InitializeEdgeDefaults(); - status_t InitializeShadingDefaults(); - status_t InitializeNoiseReductionDefaults(); - status_t InitializeColorCorrectionDefaults(); - status_t InitializeScalerDefaults(); - status_t InitializeReprocessDefaults(); - status_t InitializeMeteringRegionDefault(uint32_t tag, - int32_t* region /*out*/); - status_t InitializeControlefaults(); - status_t InitializeInfoDefaults(); - status_t InitializeLensDefaults(); - status_t ProcessAE(); status_t ProcessAF(); status_t ProcessAWB(); @@ -98,129 +74,9 @@ class EmulatedRequestState { std::unique_ptr<HalCameraMetadata> request_settings_; // Supported capabilities and features - static const std::set<uint8_t> kSupportedCapabilites; - static const std::set<uint8_t> kSupportedHWLevels; - std::unique_ptr<HalCameraMetadata> static_metadata_; - static const std::vector<int64_t> kSupportedUseCases; - - // android.blacklevel.* - uint8_t black_level_lock_ = ANDROID_BLACK_LEVEL_LOCK_ON; - bool report_black_level_lock_ = false; - - // android.colorcorrection.* - std::set<uint8_t> available_color_aberration_modes_; - - // android.edge.* - std::set<uint8_t> available_edge_modes_; - bool report_edge_mode_ = false; - - // android.shading.* - std::set<uint8_t> available_shading_modes_; - - // android.noiseReduction.* - std::set<uint8_t> available_noise_reduction_modes_; - - // android.request.* - std::set<uint8_t> available_capabilities_; - std::set<int32_t> available_characteristics_; - std::set<int32_t> available_results_; - std::set<int32_t> available_requests_; - uint8_t max_pipeline_depth_ = 0; - bool supports_manual_sensor_ = false; - bool supports_manual_post_processing_ = false; - bool is_backward_compatible_ = false; - bool is_raw_capable_ = false; - bool supports_private_reprocessing_ = false; - bool supports_yuv_reprocessing_ = false; - bool supports_remosaic_reprocessing_ = false; - bool supports_stream_use_case_ = false; - uint8_t partial_result_count = 1; - - // android.control.* - struct SceneOverride { - uint8_t ae_mode, awb_mode, af_mode; - SceneOverride() - : ae_mode(ANDROID_CONTROL_AE_MODE_OFF), - awb_mode(ANDROID_CONTROL_AWB_MODE_OFF), - af_mode(ANDROID_CONTROL_AF_MODE_OFF) { - } - SceneOverride(uint8_t ae, uint8_t awb, uint8_t af) - : ae_mode(ae), awb_mode(awb), af_mode(af) { - } - }; - - struct FPSRange { - int32_t min_fps, max_fps; - FPSRange() : min_fps(-1), max_fps(-1) { - } - FPSRange(int32_t min, int32_t max) : min_fps(min), max_fps(max) { - } - }; + std::unique_ptr<EmulatedCameraDeviceInfo> device_info_; - struct ExtendedSceneModeCapability { - int32_t mode, max_width, max_height; - float min_zoom, max_zoom; - ExtendedSceneModeCapability() - : mode(ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED), - max_width(-1), - max_height(-1), - min_zoom(1.0f), - max_zoom(1.0f) { - } - ExtendedSceneModeCapability(int32_t m, int32_t w, int32_t h, float min_z, - float max_z) - : mode(m), max_width(w), max_height(h), min_zoom(min_z), max_zoom(max_z) { - } - }; - - std::set<uint8_t> available_control_modes_; - std::set<uint8_t> available_ae_modes_; - std::set<uint8_t> available_af_modes_; - std::set<uint8_t> available_awb_modes_; - std::set<uint8_t> available_scenes_; - std::set<uint8_t> available_antibanding_modes_; - std::set<uint8_t> available_effects_; - std::set<uint8_t> available_vstab_modes_; - std::set<uint8_t> available_sensor_pixel_modes_; - std::vector<ExtendedSceneModeCapability> available_extended_scene_mode_caps_; - std::unordered_map<uint8_t, SceneOverride> scene_overrides_; - std::vector<FPSRange> available_fps_ranges_; - int32_t exposure_compensation_range_[2] = {0, 0}; - float max_zoom_ = 1.0f; - bool zoom_ratio_supported_ = false; - float min_zoom_ = 1.0f; - camera_metadata_rational exposure_compensation_step_ = {0, 1}; - bool exposure_compensation_supported_ = false; - int32_t exposure_compensation_ = 0; - int32_t ae_metering_region_[5] = {0, 0, 0, 0, 0}; - int32_t awb_metering_region_[5] = {0, 0, 0, 0, 0}; - int32_t af_metering_region_[5] = {0, 0, 0, 0, 0}; - size_t max_ae_regions_ = 0; - size_t max_awb_regions_ = 0; - size_t max_af_regions_ = 0; - uint8_t control_mode_ = ANDROID_CONTROL_MODE_AUTO; - uint8_t sensor_pixel_mode_ = ANDROID_SENSOR_PIXEL_MODE_DEFAULT; - uint8_t scene_mode_ = ANDROID_CONTROL_SCENE_MODE_DISABLED; - uint8_t ae_mode_ = ANDROID_CONTROL_AE_MODE_ON; - uint8_t awb_mode_ = ANDROID_CONTROL_AWB_MODE_AUTO; - uint8_t af_mode_ = ANDROID_CONTROL_AF_MODE_AUTO; - uint8_t ae_lock_ = ANDROID_CONTROL_AE_LOCK_OFF; - uint8_t ae_state_ = ANDROID_CONTROL_AE_STATE_INACTIVE; - uint8_t awb_state_ = ANDROID_CONTROL_AWB_STATE_INACTIVE; - uint8_t awb_lock_ = ANDROID_CONTROL_AWB_LOCK_OFF; - uint8_t af_state_ = ANDROID_CONTROL_AF_STATE_INACTIVE; - uint8_t af_trigger_ = ANDROID_CONTROL_AF_TRIGGER_IDLE; - uint8_t ae_trigger_ = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; - uint8_t autoframing_ = ANDROID_CONTROL_AUTOFRAMING_OFF; - FPSRange ae_target_fps_ = {0, 0}; - float zoom_ratio_ = 1.0f; - uint8_t extended_scene_mode_ = ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED; - static const int32_t kMinimumStreamingFPS = 20; - bool ae_lock_available_ = false; - bool report_ae_lock_ = false; - bool scenes_supported_ = false; size_t ae_frame_counter_ = 0; - bool vstab_available_ = false; const size_t kAEPrecaptureMinFrames = 10; // Fake AE related constants const float kExposureTrackRate = .2f; // This is the rate at which the fake @@ -233,98 +89,13 @@ class EmulatedRequestState { const float kExposureWanderMax = 1; const uint32_t kAETargetThreshold = 10; // Defines a threshold for reaching the AE target - int32_t post_raw_boost_ = 100; - bool report_post_raw_boost_ = false; nsecs_t ae_target_exposure_time_ = EmulatedSensor::kDefaultExposureTime; nsecs_t current_exposure_time_ = EmulatedSensor::kDefaultExposureTime; - bool awb_lock_available_ = false; - bool report_awb_lock_ = false; bool af_mode_changed_ = false; - bool af_supported_ = false; - bool picture_caf_supported_ = false; - bool video_caf_supported_ = false; - int32_t settings_override_ = ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF; uint32_t settings_overriding_frame_number_ = 0; - // android.flash.* - bool is_flash_supported_ = false; - uint8_t flash_state_ = ANDROID_FLASH_STATE_UNAVAILABLE; - int32_t flash_strength_level_ = 1; - - // android.sensor.* - std::pair<int32_t, int32_t> sensor_sensitivity_range_; - std::pair<nsecs_t, nsecs_t> sensor_exposure_time_range_; - nsecs_t sensor_max_frame_duration_ = - EmulatedSensor::kSupportedFrameDurationRange[1]; - nsecs_t sensor_exposure_time_ = EmulatedSensor::kDefaultExposureTime; - nsecs_t sensor_frame_duration_ = EmulatedSensor::kDefaultFrameDuration; - int32_t sensor_sensitivity_ = EmulatedSensor::kDefaultSensitivity; - bool report_frame_duration_ = false; - bool report_sensitivity_ = false; - bool report_exposure_time_ = false; - std::set<int32_t> available_test_pattern_modes_; - bool report_rolling_shutter_skew_ = false; - bool report_neutral_color_point_ = false; - bool report_green_split_ = false; - bool report_noise_profile_ = false; - bool report_extended_scene_mode_ = false; - uint32_t timestamp_source_ = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN; - - // android.scaler.* - bool report_rotate_and_crop_ = false; - uint8_t rotate_and_crop_ = ANDROID_SCALER_ROTATE_AND_CROP_NONE; - int32_t scaler_crop_region_default_[4] = {0, 0, 0, 0}; - int32_t scaler_crop_region_max_resolution_[4] = {0, 0, 0, 0}; - std::set<uint8_t> available_rotate_crop_modes_; - - // android.statistics.* - std::set<uint8_t> available_hot_pixel_map_modes_; - std::set<uint8_t> available_lens_shading_map_modes_; - std::set<uint8_t> available_face_detect_modes_; - uint8_t current_scene_flicker_ = ANDROID_STATISTICS_SCENE_FLICKER_NONE; - bool report_scene_flicker_ = false; - - // android.tonemap.* - std::set<uint8_t> available_tonemap_modes_; - - // android.info.* - uint8_t supported_hw_level_ = 0; - static const size_t kTemplateCount = - static_cast<size_t>(RequestTemplate::kManual) + 1; - std::unique_ptr<HalCameraMetadata> default_requests_[kTemplateCount]; - // Set to true if the camera device has HW level FULL or LEVEL3 - bool is_level_full_or_higher_ = false; - - // android.lens.* - float minimum_focus_distance_ = 0.f; - float aperture_ = 0.f; - float focal_length_ = 0.f; - float focus_distance_ = 0.f; - bool report_focus_distance_ = false; - uint8_t lens_state_ = ANDROID_LENS_STATE_STATIONARY; - bool report_focus_range_ = false; - float filter_density_ = 0.f; - bool report_filter_density_ = false; - std::set<uint8_t> available_ois_modes_; - uint8_t ois_mode_ = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; - bool report_ois_mode_ = false; - float pose_rotation_[4] = {.0f}; - float pose_translation_[3] = {.0f}; - float distortion_[5] = {.0f}; - float intrinsic_calibration_[5] = {.0f}; - bool report_pose_rotation_ = false; - bool report_pose_translation_ = false; - bool report_distortion_ = false; - bool report_intrinsic_calibration_ = false; - bool report_active_sensor_crop_ = false; - bool report_lens_intrinsics_samples_ = false; - int32_t shading_map_size_[2] = {0}; - unsigned int rand_seed_ = 1; - // android.hotpixel.* - std::set<uint8_t> available_hot_pixel_modes_; - uint32_t camera_id_; EmulatedRequestState(const EmulatedRequestState&) = delete; diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp index f96a565..79cedcc 100644 --- a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp @@ -624,6 +624,9 @@ bool EmulatedSensor::IsStreamCombinationSupported( return false; } + // TODO: Check session parameters. For now assuming all combinations + // are supported. + return true; } |