1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "EmulatedLogicalState"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19
20 #include "EmulatedLogicalRequestState.h"
21
22 #include <log/log.h>
23
24 #include "vendor_tag_defs.h"
25
26 namespace android {
27
EmulatedLogicalRequestState(uint32_t camera_id)28 EmulatedLogicalRequestState::EmulatedLogicalRequestState(uint32_t camera_id)
29 : logical_camera_id_(camera_id),
30 logical_request_state_(std::make_unique<EmulatedRequestState>(camera_id)) {
31 }
32
~EmulatedLogicalRequestState()33 EmulatedLogicalRequestState::~EmulatedLogicalRequestState() {
34 }
35
Initialize(std::unique_ptr<HalCameraMetadata> static_meta,PhysicalDeviceMapPtr physical_devices)36 status_t EmulatedLogicalRequestState::Initialize(
37 std::unique_ptr<HalCameraMetadata> static_meta,
38 PhysicalDeviceMapPtr physical_devices) {
39 if ((physical_devices.get() != nullptr) && (!physical_devices->empty())) {
40 physical_device_map_ = std::move(physical_devices);
41 // If possible map the available focal lengths to individual physical devices
42 camera_metadata_ro_entry_t logical_entry, physical_entry;
43 auto ret = static_meta->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
44 &logical_entry);
45 if ((ret == OK) && (logical_entry.count > 1)) {
46 for (size_t i = 0; i < logical_entry.count; i++) {
47 for (const auto& it : *physical_device_map_) {
48 if (it.second.first != CameraDeviceStatus::kPresent) {
49 continue;
50 }
51 ret = it.second.second->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
52 &physical_entry);
53 if ((ret == OK) && (physical_entry.count > 0)) {
54 if (logical_entry.data.f[i] == physical_entry.data.f[0]) {
55 physical_focal_length_map_[physical_entry.data.f[0]] = it.first;
56 break;
57 }
58 }
59 }
60 }
61 }
62
63 if (physical_focal_length_map_.size() > 1) {
64 is_logical_device_ = true;
65 current_focal_length_ = logical_entry.data.f[0];
66 for (const auto& it : *physical_device_map_) {
67 std::unique_ptr<EmulatedRequestState> physical_request_state =
68 std::make_unique<EmulatedRequestState>(it.first);
69 auto ret = physical_request_state->Initialize(
70 HalCameraMetadata::Clone(it.second.second.get()));
71 if (ret != OK) {
72 ALOGE("%s: Physical device: %u request state initialization failed!",
73 __FUNCTION__, it.first);
74 return ret;
75 }
76 physical_request_states_.emplace(it.first,
77 std::move(physical_request_state));
78 }
79 }
80 }
81
82 return logical_request_state_->Initialize(std::move(static_meta));
83 }
84
GetDefaultRequest(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * default_settings)85 status_t EmulatedLogicalRequestState::GetDefaultRequest(
86 RequestTemplate type,
87 std::unique_ptr<HalCameraMetadata>* default_settings /*out*/) {
88 return logical_request_state_->GetDefaultRequest(type, default_settings);
89 };
90
91 std::unique_ptr<HwlPipelineResult>
InitializeLogicalResult(uint32_t pipeline_id,uint32_t frame_number)92 EmulatedLogicalRequestState::InitializeLogicalResult(uint32_t pipeline_id,
93 uint32_t frame_number) {
94 auto ret = logical_request_state_->InitializeResult(pipeline_id, frame_number);
95 if (is_logical_device_) {
96 if ((physical_camera_output_ids_.get() != nullptr) &&
97 (!physical_camera_output_ids_->empty())) {
98 ret->physical_camera_results.reserve(physical_camera_output_ids_->size());
99 for (const auto& it : *physical_camera_output_ids_) {
100 ret->physical_camera_results[it] =
101 std::move(physical_request_states_[it]
102 ->InitializeResult(pipeline_id, frame_number)
103 ->result_metadata);
104 }
105 }
106 auto physical_device_id =
107 std::to_string(physical_focal_length_map_[current_focal_length_]);
108 std::vector<uint8_t> result;
109 result.reserve(physical_device_id.size() + 1);
110 result.insert(result.end(), physical_device_id.begin(),
111 physical_device_id.end());
112 result.push_back('\0');
113
114 ret->result_metadata->Set(ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
115 result.data(), result.size());
116 }
117
118 return ret;
119 }
120
InitializeLogicalSettings(std::unique_ptr<HalCameraMetadata> request_settings,std::unique_ptr<std::set<uint32_t>> physical_camera_output_ids,EmulatedSensor::LogicalCameraSettings * logical_settings)121 status_t EmulatedLogicalRequestState::InitializeLogicalSettings(
122 std::unique_ptr<HalCameraMetadata> request_settings,
123 std::unique_ptr<std::set<uint32_t>> physical_camera_output_ids,
124 EmulatedSensor::LogicalCameraSettings* logical_settings /*out*/) {
125 if (logical_settings == nullptr) {
126 return BAD_VALUE;
127 }
128
129 // All logical and physical devices can potentially receive individual client
130 // requests (Currently this is not the case due to HWL API limitations).
131 // The emulated sensor can adapt its characteristics and apply most of them
132 // independently however the frame duration needs to be the same across all
133 // settings.
134 // Track the maximum frame duration and override this value at the end for all
135 // logical settings.
136 nsecs_t max_frame_duration = 0;
137 if (is_logical_device_) {
138 std::swap(physical_camera_output_ids_, physical_camera_output_ids);
139
140 for (const auto& physical_request_state : physical_request_states_) {
141 // All physical devices will receive requests and will keep
142 // updating their respective request state.
143 // However only physical devices referenced by client need to propagate
144 // and apply their settings.
145 EmulatedSensor::SensorSettings physical_sensor_settings;
146 auto ret = physical_request_state.second->InitializeSensorSettings(
147 HalCameraMetadata::Clone(request_settings.get()),
148 &physical_sensor_settings);
149 if (ret != OK) {
150 ALOGE(
151 "%s: Initialization of physical sensor settings for device id: %u "
152 "failed!",
153 __FUNCTION__, physical_request_state.first);
154 return ret;
155 }
156
157 if (physical_camera_output_ids_->find(physical_request_state.first) !=
158 physical_camera_output_ids_->end()) {
159 logical_settings->emplace(physical_request_state.first,
160 physical_sensor_settings);
161 if (max_frame_duration < physical_sensor_settings.exposure_time) {
162 max_frame_duration = physical_sensor_settings.exposure_time;
163 }
164 }
165 }
166
167 camera_metadata_ro_entry entry;
168 auto stat = request_settings->Get(ANDROID_LENS_FOCAL_LENGTH, &entry);
169 if ((stat == OK) && (entry.count == 1)) {
170 if (physical_focal_length_map_.find(entry.data.f[0]) !=
171 physical_focal_length_map_.end()) {
172 current_focal_length_ = entry.data.f[0];
173 } else {
174 ALOGE("%s: Unsupported focal length set: %5.2f, re-using older value!",
175 __FUNCTION__, entry.data.f[0]);
176 }
177 } else {
178 ALOGW("%s: Focal length absent from request, re-using older value!",
179 __FUNCTION__);
180 }
181 }
182
183 EmulatedSensor::SensorSettings sensor_settings;
184 auto ret = logical_request_state_->InitializeSensorSettings(
185 std::move(request_settings), &sensor_settings);
186 logical_settings->emplace(logical_camera_id_, sensor_settings);
187 if (max_frame_duration < sensor_settings.exposure_time) {
188 max_frame_duration = sensor_settings.exposure_time;
189 }
190
191 for (auto it : *logical_settings) {
192 it.second.frame_duration = max_frame_duration;
193 }
194
195 return ret;
196 }
197
198 std::unique_ptr<HalCameraMetadata>
AdaptLogicalCharacteristics(std::unique_ptr<HalCameraMetadata> logical_chars,PhysicalDeviceMapPtr physical_devices)199 EmulatedLogicalRequestState::AdaptLogicalCharacteristics(
200 std::unique_ptr<HalCameraMetadata> logical_chars,
201 PhysicalDeviceMapPtr physical_devices) {
202 if ((logical_chars.get() == nullptr) || (physical_devices.get() == nullptr)) {
203 return nullptr;
204 }
205
206 // Update 'android.logicalMultiCamera.physicalIds' according to the newly
207 // assigned physical ids.
208 // Additionally if possible try to emulate a logical camera device backed by
209 // physical devices with different focal lengths. Usually real logical
210 // cameras like that will have device specific logic to switch between
211 // physical sensors. Unfortunately we cannot infer this behavior using only
212 // static camera characteristics. Instead of this, detect the different
213 // focal lengths and update the logical
214 // "android.lens.info.availableFocalLengths" accordingly.
215 std::vector<uint8_t> physical_ids;
216 std::set<float> focal_lengths;
217 camera_metadata_ro_entry_t entry;
218 for (const auto& physical_device : *physical_devices) {
219 auto physical_id = std::to_string(physical_device.first);
220 physical_ids.insert(physical_ids.end(), physical_id.begin(),
221 physical_id.end());
222 physical_ids.push_back('\0');
223 auto ret = physical_device.second.second->Get(
224 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &entry);
225 if ((ret == OK) && (entry.count > 0)) {
226 focal_lengths.insert(entry.data.f, entry.data.f + entry.count);
227 }
228 }
229 logical_chars->Set(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS,
230 physical_ids.data(), physical_ids.size());
231
232 if (focal_lengths.size() > 1) {
233 std::vector<float> focal_buffer;
234 focal_buffer.reserve(focal_lengths.size());
235 focal_buffer.insert(focal_buffer.end(), focal_lengths.begin(),
236 focal_lengths.end());
237 logical_chars->Set(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
238 focal_buffer.data(), focal_buffer.size());
239
240 // Possibly needs to be removed at some later point:
241 int32_t default_physical_id = physical_devices->begin()->first;
242 logical_chars->Set(google_camera_hal::kLogicalCamDefaultPhysicalId,
243 &default_physical_id, 1);
244
245 logical_chars->Get(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
246 std::set<int32_t> keys(entry.data.i32, entry.data.i32 + entry.count);
247 keys.emplace(ANDROID_LENS_FOCAL_LENGTH);
248 keys.emplace(ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
249 std::vector<int32_t> keys_buffer(keys.begin(), keys.end());
250 logical_chars->Set(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
251 keys_buffer.data(), keys_buffer.size());
252
253 keys.clear();
254 keys_buffer.clear();
255 logical_chars->Get(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
256 keys.insert(entry.data.i32, entry.data.i32 + entry.count);
257 // Due to API limitations we currently don't support individual physical requests
258 logical_chars->Erase(ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
259 keys.erase(ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
260 keys.emplace(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
261 keys.emplace(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
262 keys_buffer.insert(keys_buffer.end(), keys.begin(), keys.end());
263 logical_chars->Set(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
264 keys_buffer.data(), keys_buffer.size());
265
266 keys.clear();
267 keys_buffer.clear();
268 logical_chars->Get(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry);
269 keys.insert(entry.data.i32, entry.data.i32 + entry.count);
270 keys.emplace(ANDROID_LENS_FOCAL_LENGTH);
271 keys_buffer.insert(keys_buffer.end(), keys.begin(), keys.end());
272 logical_chars->Set(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
273 keys_buffer.data(), keys_buffer.size());
274 } else {
275 ALOGW(
276 "%s: The logical camera doesn't support different focal lengths. "
277 "Emulation "
278 "could be"
279 " very limited in this case!",
280 __FUNCTION__);
281 }
282
283 return logical_chars;
284 }
285
286 } // namespace android
287