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