diff options
24 files changed, 4552 insertions, 1235 deletions
diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp index a8d7f2c..0295e95 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2019 The Android Open Source Project + * Copyright (C) 2019 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. @@ -28,9 +28,11 @@ namespace android { std::unique_ptr<CameraDeviceHwl> EmulatedCameraDeviceHwlImpl::Create( uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state) { auto device = std::unique_ptr<EmulatedCameraDeviceHwlImpl>( new EmulatedCameraDeviceHwlImpl(camera_id, std::move(static_meta), + std::move(physical_devices), torch_state)); if (device == nullptr) { @@ -53,11 +55,12 @@ std::unique_ptr<CameraDeviceHwl> EmulatedCameraDeviceHwlImpl::Create( EmulatedCameraDeviceHwlImpl::EmulatedCameraDeviceHwlImpl( uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state) : camera_id_(camera_id), static_metadata_(std::move(static_meta)), - torch_state_(torch_state) { -} + physical_device_map_(std::move(physical_devices)), + torch_state_(torch_state) {} uint32_t EmulatedCameraDeviceHwlImpl::GetCameraId() const { return camera_id_; @@ -97,9 +100,27 @@ status_t EmulatedCameraDeviceHwlImpl::GetCameraCharacteristics( } status_t EmulatedCameraDeviceHwlImpl::GetPhysicalCameraCharacteristics( - uint32_t /*physical_camera_id*/, - std::unique_ptr<HalCameraMetadata>* /*characteristics*/) const { - // TODO: Logical camera support + uint32_t physical_camera_id, + std::unique_ptr<HalCameraMetadata>* characteristics) const { + if (characteristics == nullptr) { + return BAD_VALUE; + } + + if (physical_device_map_.get() == nullptr) { + ALOGE("%s: Camera %d is not a logical device!", __func__, camera_id_); + return NO_INIT; + } + + if (physical_device_map_->find(physical_camera_id) == + physical_device_map_->end()) { + ALOGE("%s: Physical camera id %d is not part of logical camera %d!", + __func__, physical_camera_id, camera_id_); + return NO_INIT; + } + + *characteristics = HalCameraMetadata::Clone( + physical_device_map_->at(physical_camera_id).get()); + return OK; } @@ -126,7 +147,8 @@ status_t EmulatedCameraDeviceHwlImpl::CreateCameraDeviceSessionHwl( std::unique_ptr<HalCameraMetadata> meta = HalCameraMetadata::Clone(static_metadata_.get()); *session = EmulatedCameraDeviceSessionHwlImpl::Create( - camera_id_, std::move(meta), torch_state_); + camera_id_, std::move(meta), 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 2bfe677..90352f5 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h @@ -22,6 +22,7 @@ #include "EmulatedSensor.h" #include "EmulatedTorchState.h" +#include "utils/HWLUtils.h" #include "utils/StreamConfigurationMap.h" namespace android { @@ -38,6 +39,7 @@ class EmulatedCameraDeviceHwlImpl : public CameraDeviceHwl { public: static std::unique_ptr<CameraDeviceHwl> Create( uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state); virtual ~EmulatedCameraDeviceHwlImpl() = default; @@ -68,16 +70,18 @@ class EmulatedCameraDeviceHwlImpl : public CameraDeviceHwl { // End of override functions in CameraDeviceHwl. private: - const uint32_t camera_id_ = 0; - EmulatedCameraDeviceHwlImpl(uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state); status_t Initialize(); + const uint32_t camera_id_ = 0; + std::unique_ptr<HalCameraMetadata> static_metadata_; std::unique_ptr<StreamConfigurationMap> stream_coniguration_map_; + PhysicalDeviceMapPtr physical_device_map_; std::shared_ptr<EmulatedTorchState> torch_state_; SensorCharacteristics sensor_chars_; }; diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp index 29d5b33..eead2c5 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp @@ -31,6 +31,7 @@ namespace android { std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl> EmulatedCameraDeviceSessionHwlImpl::Create( uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state) { ATRACE_CALL(); if (static_meta.get() == nullptr) { @@ -38,7 +39,8 @@ EmulatedCameraDeviceSessionHwlImpl::Create( } auto session = std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl>( - new EmulatedCameraDeviceSessionHwlImpl(torch_state)); + new EmulatedCameraDeviceSessionHwlImpl(std::move(physical_devices), + torch_state)); if (session == nullptr) { ALOGE("%s: Creating EmulatedCameraDeviceSessionHwlImpl failed", __FUNCTION__); @@ -78,8 +80,21 @@ status_t EmulatedCameraDeviceSessionHwlImpl::Initialize( return ret; } + auto logical_chars = std::make_unique<LogicalCharacteristics>(); + logical_chars->emplace(camera_id_, sensor_chars_); + for (const auto& it : *physical_device_map_) { + SensorCharacteristics physical_chars; + auto stat = GetSensorCharacteristics(it.second.get(), &physical_chars); + if (stat == OK) { + logical_chars->emplace(it.first, physical_chars); + } else { + ALOGE("%s: Unable to extract physical device: %u characteristics %s (%d)", + __FUNCTION__, it.first, strerror(-ret), ret); + return ret; + } + } sp<EmulatedSensor> emulated_sensor = new EmulatedSensor(); - ret = emulated_sensor->StartUp(sensor_chars_); + ret = emulated_sensor->StartUp(camera_id_, std::move(logical_chars)); if (ret != OK) { ALOGE("%s: Failed on sensor start up %s (%d)", __FUNCTION__, strerror(-ret), ret); @@ -90,7 +105,8 @@ status_t EmulatedCameraDeviceSessionHwlImpl::Initialize( std::make_unique<EmulatedRequestProcessor>(camera_id_, emulated_sensor); return request_processor_->Initialize( - HalCameraMetadata::Clone(static_metadata_.get())); + HalCameraMetadata::Clone(static_metadata_.get()), + ClonePhysicalDeviceMap(physical_device_map_)); } EmulatedCameraDeviceSessionHwlImpl::~EmulatedCameraDeviceSessionHwlImpl() { @@ -130,6 +146,16 @@ status_t EmulatedCameraDeviceSessionHwlImpl::ConfigurePipeline( return BAD_VALUE; } + if ((physical_camera_id != camera_id_) && + (physical_device_map_.get() != nullptr)) { + if (physical_device_map_->find(physical_camera_id) == + physical_device_map_->end()) { + ALOGE("%s: Camera: %d doesn't include physical device with id: %u", + __FUNCTION__, camera_id_, physical_camera_id); + return BAD_VALUE; + } + } + *pipeline_id = pipelines_.size(); EmulatedPipeline emulated_pipeline{.cb = hwl_pipeline_callback, .pipeline_id = *pipeline_id, @@ -274,8 +300,18 @@ uint32_t EmulatedCameraDeviceSessionHwlImpl::GetCameraId() const { std::vector<uint32_t> EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraIds() const { - // TODO: Logical camera support - return std::vector<uint32_t>{}; + if ((physical_device_map_.get() == nullptr) || + (physical_device_map_->empty())) { + return std::vector<uint32_t>{}; + } + + std::vector<uint32_t> ret; + ret.reserve(physical_device_map_->size()); + for (const auto& it : *physical_device_map_) { + ret.push_back(it.first); + } + + return ret; } status_t EmulatedCameraDeviceSessionHwlImpl::GetCameraCharacteristics( @@ -296,14 +332,29 @@ status_t EmulatedCameraDeviceSessionHwlImpl::GetCameraCharacteristics( } status_t EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraCharacteristics( - uint32_t /*physical_camera_id*/, + uint32_t physical_camera_id, std::unique_ptr<HalCameraMetadata>* characteristics) const { ATRACE_CALL(); if (characteristics == nullptr) { return BAD_VALUE; } - // TODO: Add logical stream support + if (physical_device_map_.get() == nullptr) { + ALOGE("%s: Camera: %d doesn't have physical device support!", __FUNCTION__, + camera_id_); + return BAD_VALUE; + } + + if (physical_device_map_->find(physical_camera_id) == + physical_device_map_->end()) { + ALOGE("%s: Camera: %d doesn't include physical device with id: %u", + __FUNCTION__, camera_id_, physical_camera_id); + return BAD_VALUE; + } + + (*characteristics) = HalCameraMetadata::Clone( + physical_device_map_->at(physical_camera_id).get()); + return OK; } diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h index 980540f..f576021 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h @@ -24,6 +24,7 @@ #include "EmulatedCameraDeviceHWLImpl.h" #include "EmulatedRequestProcessor.h" #include "EmulatedTorchState.h" +#include "multicam_coordinator_hwl.h" #include "utils/StreamConfigurationMap.h" namespace android { @@ -31,12 +32,15 @@ namespace android { using google_camera_hal::CameraDeviceHwl; using google_camera_hal::CameraDeviceSessionHwl; using google_camera_hal::HalStream; +using google_camera_hal::HwlOfflinePipelineRole; using google_camera_hal::HwlPipelineCallback; using google_camera_hal::HwlPipelineRequest; using google_camera_hal::HwlSessionCallback; +using google_camera_hal::IMulticamCoordinatorHwl; using google_camera_hal::StreamConfiguration; using google_camera_hal::RequestTemplate; using google_camera_hal::SessionDataKey; +using google_camera_hal::Stream; using google_camera_hal::StreamConfiguration; // Implementation of CameraDeviceSessionHwl interface @@ -44,6 +48,7 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { public: static std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl> Create( uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state); virtual ~EmulatedCameraDeviceSessionHwlImpl(); @@ -71,6 +76,13 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { return OK; } // Noop for now + status_t GetRequiredIntputStreams(const StreamConfiguration& /*overall_config*/, + HwlOfflinePipelineRole /*pipeline_role*/, + std::vector<Stream>* /*streams*/) override { + // N/A + return INVALID_OPERATION; + } + status_t GetConfiguredHalStream( uint32_t pipeline_id, std::vector<HalStream>* hal_streams) const override; @@ -93,7 +105,9 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { uint32_t physical_camera_id, std::unique_ptr<HalCameraMetadata>* characteristics) const override; - status_t SetSessionData(SessionDataKey /*key*/, void* /*value*/) override { + status_t SetSessionData(SessionDataKey /*key*/ + , + void* /*value*/) override { return OK; } // Noop for now @@ -110,6 +124,10 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { return OK; } // Noop for now + std::unique_ptr<IMulticamCoordinatorHwl> CreateMulticamCoordinatorHwl() + override { + return nullptr; + } // End override functions in CameraDeviceSessionHwl private: @@ -117,8 +135,10 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { std::unique_ptr<HalCameraMetadata> static_meta); EmulatedCameraDeviceSessionHwlImpl( + PhysicalDeviceMapPtr physical_devices, std::shared_ptr<EmulatedTorchState> torch_state) - : torch_state_(torch_state) { + : torch_state_(torch_state), + physical_device_map_(std::move(physical_devices)) { } uint8_t max_pipeline_depth_ = 0; @@ -134,6 +154,7 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { std::unique_ptr<StreamConfigurationMap> stream_coniguration_map_; SensorCharacteristics sensor_chars_; std::shared_ptr<EmulatedTorchState> torch_state_; + PhysicalDeviceMapPtr physical_device_map_; }; } // namespace android diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.cpp index ab21c96..2782783 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2019 The Android Open Source Project + * Copyright (C) 2019 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. @@ -24,6 +24,7 @@ #include "EmulatedCameraDeviceHWLImpl.h" #include "EmulatedCameraDeviceSessionHWLImpl.h" +#include "EmulatedLogicalRequestState.h" #include "EmulatedSensor.h" #include "EmulatedTorchState.h" #include "camera_common.h" @@ -34,9 +35,9 @@ namespace android { // Location of the camera configuration files. const char* EmulatedCameraProviderHwlImpl::kConfigurationFileLocation[] = { - "/vendor/etc/config/camera.json", - "/vendor/etc/config/camera_front.json", - "/vendor/etc/config/camera_depth.json", + "/vendor/etc/config/emu_camera_back.json", + "/vendor/etc/config/emu_camera_front.json", + "/vendor/etc/config/emu_camera_depth.json", }; std::unique_ptr<EmulatedCameraProviderHwlImpl> @@ -177,6 +178,7 @@ status_t GetUInt8Value(const Json::Value& value, uint32_t tag_id, if ((int_value >= 0) && (int_value <= UINT8_MAX) && (errno == 0)) { *result = int_value; } else { + ALOGE("%s: Failed parsing tag id 0x%x", __func__, tag_id); return BAD_VALUE; } } else { @@ -206,6 +208,7 @@ status_t GetInt32Value(const Json::Value& value, uint32_t tag_id, if ((int_value >= INT32_MIN) && (int_value <= INT32_MAX) && (errno == 0)) { *result = int_value; } else { + ALOGE("%s: Failed parsing tag id 0x%x", __func__, tag_id); return BAD_VALUE; } } else { @@ -222,7 +225,7 @@ status_t GetInt32Value(const Json::Value& value, uint32_t tag_id, return OK; } -status_t GetInt64Value(const Json::Value& value, uint32_t /*tag_id*/, +status_t GetInt64Value(const Json::Value& value, uint32_t tag_id, int64_t* result /*out*/) { if (result == nullptr) { return BAD_VALUE; @@ -230,9 +233,12 @@ status_t GetInt64Value(const Json::Value& value, uint32_t /*tag_id*/, if (value.isString()) { errno = 0; - auto int_value = strtol(value.asCString(), nullptr, 10); + auto int_value = strtoll(value.asCString(), nullptr, 10); if ((int_value >= INT64_MIN) && (int_value <= INT64_MAX) && (errno == 0)) { *result = int_value; + } else { + ALOGE("%s: Failed parsing tag id 0x%x", __func__, tag_id); + return BAD_VALUE; } } else { ALOGE( @@ -245,7 +251,7 @@ status_t GetInt64Value(const Json::Value& value, uint32_t /*tag_id*/, return OK; } -status_t GetFloatValue(const Json::Value& value, uint32_t /*tag_id*/, +status_t GetFloatValue(const Json::Value& value, uint32_t tag_id, float* result /*out*/) { if (result == nullptr) { return BAD_VALUE; @@ -256,6 +262,9 @@ status_t GetFloatValue(const Json::Value& value, uint32_t /*tag_id*/, auto float_value = strtof(value.asCString(), nullptr); if (errno == 0) { *result = float_value; + } else { + ALOGE("%s: Failed parsing tag id 0x%x", __func__, tag_id); + return BAD_VALUE; } } else { ALOGE( @@ -268,7 +277,7 @@ status_t GetFloatValue(const Json::Value& value, uint32_t /*tag_id*/, return OK; } -status_t GetDoubleValue(const Json::Value& value, uint32_t /*tag_id*/, +status_t GetDoubleValue(const Json::Value& value, uint32_t tag_id, double* result /*out*/) { if (result == nullptr) { return BAD_VALUE; @@ -279,6 +288,9 @@ status_t GetDoubleValue(const Json::Value& value, uint32_t /*tag_id*/, auto double_value = strtod(value.asCString(), nullptr); if (errno == 0) { *result = double_value; + } else { + ALOGE("%s: Failed parsing tag id 0x%x", __func__, tag_id); + return BAD_VALUE; } } else { ALOGE( @@ -382,11 +394,11 @@ status_t InsertRationalTag(const Json::Value& json_value, uint32_t tag_id, return ret; } -status_t EmulatedCameraProviderHwlImpl::ParseCharacteristics( - const Json::Value& value) { +uint32_t EmulatedCameraProviderHwlImpl::ParseCharacteristics( + const Json::Value& value, ssize_t id) { if (!value.isObject()) { ALOGE("%s: Configuration root is not an object", __FUNCTION__); - return false; + return BAD_VALUE; } auto static_meta = HalCameraMetadata::Create(1, 10); @@ -438,18 +450,27 @@ status_t EmulatedCameraProviderHwlImpl::ParseCharacteristics( return BAD_VALUE; } - // TODO: This probably should not be expected by GCH from every HWL impl. - // Adding anyhow to pass CTS + // Although we don't support HdrPlus, this data is still required by HWL int32_t payload_frames = 0; static_meta->Set(google_camera_hal::kHdrplusPayloadFrames, &payload_frames, 1); - static_metadata_.push_back(std::move(static_meta)); + if (id < 0) { + static_metadata_.push_back(std::move(static_meta)); + id = static_metadata_.size() - 1; + } else { + static_metadata_[id] = std::move(static_meta); + } - return OK; + return id; } status_t EmulatedCameraProviderHwlImpl::Initialize() { + // GCH expects all physical ids to be bigger than the logical ones. + // Resize 'static_metadata_' to fit all logical devices and insert them + // accordingly, push any remaining physical cameras in the back. std::string config; + static_metadata_.resize(ARRAY_SIZE(kConfigurationFileLocation)); + size_t logical_id = 0; for (const auto& config_path : kConfigurationFileLocation) { if (!android::base::ReadFileToString(config_path, &config)) { ALOGW("%s: Could not open configuration file: %s", __FUNCTION__, @@ -465,10 +486,57 @@ status_t EmulatedCameraProviderHwlImpl::Initialize() { return BAD_VALUE; } - auto ret = ParseCharacteristics(root); - if (ret != OK) { - return ret; + if (root.isArray()) { + auto device_iter = root.begin(); + auto result_id = ParseCharacteristics(*device_iter, logical_id); + if (logical_id != result_id) { + return result_id; + } + device_iter++; + + // The first device entry is always the logical camera followed by the + // physical devices. They must be at least 2. + camera_id_map_.emplace(logical_id, std::vector<uint32_t>()); + if (root.size() >= 3) { + camera_id_map_[logical_id].reserve(root.size() - 1); + while (device_iter != root.end()) { + auto physical_id = ParseCharacteristics(*device_iter, /*id*/ -1); + if (physical_id < 0) { + return physical_id; + } + camera_id_map_[logical_id].push_back(physical_id); + + device_iter++; + } + + auto physical_devices = std::make_unique<PhysicalDeviceMap>(); + for (const auto& physical_device_id : camera_id_map_[logical_id]) { + physical_devices->emplace( + physical_device_id, + HalCameraMetadata::Clone( + static_metadata_[physical_device_id].get())); + } + auto updated_logical_chars = + EmulatedLogicalRequestState::AdaptLogicalCharacteristics( + HalCameraMetadata::Clone(static_metadata_[logical_id].get()), + std::move(physical_devices)); + if (updated_logical_chars.get() != nullptr) { + static_metadata_[logical_id].swap(updated_logical_chars); + } else { + ALOGE("%s: Failed to updating logical camera characteristics!", + __FUNCTION__); + return BAD_VALUE; + } + } + } else { + auto result_id = ParseCharacteristics(root, logical_id); + if (result_id != logical_id) { + return result_id; + } + camera_id_map_.emplace(logical_id, std::vector<uint32_t>()); } + + logical_id++; } return OK; @@ -499,26 +567,27 @@ status_t EmulatedCameraProviderHwlImpl::GetVisibleCameraIds( return BAD_VALUE; } - for (size_t cameraId = 0; cameraId < static_metadata_.size(); cameraId++) { - camera_ids->push_back(cameraId); + for (const auto& device : camera_id_map_) { + camera_ids->push_back(device.first); } return OK; } status_t EmulatedCameraProviderHwlImpl::CreateCameraDeviceHwl( - uint32_t cameraId, std::unique_ptr<CameraDeviceHwl>* camera_device_hwl) { + uint32_t camera_id, std::unique_ptr<CameraDeviceHwl>* camera_device_hwl) { if (camera_device_hwl == nullptr) { ALOGE("%s: camera_device_hwl is nullptr.", __FUNCTION__); return BAD_VALUE; } - if (cameraId >= static_metadata_.size()) { + if (camera_id_map_.find(camera_id) == camera_id_map_.end()) { + ALOGE("%s: Invalid camera id: %u", __func__, camera_id); return BAD_VALUE; } std::unique_ptr<HalCameraMetadata> meta = - HalCameraMetadata::Clone(static_metadata_[cameraId].get()); + HalCameraMetadata::Clone(static_metadata_[camera_id].get()); std::shared_ptr<EmulatedTorchState> torch_state; camera_metadata_ro_entry entry; @@ -531,11 +600,17 @@ status_t EmulatedCameraProviderHwlImpl::CreateCameraDeviceHwl( } if (flash_supported) { - torch_state = std::make_shared<EmulatedTorchState>(cameraId, torch_cb_); + torch_state = std::make_shared<EmulatedTorchState>(camera_id, torch_cb_); } + auto physical_devices = std::make_unique<PhysicalDeviceMap>(); + for (const auto& physical_device_id : camera_id_map_[camera_id]) { + physical_devices->emplace( + physical_device_id, + HalCameraMetadata::Clone(static_metadata_[physical_device_id].get())); + } *camera_device_hwl = EmulatedCameraDeviceHwlImpl::Create( - cameraId, std::move(meta), torch_state); + camera_id, std::move(meta), std::move(physical_devices), torch_state); if (*camera_device_hwl == nullptr) { ALOGE("%s: Cannot create EmulatedCameraDeviceHWlImpl.", __FUNCTION__); return BAD_VALUE; @@ -551,9 +626,8 @@ status_t EmulatedCameraProviderHwlImpl::CreateBufferAllocatorHwl( return BAD_VALUE; } - // TODO: Initialize an emulated buffer allocator - - return OK; + // Currently not supported + return INVALID_OPERATION; } } // namespace android diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.h index 5acb3a4..8904795 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.h +++ b/devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2019 The Android Open Source Project + * Copyright (C) 2019 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. @@ -62,12 +62,15 @@ class EmulatedCameraProviderHwlImpl : public CameraProviderHwl { private: status_t Initialize(); - status_t ParseCharacteristics(const Json::Value& root); + uint32_t ParseCharacteristics(const Json::Value& root, ssize_t id); status_t GetTagFromName(const char* name, uint32_t* tag); static const char* kConfigurationFileLocation[]; std::vector<std::unique_ptr<HalCameraMetadata>> static_metadata_; + // Logical to physical camera Id mapping. Empty value vector in case + // of regular non-logical device. + std::unordered_map<uint32_t, std::vector<uint32_t>> camera_id_map_; HwlTorchModeStatusChangeFunc torch_cb_; }; diff --git a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.cpp b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.cpp new file mode 100644 index 0000000..ec7d0fb --- /dev/null +++ b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2019 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 "EmulatedLogicalState" +#define ATRACE_TAG ATRACE_TAG_CAMERA + +#include "EmulatedLogicalRequestState.h" + +#include <log/log.h> + +#include "vendor_tag_defs.h" + +namespace android { + +EmulatedLogicalRequestState::EmulatedLogicalRequestState(uint32_t camera_id) + : logical_camera_id_(camera_id), + logical_request_state_(std::make_unique<EmulatedRequestState>(camera_id)) { +} + +EmulatedLogicalRequestState::~EmulatedLogicalRequestState() { +} + +status_t EmulatedLogicalRequestState::Initialize( + std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices) { + if ((physical_devices.get() != nullptr) && (!physical_devices->empty())) { + physical_device_map_ = std::move(physical_devices); + // If possible map the available focal lengths to individual physical devices + camera_metadata_ro_entry_t logical_entry, physical_entry; + auto ret = static_meta->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, + &logical_entry); + if ((ret == OK) && (logical_entry.count > 1)) { + for (size_t i = 0; i < logical_entry.count; i++) { + for (const auto& it : *physical_device_map_) { + ret = it.second->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, + &physical_entry); + if ((ret == OK) && (physical_entry.count > 0)) { + if (logical_entry.data.f[i] == physical_entry.data.f[0]) { + physical_focal_length_map_[physical_entry.data.f[0]] = it.first; + break; + } + } + } + } + } + + if (physical_focal_length_map_.size() > 1) { + is_logical_device_ = true; + current_focal_length_ = logical_entry.data.f[0]; + 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.get())); + if (ret != OK) { + ALOGE("%s: Physical device: %u request state initialization failed!", + __FUNCTION__, it.first); + return ret; + } + physical_request_states_.emplace(it.first, + std::move(physical_request_state)); + } + } + } + + return logical_request_state_->Initialize(std::move(static_meta)); +} + +status_t EmulatedLogicalRequestState::GetDefaultRequest( + RequestTemplate type, + std::unique_ptr<HalCameraMetadata>* default_settings /*out*/) { + return logical_request_state_->GetDefaultRequest(type, default_settings); +}; + +std::unique_ptr<HwlPipelineResult> +EmulatedLogicalRequestState::InitializeLogicalResult(uint32_t pipeline_id, + uint32_t frame_number) { + auto ret = logical_request_state_->InitializeResult(pipeline_id, frame_number); + if (is_logical_device_) { + if ((physical_camera_output_ids_.get() != nullptr) && + (!physical_camera_output_ids_->empty())) { + ret->physical_camera_results.reserve(physical_camera_output_ids_->size()); + for (const auto& it : *physical_camera_output_ids_) { + ret->physical_camera_results[it] = + std::move(physical_request_states_[it] + ->InitializeResult(pipeline_id, frame_number) + ->result_metadata); + } + } + auto physical_device_id = + std::to_string(physical_focal_length_map_[current_focal_length_]); + std::vector<uint8_t> result; + result.reserve(physical_device_id.size() + 1); + result.insert(result.end(), physical_device_id.begin(), + physical_device_id.end()); + result.push_back('\0'); + + ret->result_metadata->Set(ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID, + result.data(), result.size()); + } + + return ret; +} + +status_t EmulatedLogicalRequestState::InitializeLogicalSettings( + std::unique_ptr<HalCameraMetadata> request_settings, + std::unique_ptr<std::set<uint32_t>> physical_camera_output_ids, + EmulatedSensor::LogicalCameraSettings* logical_settings /*out*/) { + if (logical_settings == nullptr) { + return BAD_VALUE; + } + + // All logical and physical devices can potentially receive individual client + // requests (Currently this is not the case due to HWL API limitations). + // The emulated sensor can adapt its characteristics and apply most of them + // independently however the frame duration needs to be the same across all + // settings. + // Track the maximum frame duration and override this value at the end for all + // logical settings. + nsecs_t max_frame_duration = 0; + if (is_logical_device_) { + std::swap(physical_camera_output_ids_, physical_camera_output_ids); + + for (const auto& physical_request_state : physical_request_states_) { + // All physical devices will receive requests and will keep + // updating their respective request state. + // However only physical devices referenced by client need to propagate + // and apply their settings. + EmulatedSensor::SensorSettings physical_sensor_settings; + auto ret = physical_request_state.second->InitializeSensorSettings( + HalCameraMetadata::Clone(request_settings.get()), + &physical_sensor_settings); + if (ret != OK) { + ALOGE( + "%s: Initialization of physical sensor settings for device id: %u " + "failed!", + __FUNCTION__, physical_request_state.first); + return ret; + } + + if (physical_camera_output_ids_->find(physical_request_state.first) != + physical_camera_output_ids_->end()) { + logical_settings->emplace(physical_request_state.first, + physical_sensor_settings); + if (max_frame_duration < physical_sensor_settings.exposure_time) { + max_frame_duration = physical_sensor_settings.exposure_time; + } + } + } + + camera_metadata_ro_entry entry; + auto stat = request_settings->Get(ANDROID_LENS_FOCAL_LENGTH, &entry); + if ((stat == OK) && (entry.count == 1)) { + if (physical_focal_length_map_.find(entry.data.f[0]) != + physical_focal_length_map_.end()) { + current_focal_length_ = entry.data.f[0]; + } else { + ALOGE("%s: Unsupported focal length set: %5.2f, re-using older value!", + __FUNCTION__, entry.data.f[0]); + } + } else { + ALOGW("%s: Focal length absent from request, re-using older value!", + __FUNCTION__); + } + } + + EmulatedSensor::SensorSettings sensor_settings; + auto ret = logical_request_state_->InitializeSensorSettings( + std::move(request_settings), &sensor_settings); + logical_settings->emplace(logical_camera_id_, sensor_settings); + if (max_frame_duration < sensor_settings.exposure_time) { + max_frame_duration = sensor_settings.exposure_time; + } + + for (auto it : *logical_settings) { + it.second.frame_duration = max_frame_duration; + } + + return ret; +} + +std::unique_ptr<HalCameraMetadata> +EmulatedLogicalRequestState::AdaptLogicalCharacteristics( + std::unique_ptr<HalCameraMetadata> logical_chars, + PhysicalDeviceMapPtr physical_devices) { + if ((logical_chars.get() == nullptr) || (physical_devices.get() == nullptr)) { + return nullptr; + } + + // Update 'android.logicalMultiCamera.physicalIds' according to the newly + // assigned physical ids. + // Additionally if possible try to emulate a logical camera device backed by + // physical devices with different focal lengths. Usually real logical + // cameras like that will have device specific logic to switch between + // physical sensors. Unfortunately we cannot infer this behavior using only + // static camera characteristics. Instead of this, detect the different + // focal lengths and update the logical + // "android.lens.info.availableFocalLengths" accordingly. + std::vector<uint8_t> physical_ids; + std::set<float> focal_lengths; + camera_metadata_ro_entry_t entry; + for (const auto& physical_device : *physical_devices) { + auto physical_id = std::to_string(physical_device.first); + physical_ids.insert(physical_ids.end(), physical_id.begin(), + physical_id.end()); + physical_ids.push_back('\0'); + auto ret = physical_device.second->Get( + ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &entry); + if ((ret == OK) && (entry.count > 0)) { + focal_lengths.insert(entry.data.f, entry.data.f + entry.count); + } + } + logical_chars->Set(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, + physical_ids.data(), physical_ids.size()); + + if (focal_lengths.size() > 1) { + std::vector<float> focal_buffer; + focal_buffer.reserve(focal_lengths.size()); + focal_buffer.insert(focal_buffer.end(), focal_lengths.begin(), + focal_lengths.end()); + logical_chars->Set(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, + focal_buffer.data(), focal_buffer.size()); + + // Possibly needs to be removed at some later point: + int32_t default_physical_id = physical_devices->begin()->first; + logical_chars->Set(google_camera_hal::kLogicalCamDefaultPhysicalId, + &default_physical_id, 1); + + logical_chars->Get(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry); + std::set<int32_t> keys(entry.data.i32, entry.data.i32 + entry.count); + keys.emplace(ANDROID_LENS_FOCAL_LENGTH); + keys.emplace(ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID); + std::vector<int32_t> keys_buffer(keys.begin(), keys.end()); + logical_chars->Set(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, + keys_buffer.data(), keys_buffer.size()); + + keys.clear(); + keys_buffer.clear(); + logical_chars->Get(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry); + keys.insert(entry.data.i32, entry.data.i32 + entry.count); + // Due to API limitations we currently don't support individual physical requests + logical_chars->Erase(ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS); + keys.erase(ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS); + keys.emplace(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS); + keys.emplace(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS); + keys_buffer.insert(keys_buffer.end(), keys.begin(), keys.end()); + logical_chars->Set(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, + keys_buffer.data(), keys_buffer.size()); + + keys.clear(); + keys_buffer.clear(); + logical_chars->Get(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry); + keys.insert(entry.data.i32, entry.data.i32 + entry.count); + keys.emplace(ANDROID_LENS_FOCAL_LENGTH); + keys_buffer.insert(keys_buffer.end(), keys.begin(), keys.end()); + logical_chars->Set(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, + keys_buffer.data(), keys_buffer.size()); + } else { + ALOGW( + "%s: The logical camera doesn't support different focal lengths. " + "Emulation " + "could be" + " very limited in this case!", + __FUNCTION__); + } + + return logical_chars; +} + +} // namespace android diff --git a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h new file mode 100644 index 0000000..93b4c04 --- /dev/null +++ b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2019 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_LOGICAL_REQUEST_STATE_H +#define EMULATOR_CAMERA_HAL_LOGICAL_REQUEST_STATE_H + +#include "EmulatedRequestState.h" +#include "hwl_types.h" +#include "utils/HWLUtils.h" + +namespace android { + +using google_camera_hal::HalCameraMetadata; + +class EmulatedLogicalRequestState { + public: + EmulatedLogicalRequestState(uint32_t camera_id); + virtual ~EmulatedLogicalRequestState(); + + status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_device_map); + + status_t GetDefaultRequest( + RequestTemplate type, + std::unique_ptr<HalCameraMetadata>* default_settings /*out*/); + + std::unique_ptr<HwlPipelineResult> InitializeLogicalResult( + uint32_t pipeline_id, uint32_t frame_number); + + status_t InitializeLogicalSettings( + std::unique_ptr<HalCameraMetadata> request_settings, + std::unique_ptr<std::set<uint32_t>> physical_camera_output_ids, + EmulatedSensor::LogicalCameraSettings* logical_settings /*out*/); + + static std::unique_ptr<HalCameraMetadata> AdaptLogicalCharacteristics( + std::unique_ptr<HalCameraMetadata> logical_chars, + PhysicalDeviceMapPtr physical_devices); + + private: + uint32_t logical_camera_id_ = 0; + std::unique_ptr<EmulatedRequestState> logical_request_state_; + bool is_logical_device_ = false; + std::unique_ptr<std::set<uint32_t>> physical_camera_output_ids_; + PhysicalDeviceMapPtr physical_device_map_; + // Maps a physical device id to its respective request state + std::unordered_map<uint32_t, std::unique_ptr<EmulatedRequestState>> + physical_request_states_; + // Maps particular focal length to physical device id + std::unordered_map<float, uint32_t> physical_focal_length_map_; + float current_focal_length_ = 0.f; + + EmulatedLogicalRequestState(const EmulatedLogicalRequestState&) = delete; + EmulatedLogicalRequestState& operator=(const EmulatedLogicalRequestState&) = + delete; +}; + +} // namespace android + +#endif // EMULATOR_CAMERA_HAL_LOGICAL_REQUEST_STATE_H diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp index 4d6b61c..5077f85 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp @@ -38,7 +38,7 @@ EmulatedRequestProcessor::EmulatedRequestProcessor(uint32_t camera_id, sp<EmulatedSensor> sensor) : camera_id_(camera_id), sensor_(sensor), - request_state_(std::make_unique<EmulatedRequestState>(camera_id)) { + request_state_(std::make_unique<EmulatedLogicalRequestState>(camera_id)) { ATRACE_CALL(); request_thread_ = std::thread([this] { this->RequestProcessorLoop(); }); } @@ -271,7 +271,9 @@ std::unique_ptr<SensorBuffer> EmulatedRequestProcessor::CreateSensorBuffer( buffer->pipeline_id = pipeline_id; buffer->callback = callback; buffer->frame_number = frame_number; - buffer->camera_id = camera_id_; + buffer->camera_id = emulated_stream.is_physical_camera_stream + ? emulated_stream.physical_camera_id + : camera_id_; buffer->is_input = stream.is_input; // In case buffer processing is successful, flip this flag accordingly buffer->stream_buffer.status = BufferStatus::kError; @@ -339,29 +341,53 @@ void EmulatedRequestProcessor::RequestProcessorLoop() { auto frame_number = request.output_buffers->at(0)->frame_number; auto notify_callback = request.output_buffers->at(0)->callback; auto pipeline_id = request.output_buffers->at(0)->pipeline_id; - EmulatedSensor::SensorSettings settings; - - // Repeating requests usually include valid settings only during the - // initial call. Afterwards an invalid settings pointer means that there - // are no changes in the parameters and Hal should re-use the last valid - // values. - if (request.settings.get() != nullptr) { - ret = request_state_->InitializeSensorSettings( - HalCameraMetadata::Clone(request.settings.get()), &settings); - last_settings_ = HalCameraMetadata::Clone(request.settings.get()); - } else { - ret = request_state_->InitializeSensorSettings( - HalCameraMetadata::Clone(last_settings_.get()), &settings); - } auto output_buffers = AcquireBuffers(request.output_buffers.get()); - if (!output_buffers->empty() && (ret == OK)) { - auto result = - request_state_->InitializeResult(pipeline_id, frame_number); - auto input_buffers = AcquireBuffers(request.input_buffers.get()); - sensor_->SetCurrentRequest(settings, std::move(result), - std::move(input_buffers), - std::move(output_buffers)); + auto input_buffers = AcquireBuffers(request.input_buffers.get()); + if (!output_buffers->empty()) { + std::unique_ptr<EmulatedSensor::LogicalCameraSettings> logical_settings = + std::make_unique<EmulatedSensor::LogicalCameraSettings>(); + + std::unique_ptr<std::set<uint32_t>> physical_camera_output_ids = + std::make_unique<std::set<uint32_t>>(); + for (const auto& it : *output_buffers) { + if (it->camera_id != camera_id_) { + physical_camera_output_ids->emplace(it->camera_id); + } + } + + // Repeating requests usually include valid settings only during the + // initial call. Afterwards an invalid settings pointer means that + // there are no changes in the parameters and Hal should re-use the + // last valid values. + // TODO: Add support for individual physical camera requests. + if (request.settings.get() != nullptr) { + ret = request_state_->InitializeLogicalSettings( + HalCameraMetadata::Clone(request.settings.get()), + std::move(physical_camera_output_ids), logical_settings.get()); + last_settings_ = HalCameraMetadata::Clone(request.settings.get()); + } else { + ret = request_state_->InitializeLogicalSettings( + HalCameraMetadata::Clone(last_settings_.get()), + std::move(physical_camera_output_ids), logical_settings.get()); + } + + if (ret == OK) { + auto result = request_state_->InitializeLogicalResult(pipeline_id, + frame_number); + sensor_->SetCurrentRequest( + std::move(logical_settings), std::move(result), + std::move(input_buffers), std::move(output_buffers)); + } else { + NotifyMessage msg{.type = MessageType::kError, + .message.error = { + .frame_number = frame_number, + .error_stream_id = -1, + .error_code = ErrorCode::kErrorResult, + }}; + + notify_callback.notify(pipeline_id, msg); + } } else { // No further processing is needed, just fail the result which will // complete this request. @@ -386,9 +412,11 @@ void EmulatedRequestProcessor::RequestProcessorLoop() { } status_t EmulatedRequestProcessor::Initialize( - std::unique_ptr<HalCameraMetadata> static_meta) { + std::unique_ptr<HalCameraMetadata> static_meta, + 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(static_meta), + std::move(physical_devices)); } status_t EmulatedRequestProcessor::GetDefaultRequest( diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h index 5595111..1eb609f 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h +++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h @@ -22,7 +22,7 @@ #include <queue> #include <thread> -#include "EmulatedRequestState.h" +#include "EmulatedLogicalRequestState.h" #include "EmulatedSensor.h" #include "hwl_types.h" @@ -56,7 +56,7 @@ struct PendingRequest { class EmulatedRequestProcessor { public: - EmulatedRequestProcessor(uint32_t cameraId, sp<EmulatedSensor> sensor); + EmulatedRequestProcessor(uint32_t camera_id, sp<EmulatedSensor> sensor); virtual ~EmulatedRequestProcessor(); // Process given pipeline requests and invoke the respective callback in a @@ -71,7 +71,8 @@ class EmulatedRequestProcessor { status_t Flush(); - status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta); + status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta, + PhysicalDeviceMapPtr physical_devices); private: void RequestProcessorLoop(); @@ -109,7 +110,7 @@ class EmulatedRequestProcessor { std::queue<PendingRequest> pending_requests_; uint32_t camera_id_; sp<EmulatedSensor> sensor_; - std::unique_ptr<EmulatedRequestState> + std::unique_ptr<EmulatedLogicalRequestState> request_state_; // Stores and handles 3A and related camera states. std::unique_ptr<HalCameraMetadata> last_settings_; diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp index 5ed2efd..febdfb5 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp @@ -39,6 +39,7 @@ const std::set<uint8_t> EmulatedRequestState::kSupportedCapabilites = { 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, }; const std::set<uint8_t> EmulatedRequestState::kSupportedHWLevels = { @@ -2238,7 +2239,6 @@ status_t EmulatedRequestState::InitializeLensDefaults() { ret = static_metadata_->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &entry); if ((ret == OK) && (entry.count > 0)) { - // TODO: add support for multiple focal lengths focal_length_ = entry.data.f[0]; } else { ALOGE("%s: No available focal length!", __FUNCTION__); diff --git a/devices/EmulatedCamera/hwl/EmulatedScene.cpp b/devices/EmulatedCamera/hwl/EmulatedScene.cpp index 7810398..26784d1 100644 --- a/devices/EmulatedCamera/hwl/EmulatedScene.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedScene.cpp @@ -85,20 +85,7 @@ const uint8_t EmulatedScene::kScene[EmulatedScene::kSceneWidth * EmulatedScene::EmulatedScene(int sensor_width_px, int sensor_height_px, float sensor_sensitivity) - : sensor_width_(sensor_width_px), - sensor_height_(sensor_height_px), - hour_(12), - exposure_duration_(0.033f), - sensor_sensitivity_(sensor_sensitivity) { - // Map scene to sensor pixels - if (sensor_width_ > sensor_height_) { - map_div_ = (sensor_width_ / (kSceneWidth + 1)) + 1; - } else { - map_div_ = (sensor_height_ / (kSceneHeight + 1)) + 1; - } - offset_x_ = (kSceneWidth * map_div_ - sensor_width_) / 2; - offset_y_ = (kSceneHeight * map_div_ - sensor_height_) / 2; - + : hour_(12), exposure_duration_(0.033f) { // Assume that sensor filters are sRGB primaries to start filter_r_[0] = 3.2406f; filter_r_[1] = -1.5372f; @@ -112,11 +99,30 @@ EmulatedScene::EmulatedScene(int sensor_width_px, int sensor_height_px, filter_b_[0] = 0.0557f; filter_b_[1] = -0.2040f; filter_b_[2] = 1.0570f; + + Initialize(sensor_width_px, sensor_height_px, sensor_sensitivity); } EmulatedScene::~EmulatedScene() { } +void EmulatedScene::Initialize(int sensor_width_px, int sensor_height_px, + float sensor_sensitivity) { + sensor_width_ = sensor_width_px; + sensor_height_ = sensor_height_px; + sensor_sensitivity_ = sensor_sensitivity; + + // Map scene to sensor pixels + if (sensor_width_ > sensor_height_) { + map_div_ = (sensor_width_ / (kSceneWidth + 1)) + 1; + } + else { + map_div_ = (sensor_height_ / (kSceneHeight + 1)) + 1; + } + offset_x_ = (kSceneWidth * map_div_ - sensor_width_) / 2; + offset_y_ = (kSceneHeight * map_div_ - sensor_height_) / 2; +} + void EmulatedScene::SetColorFilterXYZ(float rX, float rY, float rZ, float grX, float grY, float grZ, float gbX, float gbY, float gbZ, float bX, float bY, float bZ) { diff --git a/devices/EmulatedCamera/hwl/EmulatedScene.h b/devices/EmulatedCamera/hwl/EmulatedScene.h index 58473e4..a61d735 100644 --- a/devices/EmulatedCamera/hwl/EmulatedScene.h +++ b/devices/EmulatedCamera/hwl/EmulatedScene.h @@ -36,6 +36,9 @@ class EmulatedScene { float sensor_sensitivity); ~EmulatedScene(); + void Initialize(int sensor_width_px, int sensor_height_px, + float sensor_sensitivity); + // Set the filter coefficients for the red, green, and blue filters on the // sensor. Used as an optimization to pre-calculate various illuminance // values. Two different green filters can be provided, to account for @@ -56,8 +59,8 @@ class EmulatedScene { void SetExposureDuration(float seconds); // Calculate scene information for current hour and the time offset since - // the hour. Must be called at least once before calling getLuminousExposure. - // Resets pixel readout location to 0,0 + // the hour. Must be called at least once before calling + // getLuminousExposure. Resets pixel readout location to 0,0 void CalculateScene(nsecs_t time); // Set sensor pixel readout location. @@ -170,7 +173,7 @@ class EmulatedScene { static const uint8_t kMaterialsFlags[NUM_MATERIALS]; static const uint8_t kScene[]; -}; + }; } // namespace android diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp index babcb10..116263e 100644 --- a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp @@ -57,6 +57,9 @@ const int32_t EmulatedSensor::kSupportedSensitivityRange[2] = {100, 1600}; const int32_t EmulatedSensor::kDefaultSensitivity = 100; // ISO const nsecs_t EmulatedSensor::kDefaultExposureTime = ms2ns(15); const nsecs_t EmulatedSensor::kDefaultFrameDuration = ms2ns(33); +// Deadline within we should return the results as soon as possible to +// avoid skewing the frame cycle due to external delays. +const nsecs_t EmulatedSensor::kReturnResultThreshod = 3 * kDefaultFrameDuration; // Sensor defaults const uint8_t EmulatedSensor::kSupportedColorFilterArrangement = @@ -328,45 +331,45 @@ bool EmulatedSensor::IsStreamCombinationSupported( return true; } -status_t EmulatedSensor::StartUp(SensorCharacteristics characteristics) { - ALOGV("%s: E", __FUNCTION__); +status_t EmulatedSensor::StartUp( + uint32_t logical_camera_id, + std::unique_ptr<LogicalCharacteristics> logical_chars) { + if (isRunning()) { + return OK; + } - if (!AreCharacteristicsSupported(characteristics)) { - ALOGE("%s: Sensor characteristics not supported!", __FUNCTION__); + if (logical_chars.get() == nullptr) { return BAD_VALUE; } - std::unique_ptr<ExifUtils> exif_utils(ExifUtils::Create(characteristics)); + auto device_chars = logical_chars->find(logical_camera_id); + if (device_chars == logical_chars->end()) { + ALOGE( + "%s: Logical camera id: %u absent from logical camera characteristics!", + __FUNCTION__, logical_camera_id); + return BAD_VALUE; + } - if (isRunning()) { - return OK; + for (const auto& it : *logical_chars) { + if (!AreCharacteristicsSupported(it.second)) { + ALOGE("%s: Sensor characteristics for camera id: %u not supported!", + __FUNCTION__, it.first); + return BAD_VALUE; + } } - chars_ = characteristics; - scene_ = std::make_unique<EmulatedScene>(chars_.width, chars_.height, + logical_camera_id_ = logical_camera_id; + chars_ = std::move(logical_chars); + scene_ = std::make_unique<EmulatedScene>(device_chars->second.width, + device_chars->second.height, kElectronsPerLuxSecond); - scene_->SetColorFilterXYZ( - chars_.color_filter.rX, chars_.color_filter.rY, chars_.color_filter.rZ, - chars_.color_filter.grX, chars_.color_filter.grY, chars_.color_filter.grZ, - chars_.color_filter.gbX, chars_.color_filter.gbY, chars_.color_filter.gbZ, - chars_.color_filter.bX, chars_.color_filter.bY, chars_.color_filter.bZ); - row_readout_time_ = chars_.frame_duration_range[0] / chars_.height; - base_gain_factor_ = - (float)chars_.max_raw_value / EmulatedSensor::kSaturationElectrons; - jpeg_compressor_ = std::make_unique<JpegCompressor>(std::move(exif_utils)); - - if ((chars_.lens_shading_map_size[0] > 0) && - (chars_.lens_shading_map_size[1] > 0)) { - // Perfect lens, no actual shading needed. - lens_shading_map_.resize( - chars_.lens_shading_map_size[0] * chars_.lens_shading_map_size[1] * 4, - 1.f); - } + jpeg_compressor_ = std::make_unique<JpegCompressor>(); auto res = run(LOG_TAG, ANDROID_PRIORITY_URGENT_DISPLAY); if (res != OK) { ALOGE("Unable to start up sensor capture thread: %d", res); } + return res; } @@ -379,12 +382,13 @@ status_t EmulatedSensor::ShutDown() { return res; } -void EmulatedSensor::SetCurrentRequest(SensorSettings settings, - std::unique_ptr<HwlPipelineResult> result, - std::unique_ptr<Buffers> input_buffers, - std::unique_ptr<Buffers> output_buffers) { +void EmulatedSensor::SetCurrentRequest( + std::unique_ptr<LogicalCameraSettings> logical_settings, + std::unique_ptr<HwlPipelineResult> result, + std::unique_ptr<Buffers> input_buffers, + std::unique_ptr<Buffers> output_buffers) { Mutex::Autolock lock(control_mutex_); - current_settings_ = settings; + current_settings_ = std::move(logical_settings); current_result_ = std::move(result); current_input_buffers_ = std::move(input_buffers); current_output_buffers_ = std::move(output_buffers); @@ -415,8 +419,7 @@ status_t EmulatedSensor::Flush() { // First recreate the jpeg compressor. This will abort any ongoing processing // and flush any pending jobs. - std::unique_ptr<ExifUtils> exif_utils(ExifUtils::Create(chars_)); - jpeg_compressor_ = std::make_unique<JpegCompressor>(std::move(exif_utils)); + jpeg_compressor_ = std::make_unique<JpegCompressor>(); // Then return any pending frames here if ((current_input_buffers_.get() != nullptr) && @@ -464,11 +467,11 @@ bool EmulatedSensor::threadLoop() { std::unique_ptr<Buffers> next_buffers; std::unique_ptr<Buffers> next_input_buffer; std::unique_ptr<HwlPipelineResult> next_result; - SensorSettings settings; + std::unique_ptr<LogicalCameraSettings> settings; HwlPipelineCallback callback = {nullptr, nullptr}; { Mutex::Autolock lock(control_mutex_); - settings = current_settings_; + std::swap(settings, current_settings_); std::swap(next_buffers, current_output_buffers_); std::swap(next_input_buffer, current_input_buffers_); std::swap(next_result, current_result_); @@ -479,13 +482,16 @@ bool EmulatedSensor::threadLoop() { vsync_.signal(); } - if (settings.frame_duration == 0) { - settings.frame_duration = EmulatedSensor::kSupportedFrameDurationRange[0]; + auto frame_duration = EmulatedSensor::kSupportedFrameDurationRange[0]; + // Frame duration must always be the same among all physical devices + if ((settings.get() != nullptr) && (!settings->empty())) { + frame_duration = settings->begin()->second.frame_duration; } + nsecs_t start_real_time = systemTime(); // Stagefright cares about system time for timestamps, so base simulated // time on that. - nsecs_t frame_end_real_time = start_real_time + settings.frame_duration; + nsecs_t frame_end_real_time = start_real_time + frame_duration; /** * Stage 2: Capture new image @@ -515,7 +521,7 @@ bool EmulatedSensor::threadLoop() { } } - if (next_buffers != nullptr) { + if ((next_buffers != nullptr) && (settings != nullptr)) { callback = next_buffers->at(0)->callback; if (callback.notify != nullptr) { NotifyMessage msg{ @@ -525,49 +531,52 @@ bool EmulatedSensor::threadLoop() { .timestamp_ns = static_cast<uint64_t>(next_capture_time_)}}; callback.notify(next_result->pipeline_id, msg); } - ALOGVV("Starting next capture: Exposure: %f ms, gain: %d", - ns2ms(settings.exposureTime), gain); - scene_->SetExposureDuration((float)settings.exposure_time / 1e9); - scene_->CalculateScene(next_capture_time_); - next_result->result_metadata->Set(ANDROID_SENSOR_TIMESTAMP, - &next_capture_time_, 1); - if (settings.lens_shading_map_mode == - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON) { - next_result->result_metadata->Set(ANDROID_STATISTICS_LENS_SHADING_MAP, - lens_shading_map_.data(), - lens_shading_map_.size()); - } - if (settings.report_neutral_color_point) { - next_result->result_metadata->Set(ANDROID_SENSOR_NEUTRAL_COLOR_POINT, - kNeutralColorPoint, - ARRAY_SIZE(kNeutralColorPoint)); - } - if (settings.report_green_split) { - next_result->result_metadata->Set(ANDROID_SENSOR_GREEN_SPLIT, - &kGreenSplit, 1); - } - if (settings.report_noise_profile) { - // TODO: pass the results as parameter to capture instead of re-calculating - float total_gain = settings.gain / 100.0 * base_gain_factor_; - float noise_var_gain = total_gain * total_gain; - float read_noise_var = - kReadNoiseVarBeforeGain * noise_var_gain + kReadNoiseVarAfterGain; - // Noise profile is the same across all 4 CFA channels - double noise_profile[2 * 4] = { - noise_var_gain, read_noise_var, noise_var_gain, read_noise_var, - noise_var_gain, read_noise_var, noise_var_gain, read_noise_var}; - next_result->result_metadata->Set(ANDROID_SENSOR_NOISE_PROFILE, - noise_profile, - ARRAY_SIZE(noise_profile)); - } - auto b = next_buffers->begin(); while (b != next_buffers->end()) { + auto device_settings = settings->find((*b)->camera_id); + if (device_settings == settings->end()) { + ALOGE("%s: Sensor settings absent for device: %d", __func__, + (*b)->camera_id); + b = next_buffers->erase(b); + continue; + } + + auto device_chars = chars_->find((*b)->camera_id); + if (device_chars == chars_->end()) { + ALOGE("%s: Sensor characteristics absent for device: %d", __func__, + (*b)->camera_id); + b = next_buffers->erase(b); + continue; + } + + ALOGVV("Starting next capture: Exposure: %" PRIu64 " ms, gain: %d", + ns2ms(device_settings->second.exposure_time), + device_settings->second.gain); + + scene_->Initialize(device_chars->second.width, + device_chars->second.height, kElectronsPerLuxSecond); + scene_->SetExposureDuration((float)device_settings->second.exposure_time / + 1e9); + scene_->SetColorFilterXYZ(device_chars->second.color_filter.rX, + device_chars->second.color_filter.rY, + device_chars->second.color_filter.rZ, + device_chars->second.color_filter.grX, + device_chars->second.color_filter.grY, + device_chars->second.color_filter.grZ, + device_chars->second.color_filter.gbX, + device_chars->second.color_filter.gbY, + device_chars->second.color_filter.gbZ, + device_chars->second.color_filter.bX, + device_chars->second.color_filter.bY, + device_chars->second.color_filter.bZ); + scene_->CalculateScene(next_capture_time_); + (*b)->stream_buffer.status = BufferStatus::kOk; switch ((*b)->format) { case HAL_PIXEL_FORMAT_RAW16: if (!reprocess_request) { - CaptureRaw((*b)->plane.img.img, settings.gain, (*b)->width); + CaptureRaw((*b)->plane.img.img, device_settings->second.gain, + (*b)->width, device_chars->second); } else { ALOGE("%s: Reprocess requests with output format %x no supported!", __FUNCTION__, (*b)->format); @@ -577,7 +586,8 @@ bool EmulatedSensor::threadLoop() { case HAL_PIXEL_FORMAT_RGB_888: if (!reprocess_request) { CaptureRGB((*b)->plane.img.img, (*b)->width, (*b)->height, - (*b)->plane.img.stride, RGBLayout::RGB, settings.gain); + (*b)->plane.img.stride, RGBLayout::RGB, + device_settings->second.gain, device_chars->second); } else { ALOGE("%s: Reprocess requests with output format %x no supported!", __FUNCTION__, (*b)->format); @@ -587,7 +597,8 @@ bool EmulatedSensor::threadLoop() { case HAL_PIXEL_FORMAT_RGBA_8888: if (!reprocess_request) { CaptureRGB((*b)->plane.img.img, (*b)->width, (*b)->height, - (*b)->plane.img.stride, RGBLayout::RGBA, settings.gain); + (*b)->plane.img.stride, RGBLayout::RGBA, + device_settings->second.gain, device_chars->second); } else { ALOGE("%s: Reprocess requests with output format %x no supported!", __FUNCTION__, (*b)->format); @@ -622,14 +633,17 @@ bool EmulatedSensor::threadLoop() { .height = jpeg_input->height, .planes = jpeg_input->yuv_planes}; - auto ret = ProcessYUV420(yuv_input, yuv_output, settings.gain, - reprocess_request); + auto ret = ProcessYUV420(yuv_input, yuv_output, + device_settings->second.gain, + reprocess_request, device_chars->second); if (ret != 0) { (*b)->stream_buffer.status = BufferStatus::kError; break; } auto jpeg_job = std::make_unique<JpegYUV420Job>(); + jpeg_job->exif_utils = std::unique_ptr<ExifUtils>( + ExifUtils::Create(device_chars->second)); jpeg_job->input = std::move(jpeg_input); // If jpeg compression is successful, then the jpeg compressor // must set the corresponding status. @@ -659,8 +673,9 @@ bool EmulatedSensor::threadLoop() { YUV420Frame yuv_output{.width = (*b)->width, .height = (*b)->height, .planes = (*b)->plane.img_y_crcb}; - auto ret = ProcessYUV420(yuv_input, yuv_output, settings.gain, - reprocess_request); + auto ret = + ProcessYUV420(yuv_input, yuv_output, device_settings->second.gain, + reprocess_request, device_chars->second); if (ret != 0) { (*b)->stream_buffer.status = BufferStatus::kError; } @@ -668,8 +683,9 @@ bool EmulatedSensor::threadLoop() { case HAL_PIXEL_FORMAT_Y16: if (!reprocess_request) { if ((*b)->dataSpace == HAL_DATASPACE_DEPTH) { - CaptureDepth((*b)->plane.img.img, settings.gain, (*b)->width, - (*b)->height, (*b)->plane.img.stride); + CaptureDepth((*b)->plane.img.img, device_settings->second.gain, + (*b)->width, (*b)->height, (*b)->plane.img.stride, + device_chars->second); } else { ALOGE("%s: Format %x with dataspace %x is TODO", __FUNCTION__, (*b)->format, (*b)->dataSpace); @@ -699,14 +715,25 @@ bool EmulatedSensor::threadLoop() { next_input_buffer->clear(); } - if ((callback.process_pipeline_result != nullptr) && - (next_result.get() != nullptr) && - (next_result->result_metadata.get() != nullptr)) { - callback.process_pipeline_result(std::move(next_result)); + nsecs_t work_done_real_time = systemTime(); + // Returning the results at this point is not entirely correct from timing + // perspective. Under ideal conditions where 'ReturnResults' completes + // in less than 'time_accuracy' we need to return the results after the + // frame cycle expires. However under real conditions various system + // components like SurfaceFlinger, Encoder, LMK etc. could be consuming most + // of the resources and the duration of "ReturnResults" can get comparable to + // 'kDefaultFrameDuration'. This will skew the frame cycle and can result in + // potential frame drops. To avoid this scenario when we are running under + // tight deadlines (less than 'kReturnResultThreshod') try to return the + // results immediately. In all other cases with more relaxed deadlines + // the occasional bump during 'ReturnResults' should not have any + // noticeable effect. + if ((work_done_real_time + kReturnResultThreshod) > frame_end_real_time) { + ReturnResults(callback, std::move(settings), std::move(next_result)); } + work_done_real_time = systemTime(); ALOGVV("Sensor vertical blanking interval"); - nsecs_t work_done_real_time = systemTime(); const nsecs_t time_accuracy = 2e6; // 2 ms of imprecision is ok if (work_done_real_time < frame_end_real_time - time_accuracy) { timespec t; @@ -722,12 +749,120 @@ bool EmulatedSensor::threadLoop() { ALOGVV("Frame cycle took %" PRIu64 " ms, target %" PRIu64 " ms", ns2ms(end_real_time - start_real_time), ns2ms(frame_duration)); + ReturnResults(callback, std::move(settings), std::move(next_result)); + return true; }; -void EmulatedSensor::CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width) { +void EmulatedSensor::ReturnResults( + HwlPipelineCallback callback, + std::unique_ptr<LogicalCameraSettings> settings, + std::unique_ptr<HwlPipelineResult> result) { + if ((callback.process_pipeline_result != nullptr) && + (result.get() != nullptr) && (result->result_metadata.get() != nullptr)) { + auto logical_settings = settings->find(logical_camera_id_); + if (logical_settings == settings->end()) { + ALOGE("%s: Logical camera id: %u not found in settings!", __FUNCTION__, + logical_camera_id_); + return; + } + auto device_chars = chars_->find(logical_camera_id_); + if (device_chars == chars_->end()) { + ALOGE("%s: Sensor characteristics absent for device: %d", __func__, + logical_camera_id_); + return; + } + + result->result_metadata->Set(ANDROID_SENSOR_TIMESTAMP, &next_capture_time_, + 1); + if (logical_settings->second.lens_shading_map_mode == + ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON) { + if ((device_chars->second.lens_shading_map_size[0] > 0) && + (device_chars->second.lens_shading_map_size[1] > 0)) { + // Perfect lens, no actual shading needed. + std::vector<float> lens_shading_map( + device_chars->second.lens_shading_map_size[0] * + device_chars->second.lens_shading_map_size[1] * 4, + 1.f); + + result->result_metadata->Set(ANDROID_STATISTICS_LENS_SHADING_MAP, + lens_shading_map.data(), + lens_shading_map.size()); + } + } + if (logical_settings->second.report_neutral_color_point) { + result->result_metadata->Set(ANDROID_SENSOR_NEUTRAL_COLOR_POINT, + kNeutralColorPoint, + ARRAY_SIZE(kNeutralColorPoint)); + } + if (logical_settings->second.report_green_split) { + result->result_metadata->Set(ANDROID_SENSOR_GREEN_SPLIT, &kGreenSplit, 1); + } + + if (logical_settings->second.report_noise_profile) { + CalculateAndAppendNoiseProfile( + logical_settings->second.gain, + GetBaseGainFactor(device_chars->second.max_raw_value), + result->result_metadata.get()); + } + + if (!result->physical_camera_results.empty()) { + for (auto& it : result->physical_camera_results) { + auto physical_settings = settings->find(it.first); + if (physical_settings == settings->end()) { + ALOGE("%s: Physical settings for camera id: %u are absent!", + __FUNCTION__, it.first); + continue; + } + + // Sensor timestamp for all physical devices must be the same. + it.second->Set(ANDROID_SENSOR_TIMESTAMP, &next_capture_time_, 1); + if (physical_settings->second.report_neutral_color_point) { + it.second->Set(ANDROID_SENSOR_NEUTRAL_COLOR_POINT, kNeutralColorPoint, + ARRAY_SIZE(kNeutralColorPoint)); + } + if (physical_settings->second.report_green_split) { + it.second->Set(ANDROID_SENSOR_GREEN_SPLIT, &kGreenSplit, 1); + } + if (physical_settings->second.report_noise_profile) { + auto device_chars = chars_->find(it.first); + if (device_chars == chars_->end()) { + ALOGE("%s: Sensor characteristics absent for device: %d", __func__, + it.first); + } + CalculateAndAppendNoiseProfile( + physical_settings->second.gain, + GetBaseGainFactor(device_chars->second.max_raw_value), + it.second.get()); + } + } + } + + callback.process_pipeline_result(std::move(result)); + } +} + +void EmulatedSensor::CalculateAndAppendNoiseProfile( + float gain /*in ISO*/, float base_gain_factor, + HalCameraMetadata* result /*out*/) { + if (result != nullptr) { + float total_gain = gain / 100.0 * base_gain_factor; + float noise_var_gain = total_gain * total_gain; + float read_noise_var = + kReadNoiseVarBeforeGain * noise_var_gain + kReadNoiseVarAfterGain; + // Noise profile is the same across all 4 CFA channels + double noise_profile[2 * 4] = { + noise_var_gain, read_noise_var, noise_var_gain, read_noise_var, + noise_var_gain, read_noise_var, noise_var_gain, read_noise_var}; + result->Set(ANDROID_SENSOR_NOISE_PROFILE, noise_profile, + ARRAY_SIZE(noise_profile)); + } +} + +void EmulatedSensor::CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width, + const SensorCharacteristics& chars) { ATRACE_CALL(); - float total_gain = gain / 100.0 * base_gain_factor_; + float total_gain = gain / 100.0 * GetBaseGainFactor(chars.max_raw_value); float noise_var_gain = total_gain * total_gain; float read_noise_var = kReadNoiseVarBeforeGain * noise_var_gain + kReadNoiseVarAfterGain; @@ -736,10 +871,10 @@ void EmulatedSensor::CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width) { int bayer_select[4] = {EmulatedScene::R, EmulatedScene::Gr, EmulatedScene::Gb, EmulatedScene::B}; scene_->SetReadoutPixel(0, 0); - for (unsigned int y = 0; y < chars_.height; y++) { + for (unsigned int y = 0; y < chars.height; y++) { int* bayer_row = bayer_select + (y & 0x1) * 2; uint16_t* px = (uint16_t*)img + y * width; - for (unsigned int x = 0; x < chars_.width; x++) { + for (unsigned int x = 0; x < chars.width; x++) { uint32_t electron_count; electron_count = scene_->GetPixelElectrons()[bayer_row[x & 0x1]]; @@ -751,7 +886,7 @@ void EmulatedSensor::CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width) { // TODO: Better A/D saturation curve? uint16_t raw_count = electron_count * total_gain; raw_count = - (raw_count < chars_.max_raw_value) ? raw_count : chars_.max_raw_value; + (raw_count < chars.max_raw_value) ? raw_count : chars.max_raw_value; // Calculate noise value // TODO: Use more-correct Gaussian instead of uniform noise @@ -760,7 +895,7 @@ void EmulatedSensor::CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width) { // Scaled to roughly match gaussian/uniform noise stddev float noise_sample = rand_r(&rand_seed_) * (2.5 / (1.0 + RAND_MAX)) - 1.25; - raw_count += chars_.black_level_pattern[bayer_row[x & 0x1]]; + raw_count += chars.black_level_pattern[bayer_row[x & 0x1]]; raw_count += noise_stddev * noise_sample; *px++ = raw_count; @@ -772,19 +907,19 @@ void EmulatedSensor::CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width) { } void EmulatedSensor::CaptureRGB(uint8_t* img, uint32_t width, uint32_t height, - uint32_t stride, RGBLayout layout, - uint32_t gain) { + uint32_t stride, RGBLayout layout, uint32_t gain, + const SensorCharacteristics& chars) { ATRACE_CALL(); - float total_gain = gain / 100.0 * base_gain_factor_; + float total_gain = gain / 100.0 * GetBaseGainFactor(chars.max_raw_value); // In fixed-point math, calculate total scaling from electrons to 8bpp - int scale64x = 64 * total_gain * 255 / chars_.max_raw_value; - uint32_t inc_h = ceil((float)chars_.width / width); - uint32_t inc_v = ceil((float)chars_.height / height); + int scale64x = 64 * total_gain * 255 / chars.max_raw_value; + uint32_t inc_h = ceil((float)chars.width / width); + uint32_t inc_v = ceil((float)chars.height / height); - for (unsigned int y = 0, outy = 0; y < chars_.height; y += inc_v, outy++) { + for (unsigned int y = 0, outy = 0; y < chars.height; y += inc_v, outy++) { scene_->SetReadoutPixel(0, y); uint8_t* px = img + outy * stride; - for (unsigned int x = 0; x < chars_.width; x += inc_h) { + for (unsigned int x = 0; x < chars.width; x += inc_h) { uint32_t r_count, g_count, b_count; // TODO: Perfect demosaicing is a cheat const uint32_t* pixel = scene_->GetPixelElectrons(); @@ -824,13 +959,14 @@ void EmulatedSensor::CaptureRGB(uint8_t* img, uint32_t width, uint32_t height, } void EmulatedSensor::CaptureYUV420(YCbCrPlanes yuv_layout, uint32_t width, - uint32_t height, uint32_t gain) { + uint32_t height, uint32_t gain, + const SensorCharacteristics& chars) { ATRACE_CALL(); - float total_gain = gain / 100.0 * base_gain_factor_; + float total_gain = gain / 100.0 * GetBaseGainFactor(chars.max_raw_value); // Using fixed-point math with 6 bits of fractional precision. // In fixed-point math, calculate total scaling from electrons to 8bpp const int scale64x = - kFixedBitPrecision * total_gain * 255 / chars_.max_raw_value; + kFixedBitPrecision * total_gain * 255 / chars.max_raw_value; // Fixed-point coefficients for RGB-YUV transform // Based on JFIF RGB->YUV transform. // Cb/Cr offset scaled by 64x twice since they're applied post-multiply @@ -842,9 +978,9 @@ void EmulatedSensor::CaptureYUV420(YCbCrPlanes yuv_layout, uint32_t width, const int scale_out_sq = scale_out * scale_out; // after multiplies // inc = how many pixels to skip while reading every next pixel - uint32_t inc_h = ceil((float)chars_.width / width); - uint32_t inc_v = ceil((float)chars_.height / height); - for (unsigned int y = 0, out_y = 0; y < chars_.height; y += inc_v, out_y++) { + uint32_t inc_h = ceil((float)chars.width / width); + uint32_t inc_v = ceil((float)chars.height / height); + for (unsigned int y = 0, out_y = 0; y < chars.height; y += inc_v, out_y++) { uint8_t* px_y = yuv_layout.img_y + out_y * yuv_layout.y_stride; uint8_t* px_cb = yuv_layout.img_cb + (out_y / 2) * yuv_layout.cbcr_stride; uint8_t* px_cr = yuv_layout.img_cr + (out_y / 2) * yuv_layout.cbcr_stride; @@ -887,18 +1023,19 @@ void EmulatedSensor::CaptureYUV420(YCbCrPlanes yuv_layout, uint32_t width, } void EmulatedSensor::CaptureDepth(uint8_t* img, uint32_t gain, uint32_t width, - uint32_t height, uint32_t stride) { + uint32_t height, uint32_t stride, + const SensorCharacteristics& chars) { ATRACE_CALL(); - float total_gain = gain / 100.0 * base_gain_factor_; + float total_gain = gain / 100.0 * GetBaseGainFactor(chars.max_raw_value); // In fixed-point math, calculate scaling factor to 13bpp millimeters - int scale64x = 64 * total_gain * 8191 / chars_.max_raw_value; - uint32_t inc_h = ceil((float)chars_.width / width); - uint32_t inc_v = ceil((float)chars_.height / height); + int scale64x = 64 * total_gain * 8191 / chars.max_raw_value; + uint32_t inc_h = ceil((float)chars.width / width); + uint32_t inc_v = ceil((float)chars.height / height); - for (unsigned int y = 0, out_y = 0; y < chars_.height; y += inc_v, out_y++) { + for (unsigned int y = 0, out_y = 0; y < chars.height; y += inc_v, out_y++) { scene_->SetReadoutPixel(0, y); uint16_t* px = ((uint16_t*)img) + out_y * stride; - for (unsigned int x = 0; x < chars_.width; x += inc_h) { + for (unsigned int x = 0; x < chars.width; x += inc_h) { uint32_t depth_count; // TODO: Make up real depth scene instead of using green channel // as depth @@ -916,7 +1053,8 @@ void EmulatedSensor::CaptureDepth(uint8_t* img, uint32_t gain, uint32_t width, status_t EmulatedSensor::ProcessYUV420(const YUV420Frame& input, const YUV420Frame& output, uint32_t gain, - bool reprocess_request) { + bool reprocess_request, + const SensorCharacteristics& chars) { ATRACE_CALL(); size_t input_width, input_height; YCbCrPlanes input_planes, output_planes; @@ -961,7 +1099,7 @@ status_t EmulatedSensor::ProcessYUV420(const YUV420Frame& input, .y_stride = static_cast<uint32_t>(input_width), .cbcr_stride = static_cast<uint32_t>(input_width) / 2, .cbcr_step = 1}; - CaptureYUV420(input_planes, input_width, input_height, gain); + CaptureYUV420(input_planes, input_width, input_height, gain, chars); } output_planes = output.planes; diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.h b/devices/EmulatedCamera/hwl/EmulatedSensor.h index 09a4470..3f19754 100644 --- a/devices/EmulatedCamera/hwl/EmulatedSensor.h +++ b/devices/EmulatedCamera/hwl/EmulatedSensor.h @@ -134,6 +134,9 @@ struct SensorCharacteristics { uint32_t max_pipeline_depth = 0; }; +// Maps logical/physical camera ids to sensor characteristics +typedef std::unordered_map<uint32_t, SensorCharacteristics> LogicalCharacteristics; + class EmulatedSensor : private Thread, public virtual RefBase { public: EmulatedSensor(); @@ -168,11 +171,12 @@ class EmulatedSensor : private Thread, public virtual RefBase { * Power control */ - status_t StartUp(SensorCharacteristics characteristics); + status_t StartUp(uint32_t logical_camera_id, + std::unique_ptr<LogicalCharacteristics> logical_chars); status_t ShutDown(); /* - * Settings control + * Physical camera settings control */ struct SensorSettings { nsecs_t exposure_time = 0; @@ -184,7 +188,10 @@ class EmulatedSensor : private Thread, public virtual RefBase { bool report_noise_profile = false; }; - void SetCurrentRequest(SensorSettings settings, + // Maps physical and logical camera ids to individual device settings + typedef std::unordered_map<uint32_t, SensorSettings> LogicalCameraSettings; + + void SetCurrentRequest(std::unique_ptr<LogicalCameraSettings> logical_settings, std::unique_ptr<HwlPipelineResult> result, std::unique_ptr<Buffers> input_buffers, std::unique_ptr<Buffers> output_buffers); @@ -208,6 +215,7 @@ class EmulatedSensor : private Thread, public virtual RefBase { static const nsecs_t kDefaultExposureTime; static const int32_t kDefaultSensitivity; static const nsecs_t kDefaultFrameDuration; + static const nsecs_t kReturnResultThreshod; static const uint32_t kDefaultBlackLevelPattern[4]; static const camera_metadata_rational kDefaultColorTransform[9]; static const float kDefaultColorCorrectionGains[4]; @@ -218,17 +226,11 @@ class EmulatedSensor : private Thread, public virtual RefBase { private: /** - * Sensor characteristics + * Logical characteristics */ - SensorCharacteristics chars_; - - float base_gain_factor_; + std::unique_ptr<LogicalCharacteristics> chars_; - // While each row has to read out, reset, and then expose, the (reset + - // expose) sequence can be overlapped by other row readouts, so the final - // minimum frame duration is purely a function of row readout time, at least - // if there's a reasonable number of rows. - nsecs_t row_readout_time_; + uint32_t logical_camera_id_ = 0; static const nsecs_t kMinVerticalBlank; @@ -254,14 +256,13 @@ class EmulatedSensor : private Thread, public virtual RefBase { static const int32_t kFixedBitPrecision; static const int32_t kSaturationPoint; - std::vector<float> lens_shading_map_; std::vector<int32_t> gamma_table_; Mutex control_mutex_; // Lock before accessing control parameters // Start of control parameters Condition vsync_; bool got_vsync_; - SensorSettings current_settings_; + std::unique_ptr<LogicalCameraSettings> current_settings_; std::unique_ptr<HwlPipelineResult> current_result_; std::unique_ptr<Buffers> current_output_buffers_; std::unique_ptr<Buffers> current_input_buffers_; @@ -281,14 +282,16 @@ class EmulatedSensor : private Thread, public virtual RefBase { std::unique_ptr<EmulatedScene> scene_; - void CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width); + void CaptureRaw(uint8_t* img, uint32_t gain, uint32_t width, + const SensorCharacteristics& chars); enum RGBLayout { RGB, RGBA, ARGB }; void CaptureRGB(uint8_t* img, uint32_t width, uint32_t height, - uint32_t stride, RGBLayout layout, uint32_t gain); + uint32_t stride, RGBLayout layout, uint32_t gain, + const SensorCharacteristics& chars); void CaptureYUV420(YCbCrPlanes yuv_layout, uint32_t width, uint32_t height, - uint32_t gain); - void CaptureDepth(uint8_t* img, uint32_t gain, uint32_t width, - uint32_t height, uint32_t stride); + uint32_t gain, const SensorCharacteristics& chars); + void CaptureDepth(uint8_t* img, uint32_t gain, uint32_t width, uint32_t height, + uint32_t stride, const SensorCharacteristics& chars); struct YUV420Frame { uint32_t width = 0; @@ -297,11 +300,23 @@ class EmulatedSensor : private Thread, public virtual RefBase { }; status_t ProcessYUV420(const YUV420Frame& input, const YUV420Frame& output, - uint32_t gain, bool reprocess_request); + uint32_t gain, bool reprocess_request, + const SensorCharacteristics& chars); inline int32_t ApplysRGBGamma(int32_t value, int32_t saturation); bool WaitForVSyncLocked(nsecs_t reltime); + void CalculateAndAppendNoiseProfile(float gain /*in ISO*/, + float base_gain_factor, + HalCameraMetadata* result /*out*/); + + void ReturnResults(HwlPipelineCallback callback, + std::unique_ptr<LogicalCameraSettings> settings, + std::unique_ptr<HwlPipelineResult> result); + + static float GetBaseGainFactor(float max_raw_value) { + return max_raw_value / EmulatedSensor::kSaturationElectrons; + } }; } // namespace android diff --git a/devices/EmulatedCamera/hwl/JpegCompressor.cpp b/devices/EmulatedCamera/hwl/JpegCompressor.cpp index 86c955c..43b1830 100644 --- a/devices/EmulatedCamera/hwl/JpegCompressor.cpp +++ b/devices/EmulatedCamera/hwl/JpegCompressor.cpp @@ -31,8 +31,7 @@ using google_camera_hal::ErrorCode; using google_camera_hal::MessageType; using google_camera_hal::NotifyMessage; -JpegCompressor::JpegCompressor(std::unique_ptr<ExifUtils> exif_utils) - : exif_utils_(std::move(exif_utils)) { +JpegCompressor::JpegCompressor() { ATRACE_CALL(); char value[PROPERTY_VALUE_MAX]; if (property_get("ro.product.vendor.manufacturer", value, "unknown") <= 0) { @@ -110,9 +109,9 @@ void JpegCompressor::CompressYUV420(std::unique_ptr<JpegYUV420Job> job) { size_t app1_buffer_size = 0; std::vector<uint8_t> thumbnail_jpeg_buffer; size_t encoded_thumbnail_size = 0; - if ((exif_utils_.get() != nullptr) && + if ((job->exif_utils.get() != nullptr) && (job->result_metadata.get() != nullptr)) { - if (exif_utils_->Initialize()) { + if (job->exif_utils->Initialize()) { camera_metadata_ro_entry_t entry; size_t thumbnail_width = 0; size_t thumbnail_height = 0; @@ -150,8 +149,8 @@ void JpegCompressor::CompressYUV420(std::unique_ptr<JpegYUV420Job> job) { } } - if (exif_utils_->SetFromMetadata(*job->result_metadata, job->input->width, - job->input->height)) { + if (job->exif_utils->SetFromMetadata( + *job->result_metadata, job->input->width, job->input->height)) { if (!thumb_yuv420_frame.empty()) { thumbnail_jpeg_buffer.resize(64 * 1024); // APP1 is limited by 64k encoded_thumbnail_size = CompressYUV420Frame( @@ -170,14 +169,14 @@ void JpegCompressor::CompressYUV420(std::unique_ptr<JpegYUV420Job> job) { } } - exif_utils_->SetMake(exif_make_); - exif_utils_->SetModel(exif_model_); - if (exif_utils_->GenerateApp1(thumbnail_jpeg_buffer.empty() - ? nullptr - : thumbnail_jpeg_buffer.data(), - encoded_thumbnail_size)) { - app1_buffer = exif_utils_->GetApp1Buffer(); - app1_buffer_size = exif_utils_->GetApp1Length(); + job->exif_utils->SetMake(exif_make_); + job->exif_utils->SetModel(exif_model_); + if (job->exif_utils->GenerateApp1(thumbnail_jpeg_buffer.empty() + ? nullptr + : thumbnail_jpeg_buffer.data(), + encoded_thumbnail_size)) { + app1_buffer = job->exif_utils->GetApp1Buffer(); + app1_buffer_size = job->exif_utils->GetApp1Length(); } else { ALOGE("%s: Unable to generate App1 buffer", __FUNCTION__); } diff --git a/devices/EmulatedCamera/hwl/JpegCompressor.h b/devices/EmulatedCamera/hwl/JpegCompressor.h index faaa3e1..1ebda72 100644 --- a/devices/EmulatedCamera/hwl/JpegCompressor.h +++ b/devices/EmulatedCamera/hwl/JpegCompressor.h @@ -62,11 +62,12 @@ struct JpegYUV420Job { std::unique_ptr<JpegYUV420Input> input; std::unique_ptr<SensorBuffer> output; std::unique_ptr<HalCameraMetadata> result_metadata; + std::unique_ptr<ExifUtils> exif_utils; }; class JpegCompressor { public: - JpegCompressor(std::unique_ptr<ExifUtils> exif_utils); + JpegCompressor(); virtual ~JpegCompressor(); status_t QueueYUV420(std::unique_ptr<JpegYUV420Job> job); @@ -77,7 +78,6 @@ class JpegCompressor { std::atomic_bool jpeg_done_ = false; std::thread jpeg_processing_thread_; std::queue<std::unique_ptr<JpegYUV420Job>> pending_yuv_jobs_; - std::unique_ptr<ExifUtils> exif_utils_; std::string exif_make_, exif_model_; j_common_ptr jpeg_error_info_; diff --git a/devices/EmulatedCamera/hwl/configs/camera_front.json b/devices/EmulatedCamera/hwl/configs/camera_front.json deleted file mode 100644 index 7da89da..0000000 --- a/devices/EmulatedCamera/hwl/configs/camera_front.json +++ /dev/null @@ -1,951 +0,0 @@ -{ - "android.colorCorrection.availableAberrationModes": [ - "0" - ], - "android.control.aeAvailableAntibandingModes": [ - "0", - "3" - ], - "android.control.aeAvailableModes": [ - "0", - "1" - ], - "android.control.aeAvailableTargetFpsRanges": [ - "7", - "7", - "10", - "10", - "15", - "15", - "8", - "30", - "10", - "30", - "15", - "30", - "30", - "30" - ], - "android.control.aeCompensationRange": [ - "-20", - "20" - ], - "android.control.aeCompensationStep": [ - "10", - "100" - ], - "android.control.aeLockAvailable": [ - "TRUE" - ], - "android.control.afAvailableModes": [ - "0" - ], - "android.control.availableEffects": [ - "0", - "1", - "2", - "4", - "5", - "8" - ], - "android.control.availableModes": [ - "0", - "1", - "2" - ], - "android.control.availableSceneModes": [ - "0", - "1" - ], - "android.control.availableVideoStabilizationModes": [ - "0" - ], - "android.control.awbAvailableModes": [ - "0", - "1", - "2", - "3", - "5", - "6" - ], - "android.control.awbLockAvailable": [ - "TRUE" - ], - "android.control.maxRegions": [ - "0", - "0", - "0" - ], - "android.control.postRawSensitivityBoostRange": [ - "100", - "100" - ], - "android.control.sceneModeOverrides": [ - "1", - "1", - "0", - "1", - "1", - "0" - ], - "android.edge.availableEdgeModes": [ - "0", - "1", - "2" - ], - "android.flash.colorTemperature": [ - "0" - ], - "android.flash.info.available": [ - "FALSE" - ], - "android.flash.info.chargeDuration": [ - "0" - ], - "android.flash.maxEnergy": [ - "0" - ], - "android.hotPixel.availableHotPixelModes": [ - "0", - "1", - "2" - ], - "android.info.supportedHardwareLevel": [ - "LIMITED" - ], - "android.jpeg.availableThumbnailSizes": [ - "0", - "0", - "320", - "240", - "384", - "384", - "512", - "288", - "512", - "384" - ], - "android.jpeg.maxSize": [ - "9953664" - ], - "android.lens.facing": [ - "FRONT" - ], - "android.lens.info.availableApertures": [ - "2.40000010" - ], - "android.lens.info.availableFilterDensities": [ - "0.00000000" - ], - "android.lens.info.availableFocalLengths": [ - "1.86000001" - ], - "android.lens.info.availableOpticalStabilization": [ - "0" - ], - "android.lens.info.focusDistanceCalibration": [ - "UNCALIBRATED" - ], - "android.lens.info.hyperfocalDistance": [ - "0.00000000" - ], - "android.lens.info.minimumFocusDistance": [ - "0.00000000" - ], - "android.noiseReduction.availableNoiseReductionModes": [ - "0", - "1", - "2" - ], - "android.request.availableCapabilities": [ - "BACKWARD_COMPATIBLE", - "BURST_CAPTURE" - ], - "android.request.availableCharacteristicsKeys": [ - "4", - "65554", - "65555", - "65556", - "65557", - "65558", - "65559", - "65560", - "65561", - "65562", - "65563", - "65564", - "65572", - "65573", - "65574", - "65575", - "327680", - "393217", - "1376256", - "458759", - "524293", - "589826", - "589827", - "589831", - "589828", - "589829", - "655362", - "786444", - "786438", - "786443", - "786442", - "851972", - "851978", - "851981", - "917529", - "917516", - "917509", - "917510", - "917511", - "917512", - "917513", - "917514", - "983040", - "983042", - "983043", - "983044", - "983045", - "983046", - "983041", - "983047", - "983048", - "917517", - "917518", - "917507", - "917508", - "1048578", - "1179648", - "1179654", - "1179655", - "1179650", - "1507329", - "1245188", - "983050" - ], - "android.request.availableRequestKeys": [ - "65536", - "393216", - "65542", - "65537", - "65538", - "65539", - "65541", - "65543", - "65545", - "65546", - "65547", - "65549", - "65550", - "65551", - "65552", - "65553", - "262146", - "458752", - "458753", - "458754", - "458755", - "458756", - "458757", - "458758", - "851968", - "1114112", - "524292", - "655360", - "3", - "65576", - "786433" - ], - "android.request.availableResultKeys": [ - "65536", - "917530", - "1114126", - "917505", - "917506", - "65568", - "65570", - "65542", - "65567", - "65537", - "65538", - "65539", - "65541", - "65543", - "65545", - "65546", - "65547", - "65549", - "65550", - "65551", - "65552", - "65553", - "262146", - "262149", - "458752", - "458753", - "458754", - "458755", - "458756", - "458757", - "458758", - "851968", - "1114112", - "524292", - "655360", - "3", - "65576", - "917520" - ], - "android.request.maxNumInputStreams": [ - "0" - ], - "android.request.maxNumOutputStreams": [ - "1", - "3", - "1" - ], - "android.request.partialResultCount": [ - "1" - ], - "android.request.pipelineMaxDepth": [ - "7" - ], - "android.scaler.availableMaxDigitalZoom": [ - "4.00000000" - ], - "android.scaler.availableMinFrameDurations": [ - "34", - "1920", - "1080", - "33331760", - "34", - "1440", - "1080", - "33331760", - "34", - "1280", - "720", - "33331760", - "34", - "1072", - "1072", - "33331760", - "34", - "960", - "720", - "33331760", - "34", - "720", - "480", - "33331760", - "34", - "640", - "480", - "33331760", - "34", - "352", - "288", - "33331760", - "34", - "320", - "240", - "33331760", - "34", - "256", - "144", - "33331760", - "34", - "176", - "144", - "33331760", - "35", - "1920", - "1080", - "33331760", - "35", - "1440", - "1080", - "33331760", - "35", - "1280", - "720", - "33331760", - "35", - "1072", - "1072", - "33331760", - "35", - "960", - "720", - "33331760", - "35", - "720", - "480", - "33331760", - "35", - "640", - "480", - "33331760", - "35", - "352", - "288", - "33331760", - "35", - "320", - "240", - "33331760", - "35", - "256", - "144", - "33331760", - "35", - "176", - "144", - "33331760", - "33", - "1920", - "1080", - "33331760", - "33", - "1440", - "1080", - "33331760", - "33", - "1280", - "720", - "33331760", - "33", - "1072", - "1072", - "33331760", - "33", - "960", - "720", - "33331760", - "33", - "720", - "480", - "33331760", - "33", - "640", - "480", - "33331760", - "33", - "352", - "288", - "33331760", - "33", - "320", - "240", - "33331760", - "33", - "256", - "144", - "33331760", - "33", - "176", - "144", - "33331760" - ], - "android.scaler.availableStallDurations": [ - "34", - "1920", - "1080", - "0", - "34", - "1440", - "1080", - "0", - "34", - "1280", - "720", - "0", - "34", - "1072", - "1072", - "0", - "34", - "960", - "720", - "0", - "34", - "720", - "480", - "0", - "34", - "640", - "480", - "0", - "34", - "352", - "288", - "0", - "34", - "320", - "240", - "0", - "34", - "256", - "144", - "0", - "34", - "176", - "144", - "0", - "35", - "1920", - "1080", - "0", - "35", - "1440", - "1080", - "0", - "35", - "1280", - "720", - "0", - "35", - "1072", - "1072", - "0", - "35", - "960", - "720", - "0", - "35", - "720", - "480", - "0", - "35", - "640", - "480", - "0", - "35", - "352", - "288", - "0", - "35", - "320", - "240", - "0", - "35", - "256", - "144", - "0", - "35", - "176", - "144", - "0", - "33", - "1920", - "1080", - "33331760", - "33", - "1440", - "1080", - "33331760", - "33", - "1280", - "720", - "33331760", - "33", - "1072", - "1072", - "33331760", - "33", - "960", - "720", - "33331760", - "33", - "720", - "480", - "33331760", - "33", - "640", - "480", - "33331760", - "33", - "352", - "288", - "33331760", - "33", - "320", - "240", - "33331760", - "33", - "256", - "144", - "33331760", - "33", - "176", - "144", - "33331760" - ], - "android.scaler.availableStreamConfigurations": [ - "34", - "1920", - "1080", - "OUTPUT", - "34", - "1440", - "1080", - "OUTPUT", - "34", - "1280", - "720", - "OUTPUT", - "34", - "1072", - "1072", - "OUTPUT", - "34", - "960", - "720", - "OUTPUT", - "34", - "720", - "480", - "OUTPUT", - "34", - "640", - "480", - "OUTPUT", - "34", - "352", - "288", - "OUTPUT", - "34", - "320", - "240", - "OUTPUT", - "34", - "256", - "144", - "OUTPUT", - "34", - "176", - "144", - "OUTPUT", - "35", - "1920", - "1080", - "OUTPUT", - "35", - "1440", - "1080", - "OUTPUT", - "35", - "1280", - "720", - "OUTPUT", - "35", - "1072", - "1072", - "OUTPUT", - "35", - "960", - "720", - "OUTPUT", - "35", - "720", - "480", - "OUTPUT", - "35", - "640", - "480", - "OUTPUT", - "35", - "352", - "288", - "OUTPUT", - "35", - "320", - "240", - "OUTPUT", - "35", - "256", - "144", - "OUTPUT", - "35", - "176", - "144", - "OUTPUT", - "33", - "1920", - "1080", - "OUTPUT", - "33", - "1440", - "1080", - "OUTPUT", - "33", - "1280", - "720", - "OUTPUT", - "33", - "1072", - "1072", - "OUTPUT", - "33", - "960", - "720", - "OUTPUT", - "33", - "720", - "480", - "OUTPUT", - "33", - "640", - "480", - "OUTPUT", - "33", - "352", - "288", - "OUTPUT", - "33", - "320", - "240", - "OUTPUT", - "33", - "256", - "144", - "OUTPUT", - "33", - "176", - "144", - "OUTPUT" - ], - "android.scaler.croppingType": [ - "FREEFORM" - ], - "android.sensor.availableTestPatternModes": [ - "0" - ], - "android.sensor.blackLevelPattern": [ - "1000", - "1000", - "1000", - "1000" - ], - "android.sensor.calibrationTransform1": [ - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128" - ], - "android.sensor.calibrationTransform2": [ - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128" - ], - "android.sensor.colorTransform1": [ - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128" - ], - "android.sensor.colorTransform2": [ - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128" - ], - "android.sensor.forwardMatrix1": [ - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128" - ], - "android.sensor.forwardMatrix2": [ - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128", - "0", - "128", - "0", - "128", - "0", - "128", - "128", - "128" - ], - "android.sensor.info.activeArraySize": [ - "0", - "0", - "1920", - "1080" - ], - "android.sensor.info.colorFilterArrangement": [ - "RGGB" - ], - "android.sensor.info.exposureTimeRange": [ - "14000", - "125000000" - ], - "android.sensor.info.maxFrameDuration": [ - "500000000" - ], - "android.sensor.info.physicalSize": [ - "3.84711116", - "2.16400003" - ], - "android.sensor.info.pixelArraySize": [ - "1920", - "1080" - ], - "android.sensor.info.preCorrectionActiveArraySize": [ - "0", - "0", - "1920", - "1080" - ], - "android.sensor.info.sensitivityRange": [ - "100", - "1600" - ], - "android.sensor.info.timestampSource": [ - "UNKNOWN" - ], - "android.sensor.info.whiteLevel": [ - "4000" - ], - "android.sensor.maxAnalogSensitivity": [ - "800" - ], - "android.sensor.orientation": [ - "270" - ], - "android.sensor.profileHueSatMapDimensions": [ - "1", - "2", - "1" - ], - "android.sensor.referenceIlluminant1": [ - "DAYLIGHT" - ], - "android.sensor.referenceIlluminant2": [ - "1" - ], - "android.shading.availableModes": [ - "0", - "1", - "2" - ], - "android.statistics.info.availableFaceDetectModes": [ - "0", - "1" - ], - "android.statistics.info.availableHotPixelMapModes": [ - "0" - ], - "android.statistics.info.availableLensShadingMapModes": [ - "0" - ], - "android.statistics.info.histogramBucketCount": [ - "64" - ], - "android.statistics.info.maxFaceCount": [ - "16" - ], - "android.statistics.info.maxHistogramCount": [ - "1000" - ], - "android.statistics.info.maxSharpnessMapValue": [ - "1000" - ], - "android.statistics.info.sharpnessMapSize": [ - "64", - "64" - ], - "android.sync.maxLatency": [ - "PER_FRAME_CONTROL" - ], - "android.tonemap.availableToneMapModes": [ - "1", - "2" - ], - "android.tonemap.maxCurvePoints": [ - "128" - ] -} diff --git a/devices/EmulatedCamera/hwl/configs/camera.json b/devices/EmulatedCamera/hwl/configs/emu_camera_back.json index 0bdb7ad..0bdb7ad 100644 --- a/devices/EmulatedCamera/hwl/configs/camera.json +++ b/devices/EmulatedCamera/hwl/configs/emu_camera_back.json diff --git a/devices/EmulatedCamera/hwl/configs/camera_depth.json b/devices/EmulatedCamera/hwl/configs/emu_camera_depth.json index 8a53d72..8a53d72 100644 --- a/devices/EmulatedCamera/hwl/configs/camera_depth.json +++ b/devices/EmulatedCamera/hwl/configs/emu_camera_depth.json diff --git a/devices/EmulatedCamera/hwl/configs/emu_camera_front.json b/devices/EmulatedCamera/hwl/configs/emu_camera_front.json new file mode 100644 index 0000000..49a661a --- /dev/null +++ b/devices/EmulatedCamera/hwl/configs/emu_camera_front.json @@ -0,0 +1,3528 @@ +[ + { + "android.colorCorrection.availableAberrationModes": [ + "0", + "1", + "2" + ], + "android.control.aeAvailableAntibandingModes": [ + "0", + "1", + "2", + "3" + ], + "android.control.aeAvailableModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.control.aeAvailableTargetFpsRanges": [ + "15", + "15", + "7", + "30", + "15", + "30", + "30", + "30" + ], + "android.control.aeCompensationRange": [ + "-24", + "24" + ], + "android.control.aeCompensationStep": [ + "1", + "6" + ], + "android.control.aeLockAvailable": [ + "TRUE" + ], + "android.control.afAvailableModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.control.availableEffects": [ + "0" + ], + "android.control.availableModes": [ + "0", + "1", + "2" + ], + "android.control.availableSceneModes": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "12", + "13", + "14", + "15", + "18" + ], + "android.control.availableVideoStabilizationModes": [ + "0", + "1" + ], + "android.control.awbAvailableModes": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "0" + ], + "android.control.awbLockAvailable": [ + "TRUE" + ], + "android.control.maxRegions": [ + "1", + "0", + "1" + ], + "android.control.postRawSensitivityBoostRange": [ + "100", + "100" + ], + "android.control.sceneModeOverrides": [ + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0" + ], + "android.distortionCorrection.availableModes": [ + "0" + ], + "android.edge.availableEdgeModes": [ + "1", + "2", + "0" + ], + "android.flash.info.available": [ + "TRUE" + ], + "android.hotPixel.availableHotPixelModes": [ + "0", + "1", + "2" + ], + "android.info.supportedHardwareLevel": [ + "FULL" + ], + "android.jpeg.availableThumbnailSizes": [ + "0", + "0", + "176", + "144", + "240", + "144", + "256", + "144", + "240", + "160", + "256", + "154", + "246", + "184", + "240", + "240", + "320", + "240" + ], + "android.jpeg.maxSize": [ + "300000" + ], + "android.lens.distortion": [ + "0.08807813", + "-0.22617353", + "0.16460505", + "0.00000000", + "0.00000000" + ], + "android.lens.facing": [ + "FRONT" + ], + "android.lens.info.availableApertures": [ + "1.73000002" + ], + "android.lens.info.availableFilterDensities": [ + "0.00000000" + ], + "android.lens.info.availableFocalLengths": [ + "4.38000011" + ], + "android.lens.info.availableOpticalStabilization": [ + "0" + ], + "android.lens.info.focusDistanceCalibration": [ + "APPROXIMATE" + ], + "android.lens.info.hyperfocalDistance": [ + "0.25249681" + ], + "android.lens.info.minimumFocusDistance": [ + "10.20408154" + ], + "android.lens.info.shadingMapSize": [ + "17", + "13" + ], + "android.lens.intrinsicCalibration": [ + "3225.77416992", + "3225.77416992", + "960.50427246", + "540.46704102", + "0.00000000" + ], + "android.lens.poseReference": [ + "PRIMARY_CAMERA" + ], + "android.lens.poseRotation": [ + "0.00000000", + "0.00000000", + "0.00000000", + "1.00000000" + ], + "android.lens.poseTranslation": [ + "-0.00000000", + "-0.00000000", + "-0.00000000" + ], + "android.logicalMultiCamera.physicalIds": [ + "51", + "0", + "52", + "0" + ], + "android.logicalMultiCamera.sensorSyncType": [ + "CALIBRATED" + ], + "android.noiseReduction.availableNoiseReductionModes": [ + "0", + "1", + "2", + "3" + ], + "android.reprocess.maxCaptureStall": [ + "2" + ], + "android.request.availableCapabilities": [ + "BACKWARD_COMPATIBLE", + "RAW", + "READ_SENSOR_SETTINGS", + "MANUAL_SENSOR", + "BURST_CAPTURE", + "MANUAL_POST_PROCESSING", + "LOGICAL_MULTI_CAMERA" + ], + "android.request.availableCharacteristicsKeys": [ + "4", + "65554", + "65555", + "65556", + "65557", + "65558", + "65559", + "65560", + "65561", + "65562", + "65563", + "65564", + "65565", + "65571", + "65572", + "65573", + "65574", + "65575", + "1638402", + "1638401", + "1638403", + "1638404", + "1769473", + "196610", + "327680", + "393217", + "458759", + "458760", + "589824", + "589825", + "589826", + "589827", + "589828", + "589829", + "589830", + "589831", + "524293", + "1703936", + "1703937", + "1703938", + "655362", + "786438", + "786440", + "786442", + "786443", + "786444", + "786445", + "786446", + "786447", + "786448", + "851972", + "851977", + "851978", + "851979", + "851976", + "851980", + "851981", + "983040", + "917526", + "917523", + "917534", + "983041", + "983042", + "983043", + "983044", + "983045", + "983046", + "983047", + "983048", + "983049", + "983050", + "917507", + "917508", + "917509", + "917510", + "917511", + "917512", + "917513", + "917514", + "917516", + "917517", + "917518", + "917519", + "917529", + "1048578", + "1179648", + "1179650", + "1179654", + "1179655", + "1179656", + "1245188", + "1245189", + "1376256", + "1507329", + "1572865", + "524300", + "524301", + "524295", + "524294", + "524298" + ], + "android.request.availableRequestKeys": [ + "0", + "1", + "2", + "3", + "65536", + "65537", + "65538", + "65539", + "65540", + "65541", + "65542", + "65543", + "65544", + "65545", + "65546", + "65547", + "65549", + "65550", + "65551", + "65552", + "65553", + "65576", + "1769472", + "196608", + "262146", + "393216", + "458752", + "458753", + "458754", + "458755", + "458756", + "458757", + "458758", + "524288", + "524289", + "524290", + "524291", + "524292", + "655360", + "786433", + "851968", + "917504", + "917505", + "917506", + "917520", + "1048576", + "1114112", + "1114115", + "1114128", + "1114129", + "1245184", + "1245185", + "1245186", + "1245187", + "1441792" + ], + "android.request.availableResultKeys": [ + "0", + "1", + "2", + "65537", + "65539", + "65540", + "65567", + "65543", + "65544", + "65568", + "65547", + "65570", + "65551", + "65576", + "196608", + "262146", + "262149", + "458752", + "458753", + "458754", + "458755", + "458756", + "458757", + "458758", + "524288", + "524289", + "524290", + "524291", + "524296", + "524297", + "524294", + "524295", + "524298", + "524301", + "524292", + "655360", + "786433", + "851968", + "917526", + "917523", + "917504", + "917505", + "917506", + "917520", + "917522", + "917525", + "1048576", + "1114112", + "1114121", + "1114124", + "1114125", + "1114126", + "1114118", + "1114119", + "1114129", + "1114130", + "1114131", + "1114132", + "1245184", + "1245185", + "1245186", + "1245187", + "1441792", + "65541", + "65542", + "65545", + "65552", + "1114123", + "1703938", + "917530" + ], + "android.request.maxNumInputStreams": [ + "0" + ], + "android.request.maxNumOutputStreams": [ + "1", + "3", + "2" + ], + "android.request.partialResultCount": [ + "1" + ], + "android.request.pipelineMaxDepth": [ + "8" + ], + "android.scaler.availableMaxDigitalZoom": [ + "8.00000000" + ], + "android.scaler.availableMinFrameDurations": [ + "34", + "1920", + "1440", + "33331760", + "35", + "1920", + "1440", + "33331760", + "33", + "1920", + "1440", + "33331760", + "34", + "1920", + "1080", + "33331760", + "35", + "1920", + "1080", + "33331760", + "33", + "1920", + "1080", + "33331760", + "34", + "1920", + "960", + "33331760", + "35", + "1920", + "960", + "33331760", + "33", + "1920", + "960", + "33331760", + "34", + "1600", + "1200", + "33331760", + "35", + "1600", + "1200", + "33331760", + "33", + "1600", + "1200", + "33331760", + "34", + "1440", + "1080", + "33331760", + "35", + "1440", + "1080", + "33331760", + "33", + "1440", + "1080", + "33331760", + "34", + "1280", + "960", + "33331760", + "35", + "1280", + "960", + "33331760", + "33", + "1280", + "960", + "33331760", + "34", + "1280", + "720", + "33331760", + "35", + "1280", + "720", + "33331760", + "33", + "1280", + "720", + "33331760", + "34", + "1024", + "768", + "33331760", + "35", + "1024", + "768", + "33331760", + "33", + "1024", + "768", + "33331760", + "34", + "800", + "600", + "33331760", + "35", + "800", + "600", + "33331760", + "33", + "800", + "600", + "33331760", + "34", + "720", + "480", + "33331760", + "35", + "720", + "480", + "33331760", + "33", + "720", + "480", + "33331760", + "34", + "640", + "480", + "33331760", + "35", + "640", + "480", + "33331760", + "33", + "640", + "480", + "33331760", + "34", + "640", + "360", + "33331760", + "35", + "640", + "360", + "33331760", + "33", + "640", + "360", + "33331760", + "34", + "352", + "288", + "33331760", + "35", + "352", + "288", + "33331760", + "33", + "352", + "288", + "33331760", + "34", + "320", + "240", + "33331760", + "35", + "320", + "240", + "33331760", + "33", + "320", + "240", + "33331760", + "34", + "176", + "144", + "33331760", + "35", + "176", + "144", + "33331760", + "33", + "176", + "144", + "33331760", + "32", + "1920", + "1440", + "33320000" + ], + "android.scaler.availableStallDurations": [ + "33", + "1920", + "1440", + "17971200", + "33", + "1920", + "1080", + "13478400", + "33", + "1920", + "960", + "11980800", + "33", + "1600", + "1200", + "12480000", + "33", + "1440", + "1080", + "10108800", + "33", + "1280", + "960", + "7987200", + "33", + "1280", + "720", + "5990400", + "33", + "1024", + "768", + "5111808", + "33", + "800", + "600", + "3120000", + "33", + "720", + "480", + "2246400", + "33", + "640", + "480", + "1996800", + "33", + "640", + "360", + "1497600", + "33", + "352", + "288", + "658944", + "33", + "320", + "240", + "499200", + "33", + "176", + "144", + "164736" + ], + "android.scaler.availableStreamConfigurations": [ + "32", + "1920", + "1440", + "OUTPUT", + "35", + "1920", + "1440", + "OUTPUT", + "35", + "1920", + "1080", + "OUTPUT", + "35", + "1920", + "960", + "OUTPUT", + "35", + "1600", + "1200", + "OUTPUT", + "35", + "1440", + "1080", + "OUTPUT", + "35", + "1280", + "960", + "OUTPUT", + "35", + "1280", + "720", + "OUTPUT", + "35", + "1024", + "768", + "OUTPUT", + "35", + "800", + "600", + "OUTPUT", + "35", + "720", + "480", + "OUTPUT", + "35", + "640", + "480", + "OUTPUT", + "35", + "640", + "360", + "OUTPUT", + "35", + "352", + "288", + "OUTPUT", + "35", + "320", + "240", + "OUTPUT", + "35", + "176", + "144", + "OUTPUT", + "34", + "1920", + "1440", + "OUTPUT", + "34", + "1920", + "1080", + "OUTPUT", + "34", + "1920", + "960", + "OUTPUT", + "34", + "1600", + "1200", + "OUTPUT", + "34", + "1440", + "1080", + "OUTPUT", + "34", + "1280", + "960", + "OUTPUT", + "34", + "1280", + "720", + "OUTPUT", + "34", + "1024", + "768", + "OUTPUT", + "34", + "800", + "600", + "OUTPUT", + "34", + "720", + "480", + "OUTPUT", + "34", + "640", + "480", + "OUTPUT", + "34", + "640", + "360", + "OUTPUT", + "34", + "352", + "288", + "OUTPUT", + "34", + "320", + "240", + "OUTPUT", + "34", + "176", + "144", + "OUTPUT", + "33", + "1920", + "1440", + "OUTPUT", + "33", + "1920", + "1080", + "OUTPUT", + "33", + "1920", + "960", + "OUTPUT", + "33", + "1600", + "1200", + "OUTPUT", + "33", + "1440", + "1080", + "OUTPUT", + "33", + "1280", + "960", + "OUTPUT", + "33", + "1280", + "720", + "OUTPUT", + "33", + "1024", + "768", + "OUTPUT", + "33", + "800", + "600", + "OUTPUT", + "33", + "720", + "480", + "OUTPUT", + "33", + "640", + "480", + "OUTPUT", + "33", + "640", + "360", + "OUTPUT", + "33", + "352", + "288", + "OUTPUT", + "33", + "320", + "240", + "OUTPUT" + ], + "android.scaler.croppingType": [ + "CENTER_ONLY" + ], + "android.sensor.availableTestPatternModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.sensor.blackLevelPattern": [ + "64", + "64", + "64", + "64" + ], + "android.sensor.calibrationTransform1": [ + "58", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "128", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "85", + "128" + ], + "android.sensor.calibrationTransform2": [ + "84", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "128", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "45", + "128" + ], + "android.sensor.colorTransform1": [ + "221", + "128", + "-105", + "128", + "-34", + "128", + "-124", + "128", + "240", + "128", + "5", + "128", + "5", + "128", + "-19", + "128", + "99", + "128" + ], + "android.sensor.colorTransform2": [ + "360", + "128", + "-249", + "128", + "-63", + "128", + "-137", + "128", + "279", + "128", + "-1", + "128", + "7", + "128", + "-18", + "128", + "159", + "128" + ], + "android.sensor.forwardMatrix1": [ + "56", + "128", + "49", + "128", + "18", + "128", + "28", + "128", + "92", + "128", + "8", + "128", + "2", + "128", + "12", + "128", + "91", + "128" + ], + "android.sensor.forwardMatrix2": [ + "56", + "128", + "49", + "128", + "18", + "128", + "28", + "128", + "92", + "128", + "8", + "128", + "2", + "128", + "12", + "128", + "91", + "128" + ], + "android.sensor.info.activeArraySize": [ + "0", + "0", + "1920", + "1440" + ], + "android.sensor.info.colorFilterArrangement": [ + "RGGB" + ], + "android.sensor.info.exposureTimeRange": [ + "13611", + "10319000832" + ], + "android.sensor.info.lensShadingApplied": [ + "TRUE" + ], + "android.sensor.info.maxFrameDuration": [ + "1319055264" + ], + "android.sensor.info.physicalSize": [ + "5.64480019", + "4.23360014" + ], + "android.sensor.info.pixelArraySize": [ + "1920", + "1440" + ], + "android.sensor.info.preCorrectionActiveArraySize": [ + "0", + "0", + "1920", + "1440" + ], + "android.sensor.info.sensitivityRange": [ + "100", + "1000" + ], + "android.sensor.info.timestampSource": [ + "REALTIME" + ], + "android.sensor.info.whiteLevel": [ + "1023" + ], + "android.sensor.maxAnalogSensitivity": [ + "444" + ], + "android.sensor.orientation": [ + "270" + ], + "android.sensor.profileHueSatMapDimensions": [ + "0", + "0", + "0" + ], + "android.sensor.referenceIlluminant1": [ + "D65" + ], + "android.sensor.referenceIlluminant2": [ + "17" + ], + "android.shading.availableModes": [ + "0", + "1", + "2" + ], + "android.statistics.info.availableFaceDetectModes": [ + "0", + "1", + "2" + ], + "android.statistics.info.availableHotPixelMapModes": [ + "0" + ], + "android.statistics.info.availableLensShadingMapModes": [ + "0", + "1" + ], + "android.statistics.info.maxFaceCount": [ + "10" + ], + "android.sync.maxLatency": [ + "PER_FRAME_CONTROL" + ], + "android.tonemap.availableToneMapModes": [ + "0", + "1", + "2" + ], + "android.tonemap.maxCurvePoints": [ + "64" + ] + }, + { + "android.colorCorrection.availableAberrationModes": [ + "0", + "1", + "2" + ], + "android.control.aeAvailableAntibandingModes": [ + "0", + "1", + "2", + "3" + ], + "android.control.aeAvailableModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.control.aeAvailableTargetFpsRanges": [ + "15", + "15", + "7", + "30", + "15", + "30", + "30", + "30" + ], + "android.control.aeCompensationRange": [ + "-24", + "24" + ], + "android.control.aeCompensationStep": [ + "1", + "6" + ], + "android.control.aeLockAvailable": [ + "TRUE" + ], + "android.control.afAvailableModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.control.availableEffects": [ + "0" + ], + "android.control.availableModes": [ + "0", + "1", + "2" + ], + "android.control.availableSceneModes": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "12", + "13", + "14", + "15", + "18" + ], + "android.control.availableVideoStabilizationModes": [ + "0" + ], + "android.control.awbAvailableModes": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "0" + ], + "android.control.awbLockAvailable": [ + "TRUE" + ], + "android.control.maxRegions": [ + "1", + "0", + "1" + ], + "android.control.postRawSensitivityBoostRange": [ + "100", + "100" + ], + "android.control.sceneModeOverrides": [ + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0" + ], + "android.distortionCorrection.availableModes": [ + "0" + ], + "android.edge.availableEdgeModes": [ + "1", + "2", + "0" + ], + "android.flash.info.available": [ + "TRUE" + ], + "android.hotPixel.availableHotPixelModes": [ + "0", + "1", + "2" + ], + "android.info.supportedHardwareLevel": [ + "FULL" + ], + "android.jpeg.availableThumbnailSizes": [ + "0", + "0", + "176", + "144", + "240", + "144", + "256", + "144", + "240", + "160", + "256", + "154", + "246", + "184", + "240", + "240", + "320", + "240" + ], + "android.jpeg.maxSize": [ + "300000" + ], + "android.lens.distortion": [ + "0.08807813", + "-0.22617353", + "0.16460505", + "0.00000000", + "0.00000000" + ], + "android.lens.facing": [ + "FRONT" + ], + "android.lens.info.availableApertures": [ + "1.73000002" + ], + "android.lens.info.availableFilterDensities": [ + "0.00000000" + ], + "android.lens.info.availableFocalLengths": [ + "4.38000011" + ], + "android.lens.info.availableOpticalStabilization": [ + "0", + "1" + ], + "android.lens.info.focusDistanceCalibration": [ + "APPROXIMATE" + ], + "android.lens.info.hyperfocalDistance": [ + "0.25249681" + ], + "android.lens.info.minimumFocusDistance": [ + "10.20408154" + ], + "android.lens.info.shadingMapSize": [ + "17", + "13" + ], + "android.lens.intrinsicCalibration": [ + "3225.77416992", + "3225.77416992", + "960.50427246", + "540.46704102", + "0.00000000" + ], + "android.lens.poseReference": [ + "PRIMARY_CAMERA" + ], + "android.lens.poseRotation": [ + "0.00000000", + "0.00000000", + "0.00000000", + "1.00000000" + ], + "android.lens.poseTranslation": [ + "-0.00000000", + "-0.00000000", + "-0.00000000" + ], + "android.noiseReduction.availableNoiseReductionModes": [ + "0", + "1", + "2", + "3" + ], + "android.reprocess.maxCaptureStall": [ + "2" + ], + "android.request.availableCapabilities": [ + "BACKWARD_COMPATIBLE", + "RAW", + "READ_SENSOR_SETTINGS", + "MANUAL_SENSOR", + "BURST_CAPTURE", + "MANUAL_POST_PROCESSING" + ], + "android.request.availableCharacteristicsKeys": [ + "4", + "65554", + "65555", + "65556", + "65557", + "65558", + "65559", + "65560", + "65561", + "65562", + "65563", + "65564", + "65565", + "65571", + "65572", + "65573", + "65574", + "65575", + "1638402", + "1638401", + "1638403", + "1638404", + "1769473", + "196610", + "327680", + "393217", + "458759", + "458760", + "589824", + "589825", + "589826", + "589827", + "589828", + "589829", + "589830", + "589831", + "524293", + "1703936", + "1703937", + "1703938", + "655362", + "786438", + "786440", + "786442", + "786443", + "786444", + "786445", + "786446", + "786447", + "786448", + "851972", + "851977", + "851978", + "851979", + "851976", + "851980", + "851981", + "983040", + "917526", + "917523", + "917534", + "983041", + "983042", + "983043", + "983044", + "983045", + "983046", + "983047", + "983048", + "983049", + "983050", + "917507", + "917508", + "917509", + "917510", + "917511", + "917512", + "917513", + "917514", + "917516", + "917517", + "917518", + "917519", + "917529", + "1048578", + "1179648", + "1179650", + "1179654", + "1179655", + "1179656", + "1245188", + "1245189", + "1376256", + "1507329", + "1572865", + "524300", + "524301", + "524295", + "524294", + "524298" + ], + "android.request.availableRequestKeys": [ + "0", + "1", + "2", + "3", + "65536", + "65537", + "65538", + "65539", + "65540", + "65541", + "65542", + "65543", + "65544", + "65545", + "65546", + "65547", + "65549", + "65550", + "65551", + "65552", + "65553", + "65576", + "1769472", + "196608", + "262146", + "393216", + "458752", + "458753", + "458754", + "458755", + "458756", + "458757", + "458758", + "524288", + "524289", + "524290", + "524291", + "524292", + "655360", + "786433", + "851968", + "917504", + "917505", + "917506", + "917520", + "1048576", + "1114112", + "1114115", + "1114128", + "1114129", + "1245184", + "1245185", + "1245186", + "1245187", + "1441792" + ], + "android.request.availableResultKeys": [ + "0", + "1", + "2", + "65537", + "65539", + "65540", + "65567", + "65543", + "65544", + "65568", + "65547", + "65570", + "65551", + "65576", + "196608", + "262146", + "262149", + "458752", + "458753", + "458754", + "458755", + "458756", + "458757", + "458758", + "524288", + "524289", + "524290", + "524291", + "524296", + "524297", + "524294", + "524295", + "524298", + "524301", + "524292", + "655360", + "786433", + "851968", + "917526", + "917523", + "917504", + "917505", + "917506", + "917520", + "917522", + "917525", + "1048576", + "1114112", + "1114121", + "1114124", + "1114125", + "1114126", + "1114118", + "1114119", + "1114129", + "1114130", + "1114131", + "1114132", + "1245184", + "1245185", + "1245186", + "1245187", + "1441792", + "65541", + "65542", + "65545", + "65552", + "1114123", + "917530" + ], + "android.request.maxNumInputStreams": [ + "0" + ], + "android.request.maxNumOutputStreams": [ + "1", + "3", + "2" + ], + "android.request.partialResultCount": [ + "1" + ], + "android.request.pipelineMaxDepth": [ + "8" + ], + "android.scaler.availableMaxDigitalZoom": [ + "8.00000000" + ], + "android.scaler.availableMinFrameDurations": [ + "34", + "1920", + "1440", + "33331760", + "35", + "1920", + "1440", + "33331760", + "33", + "1920", + "1440", + "33331760", + "34", + "1920", + "1080", + "33331760", + "35", + "1920", + "1080", + "33331760", + "33", + "1920", + "1080", + "33331760", + "34", + "1920", + "960", + "33331760", + "35", + "1920", + "960", + "33331760", + "33", + "1920", + "960", + "33331760", + "34", + "1600", + "1200", + "33331760", + "35", + "1600", + "1200", + "33331760", + "33", + "1600", + "1200", + "33331760", + "34", + "1440", + "1080", + "33331760", + "35", + "1440", + "1080", + "33331760", + "33", + "1440", + "1080", + "33331760", + "34", + "1280", + "960", + "33331760", + "35", + "1280", + "960", + "33331760", + "33", + "1280", + "960", + "33331760", + "34", + "1280", + "720", + "33331760", + "35", + "1280", + "720", + "33331760", + "33", + "1280", + "720", + "33331760", + "34", + "1024", + "768", + "33331760", + "35", + "1024", + "768", + "33331760", + "33", + "1024", + "768", + "33331760", + "34", + "800", + "600", + "33331760", + "35", + "800", + "600", + "33331760", + "33", + "800", + "600", + "33331760", + "34", + "720", + "480", + "33331760", + "35", + "720", + "480", + "33331760", + "33", + "720", + "480", + "33331760", + "34", + "640", + "480", + "33331760", + "35", + "640", + "480", + "33331760", + "33", + "640", + "480", + "33331760", + "34", + "640", + "360", + "33331760", + "35", + "640", + "360", + "33331760", + "33", + "640", + "360", + "33331760", + "34", + "352", + "288", + "33331760", + "35", + "352", + "288", + "33331760", + "33", + "352", + "288", + "33331760", + "34", + "320", + "240", + "33331760", + "35", + "320", + "240", + "33331760", + "33", + "320", + "240", + "33331760", + "34", + "176", + "144", + "33331760", + "35", + "176", + "144", + "33331760", + "33", + "176", + "144", + "33331760", + "32", + "1920", + "1440", + "33320000" + ], + "android.scaler.availableStallDurations": [ + "33", + "1920", + "1440", + "17971200", + "33", + "1920", + "1080", + "13478400", + "33", + "1920", + "960", + "11980800", + "33", + "1600", + "1200", + "12480000", + "33", + "1440", + "1080", + "10108800", + "33", + "1280", + "960", + "7987200", + "33", + "1280", + "720", + "5990400", + "33", + "1024", + "768", + "5111808", + "33", + "800", + "600", + "3120000", + "33", + "720", + "480", + "2246400", + "33", + "640", + "480", + "1996800", + "33", + "640", + "360", + "1497600", + "33", + "352", + "288", + "658944", + "33", + "320", + "240", + "499200", + "33", + "176", + "144", + "164736" + ], + "android.scaler.availableStreamConfigurations": [ + "34", + "1920", + "1440", + "OUTPUT", + "35", + "1920", + "1440", + "OUTPUT", + "33", + "1920", + "1440", + "OUTPUT", + "34", + "1920", + "1080", + "OUTPUT", + "35", + "1920", + "1080", + "OUTPUT", + "33", + "1920", + "1080", + "OUTPUT", + "34", + "1920", + "960", + "OUTPUT", + "35", + "1920", + "960", + "OUTPUT", + "33", + "1920", + "960", + "OUTPUT", + "34", + "1600", + "1200", + "OUTPUT", + "35", + "1600", + "1200", + "OUTPUT", + "33", + "1600", + "1200", + "OUTPUT", + "34", + "1440", + "1080", + "OUTPUT", + "35", + "1440", + "1080", + "OUTPUT", + "33", + "1440", + "1080", + "OUTPUT", + "34", + "1280", + "960", + "OUTPUT", + "35", + "1280", + "960", + "OUTPUT", + "33", + "1280", + "960", + "OUTPUT", + "34", + "1280", + "720", + "OUTPUT", + "35", + "1280", + "720", + "OUTPUT", + "33", + "1280", + "720", + "OUTPUT", + "34", + "1024", + "768", + "OUTPUT", + "35", + "1024", + "768", + "OUTPUT", + "33", + "1024", + "768", + "OUTPUT", + "34", + "800", + "600", + "OUTPUT", + "35", + "800", + "600", + "OUTPUT", + "33", + "800", + "600", + "OUTPUT", + "34", + "720", + "480", + "OUTPUT", + "35", + "720", + "480", + "OUTPUT", + "33", + "720", + "480", + "OUTPUT", + "34", + "640", + "480", + "OUTPUT", + "35", + "640", + "480", + "OUTPUT", + "33", + "640", + "480", + "OUTPUT", + "34", + "640", + "360", + "OUTPUT", + "35", + "640", + "360", + "OUTPUT", + "33", + "640", + "360", + "OUTPUT", + "34", + "352", + "288", + "OUTPUT", + "35", + "352", + "288", + "OUTPUT", + "33", + "352", + "288", + "OUTPUT", + "34", + "320", + "240", + "OUTPUT", + "35", + "320", + "240", + "OUTPUT", + "33", + "320", + "240", + "OUTPUT", + "34", + "176", + "144", + "OUTPUT", + "35", + "176", + "144", + "OUTPUT", + "33", + "176", + "144", + "OUTPUT", + "32", + "1920", + "1440", + "OUTPUT" + ], + "android.scaler.croppingType": [ + "CENTER_ONLY" + ], + "android.sensor.availableTestPatternModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.sensor.blackLevelPattern": [ + "64", + "64", + "64", + "64" + ], + "android.sensor.calibrationTransform1": [ + "58", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "128", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "85", + "128" + ], + "android.sensor.calibrationTransform2": [ + "84", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "128", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "45", + "128" + ], + "android.sensor.colorTransform1": [ + "221", + "128", + "-105", + "128", + "-34", + "128", + "-124", + "128", + "240", + "128", + "5", + "128", + "5", + "128", + "-19", + "128", + "99", + "128" + ], + "android.sensor.colorTransform2": [ + "360", + "128", + "-249", + "128", + "-63", + "128", + "-137", + "128", + "279", + "128", + "-1", + "128", + "7", + "128", + "-18", + "128", + "159", + "128" + ], + "android.sensor.forwardMatrix1": [ + "56", + "128", + "49", + "128", + "18", + "128", + "28", + "128", + "92", + "128", + "8", + "128", + "2", + "128", + "12", + "128", + "91", + "128" + ], + "android.sensor.forwardMatrix2": [ + "56", + "128", + "49", + "128", + "18", + "128", + "28", + "128", + "92", + "128", + "8", + "128", + "2", + "128", + "12", + "128", + "91", + "128" + ], + "android.sensor.info.activeArraySize": [ + "0", + "0", + "1920", + "1440" + ], + "android.sensor.info.colorFilterArrangement": [ + "RGGB" + ], + "android.sensor.info.exposureTimeRange": [ + "13611", + "10319000832" + ], + "android.sensor.info.lensShadingApplied": [ + "TRUE" + ], + "android.sensor.info.maxFrameDuration": [ + "1319055264" + ], + "android.sensor.info.physicalSize": [ + "5.64480019", + "4.23360014" + ], + "android.sensor.info.pixelArraySize": [ + "1920", + "1440" + ], + "android.sensor.info.preCorrectionActiveArraySize": [ + "0", + "0", + "1920", + "1440" + ], + "android.sensor.info.sensitivityRange": [ + "100", + "1000" + ], + "android.sensor.info.timestampSource": [ + "REALTIME" + ], + "android.sensor.info.whiteLevel": [ + "1023" + ], + "android.sensor.maxAnalogSensitivity": [ + "444" + ], + "android.sensor.orientation": [ + "270" + ], + "android.sensor.profileHueSatMapDimensions": [ + "0", + "0", + "0" + ], + "android.sensor.referenceIlluminant1": [ + "D65" + ], + "android.sensor.referenceIlluminant2": [ + "17" + ], + "android.shading.availableModes": [ + "0", + "1", + "2" + ], + "android.statistics.info.availableFaceDetectModes": [ + "0", + "1", + "2" + ], + "android.statistics.info.availableHotPixelMapModes": [ + "0" + ], + "android.statistics.info.availableLensShadingMapModes": [ + "0", + "1" + ], + "android.statistics.info.maxFaceCount": [ + "10" + ], + "android.sync.maxLatency": [ + "PER_FRAME_CONTROL" + ], + "android.tonemap.availableToneMapModes": [ + "0", + "1", + "2" + ], + "android.tonemap.maxCurvePoints": [ + "64" + ] + }, + { + "android.colorCorrection.availableAberrationModes": [ + "0", + "1", + "2" + ], + "android.control.aeAvailableAntibandingModes": [ + "0", + "1", + "2", + "3" + ], + "android.control.aeAvailableModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.control.aeAvailableTargetFpsRanges": [ + "15", + "15", + "15", + "30", + "7", + "30", + "30", + "30" + ], + "android.control.aeCompensationRange": [ + "-24", + "24" + ], + "android.control.aeCompensationStep": [ + "1", + "6" + ], + "android.control.aeLockAvailable": [ + "TRUE" + ], + "android.control.afAvailableModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.control.availableEffects": [ + "0" + ], + "android.control.availableModes": [ + "0", + "1", + "2" + ], + "android.control.availableSceneModes": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "12", + "13", + "14", + "15", + "18" + ], + "android.control.availableVideoStabilizationModes": [ + "0", + "1" + ], + "android.control.awbAvailableModes": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "0" + ], + "android.control.awbLockAvailable": [ + "TRUE" + ], + "android.control.maxRegions": [ + "1", + "0", + "1" + ], + "android.control.postRawSensitivityBoostRange": [ + "100", + "100" + ], + "android.control.sceneModeOverrides": [ + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0", + "1", + "1", + "0" + ], + "android.distortionCorrection.availableModes": [ + "0" + ], + "android.edge.availableEdgeModes": [ + "1", + "2", + "0" + ], + "android.flash.info.available": [ + "TRUE" + ], + "android.hotPixel.availableHotPixelModes": [ + "0", + "1", + "2" + ], + "android.info.supportedHardwareLevel": [ + "FULL" + ], + "android.jpeg.availableThumbnailSizes": [ + "0", + "0", + "176", + "144", + "240", + "144", + "256", + "144", + "240", + "160", + "256", + "154", + "246", + "184", + "240", + "240", + "320", + "240" + ], + "android.jpeg.maxSize": [ + "300000" + ], + "android.lens.distortion": [ + "0.27679554", + "-1.56508207", + "3.02522445", + "0.00000000", + "0.00000000" + ], + "android.lens.facing": [ + "FRONT" + ], + "android.lens.info.availableApertures": [ + "2.40000010" + ], + "android.lens.info.availableFilterDensities": [ + "0.00000000" + ], + "android.lens.info.availableFocalLengths": [ + "5.84000015" + ], + "android.lens.info.availableOpticalStabilization": [ + "0", + "1" + ], + "android.lens.info.focusDistanceCalibration": [ + "APPROXIMATE" + ], + "android.lens.info.hyperfocalDistance": [ + "0.14073935" + ], + "android.lens.info.minimumFocusDistance": [ + "10.10101032" + ], + "android.lens.info.shadingMapSize": [ + "17", + "13" + ], + "android.lens.intrinsicCalibration": [ + "5941.24902344", + "5941.24902344", + "960.14233398", + "540.47375488", + "0.00000000" + ], + "android.lens.poseReference": [ + "PRIMARY_CAMERA" + ], + "android.lens.poseRotation": [ + "-0.00032215", + "0.00118852", + "-0.00006529", + "0.99999928" + ], + "android.lens.poseTranslation": [ + "0.00034755", + "0.01267981", + "-0.00284645" + ], + "android.noiseReduction.availableNoiseReductionModes": [ + "0", + "1", + "2", + "3" + ], + "android.reprocess.maxCaptureStall": [ + "2" + ], + "android.request.availableCapabilities": [ + "BACKWARD_COMPATIBLE", + "RAW", + "READ_SENSOR_SETTINGS", + "MANUAL_SENSOR", + "BURST_CAPTURE", + "MANUAL_POST_PROCESSING" + ], + "android.request.availableCharacteristicsKeys": [ + "4", + "65554", + "65555", + "65556", + "65557", + "65558", + "65559", + "65560", + "65561", + "65562", + "65563", + "65564", + "65565", + "65571", + "65572", + "65573", + "65574", + "65575", + "1638402", + "1638401", + "1638403", + "1638404", + "1769473", + "196610", + "327680", + "393217", + "458759", + "458760", + "589824", + "589825", + "589826", + "589827", + "589828", + "589829", + "589830", + "589831", + "524293", + "1703936", + "1703937", + "1703938", + "655362", + "786438", + "786440", + "786442", + "786443", + "786444", + "786445", + "786446", + "786447", + "786448", + "851972", + "851977", + "851978", + "851979", + "851976", + "851980", + "851981", + "983040", + "917526", + "917523", + "917534", + "983041", + "983042", + "983043", + "983044", + "983045", + "983046", + "983047", + "983048", + "983049", + "983050", + "917507", + "917508", + "917509", + "917510", + "917511", + "917512", + "917513", + "917514", + "917516", + "917517", + "917518", + "917519", + "917529", + "1048578", + "1179648", + "1179650", + "1179654", + "1179655", + "1179656", + "1245188", + "1245189", + "1376256", + "1507329", + "1572865", + "524300", + "524301", + "524295", + "524294", + "524298" + ], + "android.request.availableRequestKeys": [ + "0", + "1", + "2", + "3", + "65536", + "65537", + "65538", + "65539", + "65540", + "65541", + "65542", + "65543", + "65544", + "65545", + "65546", + "65547", + "65549", + "65550", + "65551", + "65552", + "65553", + "65576", + "1769472", + "196608", + "262146", + "393216", + "458752", + "458753", + "458754", + "458755", + "458756", + "458757", + "458758", + "524288", + "524289", + "524290", + "524291", + "524292", + "655360", + "786433", + "851968", + "917504", + "917505", + "917506", + "917520", + "1048576", + "1114112", + "1114115", + "1114128", + "1114129", + "1245184", + "1245185", + "1245186", + "1245187", + "1441792" + ], + "android.request.availableResultKeys": [ + "0", + "1", + "2", + "65537", + "65539", + "65540", + "65567", + "65543", + "65544", + "65568", + "65547", + "65570", + "65551", + "65576", + "196608", + "262146", + "262149", + "458752", + "458753", + "458754", + "458755", + "458756", + "458757", + "458758", + "524288", + "524289", + "524290", + "524291", + "524296", + "524297", + "524294", + "524295", + "524298", + "524301", + "524292", + "655360", + "786433", + "851968", + "917526", + "917523", + "917504", + "917505", + "917506", + "917520", + "917522", + "917525", + "1048576", + "1114112", + "1114121", + "1114124", + "1114125", + "1114126", + "1114118", + "1114119", + "1114129", + "1114130", + "1114131", + "1114132", + "1245184", + "1245185", + "1245186", + "1245187", + "1441792", + "65541", + "65542", + "65545", + "65552", + "1114123", + "917530" + ], + "android.request.maxNumInputStreams": [ + "0" + ], + "android.request.maxNumOutputStreams": [ + "1", + "3", + "2" + ], + "android.request.partialResultCount": [ + "1" + ], + "android.request.pipelineMaxDepth": [ + "8" + ], + "android.scaler.availableMaxDigitalZoom": [ + "8.00000000" + ], + "android.scaler.availableMinFrameDurations": [ + "34", + "1920", + "1440", + "33331760", + "35", + "1920", + "1440", + "33331760", + "33", + "1920", + "1440", + "33331760", + "34", + "1920", + "1080", + "33331760", + "35", + "1920", + "1080", + "33331760", + "33", + "1920", + "1080", + "33331760", + "34", + "1920", + "960", + "33331760", + "35", + "1920", + "960", + "33331760", + "33", + "1920", + "960", + "33331760", + "34", + "1600", + "1200", + "33331760", + "35", + "1600", + "1200", + "33331760", + "33", + "1600", + "1200", + "33331760", + "34", + "1440", + "1080", + "33331760", + "35", + "1440", + "1080", + "33331760", + "33", + "1440", + "1080", + "33331760", + "34", + "1280", + "960", + "33331760", + "35", + "1280", + "960", + "33331760", + "33", + "1280", + "960", + "33331760", + "34", + "1280", + "720", + "33331760", + "35", + "1280", + "720", + "33331760", + "33", + "1280", + "720", + "33331760", + "34", + "1024", + "768", + "33331760", + "35", + "1024", + "768", + "33331760", + "33", + "1024", + "768", + "33331760", + "34", + "800", + "600", + "33331760", + "35", + "800", + "600", + "33331760", + "33", + "800", + "600", + "33331760", + "34", + "720", + "480", + "33331760", + "35", + "720", + "480", + "33331760", + "33", + "720", + "480", + "33331760", + "34", + "640", + "480", + "33331760", + "35", + "640", + "480", + "33331760", + "33", + "640", + "480", + "33331760", + "34", + "640", + "360", + "33331760", + "35", + "640", + "360", + "33331760", + "33", + "640", + "360", + "33331760", + "34", + "352", + "288", + "33331760", + "35", + "352", + "288", + "33331760", + "33", + "352", + "288", + "33331760", + "34", + "320", + "240", + "33331760", + "35", + "320", + "240", + "33331760", + "33", + "320", + "240", + "33331760", + "34", + "176", + "144", + "33331760", + "35", + "176", + "144", + "33331760", + "33", + "176", + "144", + "33331760", + "32", + "1920", + "1440", + "33326886" + ], + "android.scaler.availableStallDurations": [ + "33", + "1920", + "1440", + "17971200", + "33", + "1920", + "1080", + "13478400", + "33", + "1920", + "960", + "11980800", + "33", + "1600", + "1200", + "12480000", + "33", + "1440", + "1080", + "10108800", + "33", + "1280", + "960", + "7987200", + "33", + "1280", + "720", + "5990400", + "33", + "1024", + "768", + "5111808", + "33", + "800", + "600", + "3120000", + "33", + "720", + "480", + "2246400", + "33", + "640", + "480", + "1996800", + "33", + "640", + "360", + "1497600", + "33", + "352", + "288", + "658944", + "33", + "320", + "240", + "499200", + "33", + "176", + "144", + "164736" + ], + "android.scaler.availableStreamConfigurations": [ + "34", + "1920", + "1440", + "OUTPUT", + "35", + "1920", + "1440", + "OUTPUT", + "33", + "1920", + "1440", + "OUTPUT", + "34", + "1920", + "1080", + "OUTPUT", + "35", + "1920", + "1080", + "OUTPUT", + "33", + "1920", + "1080", + "OUTPUT", + "34", + "1920", + "960", + "OUTPUT", + "35", + "1920", + "960", + "OUTPUT", + "33", + "1920", + "960", + "OUTPUT", + "34", + "1600", + "1200", + "OUTPUT", + "35", + "1600", + "1200", + "OUTPUT", + "33", + "1600", + "1200", + "OUTPUT", + "34", + "1440", + "1080", + "OUTPUT", + "35", + "1440", + "1080", + "OUTPUT", + "33", + "1440", + "1080", + "OUTPUT", + "34", + "1280", + "960", + "OUTPUT", + "35", + "1280", + "960", + "OUTPUT", + "33", + "1280", + "960", + "OUTPUT", + "34", + "1280", + "720", + "OUTPUT", + "35", + "1280", + "720", + "OUTPUT", + "33", + "1280", + "720", + "OUTPUT", + "34", + "1024", + "768", + "OUTPUT", + "35", + "1024", + "768", + "OUTPUT", + "33", + "1024", + "768", + "OUTPUT", + "34", + "800", + "600", + "OUTPUT", + "35", + "800", + "600", + "OUTPUT", + "33", + "800", + "600", + "OUTPUT", + "34", + "720", + "480", + "OUTPUT", + "35", + "720", + "480", + "OUTPUT", + "33", + "720", + "480", + "OUTPUT", + "34", + "640", + "480", + "OUTPUT", + "35", + "640", + "480", + "OUTPUT", + "33", + "640", + "480", + "OUTPUT", + "34", + "640", + "360", + "OUTPUT", + "35", + "640", + "360", + "OUTPUT", + "33", + "640", + "360", + "OUTPUT", + "34", + "352", + "288", + "OUTPUT", + "35", + "352", + "288", + "OUTPUT", + "33", + "352", + "288", + "OUTPUT", + "34", + "320", + "240", + "OUTPUT", + "35", + "320", + "240", + "OUTPUT", + "33", + "320", + "240", + "OUTPUT", + "34", + "176", + "144", + "OUTPUT", + "35", + "176", + "144", + "OUTPUT", + "32", + "1920", + "1440", + "OUTPUT" + ], + "android.scaler.croppingType": [ + "CENTER_ONLY" + ], + "android.sensor.availableTestPatternModes": [ + "0", + "1", + "2", + "3", + "4" + ], + "android.sensor.blackLevelPattern": [ + "64", + "64", + "64", + "64" + ], + "android.sensor.calibrationTransform1": [ + "68", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "128", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "78", + "128" + ], + "android.sensor.calibrationTransform2": [ + "97", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "128", + "128", + "0", + "128", + "0", + "128", + "0", + "128", + "41", + "128" + ], + "android.sensor.colorTransform1": [ + "221", + "128", + "-105", + "128", + "-34", + "128", + "-124", + "128", + "240", + "128", + "5", + "128", + "5", + "128", + "-19", + "128", + "99", + "128" + ], + "android.sensor.colorTransform2": [ + "360", + "128", + "-249", + "128", + "-63", + "128", + "-137", + "128", + "279", + "128", + "-1", + "128", + "7", + "128", + "-18", + "128", + "159", + "128" + ], + "android.sensor.forwardMatrix1": [ + "56", + "128", + "49", + "128", + "18", + "128", + "28", + "128", + "92", + "128", + "8", + "128", + "2", + "128", + "12", + "128", + "91", + "128" + ], + "android.sensor.forwardMatrix2": [ + "56", + "128", + "49", + "128", + "18", + "128", + "28", + "128", + "92", + "128", + "8", + "128", + "2", + "128", + "12", + "128", + "91", + "128" + ], + "android.sensor.info.activeArraySize": [ + "0", + "0", + "1920", + "1440" + ], + "android.sensor.info.colorFilterArrangement": [ + "RGGB" + ], + "android.sensor.info.exposureTimeRange": [ + "9377", + "13388615424" + ], + "android.sensor.info.lensShadingApplied": [ + "TRUE" + ], + "android.sensor.info.maxFrameDuration": [ + "1319055264" + ], + "android.sensor.info.physicalSize": [ + "4.65600014", + "3.49600005" + ], + "android.sensor.info.pixelArraySize": [ + "1920", + "1440" + ], + "android.sensor.info.preCorrectionActiveArraySize": [ + "0", + "0", + "1920", + "1440" + ], + "android.sensor.info.sensitivityRange": [ + "100", + "1000" + ], + "android.sensor.info.timestampSource": [ + "REALTIME" + ], + "android.sensor.info.whiteLevel": [ + "1023" + ], + "android.sensor.maxAnalogSensitivity": [ + "640" + ], + "android.sensor.orientation": [ + "270" + ], + "android.sensor.profileHueSatMapDimensions": [ + "0", + "0", + "0" + ], + "android.sensor.referenceIlluminant1": [ + "D65" + ], + "android.sensor.referenceIlluminant2": [ + "17" + ], + "android.shading.availableModes": [ + "0", + "1", + "2" + ], + "android.statistics.info.availableFaceDetectModes": [ + "0", + "1", + "2" + ], + "android.statistics.info.availableHotPixelMapModes": [ + "0" + ], + "android.statistics.info.availableLensShadingMapModes": [ + "0", + "1" + ], + "android.statistics.info.maxFaceCount": [ + "10" + ], + "android.sync.maxLatency": [ + "PER_FRAME_CONTROL" + ], + "android.tonemap.availableToneMapModes": [ + "0", + "1", + "2" + ], + "android.tonemap.maxCurvePoints": [ + "64" + ] + } +] diff --git a/devices/EmulatedCamera/hwl/tools/parse_bugreport.py b/devices/EmulatedCamera/hwl/tools/parse_bugreport.py index d1699e9..c806ddd 100755 --- a/devices/EmulatedCamera/hwl/tools/parse_bugreport.py +++ b/devices/EmulatedCamera/hwl/tools/parse_bugreport.py @@ -38,10 +38,11 @@ def storeJsonConfigration(filePath, chars): """ Parse media.camera dump section and populate the camera -characteristics dictionary. +characteristics list of dictionaries. """ -def parseCameraDump(deviceId, cameraDumpPath, chars): +def parseCameraDump(deviceId, cameraDumpPath, tagList): deviceRegExp = "== Camera HAL device device@[0-9]+\.[0-9]+/{0} \(v3.".format(deviceId) + physicalDeviceRegExp = "Physical camera [0-9] characteristics:" tagRegExp = " {4}android[a-zA-Z0-9\.]+ \([a-z0-9]+\): " tagValueRegExp = "[^a-zA-Z0-9-\._]" with open(cameraDumpPath, "r") as file: @@ -50,45 +51,51 @@ def parseCameraDump(deviceId, cameraDumpPath, chars): print "Camera device id: {0} not found".format(deviceId) sys.exit() - tags = re.split(tagRegExp, devices[1]) - tagsContent = re.findall(tagRegExp, devices[1]) - i = 0; - parseEnd = False - for tag in tags[1:]: - if parseEnd: - break + physicalDevices = re.split(physicalDeviceRegExp, devices[1]) + physicalIdx = 0 + for physicalDevice in physicalDevices: + physicalIdx += 1 + tags = re.split(tagRegExp, physicalDevice) + tagsContent = re.findall(tagRegExp, physicalDevice) + i = 0; + parseEnd = False + deviceChars = dict() + for tag in tags[1:]: + if parseEnd: + break - lines = tag.splitlines() - if len(lines) < 2: - print "Empty tag entry, skipping!" - continue - tagName = tagsContent[i].split()[0] + lines = tag.splitlines() + if len(lines) < 2: + print "Empty tag entry, skipping!" + continue + tagName = tagsContent[i].split()[0] - if tagName is None or len(tagName) < 1: - print "Invalid tag found, skipping!" - continue + if tagName is None or len(tagName) < 1: + print "Invalid tag found, skipping!" + continue - i += 1 - for line in lines[1:]: - if line.startswith('== Camera HAL device device'): - parseEnd = True - break + i += 1 + for line in lines[1:]: + if line.startswith('== Camera HAL device device'): + parseEnd = True + break - values = re.split(r' {8}', line) - if len(values) == 2: - key = tagName - tagValues = filter(None, re.split(tagValueRegExp, values[1])) - if chars.has_key(key): - chars[key] = chars[key] + tagValues + values = re.split(r' {8}', line) + if len(values) == 2: + key = tagName + tagValues = filter(None, re.split(tagValueRegExp, values[1])) + if deviceChars.has_key(key): + deviceChars[key] = deviceChars[key] + tagValues + else: + deviceChars[key] = tagValues else: - chars[key] = tagValues - else: - break + break + tagList.append(deviceChars) os.remove(cameraDumpPath) if __name__ == '__main__': argc = len(sys.argv) - deviceId = "legacy/0" + deviceId = "" bugreportPath = "" configPath = "" if argc >= 4: @@ -110,7 +117,7 @@ if __name__ == '__main__': print("Camera dump not found in bugreport!") sys.exit() - chars = dict() - parseCameraDump(deviceId, bugzip.extract(cameraDumpFile), chars) - storeJsonConfigration(configPath, chars) + tagList = list() + parseCameraDump(deviceId, bugzip.extract(cameraDumpFile), tagList) + storeJsonConfigration(configPath, tagList) diff --git a/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp b/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp index 6a5b711..e68ea56 100644 --- a/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp +++ b/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp @@ -205,4 +205,12 @@ status_t GetSensorCharacteristics(const HalCameraMetadata* metadata, return ret; } +PhysicalDeviceMapPtr ClonePhysicalDeviceMap(const PhysicalDeviceMapPtr& src) { + auto ret = std::make_unique<PhysicalDeviceMap>(); + for (const auto& it : *src) { + ret->emplace(it.first, HalCameraMetadata::Clone(it.second.get())); + } + return ret; +} + } // namespace android diff --git a/devices/EmulatedCamera/hwl/utils/HWLUtils.h b/devices/EmulatedCamera/hwl/utils/HWLUtils.h index 860b51d..d9ec11d 100644 --- a/devices/EmulatedCamera/hwl/utils/HWLUtils.h +++ b/devices/EmulatedCamera/hwl/utils/HWLUtils.h @@ -31,12 +31,17 @@ namespace android { +typedef std::unordered_map<uint32_t, std::unique_ptr<HalCameraMetadata>> + PhysicalDeviceMap; +typedef std::unique_ptr<PhysicalDeviceMap> PhysicalDeviceMapPtr; + using google_camera_hal::HalCameraMetadata; // Metadata utility functions start bool HasCapability(const HalCameraMetadata* metadata, uint8_t capability); status_t GetSensorCharacteristics(const HalCameraMetadata* metadata, SensorCharacteristics* sensor_chars /*out*/); +PhysicalDeviceMapPtr ClonePhysicalDeviceMap(const PhysicalDeviceMapPtr& src); // Metadata utility functions end } // namespace android |