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 #define LOG_TAG "EmulatedCameraDevSession"
17 #define ATRACE_TAG ATRACE_TAG_CAMERA
18
19 #include "EmulatedCameraDeviceSessionHWLImpl.h"
20
21 #include <hardware/gralloc.h>
22 #include <inttypes.h>
23 #include <log/log.h>
24 #include <utils/Trace.h>
25
26 #include "EmulatedSensor.h"
27 #include "utils/HWLUtils.h"
28
29 namespace android {
30
31 std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl>
Create(uint32_t camera_id,std::unique_ptr<HalCameraMetadata> static_meta,PhysicalDeviceMapPtr physical_devices,std::shared_ptr<EmulatedTorchState> torch_state)32 EmulatedCameraDeviceSessionHwlImpl::Create(
33 uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
34 PhysicalDeviceMapPtr physical_devices,
35 std::shared_ptr<EmulatedTorchState> torch_state) {
36 ATRACE_CALL();
37 if (static_meta.get() == nullptr) {
38 return nullptr;
39 }
40
41 auto session = std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl>(
42 new EmulatedCameraDeviceSessionHwlImpl(std::move(physical_devices),
43 torch_state));
44 if (session == nullptr) {
45 ALOGE("%s: Creating EmulatedCameraDeviceSessionHwlImpl failed",
46 __FUNCTION__);
47 return nullptr;
48 }
49
50 status_t res = session->Initialize(camera_id, std::move(static_meta));
51 if (res != OK) {
52 ALOGE("%s: Initializing EmulatedCameraDeviceSessionHwlImpl failed: %s(%d)",
53 __FUNCTION__, strerror(-res), res);
54 return nullptr;
55 }
56
57 return session;
58 }
59
Initialize(uint32_t camera_id,std::unique_ptr<HalCameraMetadata> static_meta)60 status_t EmulatedCameraDeviceSessionHwlImpl::Initialize(
61 uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta) {
62 camera_id_ = camera_id;
63 static_metadata_ = std::move(static_meta);
64 stream_coniguration_map_ =
65 std::make_unique<StreamConfigurationMap>(*static_metadata_);
66 camera_metadata_ro_entry_t entry;
67 auto ret = static_metadata_->Get(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry);
68 if (ret != OK) {
69 ALOGE("%s: Unable to extract ANDROID_REQUEST_PIPELINE_MAX_DEPTH, %s (%d)",
70 __FUNCTION__, strerror(-ret), ret);
71 return ret;
72 }
73
74 max_pipeline_depth_ = entry.data.u8[0];
75
76 ret = GetSensorCharacteristics(static_metadata_.get(), &sensor_chars_);
77 if (ret != OK) {
78 ALOGE("%s: Unable to extract sensor characteristics %s (%d)", __FUNCTION__,
79 strerror(-ret), ret);
80 return ret;
81 }
82
83 auto logical_chars = std::make_unique<LogicalCharacteristics>();
84 logical_chars->emplace(camera_id_, sensor_chars_);
85 for (const auto& it : *physical_device_map_) {
86 SensorCharacteristics physical_chars;
87 auto stat = GetSensorCharacteristics(it.second.second.get(), &physical_chars);
88 if (stat == OK) {
89 logical_chars->emplace(it.first, physical_chars);
90 } else {
91 ALOGE("%s: Unable to extract physical device: %u characteristics %s (%d)",
92 __FUNCTION__, it.first, strerror(-ret), ret);
93 return ret;
94 }
95 }
96 sp<EmulatedSensor> emulated_sensor = new EmulatedSensor();
97 ret = emulated_sensor->StartUp(camera_id_, std::move(logical_chars));
98 if (ret != OK) {
99 ALOGE("%s: Failed on sensor start up %s (%d)", __FUNCTION__, strerror(-ret),
100 ret);
101 return ret;
102 }
103
104 request_processor_ =
105 std::make_unique<EmulatedRequestProcessor>(camera_id_, emulated_sensor);
106
107 return request_processor_->Initialize(
108 HalCameraMetadata::Clone(static_metadata_.get()),
109 ClonePhysicalDeviceMap(physical_device_map_));
110 }
111
~EmulatedCameraDeviceSessionHwlImpl()112 EmulatedCameraDeviceSessionHwlImpl::~EmulatedCameraDeviceSessionHwlImpl() {
113 if (torch_state_.get() != nullptr) {
114 torch_state_->ReleaseFlashHw();
115 }
116 }
117
ConstructDefaultRequestSettings(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * default_settings)118 status_t EmulatedCameraDeviceSessionHwlImpl::ConstructDefaultRequestSettings(
119 RequestTemplate type, std::unique_ptr<HalCameraMetadata>* default_settings) {
120 ATRACE_CALL();
121 std::lock_guard<std::mutex> lock(api_mutex_);
122
123 return request_processor_->GetDefaultRequest(type, default_settings);
124 }
125
ConfigurePipeline(uint32_t physical_camera_id,HwlPipelineCallback hwl_pipeline_callback,const StreamConfiguration & request_config,const StreamConfiguration &,uint32_t * pipeline_id)126 status_t EmulatedCameraDeviceSessionHwlImpl::ConfigurePipeline(
127 uint32_t physical_camera_id, HwlPipelineCallback hwl_pipeline_callback,
128 const StreamConfiguration& request_config,
129 const StreamConfiguration& /*overall_config*/, uint32_t* pipeline_id) {
130 ATRACE_CALL();
131 std::lock_guard<std::mutex> lock(api_mutex_);
132 if (pipeline_id == nullptr) {
133 ALOGE("%s pipeline_id is nullptr", __FUNCTION__);
134 return BAD_VALUE;
135 }
136
137 if (pipelines_built_) {
138 ALOGE("%s Cannot configure pipelines after calling BuildPipelines()",
139 __FUNCTION__);
140 return ALREADY_EXISTS;
141 }
142
143 if (!EmulatedSensor::IsStreamCombinationSupported(
144 request_config, *stream_coniguration_map_, sensor_chars_)) {
145 ALOGE("%s: Stream combination not supported!", __FUNCTION__);
146 return BAD_VALUE;
147 }
148
149 if ((physical_camera_id != camera_id_) &&
150 (physical_device_map_.get() != nullptr)) {
151 if (physical_device_map_->find(physical_camera_id) ==
152 physical_device_map_->end()) {
153 ALOGE("%s: Camera: %d doesn't include physical device with id: %u",
154 __FUNCTION__, camera_id_, physical_camera_id);
155 return BAD_VALUE;
156 }
157 }
158
159 *pipeline_id = pipelines_.size();
160 EmulatedPipeline emulated_pipeline{.cb = hwl_pipeline_callback,
161 .physical_camera_id = physical_camera_id,
162 .pipeline_id = *pipeline_id,};
163
164 emulated_pipeline.streams.reserve(request_config.streams.size());
165 for (const auto& stream : request_config.streams) {
166 bool is_input = stream.stream_type == google_camera_hal::StreamType::kInput;
167 emulated_pipeline.streams.emplace(
168 stream.id,
169 EmulatedStream(
170 {{.id = stream.id,
171 .override_format =
172 is_input ? stream.format
173 : EmulatedSensor::OverrideFormat(stream.format),
174 .producer_usage = is_input ? 0
175 : GRALLOC_USAGE_HW_CAMERA_WRITE |
176 GRALLOC_USAGE_HW_CAMERA_READ,
177 .consumer_usage = 0,
178 .max_buffers = max_pipeline_depth_,
179 .override_data_space = stream.data_space,
180 .is_physical_camera_stream = stream.is_physical_camera_stream,
181 .physical_camera_id = stream.physical_camera_id},
182 .width = stream.width,
183 .height = stream.height,
184 .buffer_size = stream.buffer_size,
185 .is_input = is_input,}));
186 }
187
188 pipelines_.push_back(emulated_pipeline);
189
190 return OK;
191 }
192
GetConfiguredHalStream(uint32_t pipeline_id,std::vector<HalStream> * hal_streams) const193 status_t EmulatedCameraDeviceSessionHwlImpl::GetConfiguredHalStream(
194 uint32_t pipeline_id, std::vector<HalStream>* hal_streams) const {
195 ATRACE_CALL();
196 std::lock_guard<std::mutex> lock(api_mutex_);
197 if (hal_streams == nullptr) {
198 ALOGE("%s hal_streams is nullptr", __FUNCTION__);
199 return BAD_VALUE;
200 }
201
202 if (!pipelines_built_) {
203 ALOGE("%s No pipeline was built.", __FUNCTION__);
204 return NO_INIT;
205 }
206
207 if (pipeline_id >= pipelines_.size()) {
208 ALOGE("%s: Unknown pipeline ID: %u", __FUNCTION__, pipeline_id);
209 return NAME_NOT_FOUND;
210 }
211
212 const auto& streams = pipelines_[pipeline_id].streams;
213 hal_streams->reserve(streams.size());
214 for (const auto& it : streams) {
215 hal_streams->push_back(it.second);
216 }
217
218 return OK;
219 }
220
BuildPipelines()221 status_t EmulatedCameraDeviceSessionHwlImpl::BuildPipelines() {
222 ATRACE_CALL();
223 std::lock_guard<std::mutex> lock(api_mutex_);
224 if (pipelines_built_) {
225 ALOGE("%s Pipelines have already been built!", __FUNCTION__);
226 return ALREADY_EXISTS;
227 } else if (pipelines_.size() == 0) {
228 ALOGE("%s No pipelines have been configured yet!", __FUNCTION__);
229 return NO_INIT;
230 }
231
232 pipelines_built_ = true;
233
234 return OK;
235 }
236
DestroyPipelines()237 void EmulatedCameraDeviceSessionHwlImpl::DestroyPipelines() {
238 ATRACE_CALL();
239 std::lock_guard<std::mutex> lock(api_mutex_);
240 if (!pipelines_built_) {
241 // Not an error - nothing to destroy
242 ALOGV("%s nothing to destroy", __FUNCTION__);
243 return;
244 }
245
246 pipelines_built_ = false;
247 pipelines_.clear();
248 }
249
SubmitRequests(uint32_t frame_number,const std::vector<HwlPipelineRequest> & requests)250 status_t EmulatedCameraDeviceSessionHwlImpl::SubmitRequests(
251 uint32_t frame_number, const std::vector<HwlPipelineRequest>& requests) {
252 ATRACE_CALL();
253 std::lock_guard<std::mutex> lock(api_mutex_);
254
255 // Check whether reprocess request has valid/supported outputs.
256 for (const auto& request : requests) {
257 if (!request.input_buffers.empty()) {
258 for (const auto& input_buffer : request.input_buffers) {
259 const auto& streams = pipelines_[request.pipeline_id].streams;
260 auto input_stream = streams.at(input_buffer.stream_id);
261 auto output_formats =
262 stream_coniguration_map_->GetValidOutputFormatsForInput(
263 input_stream.override_format);
264 for (const auto& output_buffer : request.output_buffers) {
265 auto output_stream = streams.at(output_buffer.stream_id);
266 if (output_formats.find(output_stream.override_format) ==
267 output_formats.end()) {
268 ALOGE(
269 "%s: Reprocess request with input format: 0x%x to output "
270 "format: 0x%x"
271 " not supported!",
272 __FUNCTION__, input_stream.override_format,
273 output_stream.override_format);
274 return BAD_VALUE;
275 }
276 }
277 }
278 }
279 }
280
281 if (error_state_) {
282 ALOGE("%s session is in error state and cannot process further requests",
283 __FUNCTION__);
284 return INVALID_OPERATION;
285 }
286
287 return request_processor_->ProcessPipelineRequests(frame_number, requests,
288 pipelines_);
289 }
290
Flush()291 status_t EmulatedCameraDeviceSessionHwlImpl::Flush() {
292 ATRACE_CALL();
293 std::lock_guard<std::mutex> lock(api_mutex_);
294 return request_processor_->Flush();
295 }
296
GetCameraId() const297 uint32_t EmulatedCameraDeviceSessionHwlImpl::GetCameraId() const {
298 return camera_id_;
299 }
300
GetPhysicalCameraIds() const301 std::vector<uint32_t> EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraIds()
302 const {
303 if ((physical_device_map_.get() == nullptr) ||
304 (physical_device_map_->empty())) {
305 return std::vector<uint32_t>{};
306 }
307
308 std::vector<uint32_t> ret;
309 ret.reserve(physical_device_map_->size());
310 for (const auto& it : *physical_device_map_) {
311 ret.push_back(it.first);
312 }
313
314 return ret;
315 }
316
GetCameraCharacteristics(std::unique_ptr<HalCameraMetadata> * characteristics) const317 status_t EmulatedCameraDeviceSessionHwlImpl::GetCameraCharacteristics(
318 std::unique_ptr<HalCameraMetadata>* characteristics) const {
319 ATRACE_CALL();
320 if (characteristics == nullptr) {
321 return BAD_VALUE;
322 }
323
324 (*characteristics) = HalCameraMetadata::Clone(static_metadata_.get());
325
326 if (*characteristics == nullptr) {
327 ALOGE("%s metadata clone failed", __FUNCTION__);
328 return NO_MEMORY;
329 }
330
331 return OK;
332 }
333
GetPhysicalCameraCharacteristics(uint32_t physical_camera_id,std::unique_ptr<HalCameraMetadata> * characteristics) const334 status_t EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraCharacteristics(
335 uint32_t physical_camera_id,
336 std::unique_ptr<HalCameraMetadata>* characteristics) const {
337 ATRACE_CALL();
338 if (characteristics == nullptr) {
339 return BAD_VALUE;
340 }
341
342 if (physical_device_map_.get() == nullptr) {
343 ALOGE("%s: Camera: %d doesn't have physical device support!", __FUNCTION__,
344 camera_id_);
345 return BAD_VALUE;
346 }
347
348 if (physical_device_map_->find(physical_camera_id) ==
349 physical_device_map_->end()) {
350 ALOGE("%s: Camera: %d doesn't include physical device with id: %u",
351 __FUNCTION__, camera_id_, physical_camera_id);
352 return BAD_VALUE;
353 }
354
355 (*characteristics) = HalCameraMetadata::Clone(
356 physical_device_map_->at(physical_camera_id).second.get());
357
358 return OK;
359 }
360
361 } // namespace android
362