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_NDEBUG 0
18 #define LOG_TAG "GCH_DepthProcessBlock"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <cutils/properties.h>
21 #include <hardware/gralloc1.h>
22 #include <log/log.h>
23 #include <sys/mman.h>
24 #include <utils/Trace.h>
25 
26 #include <dlfcn.h>
27 
28 #include "depth_process_block.h"
29 #include "hal_types.h"
30 #include "hal_utils.h"
31 #include "result_processor.h"
32 
33 namespace android {
34 namespace google_camera_hal {
35 
36 static std::string kDepthGeneratorLib = "/vendor/lib64/libdepthgenerator.so";
37 using android::depth_generator::CreateDepthGenerator_t;
38 const float kSmallOffset = 0.01f;
39 
Create(CameraDeviceSessionHwl * device_session_hwl,HwlRequestBuffersFunc request_stream_buffers,const DepthProcessBlockCreateData & create_data)40 std::unique_ptr<DepthProcessBlock> DepthProcessBlock::Create(
41     CameraDeviceSessionHwl* device_session_hwl,
42     HwlRequestBuffersFunc request_stream_buffers,
43     const DepthProcessBlockCreateData& create_data) {
44   ATRACE_CALL();
45   if (device_session_hwl == nullptr) {
46     ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
47     return nullptr;
48   }
49 
50   auto block = std::unique_ptr<DepthProcessBlock>(
51       new DepthProcessBlock(request_stream_buffers, create_data));
52   if (block == nullptr) {
53     ALOGE("%s: Creating DepthProcessBlock failed.", __FUNCTION__);
54     return nullptr;
55   }
56 
57   status_t res = block->InitializeBufferManagementStatus(device_session_hwl);
58   if (res != OK) {
59     ALOGE("%s: Failed to initialize HAL Buffer Management status.",
60           __FUNCTION__);
61     return nullptr;
62   }
63 
64   res = block->CalculateActiveArraySizeRatio(device_session_hwl);
65   if (res != OK) {
66     ALOGE("%s: Calculating active array size ratio failed.", __FUNCTION__);
67     return nullptr;
68   }
69 
70   // TODO(b/128633958): remove this after FLL syncing is verified
71   block->force_internal_stream_ =
72       property_get_bool("persist.camera.rgbird.forceinternal", false);
73   if (block->force_internal_stream_) {
74     ALOGI("%s: Force creating internal streams for IR pipelines", __FUNCTION__);
75   }
76 
77   block->pipelined_depth_engine_enabled_ =
78       property_get_bool("persist.camera.frontdepth.enablepipeline", true);
79 
80   // TODO(b/129910835): Change the controlling prop into some deterministic
81   // logic that controls when the front depth autocal will be triggered.
82   // depth_process_block does not control autocal in current implementation.
83   // Whenever there is a YUV buffer in the process block request, it will
84   // trigger the AutoCal. So the condition is completely controlled by
85   // rt_request_processor and result_request_processor.
86   block->rgb_ir_auto_cal_enabled_ =
87       property_get_bool("vendor.camera.frontdepth.enableautocal", true);
88 
89   return block;
90 }
91 
InitializeBufferManagementStatus(CameraDeviceSessionHwl * device_session_hwl)92 status_t DepthProcessBlock::InitializeBufferManagementStatus(
93     CameraDeviceSessionHwl* device_session_hwl) {
94   // Query characteristics to check if buffer management supported
95   std::unique_ptr<google_camera_hal::HalCameraMetadata> characteristics;
96   status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
97   if (res != OK) {
98     ALOGE("%s: Get camera characteristics failed: %s(%d)", __FUNCTION__,
99           strerror(-res), res);
100     return res;
101   }
102 
103   camera_metadata_ro_entry entry = {};
104   res = characteristics->Get(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
105                              &entry);
106   if (res == OK && entry.count > 0) {
107     buffer_management_supported_ =
108         (entry.data.u8[0] >=
109          ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
110   }
111 
112   return OK;
113 }
114 
DepthProcessBlock(HwlRequestBuffersFunc request_stream_buffers,const DepthProcessBlockCreateData & create_data)115 DepthProcessBlock::DepthProcessBlock(
116     HwlRequestBuffersFunc request_stream_buffers,
117     const DepthProcessBlockCreateData& create_data)
118     : request_stream_buffers_(request_stream_buffers),
119       rgb_internal_yuv_stream_id_(create_data.rgb_internal_yuv_stream_id),
120       ir1_internal_raw_stream_id_(create_data.ir1_internal_raw_stream_id),
121       ir2_internal_raw_stream_id_(create_data.ir2_internal_raw_stream_id) {
122 }
123 
~DepthProcessBlock()124 DepthProcessBlock::~DepthProcessBlock() {
125   ATRACE_CALL();
126   depth_generator_ = nullptr;
127 
128   if (depth_generator_lib_handle_ != nullptr) {
129     dlclose(depth_generator_lib_handle_);
130     depth_generator_lib_handle_ = nullptr;
131   }
132 }
133 
SetResultProcessor(std::unique_ptr<ResultProcessor> result_processor)134 status_t DepthProcessBlock::SetResultProcessor(
135     std::unique_ptr<ResultProcessor> result_processor) {
136   ATRACE_CALL();
137   if (result_processor == nullptr) {
138     ALOGE("%s: result_processor is nullptr", __FUNCTION__);
139     return BAD_VALUE;
140   }
141 
142   std::lock_guard<std::mutex> lock(result_processor_lock_);
143   if (result_processor_ != nullptr) {
144     ALOGE("%s: result_processor_ was already set.", __FUNCTION__);
145     return ALREADY_EXISTS;
146   }
147 
148   result_processor_ = std::move(result_processor);
149   return OK;
150 }
151 
GetStreamBufferSize(const Stream & stream,int32_t * buffer_size)152 status_t DepthProcessBlock::GetStreamBufferSize(const Stream& stream,
153                                                 int32_t* buffer_size) {
154   ATRACE_CALL();
155   // TODO(b/130764929): Use actual gralloc buffer stride instead of stream dim
156   switch (stream.format) {
157     case HAL_PIXEL_FORMAT_Y8:
158       *buffer_size = stream.width * stream.height;
159       break;
160     case HAL_PIXEL_FORMAT_Y16:
161       *buffer_size = stream.width * stream.height * 2;
162       break;
163     case HAL_PIXEL_FORMAT_YCBCR_420_888:
164       *buffer_size = static_cast<int32_t>(stream.width * stream.height * 1.5);
165       break;
166     default:
167       ALOGW("%s: Unsupported format:%d", __FUNCTION__, stream.format);
168       *buffer_size = 0;
169       break;
170   }
171 
172   return OK;
173 }
174 
ConfigureStreams(const StreamConfiguration & stream_config,const StreamConfiguration &)175 status_t DepthProcessBlock::ConfigureStreams(
176     const StreamConfiguration& stream_config,
177     const StreamConfiguration& /*overall_config*/) {
178   ATRACE_CALL();
179   std::lock_guard<std::mutex> lock(configure_lock_);
180   if (is_configured_) {
181     ALOGE("%s: Already configured.", __FUNCTION__);
182     return ALREADY_EXISTS;
183   }
184 
185   // TODO(b/128633958): remove this after FLL syncing is verified
186   if (force_internal_stream_) {
187     // Nothing to configure if this is force internal mode
188     ALOGV("%s: Force internal enabled, skip depth block config.", __FUNCTION__);
189     is_configured_ = true;
190     return OK;
191   }
192 
193   uint32_t num_depth_stream = 0;
194   for (auto& stream : stream_config.streams) {
195     if (utils::IsDepthStream(stream)) {
196       num_depth_stream++;
197       // Save depth stream as HAL configured stream
198       depth_stream_.id = stream.id;
199       depth_stream_.override_format = stream.format;
200       depth_stream_.producer_usage = GRALLOC1_PRODUCER_USAGE_CAMERA;
201       depth_stream_.consumer_usage = 0;
202       depth_stream_.max_buffers = kDepthStreamMaxBuffers;
203       depth_stream_.override_data_space = stream.data_space;
204       depth_stream_.is_physical_camera_stream = false;
205       depth_stream_.physical_camera_id = 0;
206     }
207 
208     // Save stream information for mapping purposes
209     depth_io_streams_[stream.id] = stream;
210     int32_t buffer_size = 0;
211     status_t res = GetStreamBufferSize(stream, &buffer_size);
212     if (res != OK) {
213       ALOGE("%s: Failed to get stream buffer size.", __FUNCTION__);
214       return res;
215     }
216     stream_buffer_sizes_[stream.id] = buffer_size;
217   }
218 
219   if (num_depth_stream != 1) {
220     ALOGE(
221         "%s: Depth Process Block can only config 1 depth stream. There are "
222         "%zu streams, including %u depth stream.",
223         __FUNCTION__, stream_config.streams.size(), num_depth_stream);
224     return BAD_VALUE;
225   }
226 
227   if (depth_generator_ == nullptr) {
228     status_t res = LoadDepthGenerator(&depth_generator_);
229     if (res != OK) {
230       ALOGE("%s: Creating DepthGenerator failed.", __FUNCTION__);
231       return NO_INIT;
232     }
233 
234     if (pipelined_depth_engine_enabled_ == true) {
235       auto depth_result_callback =
236           android::depth_generator::DepthResultCallbackFunction(
237               [this](DepthResultStatus result_status, uint32_t frame_number) {
238                 status_t res = ProcessDepthResult(result_status, frame_number);
239                 if (res != OK) {
240                   ALOGE("%s: Failed to process the depth result for frame %d.",
241                         __FUNCTION__, frame_number);
242                 }
243               });
244       ALOGI("%s: Async depth api is used. Callback func is set.", __FUNCTION__);
245       depth_generator_->SetResultCallback(depth_result_callback);
246     } else {
247       ALOGI("%s: Blocking depth api is used.", __FUNCTION__);
248       depth_generator_->SetResultCallback(nullptr);
249     }
250   }
251 
252   is_configured_ = true;
253   return OK;
254 }
255 
GetConfiguredHalStreams(std::vector<HalStream> * hal_streams) const256 status_t DepthProcessBlock::GetConfiguredHalStreams(
257     std::vector<HalStream>* hal_streams) const {
258   ATRACE_CALL();
259   std::lock_guard<std::mutex> lock(configure_lock_);
260   if (hal_streams == nullptr) {
261     ALOGE("%s: hal_streams is nullptr.", __FUNCTION__);
262     return BAD_VALUE;
263   }
264 
265   if (!is_configured_) {
266     ALOGE("%s: Not configured yet.", __FUNCTION__);
267     return NO_INIT;
268   }
269 
270   hal_streams->push_back(depth_stream_);
271 
272   return OK;
273 }
274 
SubmitBlockingDepthRequest(const DepthRequestInfo & request_info)275 status_t DepthProcessBlock::SubmitBlockingDepthRequest(
276     const DepthRequestInfo& request_info) {
277   ALOGV("%s: [ud] ExecuteProcessRequest for frame %d", __FUNCTION__,
278         request_info.frame_number);
279 
280   status_t res = depth_generator_->ExecuteProcessRequest(request_info);
281   if (res != OK) {
282     ALOGE("%s: Depth generator fails to process frame %d.", __FUNCTION__,
283           request_info.frame_number);
284     return res;
285   }
286 
287   res = ProcessDepthResult(DepthResultStatus::kOk, request_info.frame_number);
288   if (res != OK) {
289     ALOGE("%s: Failed to process depth result.", __FUNCTION__);
290     return res;
291   }
292 
293   return OK;
294 }
295 
SubmitAsyncDepthRequest(const DepthRequestInfo & request_info)296 status_t DepthProcessBlock::SubmitAsyncDepthRequest(
297     const DepthRequestInfo& request_info) {
298   std::unique_lock<std::mutex> lock(depth_generator_api_lock_);
299   ALOGV("%s: [ud] ExecuteProcessRequest for frame %d", __FUNCTION__,
300         request_info.frame_number);
301   status_t res = depth_generator_->EnqueueProcessRequest(request_info);
302   if (res != OK) {
303     ALOGE("%s: Failed to enqueue depth request.", __FUNCTION__);
304     return res;
305   }
306 
307   return OK;
308 }
309 
ProcessDepthResult(DepthResultStatus result_status,uint32_t frame_number)310 status_t DepthProcessBlock::ProcessDepthResult(DepthResultStatus result_status,
311                                                uint32_t frame_number) {
312   std::unique_lock<std::mutex> lock(depth_generator_api_lock_);
313   ALOGV("%s: [ud] Depth result for frame %u notified.", __FUNCTION__,
314         frame_number);
315 
316   status_t res = UnmapDepthRequestBuffers(frame_number);
317   if (res != OK) {
318     ALOGE("%s: Failed to clean up the depth request info.", __FUNCTION__);
319     return res;
320   }
321 
322   auto capture_result = std::make_unique<CaptureResult>();
323   if (capture_result == nullptr) {
324     ALOGE("%s: Creating capture_result failed.", __FUNCTION__);
325     return NO_MEMORY;
326   }
327 
328   CaptureRequest request;
329   {
330     std::lock_guard<std::mutex> pending_request_lock(pending_requests_mutex_);
331     if (pending_depth_requests_.find(frame_number) ==
332         pending_depth_requests_.end()) {
333       ALOGE("%s: Frame %u does not exist in pending requests list.",
334             __FUNCTION__, frame_number);
335     } else {
336       auto& request = pending_depth_requests_[frame_number].request;
337       capture_result->frame_number = frame_number;
338       capture_result->output_buffers = request.output_buffers;
339 
340       // In case the depth engine fails to process a depth request, mark the
341       // buffer as in error state.
342       if (result_status != DepthResultStatus::kOk) {
343         for (auto& stream_buffer : capture_result->output_buffers) {
344           if (stream_buffer.stream_id == depth_stream_.id) {
345             stream_buffer.status = BufferStatus::kError;
346           }
347         }
348       }
349 
350       capture_result->input_buffers = request.input_buffers;
351       pending_depth_requests_.erase(frame_number);
352     }
353   }
354 
355   ProcessBlockResult block_result = {.request_id = 0,
356                                      .result = std::move(capture_result)};
357   {
358     std::lock_guard<std::mutex> lock(result_processor_lock_);
359     result_processor_->ProcessResult(std::move(block_result));
360   }
361 
362   return OK;
363 }
364 
ProcessRequests(const std::vector<ProcessBlockRequest> & process_block_requests,const CaptureRequest & remaining_session_request)365 status_t DepthProcessBlock::ProcessRequests(
366     const std::vector<ProcessBlockRequest>& process_block_requests,
367     const CaptureRequest& remaining_session_request) {
368   ATRACE_CALL();
369   // TODO(b/128633958): remove this after FLL syncing is verified
370   if (force_internal_stream_) {
371     // Nothing to configure if this is force internal mode
372     ALOGE("%s: Force internal ON, Depth PB should not process request.",
373           __FUNCTION__);
374     return UNKNOWN_ERROR;
375   }
376 
377   std::lock_guard<std::mutex> lock(configure_lock_);
378   if (!is_configured_) {
379     ALOGE("%s: block is not configured.", __FUNCTION__);
380     return NO_INIT;
381   }
382 
383   if (process_block_requests.size() != 1) {
384     ALOGE("%s: Only a single request is supported but there are %zu",
385           __FUNCTION__, process_block_requests.size());
386     return BAD_VALUE;
387   }
388 
389   {
390     std::lock_guard<std::mutex> lock(result_processor_lock_);
391     if (result_processor_ == nullptr) {
392       ALOGE("%s: result processor was not set.", __FUNCTION__);
393       return NO_INIT;
394     }
395 
396     status_t res = result_processor_->AddPendingRequests(
397         process_block_requests, remaining_session_request);
398     if (res != OK) {
399       ALOGE("%s: Adding a pending request to result processor failed: %s(%d)",
400             __FUNCTION__, strerror(-res), res);
401       return res;
402     }
403   }
404 
405   auto& request = process_block_requests[0].request;
406   DepthRequestInfo request_info;
407   request_info.frame_number = request.frame_number;
408   std::unique_ptr<HalCameraMetadata> metadata = nullptr;
409   if (request.settings != nullptr) {
410     metadata = HalCameraMetadata::Clone(request.settings.get());
411   }
412 
413   std::unique_ptr<HalCameraMetadata> color_metadata = nullptr;
414   for (auto& metadata : request.input_buffer_metadata) {
415     if (metadata != nullptr) {
416       color_metadata = HalCameraMetadata::Clone(metadata.get());
417     }
418   }
419 
420   ALOGV("%s: [ud] Prepare depth request info for frame %u .", __FUNCTION__,
421         request.frame_number);
422 
423   status_t res = PrepareDepthRequestInfo(request, &request_info, metadata.get(),
424                                          color_metadata.get());
425   if (res != OK) {
426     ALOGE("%s: Failed to perpare the depth request info.", __FUNCTION__);
427     return res;
428   }
429 
430   if (pipelined_depth_engine_enabled_ == true) {
431     res = SubmitAsyncDepthRequest(request_info);
432     if (res != OK) {
433       ALOGE("%s: Failed to submit asynchronized depth request.", __FUNCTION__);
434     }
435   } else {
436     res = SubmitBlockingDepthRequest(request_info);
437     if (res != OK) {
438       ALOGE("%s: Failed to submit blocking depth request.", __FUNCTION__);
439     }
440   }
441 
442   return OK;
443 }
444 
Flush()445 status_t DepthProcessBlock::Flush() {
446   ATRACE_CALL();
447   std::lock_guard<std::mutex> lock(configure_lock_);
448   if (!is_configured_) {
449     return OK;
450   }
451 
452   // TODO(b/127322570): Implement this method.
453   return OK;
454 }
455 
LoadDepthGenerator(std::unique_ptr<DepthGenerator> * depth_generator)456 status_t DepthProcessBlock::LoadDepthGenerator(
457     std::unique_ptr<DepthGenerator>* depth_generator) {
458   ATRACE_CALL();
459   CreateDepthGenerator_t create_depth_generator;
460 
461   ALOGI("%s: Loading library: %s", __FUNCTION__, kDepthGeneratorLib.c_str());
462   depth_generator_lib_handle_ =
463       dlopen(kDepthGeneratorLib.c_str(), RTLD_NOW | RTLD_NODELETE);
464   if (depth_generator_lib_handle_ == nullptr) {
465     ALOGE("Depth generator loading %s failed.", kDepthGeneratorLib.c_str());
466     return NO_INIT;
467   }
468 
469   create_depth_generator = (CreateDepthGenerator_t)dlsym(
470       depth_generator_lib_handle_, "CreateDepthGenerator");
471   if (create_depth_generator == nullptr) {
472     ALOGE("%s: dlsym failed (%s).", __FUNCTION__, kDepthGeneratorLib.c_str());
473     dlclose(depth_generator_lib_handle_);
474     depth_generator_lib_handle_ = nullptr;
475     return NO_INIT;
476   }
477 
478   *depth_generator = std::unique_ptr<DepthGenerator>(create_depth_generator());
479   if (*depth_generator == nullptr) {
480     return NO_INIT;
481   }
482 
483   return OK;
484 }
485 
MapBuffersForDepthGenerator(const StreamBuffer & stream_buffer,depth_generator::Buffer * buffer)486 status_t DepthProcessBlock::MapBuffersForDepthGenerator(
487     const StreamBuffer& stream_buffer, depth_generator::Buffer* buffer) {
488   ATRACE_CALL();
489   buffer_handle_t buffer_handle = stream_buffer.buffer;
490   ALOGV("%s: Mapping FD=%d to CPU addr.", __FUNCTION__, buffer_handle->data[0]);
491 
492   int32_t stream_id = stream_buffer.stream_id;
493   if (stream_buffer_sizes_.find(stream_id) == stream_buffer_sizes_.end() ||
494       depth_io_streams_.find(stream_id) == depth_io_streams_.end()) {
495     ALOGE("%s: Stream buffer stream id:%d not found.", __FUNCTION__, stream_id);
496     return UNKNOWN_ERROR;
497   }
498 
499   void* virtual_addr =
500       mmap(NULL, stream_buffer_sizes_[stream_id], (PROT_READ | PROT_WRITE),
501            MAP_SHARED, buffer_handle->data[0], 0);
502 
503   if (virtual_addr == nullptr || virtual_addr == reinterpret_cast<void*>(-1)) {
504     ALOGE("%s: Failed to map the stream buffer to virtual addr.", __FUNCTION__);
505     return UNKNOWN_ERROR;
506   }
507 
508   auto& stream = depth_io_streams_[stream_id];
509   buffer->format = stream.format;
510   buffer->width = stream.width;
511   buffer->height = stream.height;
512   depth_generator::BufferPlane buffer_plane = {};
513   buffer_plane.addr = reinterpret_cast<uint8_t*>(virtual_addr);
514   // TODO(b/130764929): Use actual gralloc buffer stride instead of stream dim
515   buffer_plane.stride = stream.width;
516   buffer_plane.scanline = stream.height;
517   buffer->planes.push_back(buffer_plane);
518 
519   return OK;
520 }
521 
UnmapBuffersForDepthGenerator(const StreamBuffer & stream_buffer,uint8_t * addr)522 status_t DepthProcessBlock::UnmapBuffersForDepthGenerator(
523     const StreamBuffer& stream_buffer, uint8_t* addr) {
524   ATRACE_CALL();
525   if (addr == nullptr) {
526     ALOGE("%s: Addr is null.", __FUNCTION__);
527     return BAD_VALUE;
528   }
529 
530   int32_t stream_id = stream_buffer.stream_id;
531   if (stream_buffer_sizes_.find(stream_id) == stream_buffer_sizes_.end() ||
532       depth_io_streams_.find(stream_id) == depth_io_streams_.end()) {
533     ALOGE("%s: Stream buffer stream id:%d not found.", __FUNCTION__, stream_id);
534     return UNKNOWN_ERROR;
535   }
536 
537   munmap(addr, stream_buffer_sizes_[stream_id]);
538   return OK;
539 }
540 
RequestDepthStreamBuffer(StreamBuffer * incomplete_buffer,uint32_t frame_number)541 status_t DepthProcessBlock::RequestDepthStreamBuffer(
542     StreamBuffer* incomplete_buffer, uint32_t frame_number) {
543   if (!buffer_management_supported_) {
544     return OK;
545   }
546 
547   if (request_stream_buffers_ == nullptr) {
548     ALOGE("%s: request_stream_buffers_ is nullptr", __FUNCTION__);
549     return UNKNOWN_ERROR;
550   }
551 
552   std::vector<StreamBuffer> buffers;
553   {
554     status_t res = request_stream_buffers_(
555         incomplete_buffer->stream_id,
556         /* request one depth buffer each time */ 1, &buffers, frame_number);
557     if (res != OK) {
558       ALOGE("%s: Failed to request stream buffers from camera device session.",
559             __FUNCTION__);
560       return UNKNOWN_ERROR;
561     }
562   }
563 
564   *incomplete_buffer = buffers[0];
565   return OK;
566 }
567 
UpdateCropRegion(const CaptureRequest & request,DepthRequestInfo * depth_request_info,HalCameraMetadata * metadata)568 status_t DepthProcessBlock::UpdateCropRegion(const CaptureRequest& request,
569                                              DepthRequestInfo* depth_request_info,
570                                              HalCameraMetadata* metadata) {
571   if (request.settings != nullptr && metadata != nullptr) {
572     camera_metadata_ro_entry_t entry_crop_region_user = {};
573     if (request.settings->Get(ANDROID_SCALER_CROP_REGION,
574                               &entry_crop_region_user) == OK) {
575       const int32_t* crop_region = entry_crop_region_user.data.i32;
576       ALOGV("%s: Depth PB crop region[%d %d %d %d]", __FUNCTION__,
577             crop_region[0], crop_region[1], crop_region[2], crop_region[3]);
578 
579       int32_t resized_crop_region[4] = {};
580       // top
581       resized_crop_region[0] = crop_region[1] / logical_to_ir_ratio_;
582       if (resized_crop_region[0] < 0) {
583         resized_crop_region[0] = 0;
584       }
585       // left
586       resized_crop_region[1] = crop_region[0] / logical_to_ir_ratio_;
587       if (resized_crop_region[1] < 0) {
588         resized_crop_region[1] = 0;
589       }
590       // bottom
591       resized_crop_region[2] =
592           (crop_region[3] / logical_to_ir_ratio_) + resized_crop_region[0];
593       if (resized_crop_region[2] > ir_active_array_height_) {
594         resized_crop_region[2] = ir_active_array_height_;
595       }
596       // right
597       resized_crop_region[3] =
598           (crop_region[2] / logical_to_ir_ratio_) + resized_crop_region[1];
599       if (resized_crop_region[3] > ir_active_array_width_) {
600         resized_crop_region[3] = ir_active_array_width_;
601       }
602       metadata->Set(ANDROID_SCALER_CROP_REGION, resized_crop_region,
603                     sizeof(resized_crop_region) / sizeof(int32_t));
604 
605       depth_request_info->settings = metadata->GetRawCameraMetadata();
606     }
607   }
608   return OK;
609 }
610 
MapDepthRequestBuffers(const CaptureRequest & request,DepthRequestInfo * depth_request_info)611 status_t DepthProcessBlock::MapDepthRequestBuffers(
612     const CaptureRequest& request, DepthRequestInfo* depth_request_info) {
613   status_t res = OK;
614   depth_request_info->ir_buffer.resize(2);
615   for (auto& input_buffer : request.input_buffers) {
616     // If the stream id is invalid. The input buffer is only a place holder
617     // corresponding to the input buffer metadata for the rgb pipeline.
618     if (input_buffer.stream_id == kInvalidStreamId) {
619       ALOGV("%s: Skipping input buffer place holder for frame %u.",
620             __FUNCTION__, depth_request_info->frame_number);
621       continue;
622     }
623 
624     depth_generator::Buffer buffer = {};
625     res = MapBuffersForDepthGenerator(input_buffer, &buffer);
626     if (res != OK) {
627       ALOGE("%s: Mapping buffer for depth generator failed.", __FUNCTION__);
628       return UNKNOWN_ERROR;
629     }
630     const int32_t stream_id = input_buffer.stream_id;
631     if (stream_id == rgb_internal_yuv_stream_id_) {
632       // TODO(b/129910835): Triggering Condition
633       // Adjust the condition according to how rt_request_processor and
634       // result_request_processor handles the triggering condition. If they have
635       // full control of the logic and decide to pass yuv buffer only when
636       // autocal should be triggered, then the logic here can be as simple as
637       // this.
638       depth_request_info->color_buffer.push_back(buffer);
639     } else if (stream_id == ir1_internal_raw_stream_id_) {
640       depth_request_info->ir_buffer[0].push_back(buffer);
641     } else if (stream_id == ir2_internal_raw_stream_id_) {
642       depth_request_info->ir_buffer[1].push_back(buffer);
643     }
644   }
645 
646   res = MapBuffersForDepthGenerator(request.output_buffers[0],
647                                     &depth_request_info->depth_buffer);
648   if (res != OK) {
649     ALOGE("%s: Mapping depth buffer for depth generator failed.", __FUNCTION__);
650     return UNKNOWN_ERROR;
651   }
652 
653   return OK;
654 }
655 
PrepareDepthRequestInfo(const CaptureRequest & request,DepthRequestInfo * depth_request_info,HalCameraMetadata * metadata,const HalCameraMetadata * color_metadata)656 status_t DepthProcessBlock::PrepareDepthRequestInfo(
657     const CaptureRequest& request, DepthRequestInfo* depth_request_info,
658     HalCameraMetadata* metadata, const HalCameraMetadata* color_metadata) {
659   ATRACE_CALL();
660 
661   if (depth_request_info == nullptr) {
662     ALOGE("%s: depth_request_info is nullptr.", __FUNCTION__);
663     return BAD_VALUE;
664   }
665 
666   status_t res = UpdateCropRegion(request, depth_request_info, metadata);
667   if (res != OK) {
668     ALOGE("%s: Failed to update crop region.", __FUNCTION__);
669     return UNKNOWN_ERROR;
670   }
671 
672   if (color_metadata != nullptr) {
673     depth_request_info->color_buffer_metadata =
674         color_metadata->GetRawCameraMetadata();
675   }
676 
677   if (request.input_buffers.size() < 2 || request.input_buffers.size() > 3 ||
678       request.output_buffers.size() != 1) {
679     ALOGE(
680         "%s: Cannot prepare request info, input buffer size is not 2 or 3(is"
681         " %zu) or output buffer size is not 1(is %zu).",
682         __FUNCTION__, request.input_buffers.size(),
683         request.output_buffers.size());
684     return BAD_VALUE;
685   }
686 
687   if (buffer_management_supported_) {
688     res = RequestDepthStreamBuffer(
689         &(const_cast<CaptureRequest&>(request).output_buffers[0]),
690         request.frame_number);
691     if (res != OK) {
692       ALOGE("%s: Failed to request depth stream buffer.", __FUNCTION__);
693       return UNKNOWN_ERROR;
694     }
695   }
696 
697   res = MapDepthRequestBuffers(request, depth_request_info);
698   if (res != OK) {
699     ALOGE("%s: Failed to map buffers for depth request.", __FUNCTION__);
700     return UNKNOWN_ERROR;
701   }
702 
703   {
704     uint32_t frame_number = request.frame_number;
705     std::lock_guard<std::mutex> lock(pending_requests_mutex_);
706     if (pending_depth_requests_.find(frame_number) !=
707         pending_depth_requests_.end()) {
708       ALOGE("%s: Frame %u already exists in pending requests.", __FUNCTION__,
709             request.frame_number);
710       return UNKNOWN_ERROR;
711     } else {
712       pending_depth_requests_[frame_number] = {};
713       auto& pending_request = pending_depth_requests_[frame_number].request;
714       pending_request.frame_number = frame_number;
715       pending_request.input_buffers = request.input_buffers;
716       pending_request.output_buffers = request.output_buffers;
717       auto& pending_depth_request =
718           pending_depth_requests_[frame_number].depth_request;
719       pending_depth_request = *depth_request_info;
720     }
721   }
722 
723   return OK;
724 }
725 
UnmapDepthRequestBuffers(uint32_t frame_number)726 status_t DepthProcessBlock::UnmapDepthRequestBuffers(uint32_t frame_number) {
727   std::lock_guard<std::mutex> lock(pending_requests_mutex_);
728   if (pending_depth_requests_.find(frame_number) ==
729       pending_depth_requests_.end()) {
730     ALOGE("%s: Can not find frame %u in pending requests list.", __FUNCTION__,
731           frame_number);
732     return BAD_VALUE;
733   }
734 
735   auto& request = pending_depth_requests_[frame_number].request;
736   auto& depth_request_info = pending_depth_requests_[frame_number].depth_request;
737 
738   ATRACE_CALL();
739   if (request.input_buffers.size() < 2 || request.input_buffers.size() > 3 ||
740       request.output_buffers.size() != 1) {
741     ALOGE(
742         "%s: Cannot prepare request info, input buffer size is not 2 or 3(is "
743         "%zu) or output buffer size is not 1(is %zu).",
744         __FUNCTION__, request.input_buffers.size(),
745         request.output_buffers.size());
746     return BAD_VALUE;
747   }
748 
749   status_t res = OK;
750   for (auto& input_buffer : request.input_buffers) {
751     uint8_t* addr = nullptr;
752     int32_t stream_id = input_buffer.stream_id;
753     if (stream_id == kInvalidStreamId) {
754       ALOGV("%s: input buffer place holder found for frame %u", __FUNCTION__,
755             frame_number);
756       continue;
757     }
758 
759     if (stream_id == rgb_internal_yuv_stream_id_) {
760       addr = depth_request_info.color_buffer[0].planes[0].addr;
761     } else if (stream_id == ir1_internal_raw_stream_id_) {
762       addr = depth_request_info.ir_buffer[0][0].planes[0].addr;
763     } else if (stream_id == ir2_internal_raw_stream_id_) {
764       addr = depth_request_info.ir_buffer[1][0].planes[0].addr;
765     }
766 
767     res = UnmapBuffersForDepthGenerator(input_buffer, addr);
768     if (res != OK) {
769       ALOGE("%s: Unmapping input buffer for depth generator failed.",
770             __FUNCTION__);
771       return UNKNOWN_ERROR;
772     }
773   }
774 
775   res = UnmapBuffersForDepthGenerator(
776       request.output_buffers[0], depth_request_info.depth_buffer.planes[0].addr);
777   if (res != OK) {
778     ALOGE("%s: Unmapping depth buffer for depth generator failed.",
779           __FUNCTION__);
780     return UNKNOWN_ERROR;
781   }
782 
783   return OK;
784 }
785 
CalculateActiveArraySizeRatio(CameraDeviceSessionHwl * device_session_hwl)786 status_t DepthProcessBlock::CalculateActiveArraySizeRatio(
787     CameraDeviceSessionHwl* device_session_hwl) {
788   std::unique_ptr<HalCameraMetadata> characteristics;
789   status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
790   if (res != OK) {
791     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
792     return UNKNOWN_ERROR;
793   }
794 
795   uint32_t active_array_width = 0;
796   uint32_t active_array_height = 0;
797   camera_metadata_ro_entry entry;
798   res = characteristics->Get(
799       ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &entry);
800   if (res == OK) {
801     active_array_width = entry.data.i32[2];
802     active_array_height = entry.data.i32[3];
803     ALOGI("%s Active size (%d x %d).", __FUNCTION__, active_array_width,
804           active_array_height);
805   } else {
806     ALOGE("%s Get active size failed: %s (%d).", __FUNCTION__, strerror(-res),
807           res);
808     return UNKNOWN_ERROR;
809   }
810 
811   std::vector<uint32_t> physical_camera_ids =
812       device_session_hwl->GetPhysicalCameraIds();
813   if (physical_camera_ids.size() != 3) {
814     ALOGE("%s: Only support 3 cameras", __FUNCTION__);
815     return UNKNOWN_ERROR;
816   }
817 
818   uint32_t ir_active_array_width = 0;
819   uint32_t ir_active_array_height = 0;
820   std::unique_ptr<HalCameraMetadata> ir_characteristics;
821   for (auto camera_id : physical_camera_ids) {
822     res = device_session_hwl->GetPhysicalCameraCharacteristics(
823         camera_id, &ir_characteristics);
824     if (res != OK) {
825       ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
826       return UNKNOWN_ERROR;
827     }
828 
829     // assuming both IR camera are of the same size
830     if (hal_utils::IsIrCamera(ir_characteristics.get())) {
831       camera_metadata_ro_entry entry;
832       res = ir_characteristics->Get(
833           ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &entry);
834       if (res == OK) {
835         ir_active_array_width = entry.data.i32[2];
836         ir_active_array_height = entry.data.i32[3];
837         ALOGI("%s IR active size (%dx%d).", __FUNCTION__, ir_active_array_width,
838               ir_active_array_height);
839       } else {
840         ALOGE("%s Get ir active size failed: %s (%d).", __FUNCTION__,
841               strerror(-res), res);
842         return UNKNOWN_ERROR;
843       }
844       break;
845     }
846   }
847 
848   if (active_array_width == 0 || active_array_height == 0 ||
849       ir_active_array_width == 0 || ir_active_array_height == 0) {
850     ALOGE(
851         "%s: One dimension of the logical camera active array size or the "
852         "IR camera active array size is 0.",
853         __FUNCTION__);
854     return INVALID_OPERATION;
855   }
856 
857   float logical_aspect_ratio = 1.0;
858   float ir_aspect_ratio = 1.0;
859   if (active_array_width > active_array_height) {
860     logical_aspect_ratio = active_array_width / active_array_height;
861     ir_aspect_ratio = ir_active_array_width / ir_active_array_height;
862   } else {
863     logical_aspect_ratio = active_array_height / active_array_width;
864     ir_aspect_ratio = ir_active_array_height / ir_active_array_width;
865   }
866 
867   ir_active_array_height_ = ir_active_array_height;
868   ir_active_array_width_ = ir_active_array_width;
869 
870   float aspect_ratio_diff = logical_aspect_ratio - ir_aspect_ratio;
871   if (aspect_ratio_diff > kSmallOffset || aspect_ratio_diff < -kSmallOffset) {
872     ALOGE(
873         "%s: Logical camera aspect ratio and IR camera aspect ratio are "
874         "different from each other.",
875         __FUNCTION__);
876     return UNKNOWN_ERROR;
877   }
878 
879   logical_to_ir_ratio_ = float(active_array_height) / ir_active_array_height;
880 
881   ALOGI("%s: logical_to_ir_ratio_ = %f", __FUNCTION__, logical_to_ir_ratio_);
882 
883   return OK;
884 }
885 
886 }  // namespace google_camera_hal
887 }  // namespace android
888