• 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 <android/hardware/graphics/common/1.2/types.h>
22 #include <hardware/gralloc.h>
23 #include <inttypes.h>
24 #include <log/log.h>
25 #include <utils/Trace.h>
26 
27 #include <memory>
28 
29 #include "EmulatedSensor.h"
30 #include "utils.h"
31 #include "utils/HWLUtils.h"
32 
33 namespace android {
34 
35 using google_camera_hal::Rect;
36 using google_camera_hal::utils::GetSensorActiveArraySize;
37 using google_camera_hal::utils::HasCapability;
38 
39 using android::hardware::graphics::common::V1_2::Dataspace;
40 std::unique_ptr<EmulatedCameraZoomRatioMapperHwlImpl>
Create(const std::unordered_map<uint32_t,std::pair<Dimension,Dimension>> & dims)41 EmulatedCameraZoomRatioMapperHwlImpl::Create(
42     const std::unordered_map<uint32_t, std::pair<Dimension, Dimension>>& dims) {
43   auto zoom_ratio_mapper_hwl_impl =
44       std::make_unique<EmulatedCameraZoomRatioMapperHwlImpl>(dims);
45   return zoom_ratio_mapper_hwl_impl;
46 }
47 
EmulatedCameraZoomRatioMapperHwlImpl(const std::unordered_map<uint32_t,std::pair<Dimension,Dimension>> & dims)48 EmulatedCameraZoomRatioMapperHwlImpl::EmulatedCameraZoomRatioMapperHwlImpl(
49     const std::unordered_map<uint32_t, std::pair<Dimension, Dimension>>& dims)
50     : camera_ids_to_dimensions_(dims) {
51 }
52 
GetActiveArrayDimensionToBeUsed(uint32_t camera_id,const HalCameraMetadata * settings,Dimension * active_array_dimension) const53 bool EmulatedCameraZoomRatioMapperHwlImpl::GetActiveArrayDimensionToBeUsed(
54     uint32_t camera_id, const HalCameraMetadata* settings,
55     Dimension* active_array_dimension) const {
56   auto dim_it = camera_ids_to_dimensions_.find(camera_id);
57   if (settings == nullptr || active_array_dimension == nullptr ||
58       dim_it == camera_ids_to_dimensions_.end()) {
59     // default request / camera id not found
60     return false;
61   }
62   camera_metadata_ro_entry entry = {};
63   status_t res = settings->Get(ANDROID_SENSOR_PIXEL_MODE, &entry);
64   if (res != OK) {
65     // return default res dimension
66     *active_array_dimension = dim_it->second.second;
67     return true;
68   }
69   if (entry.data.u8[0] == ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
70     // return max res mode dimension
71     *active_array_dimension = dim_it->second.first;
72   } else {
73     *active_array_dimension = dim_it->second.second;
74   }
75   return true;
76 }
77 
78 std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl>
Create(uint32_t camera_id,std::unique_ptr<HalCameraMetadata> static_meta,PhysicalDeviceMapPtr physical_devices,std::shared_ptr<EmulatedTorchState> torch_state)79 EmulatedCameraDeviceSessionHwlImpl::Create(
80     uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
81     PhysicalDeviceMapPtr physical_devices,
82     std::shared_ptr<EmulatedTorchState> torch_state) {
83   ATRACE_CALL();
84   if (static_meta.get() == nullptr) {
85     return nullptr;
86   }
87 
88   auto session = std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl>(
89       new EmulatedCameraDeviceSessionHwlImpl(std::move(physical_devices),
90                                              torch_state));
91   if (session == nullptr) {
92     ALOGE("%s: Creating EmulatedCameraDeviceSessionHwlImpl failed",
93           __FUNCTION__);
94     return nullptr;
95   }
96 
97   status_t res = session->Initialize(camera_id, std::move(static_meta));
98   if (res != OK) {
99     ALOGE("%s: Initializing EmulatedCameraDeviceSessionHwlImpl failed: %s(%d)",
100           __FUNCTION__, strerror(-res), res);
101     return nullptr;
102   }
103 
104   return session;
105 }
106 
GetArrayDimensions(uint32_t camera_id,const HalCameraMetadata * metadata)107 static std::pair<Dimension, Dimension> GetArrayDimensions(
108     uint32_t camera_id, const HalCameraMetadata* metadata) {
109   Rect active_array_size;
110   Dimension active_array_size_dimension;
111   Dimension active_array_size_dimension_maximum_resolution;
112   status_t ret = GetSensorActiveArraySize(metadata, &active_array_size);
113   if (ret != OK) {
114     ALOGE("%s: Failed to get sensor active array size for camera id %d",
115           __FUNCTION__, (int)camera_id);
116     return std::pair<Dimension, Dimension>();
117   }
118   active_array_size_dimension = {
119       active_array_size.right - active_array_size.left + 1,
120       active_array_size.bottom - active_array_size.top + 1};
121 
122   active_array_size_dimension_maximum_resolution = active_array_size_dimension;
123   if (HasCapability(
124           metadata,
125           ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR)) {
126     status_t ret = GetSensorActiveArraySize(metadata, &active_array_size,
127                                             /*maximum_resolution=*/true);
128     if (ret != OK) {
129       ALOGE(
130           "%s: Failed to get max resolution sensor active array size for "
131           "camera id %d",
132           __FUNCTION__, (int)camera_id);
133       return std::pair<Dimension, Dimension>();
134     }
135     active_array_size_dimension_maximum_resolution = {
136         active_array_size.right - active_array_size.left + 1,
137         active_array_size.bottom - active_array_size.top + 1};
138   }
139   return std::make_pair(active_array_size_dimension_maximum_resolution,
140                         active_array_size_dimension);
141 }
142 
Initialize(uint32_t camera_id,std::unique_ptr<HalCameraMetadata> static_meta)143 status_t EmulatedCameraDeviceSessionHwlImpl::Initialize(
144     uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta) {
145   camera_id_ = camera_id;
146   static_metadata_ = std::move(static_meta);
147   stream_configuration_map_ =
148       std::make_unique<StreamConfigurationMap>(*static_metadata_);
149   stream_configuration_map_max_resolution_ =
150       std::make_unique<StreamConfigurationMap>(*static_metadata_, true);
151   camera_metadata_ro_entry_t entry;
152   auto ret = static_metadata_->Get(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry);
153   if (ret != OK) {
154     ALOGE("%s: Unable to extract ANDROID_REQUEST_PIPELINE_MAX_DEPTH, %s (%d)",
155           __FUNCTION__, strerror(-ret), ret);
156     return ret;
157   }
158 
159   max_pipeline_depth_ = entry.data.u8[0];
160 
161   std::unordered_map<uint32_t, std::pair<Dimension, Dimension>>
162       camera_ids_to_dimensions;
163   camera_ids_to_dimensions[camera_id] =
164       GetArrayDimensions(camera_id, static_metadata_.get());
165 
166   ret = GetSensorCharacteristics(static_metadata_.get(), &sensor_chars_);
167   if (ret != OK) {
168     ALOGE("%s: Unable to extract sensor characteristics %s (%d)", __FUNCTION__,
169           strerror(-ret), ret);
170     return ret;
171   }
172 
173   logical_chars_.emplace(camera_id_, sensor_chars_);
174   for (const auto& it : *physical_device_map_) {
175     SensorCharacteristics physical_chars;
176     auto stat = GetSensorCharacteristics(it.second.second.get(), &physical_chars);
177     if (stat == OK) {
178       logical_chars_.emplace(it.first, physical_chars);
179     } else {
180       ALOGE("%s: Unable to extract physical device: %u characteristics %s (%d)",
181             __FUNCTION__, it.first, strerror(-ret), ret);
182       return ret;
183     }
184     camera_ids_to_dimensions[it.first] =
185         GetArrayDimensions(it.first, it.second.second.get());
186     physical_stream_configuration_map_.emplace(
187         it.first,
188         std::make_unique<StreamConfigurationMap>(*it.second.second.get()));
189     physical_stream_configuration_map_max_resolution_.emplace(
190         it.first, std::make_unique<StreamConfigurationMap>(
191                       *it.second.second.get(), true));
192   }
193 
194   zoom_ratio_mapper_hwl_impl_ = std::move(
195       EmulatedCameraZoomRatioMapperHwlImpl::Create(camera_ids_to_dimensions));
196   return InitializeRequestProcessor();
197 }
198 
InitializeRequestProcessor()199 status_t EmulatedCameraDeviceSessionHwlImpl::InitializeRequestProcessor() {
200   sp<EmulatedSensor> emulated_sensor = new EmulatedSensor();
201   auto logical_chars = std::make_unique<LogicalCharacteristics>(logical_chars_);
202   auto ret = emulated_sensor->StartUp(camera_id_, std::move(logical_chars));
203   if (ret != OK) {
204     ALOGE("%s: Failed on sensor start up %s (%d)", __FUNCTION__, strerror(-ret),
205           ret);
206     return ret;
207   }
208 
209   request_processor_ = std::make_shared<EmulatedRequestProcessor>(
210       camera_id_, emulated_sensor, session_callback_);
211 
212   request_processor_->InitializeSensorQueue(request_processor_);
213 
214   return request_processor_->Initialize(
215       HalCameraMetadata::Clone(static_metadata_.get()),
216       ClonePhysicalDeviceMap(physical_device_map_));
217 }
218 
~EmulatedCameraDeviceSessionHwlImpl()219 EmulatedCameraDeviceSessionHwlImpl::~EmulatedCameraDeviceSessionHwlImpl() {
220   if (torch_state_.get() != nullptr) {
221     torch_state_->ReleaseFlashHw();
222   }
223 }
224 
ConstructDefaultRequestSettings(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * default_settings)225 status_t EmulatedCameraDeviceSessionHwlImpl::ConstructDefaultRequestSettings(
226     RequestTemplate type, std::unique_ptr<HalCameraMetadata>* default_settings) {
227   ATRACE_CALL();
228   std::lock_guard<std::mutex> lock(api_mutex_);
229 
230   return request_processor_->GetDefaultRequest(type, default_settings);
231 }
232 
ConfigurePipeline(uint32_t physical_camera_id,HwlPipelineCallback hwl_pipeline_callback,const StreamConfiguration & request_config,const StreamConfiguration &,uint32_t * pipeline_id)233 status_t EmulatedCameraDeviceSessionHwlImpl::ConfigurePipeline(
234     uint32_t physical_camera_id, HwlPipelineCallback hwl_pipeline_callback,
235     const StreamConfiguration& request_config,
236     const StreamConfiguration& /*overall_config*/, uint32_t* pipeline_id) {
237   ATRACE_CALL();
238   std::lock_guard<std::mutex> lock(api_mutex_);
239   if (pipeline_id == nullptr) {
240     ALOGE("%s pipeline_id is nullptr", __FUNCTION__);
241     return BAD_VALUE;
242   }
243 
244   if (pipelines_built_) {
245     ALOGE("%s Cannot configure pipelines after calling BuildPipelines()",
246           __FUNCTION__);
247     return ALREADY_EXISTS;
248   }
249 
250   if (!EmulatedSensor::IsStreamCombinationSupported(
251           physical_camera_id, request_config, *stream_configuration_map_,
252           *stream_configuration_map_max_resolution_,
253           physical_stream_configuration_map_,
254           physical_stream_configuration_map_max_resolution_, logical_chars_)) {
255     ALOGE("%s: Stream combination not supported!", __FUNCTION__);
256     return BAD_VALUE;
257   }
258 
259   if ((physical_camera_id != camera_id_) &&
260       (physical_device_map_.get() != nullptr)) {
261     if (physical_device_map_->find(physical_camera_id) ==
262         physical_device_map_->end()) {
263       ALOGE("%s: Camera: %d doesn't include physical device with id: %u",
264             __FUNCTION__, camera_id_, physical_camera_id);
265       return BAD_VALUE;
266     }
267   }
268 
269   *pipeline_id = pipelines_.size();
270   EmulatedPipeline emulated_pipeline{.cb = hwl_pipeline_callback,
271                                      .physical_camera_id = physical_camera_id,
272                                      .pipeline_id = *pipeline_id,};
273 
274   emulated_pipeline.streams.reserve(request_config.streams.size());
275   for (const auto& stream : request_config.streams) {
276     bool is_input = stream.stream_type == google_camera_hal::StreamType::kInput;
277     emulated_pipeline.streams.emplace(
278         stream.id,
279         EmulatedStream(
280             {{.id = stream.id,
281               .override_format =
282                   is_input ? stream.format
283                            : EmulatedSensor::OverrideFormat(
284                                  stream.format, stream.dynamic_profile),
285               .producer_usage = is_input ? 0
286                                          : GRALLOC_USAGE_HW_CAMERA_WRITE |
287                                                GRALLOC_USAGE_HW_CAMERA_READ,
288               .consumer_usage = 0,
289               .max_buffers = max_pipeline_depth_,
290               .override_data_space =
291                   (stream.dynamic_profile ==
292                    ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10) &&
293                           (stream.format ==
294                            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
295                       ? static_cast<android_dataspace_t>(
296                             Dataspace::BT2020_ITU_HLG)
297                       : stream.data_space,
298               .is_physical_camera_stream = stream.is_physical_camera_stream,
299               .physical_camera_id = stream.physical_camera_id},
300              .width = stream.width,
301              .height = stream.height,
302              .buffer_size = stream.buffer_size,
303              .is_input = is_input,
304              .group_id = stream.group_id,
305              .use_case = stream.use_case}));
306 
307     if (stream.group_id != -1 && stream.is_physical_camera_stream) {
308       // TODO: For quad bayer camera, the logical camera id should be used if
309       // this is not a physical camera.
310       dynamic_stream_id_map_[stream.physical_camera_id][stream.group_id] =
311           stream.id;
312     }
313     if (!stream.is_physical_camera_stream &&
314         (stream.format == HAL_PIXEL_FORMAT_RAW16)) {
315       has_raw_stream_ = true;
316     }
317   }
318 
319   pipelines_.push_back(emulated_pipeline);
320 
321   return OK;
322 }
323 
GetConfiguredHalStream(uint32_t pipeline_id,std::vector<HalStream> * hal_streams) const324 status_t EmulatedCameraDeviceSessionHwlImpl::GetConfiguredHalStream(
325     uint32_t pipeline_id, std::vector<HalStream>* hal_streams) const {
326   ATRACE_CALL();
327   std::lock_guard<std::mutex> lock(api_mutex_);
328   if (hal_streams == nullptr) {
329     ALOGE("%s hal_streams is nullptr", __FUNCTION__);
330     return BAD_VALUE;
331   }
332 
333   if (!pipelines_built_) {
334     ALOGE("%s No pipeline was built.", __FUNCTION__);
335     return NO_INIT;
336   }
337 
338   if (pipeline_id >= pipelines_.size()) {
339     ALOGE("%s: Unknown pipeline ID: %u", __FUNCTION__, pipeline_id);
340     return NAME_NOT_FOUND;
341   }
342 
343   const auto& streams = pipelines_[pipeline_id].streams;
344   hal_streams->reserve(streams.size());
345   for (const auto& it : streams) {
346     hal_streams->push_back(it.second);
347   }
348 
349   return OK;
350 }
351 
BuildPipelines()352 status_t EmulatedCameraDeviceSessionHwlImpl::BuildPipelines() {
353   ATRACE_CALL();
354   std::lock_guard<std::mutex> lock(api_mutex_);
355   if (pipelines_built_) {
356     ALOGE("%s Pipelines have already been built!", __FUNCTION__);
357     return ALREADY_EXISTS;
358   } else if (pipelines_.size() == 0) {
359     ALOGE("%s No pipelines have been configured yet!", __FUNCTION__);
360     return NO_INIT;
361   }
362 
363   status_t ret = OK;
364   if (request_processor_ == nullptr) {
365     ret = InitializeRequestProcessor();
366   }
367 
368   if (ret == OK) {
369     pipelines_built_ = true;
370   }
371 
372   return OK;
373 }
374 
DestroyPipelines()375 void EmulatedCameraDeviceSessionHwlImpl::DestroyPipelines() {
376   ATRACE_CALL();
377   std::lock_guard<std::mutex> lock(api_mutex_);
378   if (!pipelines_built_) {
379     // Not an error - nothing to destroy
380     ALOGV("%s nothing to destroy", __FUNCTION__);
381     return;
382   }
383 
384   pipelines_built_ = false;
385   has_raw_stream_ = false;
386   pipelines_.clear();
387   request_processor_ = nullptr;
388 }
389 
CheckOutputFormatsForInput(const HwlPipelineRequest & request,const std::unordered_map<uint32_t,EmulatedStream> & streams,const std::unique_ptr<StreamConfigurationMap> & stream_configuration_map,android_pixel_format_t input_format)390 status_t EmulatedCameraDeviceSessionHwlImpl::CheckOutputFormatsForInput(
391     const HwlPipelineRequest& request,
392     const std::unordered_map<uint32_t, EmulatedStream>& streams,
393     const std::unique_ptr<StreamConfigurationMap>& stream_configuration_map,
394     android_pixel_format_t input_format) {
395   auto output_formats =
396       stream_configuration_map->GetValidOutputFormatsForInput(input_format);
397   for (const auto& output_buffer : request.output_buffers) {
398     auto output_stream = streams.at(output_buffer.stream_id);
399     if (output_formats.find(output_stream.override_format) ==
400         output_formats.end()) {
401       ALOGE(
402           "%s: Reprocess request with input format: 0x%x to output "
403           "format: 0x%x"
404           " not supported!",
405           __FUNCTION__, input_format, output_stream.override_format);
406       return BAD_VALUE;
407     }
408   }
409   return OK;
410 }
411 
SubmitRequests(uint32_t frame_number,std::vector<HwlPipelineRequest> & requests)412 status_t EmulatedCameraDeviceSessionHwlImpl::SubmitRequests(
413     uint32_t frame_number, std::vector<HwlPipelineRequest>& requests) {
414   ATRACE_CALL();
415   std::lock_guard<std::mutex> lock(api_mutex_);
416 
417   // Check whether reprocess request has valid/supported outputs.
418   for (const auto& request : requests) {
419     if (!request.input_buffers.empty()) {
420       for (const auto& input_buffer : request.input_buffers) {
421         const auto& streams = pipelines_[request.pipeline_id].streams;
422         auto input_stream = streams.at(input_buffer.stream_id);
423         if ((CheckOutputFormatsForInput(request, streams,
424                                         stream_configuration_map_,
425                                         input_stream.override_format) != OK) &&
426             (CheckOutputFormatsForInput(
427                  request, streams, stream_configuration_map_max_resolution_,
428                  input_stream.override_format) != OK)) {
429           return BAD_VALUE;
430         }
431       }
432     }
433   }
434 
435   if (error_state_) {
436     ALOGE("%s session is in error state and cannot process further requests",
437           __FUNCTION__);
438     return INVALID_OPERATION;
439   }
440 
441   return request_processor_->ProcessPipelineRequests(
442       frame_number, requests, pipelines_, dynamic_stream_id_map_,
443       has_raw_stream_);
444 }
445 
Flush()446 status_t EmulatedCameraDeviceSessionHwlImpl::Flush() {
447   ATRACE_CALL();
448   std::lock_guard<std::mutex> lock(api_mutex_);
449   return request_processor_->Flush();
450 }
451 
GetCameraId() const452 uint32_t EmulatedCameraDeviceSessionHwlImpl::GetCameraId() const {
453   return camera_id_;
454 }
455 
GetPhysicalCameraIds() const456 std::vector<uint32_t> EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraIds()
457     const {
458   if ((physical_device_map_.get() == nullptr) ||
459       (physical_device_map_->empty())) {
460     return std::vector<uint32_t>{};
461   }
462 
463   std::vector<uint32_t> ret;
464   ret.reserve(physical_device_map_->size());
465   for (const auto& it : *physical_device_map_) {
466     ret.push_back(it.first);
467   }
468 
469   return ret;
470 }
471 
GetCameraCharacteristics(std::unique_ptr<HalCameraMetadata> * characteristics) const472 status_t EmulatedCameraDeviceSessionHwlImpl::GetCameraCharacteristics(
473     std::unique_ptr<HalCameraMetadata>* characteristics) const {
474   ATRACE_CALL();
475   if (characteristics == nullptr) {
476     return BAD_VALUE;
477   }
478 
479   (*characteristics) = HalCameraMetadata::Clone(static_metadata_.get());
480 
481   if (*characteristics == nullptr) {
482     ALOGE("%s metadata clone failed", __FUNCTION__);
483     return NO_MEMORY;
484   }
485 
486   return OK;
487 }
488 
GetPhysicalCameraCharacteristics(uint32_t physical_camera_id,std::unique_ptr<HalCameraMetadata> * characteristics) const489 status_t EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraCharacteristics(
490     uint32_t physical_camera_id,
491     std::unique_ptr<HalCameraMetadata>* characteristics) const {
492   ATRACE_CALL();
493   if (characteristics == nullptr) {
494     return BAD_VALUE;
495   }
496 
497   if (physical_device_map_.get() == nullptr) {
498     ALOGE("%s: Camera: %d doesn't have physical device support!", __FUNCTION__,
499           camera_id_);
500     return BAD_VALUE;
501   }
502 
503   if (physical_device_map_->find(physical_camera_id) ==
504       physical_device_map_->end()) {
505     ALOGE("%s: Camera: %d doesn't include physical device with id: %u",
506           __FUNCTION__, camera_id_, physical_camera_id);
507     return BAD_VALUE;
508   }
509 
510   (*characteristics) = HalCameraMetadata::Clone(
511       physical_device_map_->at(physical_camera_id).second.get());
512 
513   return OK;
514 }
515 
SetSessionCallback(const HwlSessionCallback & hwl_session_callback)516 void EmulatedCameraDeviceSessionHwlImpl::SetSessionCallback(
517     const HwlSessionCallback& hwl_session_callback) {
518   ATRACE_CALL();
519   std::lock_guard<std::mutex> lock(api_mutex_);
520   session_callback_ = hwl_session_callback;
521   if (request_processor_ != nullptr) {
522     request_processor_->SetSessionCallback(hwl_session_callback);
523   }
524 }
525 
526 }  // namespace android
527