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