• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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