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