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