1 /*
2 * Copyright (C) 2021 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
19 #define LOG_TAG "GCH_ZslSnapshotCaptureSession"
20 #define ATRACE_TAG ATRACE_TAG_CAMERA
21
22 #include "zsl_snapshot_capture_session.h"
23
24 #include <dlfcn.h>
25 #include <log/log.h>
26 #include <sys/stat.h>
27 #include <utils/Trace.h>
28
29 #include "hal_utils.h"
30 #include "libgooglecamerahal_flags.h"
31 #include "realtime_zsl_result_request_processor.h"
32 #include "snapshot_request_processor.h"
33 #include "snapshot_result_processor.h"
34 #include "system/graphics-base-v1.0.h"
35 #include "utils.h"
36 #include "utils/Errors.h"
37 #include "vendor_tag_defs.h"
38
39 namespace android {
40 namespace google_camera_hal {
41 namespace {
42
43 #if GCH_HWL_USE_DLOPEN
44 // HAL external process block library path
45 #if defined(_LP64)
46 constexpr char kExternalProcessBlockDir[] =
47 "/vendor/lib64/camera/google_proprietary/";
48 #else // defined(_LP64)
49 constexpr char kExternalProcessBlockDir[] =
50 "/vendor/lib/camera/google_proprietary/";
51 #endif
52 #endif // GCH_HWL_USE_DLOPEN
53
IsSwDenoiseSnapshotCompatible(const CaptureRequest & request)54 bool IsSwDenoiseSnapshotCompatible(const CaptureRequest& request) {
55 if (request.settings == nullptr) {
56 return false;
57 }
58 camera_metadata_ro_entry entry;
59 if (request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) != OK ||
60 *entry.data.u8 != ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
61 ALOGV("%s: ANDROID_CONTROL_CAPTURE_INTENT is not STILL_CAPTURE",
62 __FUNCTION__);
63 return false;
64 }
65
66 if (request.settings->Get(ANDROID_NOISE_REDUCTION_MODE, &entry) != OK ||
67 *entry.data.u8 != ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY) {
68 ALOGI("%s: ANDROID_NOISE_REDUCTION_MODE is not HQ", __FUNCTION__);
69 return false;
70 }
71
72 if (request.settings->Get(ANDROID_EDGE_MODE, &entry) != OK ||
73 *entry.data.u8 != ANDROID_EDGE_MODE_HIGH_QUALITY) {
74 ALOGI("%s: ANDROID_EDGE_MODE is not HQ", __FUNCTION__);
75 return false;
76 }
77
78 if (request.settings->Get(ANDROID_CONTROL_EFFECT_MODE, &entry) != OK ||
79 *entry.data.u8 != ANDROID_CONTROL_EFFECT_MODE_OFF) {
80 ALOGI("%s: ANDROID_CONTROL_EFFECT_MODE is not off", __FUNCTION__);
81 return false;
82 }
83
84 if (request.settings->Get(ANDROID_TONEMAP_MODE, &entry) != OK ||
85 *entry.data.u8 != ANDROID_TONEMAP_MODE_HIGH_QUALITY) {
86 ALOGI("%s: ANDROID_TONEMAP_MODE is not HQ", __FUNCTION__);
87 return false;
88 }
89
90 return true;
91 }
92 } // namespace
93
94 std::unique_ptr<ProcessBlock>
CreateSnapshotProcessBlock()95 ZslSnapshotCaptureSession::CreateSnapshotProcessBlock() {
96 ATRACE_CALL();
97 #if GCH_HWL_USE_DLOPEN
98 bool found_process_block = false;
99 for (const auto& lib_path :
100 utils::FindLibraryPaths(kExternalProcessBlockDir)) {
101 ALOGI("%s: Loading %s", __FUNCTION__, lib_path.c_str());
102 void* lib_handle = nullptr;
103 lib_handle = dlopen(lib_path.c_str(), RTLD_NOW);
104 if (lib_handle == nullptr) {
105 ALOGW("Failed loading %s.", lib_path.c_str());
106 continue;
107 }
108
109 GetProcessBlockFactoryFunc external_process_block_t =
110 reinterpret_cast<GetProcessBlockFactoryFunc>(
111 dlsym(lib_handle, "GetProcessBlockFactory"));
112 if (external_process_block_t == nullptr) {
113 ALOGE("%s: dlsym failed (%s) when loading %s.", __FUNCTION__,
114 "GetProcessBlockFactoryFunc", lib_path.c_str());
115 dlclose(lib_handle);
116 lib_handle = nullptr;
117 continue;
118 }
119
120 if (external_process_block_t()->GetBlockName() == "SnapshotProcessBlock") {
121 snapshot_process_block_factory_ = external_process_block_t;
122 snapshot_process_block_lib_handle_ = lib_handle;
123 found_process_block = true;
124 break;
125 }
126 }
127 if (!found_process_block) {
128 ALOGE("%s: snapshot process block does not exist", __FUNCTION__);
129 return nullptr;
130 }
131
132 return snapshot_process_block_factory_()->CreateProcessBlock(
133 camera_device_session_hwl_);
134 #else
135 if (GetSnapshotProcessBlockFactory == nullptr) {
136 ALOGE("%s: snapshot process block does not exist", __FUNCTION__);
137 return nullptr;
138 }
139 snapshot_process_block_factory_ = GetSnapshotProcessBlockFactory;
140 return GetSnapshotProcessBlockFactory()->CreateProcessBlock(
141 camera_device_session_hwl_);
142 #endif
143 }
144
145 std::unique_ptr<ProcessBlock>
CreateDenoiseProcessBlock()146 ZslSnapshotCaptureSession::CreateDenoiseProcessBlock() {
147 ATRACE_CALL();
148 #if GCH_HWL_USE_DLOPEN
149 bool found_process_block = false;
150 for (const auto& lib_path :
151 utils::FindLibraryPaths(kExternalProcessBlockDir)) {
152 ALOGI("%s: Loading %s", __FUNCTION__, lib_path.c_str());
153 void* lib_handle = nullptr;
154 lib_handle = dlopen(lib_path.c_str(), RTLD_NOW);
155 if (lib_handle == nullptr) {
156 ALOGW("Failed loading %s.", lib_path.c_str());
157 continue;
158 }
159
160 GetProcessBlockFactoryFunc external_process_block_t =
161 reinterpret_cast<GetProcessBlockFactoryFunc>(
162 dlsym(lib_handle, "GetProcessBlockFactory"));
163 if (external_process_block_t == nullptr) {
164 ALOGE("%s: dlsym failed (%s) when loading %s.", __FUNCTION__,
165 "GetProcessBlockFactoryFunc", lib_path.c_str());
166 dlclose(lib_handle);
167 lib_handle = nullptr;
168 continue;
169 }
170
171 if (external_process_block_t()->GetBlockName() == "DenoiseProcessBlock") {
172 denoise_process_block_factory_ = external_process_block_t;
173 denoise_process_block_lib_handle_ = lib_handle;
174 found_process_block = true;
175 break;
176 }
177 }
178 if (!found_process_block) {
179 ALOGE("%s: denoise process block does not exist", __FUNCTION__);
180 return nullptr;
181 }
182
183 return denoise_process_block_factory_()->CreateProcessBlock(
184 camera_device_session_hwl_);
185 #else
186 if (GetDenoiseProcessBlockFactory == nullptr) {
187 ALOGE("%s: denoise process block does not exist", __FUNCTION__);
188 return nullptr;
189 }
190 denoise_process_block_factory_ = GetDenoiseProcessBlockFactory;
191 return GetDenoiseProcessBlockFactory()->CreateProcessBlock(
192 camera_device_session_hwl_);
193 #endif
194 }
195
IsStreamConfigurationSupported(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config)196 bool ZslSnapshotCaptureSession::IsStreamConfigurationSupported(
197 CameraDeviceSessionHwl* device_session_hwl,
198 const StreamConfiguration& stream_config) {
199 ATRACE_CALL();
200 if (device_session_hwl == nullptr) {
201 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
202 return false;
203 }
204
205 std::unique_ptr<HalCameraMetadata> characteristics;
206 status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
207 if (res != OK) {
208 ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
209 return false;
210 }
211
212 camera_metadata_ro_entry entry;
213 res = characteristics->Get(VendorTagIds::kSwDenoiseEnabled, &entry);
214 if (res != OK || entry.data.u8[0] != 1) {
215 ALOGI("%s: Software denoised not enabled", __FUNCTION__);
216 return false;
217 }
218
219 bool has_eligible_snapshot_stream = false;
220 bool has_preview_stream = false;
221 bool has_hdr_preview_stream = false;
222 for (const auto& stream : stream_config.streams) {
223 if (stream.is_physical_camera_stream) {
224 ALOGI("%s: support logical stream only", __FUNCTION__);
225 return false;
226 }
227 if (utils::IsSecuredStream(stream)) {
228 ALOGI("%s: don't support secured stream", __FUNCTION__);
229 return false;
230 }
231 if (utils::IsJPEGSnapshotStream(stream) ||
232 utils::IsYUVSnapshotStream(stream)) {
233 if (utils::IsSoftwareDenoiseEligibleSnapshotStream(stream)) {
234 has_eligible_snapshot_stream = true;
235 }
236 } else if (utils::IsPreviewStream(stream)) {
237 has_preview_stream = true;
238 if (utils::IsHdrStream(stream)) {
239 has_hdr_preview_stream = true;
240 }
241 } else {
242 ALOGI("%s: only support preview + (snapshot and/or YUV) streams",
243 __FUNCTION__);
244 return false;
245 }
246 }
247 if (!has_eligible_snapshot_stream) {
248 ALOGI("%s: no eligible JPEG or YUV stream", __FUNCTION__);
249 return false;
250 }
251
252 if (!has_preview_stream) {
253 ALOGI("%s: no preview stream", __FUNCTION__);
254 return false;
255 }
256 if (has_hdr_preview_stream) {
257 ALOGI("%s: 10-bit HDR preview stream does not support ZSL snapshot",
258 __FUNCTION__);
259 return false;
260 }
261
262 ALOGI("%s: ZslSnapshotCaptureSession supports the stream config",
263 __FUNCTION__);
264 return true;
265 }
266
Create(const StreamConfiguration & stream_config,const std::vector<ExternalCaptureSessionFactory * > & external_capture_session_entries,const std::vector<CaptureSessionEntryFuncs> & capture_session_entries,HwlSessionCallback hwl_session_callback,CameraBufferAllocatorHwl * camera_buffer_allocator_hwl,CameraDeviceSessionHwl * camera_device_session_hwl,std::vector<HalStream> * hal_configured_streams,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)267 std::unique_ptr<CaptureSession> ZslSnapshotCaptureSession::Create(
268 const StreamConfiguration& stream_config,
269 const std::vector<ExternalCaptureSessionFactory*>&
270 external_capture_session_entries,
271 const std::vector<CaptureSessionEntryFuncs>& capture_session_entries,
272 HwlSessionCallback hwl_session_callback,
273 CameraBufferAllocatorHwl* camera_buffer_allocator_hwl,
274 CameraDeviceSessionHwl* camera_device_session_hwl,
275 std::vector<HalStream>* hal_configured_streams,
276 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
277 ATRACE_CALL();
278 auto session =
279 std::unique_ptr<ZslSnapshotCaptureSession>(new ZslSnapshotCaptureSession(
280 external_capture_session_entries, capture_session_entries,
281 hwl_session_callback, camera_buffer_allocator_hwl,
282 camera_device_session_hwl));
283 if (session == nullptr) {
284 ALOGE("%s: Creating ZslSnapshotCaptureSession failed.", __FUNCTION__);
285 return nullptr;
286 }
287
288 status_t res = session->Initialize(camera_device_session_hwl, stream_config,
289 process_capture_result, notify,
290 hal_configured_streams);
291 if (res != OK) {
292 ALOGE("%s: Initializing ZslSnapshotCaptureSession failed: %s (%d).",
293 __FUNCTION__, strerror(-res), res);
294 return nullptr;
295 }
296 return session;
297 }
298
~ZslSnapshotCaptureSession()299 ZslSnapshotCaptureSession::~ZslSnapshotCaptureSession() {
300 auto release_thread = std::thread([this]() {
301 ATRACE_NAME("Release snapshot request processor");
302 snapshot_request_processor_ = nullptr;
303 });
304 if (camera_device_session_hwl_ != nullptr) {
305 camera_device_session_hwl_->DestroyPipelines();
306 }
307 // Need to explicitly release SnapshotProcessBlock by releasing
308 // SnapshotRequestProcessor before the lib handle is released.
309 release_thread.join();
310 dlclose(snapshot_process_block_lib_handle_);
311 dlclose(denoise_process_block_lib_handle_);
312
313 ALOGI("%s: finished", __FUNCTION__);
314 }
315
BuildPipelines(ProcessBlock * process_block,ProcessBlock * snapshot_process_block,std::vector<HalStream> * hal_configured_streams)316 status_t ZslSnapshotCaptureSession::BuildPipelines(
317 ProcessBlock* process_block, ProcessBlock* snapshot_process_block,
318 std::vector<HalStream>* hal_configured_streams) {
319 ATRACE_CALL();
320 if (process_block == nullptr || hal_configured_streams == nullptr ||
321 snapshot_process_block == nullptr) {
322 ALOGE(
323 "%s: process_block (%p) or hal_configured_streams (%p) or "
324 "snapshot_process_block (%p) is nullptr",
325 __FUNCTION__, process_block, hal_configured_streams,
326 snapshot_process_block);
327 return BAD_VALUE;
328 }
329
330 status_t res;
331
332 std::vector<HalStream> snapshot_hal_configured_streams;
333 res = snapshot_process_block->GetConfiguredHalStreams(
334 &snapshot_hal_configured_streams);
335 if (res != OK) {
336 ALOGE("%s: Getting snapshot HAL streams failed: %s(%d)", __FUNCTION__,
337 strerror(-res), res);
338 return res;
339 }
340
341 for (uint32_t i = 0; i < hal_configured_streams->size(); i++) {
342 if (hal_configured_streams->at(i).id == additional_stream_id_) {
343 // Reserve additional buffer(s).
344 hal_configured_streams->at(i).max_buffers += kAdditionalBufferNumber;
345 // Allocate internal YUV stream buffers
346 res = internal_stream_manager_->AllocateBuffers(
347 hal_configured_streams->at(i),
348 /*additional_num_buffers=*/kAdditionalBufferNumber);
349 if (res != OK) {
350 ALOGE("%s: AllocateBuffers failed.", __FUNCTION__);
351 return UNKNOWN_ERROR;
352 }
353 break;
354 }
355 }
356
357 return OK;
358 }
359
ConfigureStreams(const StreamConfiguration & stream_config,RequestProcessor * request_processor,ProcessBlock * process_block,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,int32_t & additional_stream_id)360 status_t ZslSnapshotCaptureSession::ConfigureStreams(
361 const StreamConfiguration& stream_config,
362 RequestProcessor* request_processor, ProcessBlock* process_block,
363 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
364 int32_t& additional_stream_id) {
365 ATRACE_CALL();
366 if (request_processor == nullptr || process_block == nullptr) {
367 ALOGE("%s: request_processor (%p) or process_block (%p) is nullptr",
368 __FUNCTION__, request_processor, process_block);
369 return BAD_VALUE;
370 }
371 StreamConfiguration process_block_stream_config;
372 // Configure streams for request processor
373 status_t res = request_processor->ConfigureStreams(
374 internal_stream_manager_.get(), stream_config,
375 &process_block_stream_config);
376 if (res != OK) {
377 ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
378 return res;
379 }
380
381 // Check all streams are configured.
382 if (stream_config.streams.size() > process_block_stream_config.streams.size()) {
383 ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
384 __FUNCTION__, stream_config.streams.size(),
385 process_block_stream_config.streams.size());
386 return UNKNOWN_ERROR;
387 }
388 for (auto& stream : stream_config.streams) {
389 bool found = false;
390 for (auto& configured_stream : process_block_stream_config.streams) {
391 if (stream.id == configured_stream.id) {
392 found = true;
393 break;
394 }
395 }
396
397 if (!found) {
398 ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
399 stream.id);
400 return UNKNOWN_ERROR;
401 }
402 }
403
404 for (auto& stream : process_block_stream_config.streams) {
405 bool found = false;
406 for (auto& configured_stream : stream_config.streams) {
407 if (stream.id == configured_stream.id) {
408 found = true;
409 break;
410 }
411 }
412 if (!found) {
413 additional_stream_id = stream.id;
414 break;
415 }
416 }
417
418 if (additional_stream_id == -1) {
419 ALOGE("%s: Configuring stream fail due to wrong additional_stream_id",
420 __FUNCTION__);
421 return UNKNOWN_ERROR;
422 }
423
424 // Create preview result processor. Stream ID is not set at this stage.
425
426 std::unique_ptr<ResultProcessor> realtime_result_processor;
427 if (video_sw_denoise_enabled_) {
428 auto processor = RealtimeZslResultRequestProcessor::Create(
429 internal_stream_manager_.get(), additional_stream_id,
430 HAL_PIXEL_FORMAT_YCBCR_420_888, partial_result_count_);
431 realtime_zsl_result_request_processor_ = processor.get();
432 realtime_result_processor = std::move(processor);
433 } else {
434 realtime_result_processor = RealtimeZslResultProcessor::Create(
435 internal_stream_manager_.get(), additional_stream_id,
436 HAL_PIXEL_FORMAT_YCBCR_420_888, partial_result_count_);
437 }
438
439 if (realtime_result_processor == nullptr) {
440 ALOGE(
441 "%s: Creating "
442 "RealtimeZslResultProcessor/RealtimeZslResultRequestProcessor failed.",
443 __FUNCTION__);
444 return UNKNOWN_ERROR;
445 }
446 realtime_result_processor->SetResultCallback(
447 process_capture_result, notify, /*process_batch_capture_result=*/nullptr);
448
449 res = process_block->SetResultProcessor(std::move(realtime_result_processor));
450 if (res != OK) {
451 ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
452 return res;
453 }
454
455 // Configure streams for process block.
456 res = process_block->ConfigureStreams(process_block_stream_config,
457 stream_config);
458 if (res != OK) {
459 ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
460 return res;
461 }
462
463 for (auto& hal_stream : *hal_config_) {
464 if (hal_stream.id == additional_stream_id) {
465 // Set the producer usage so that the buffer will be 64 byte aligned.
466 hal_stream.producer_usage |=
467 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN);
468 }
469 }
470
471 if (video_sw_denoise_enabled_) {
472 StreamConfiguration denoise_process_block_stream_config;
473 // Configure streams for request processor
474 res = realtime_zsl_result_request_processor_->ConfigureStreams(
475 internal_stream_manager_.get(), stream_config,
476 &denoise_process_block_stream_config);
477
478 if (res != OK) {
479 ALOGE(
480 "%s: Configuring stream for process block "
481 "(RealtimeZslResultRequestProcessor) failed.",
482 __FUNCTION__);
483 return res;
484 }
485
486 std::unique_ptr<ProcessBlock> denoise_processor =
487 CreateDenoiseProcessBlock();
488 // Create preview result processor. Stream ID is not set at this stage.
489 auto basic_result_processor = BasicResultProcessor::Create();
490 if (basic_result_processor == nullptr) {
491 ALOGE("%s: Creating BasicResultProcessor failed.", __FUNCTION__);
492 return UNKNOWN_ERROR;
493 }
494 basic_result_processor_ = basic_result_processor.get();
495 basic_result_processor->SetResultCallback(
496 process_capture_result, notify,
497 /*process_batch_capture_result=*/nullptr);
498
499 res =
500 denoise_processor->SetResultProcessor(std::move(basic_result_processor));
501 if (res != OK) {
502 ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
503 return res;
504 }
505
506 // Configure streams for process block.
507 res = denoise_processor->ConfigureStreams(
508 denoise_process_block_stream_config, stream_config);
509 if (res != OK) {
510 ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
511 return res;
512 }
513
514 res = realtime_zsl_result_request_processor_->SetProcessBlock(
515 std::move(denoise_processor));
516 if (res != OK) {
517 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
518 __FUNCTION__, strerror(-res), res);
519 return res;
520 }
521 }
522
523 return OK;
524 }
525
ConfigureSnapshotStreams(const StreamConfiguration & stream_config)526 status_t ZslSnapshotCaptureSession::ConfigureSnapshotStreams(
527 const StreamConfiguration& stream_config) {
528 ATRACE_CALL();
529 if (snapshot_process_block_ == nullptr ||
530 snapshot_request_processor_ == nullptr) {
531 ALOGE(
532 "%s: snapshot_process_block_ or snapshot_request_processor_ is nullptr",
533 __FUNCTION__);
534 return BAD_VALUE;
535 }
536
537 StreamConfiguration process_block_stream_config;
538 // Configure streams for request processor
539 status_t res = snapshot_request_processor_->ConfigureStreams(
540 internal_stream_manager_.get(), stream_config,
541 &process_block_stream_config);
542 if (res != OK) {
543 ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
544 return res;
545 }
546
547 // Configure streams for snapshot process block.
548 res = snapshot_process_block_->ConfigureStreams(process_block_stream_config,
549 stream_config);
550 if (res != OK) {
551 ALOGE("%s: Configuring snapshot stream for process block failed.",
552 __FUNCTION__);
553 return res;
554 }
555
556 return OK;
557 }
558
SetupSnapshotProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)559 status_t ZslSnapshotCaptureSession::SetupSnapshotProcessChain(
560 const StreamConfiguration& stream_config,
561 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
562 ATRACE_CALL();
563 if (snapshot_process_block_ != nullptr ||
564 snapshot_result_processor_ != nullptr ||
565 snapshot_request_processor_ != nullptr) {
566 ALOGE(
567 "%s: snapshot_process_block_(%p) or snapshot_result_processor_(%p) or "
568 "snapshot_request_processor_(%p) is/are "
569 "already set",
570 __FUNCTION__, snapshot_process_block_, snapshot_result_processor_,
571 snapshot_request_processor_.get());
572 return BAD_VALUE;
573 }
574
575 std::unique_ptr<ProcessBlock> snapshot_process_block =
576 CreateSnapshotProcessBlock();
577 if (snapshot_process_block == nullptr) {
578 ALOGE("%s: Creating SnapshotProcessBlock failed.", __FUNCTION__);
579 return UNKNOWN_ERROR;
580 }
581 snapshot_process_block_ = snapshot_process_block.get();
582
583 snapshot_request_processor_ = SnapshotRequestProcessor::Create(
584 camera_device_session_hwl_, hwl_session_callback_, additional_stream_id_);
585 if (snapshot_request_processor_ == nullptr) {
586 ALOGE("%s: Creating SnapshotRequestProcessor failed.", __FUNCTION__);
587 return UNKNOWN_ERROR;
588 }
589
590 std::unique_ptr<SnapshotResultProcessor> snapshot_result_processor =
591 SnapshotResultProcessor::Create(internal_stream_manager_.get(),
592 additional_stream_id_);
593 if (snapshot_result_processor == nullptr) {
594 ALOGE("%s: Creating SnapshotResultProcessor failed.", __FUNCTION__);
595 return UNKNOWN_ERROR;
596 }
597 snapshot_result_processor_ = snapshot_result_processor.get();
598
599 status_t res = snapshot_request_processor_->SetProcessBlock(
600 std::move(snapshot_process_block));
601 if (res != OK) {
602 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
603 __FUNCTION__, strerror(-res), res);
604 return res;
605 }
606
607 res = snapshot_process_block_->SetResultProcessor(
608 std::move(snapshot_result_processor));
609
610 snapshot_result_processor_->SetResultCallback(
611 process_capture_result, notify, /*process_batch_capture_result=*/nullptr);
612 res = ConfigureSnapshotStreams(stream_config);
613 if (res != OK) {
614 ALOGE("%s: Configuring snapshot stream failed: %s(%d)", __FUNCTION__,
615 strerror(-res), res);
616 return res;
617 }
618 return OK;
619 }
620
SetupRealtimeProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)621 status_t ZslSnapshotCaptureSession::SetupRealtimeProcessChain(
622 const StreamConfiguration& stream_config,
623 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
624 ATRACE_CALL();
625 if (realtime_process_block_ != nullptr ||
626 realtime_request_processor_ != nullptr) {
627 ALOGE(
628 "%s: realtime_process_block_(%p) or realtime_request_processor_(%p) "
629 "is/are already set",
630 __FUNCTION__, realtime_process_block_,
631 realtime_request_processor_.get());
632 return BAD_VALUE;
633 }
634
635 // Create process block
636 auto realtime_process_block = CaptureSessionWrapperProcessBlock::Create(
637 external_capture_session_entries_, capture_session_entries_,
638 hwl_session_callback_, camera_buffer_allocator_hwl_,
639 camera_device_session_hwl_, hal_config_);
640 if (realtime_process_block == nullptr) {
641 ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
642 return UNKNOWN_ERROR;
643 }
644 realtime_process_block_ = realtime_process_block.get();
645
646 // Create realtime request processor.
647 realtime_request_processor_ = RealtimeZslRequestProcessor::Create(
648 camera_device_session_hwl_, HAL_PIXEL_FORMAT_YCBCR_420_888);
649 if (realtime_request_processor_ == nullptr) {
650 ALOGE("%s: Creating RealtimeZslRequestProcessor failed.", __FUNCTION__);
651 return UNKNOWN_ERROR;
652 }
653
654 // realtime result processor will be created inside ConfigureStreams when the
655 // additional stream id is determined.
656
657 status_t res = realtime_request_processor_->SetProcessBlock(
658 std::move(realtime_process_block));
659 if (res != OK) {
660 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
661 __FUNCTION__, strerror(-res), res);
662 return res;
663 }
664
665 res = ConfigureStreams(stream_config, realtime_request_processor_.get(),
666 realtime_process_block_, process_capture_result,
667 notify, additional_stream_id_);
668 if (res != OK) {
669 ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
670 res);
671 return res;
672 }
673 return OK;
674 }
675
PurgeHalConfiguredStream(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_configured_streams)676 status_t ZslSnapshotCaptureSession::PurgeHalConfiguredStream(
677 const StreamConfiguration& stream_config,
678 std::vector<HalStream>* hal_configured_streams) {
679 if (hal_configured_streams == nullptr) {
680 ALOGE("%s: HAL configured stream list is null.", __FUNCTION__);
681 return BAD_VALUE;
682 }
683
684 std::set<int32_t> framework_stream_id_set;
685 for (auto& stream : stream_config.streams) {
686 framework_stream_id_set.insert(stream.id);
687 }
688
689 std::vector<HalStream> configured_streams;
690 for (auto& hal_stream : *hal_configured_streams) {
691 if (framework_stream_id_set.find(hal_stream.id) !=
692 framework_stream_id_set.end()) {
693 configured_streams.push_back(hal_stream);
694 }
695 }
696 *hal_configured_streams = configured_streams;
697 return OK;
698 }
699
ZslSnapshotCaptureSession(const std::vector<ExternalCaptureSessionFactory * > & external_capture_session_entries,const std::vector<CaptureSessionEntryFuncs> & capture_session_entries,HwlSessionCallback hwl_session_callback,CameraBufferAllocatorHwl * camera_buffer_allocator_hwl,CameraDeviceSessionHwl * camera_device_session_hwl)700 ZslSnapshotCaptureSession::ZslSnapshotCaptureSession(
701 const std::vector<ExternalCaptureSessionFactory*>&
702 external_capture_session_entries,
703 const std::vector<CaptureSessionEntryFuncs>& capture_session_entries,
704 HwlSessionCallback hwl_session_callback,
705 CameraBufferAllocatorHwl* camera_buffer_allocator_hwl,
706 CameraDeviceSessionHwl* camera_device_session_hwl)
707 : external_capture_session_entries_(external_capture_session_entries),
708 capture_session_entries_(capture_session_entries),
709 hwl_session_callback_(hwl_session_callback),
710 camera_buffer_allocator_hwl_(camera_buffer_allocator_hwl),
711 camera_device_session_hwl_(camera_device_session_hwl) {
712 }
713
Initialize(CameraDeviceSessionHwl * camera_device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)714 status_t ZslSnapshotCaptureSession::Initialize(
715 CameraDeviceSessionHwl* camera_device_session_hwl,
716 const StreamConfiguration& stream_config,
717 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
718 std::vector<HalStream>* hal_configured_streams) {
719 ATRACE_CALL();
720 if (!IsStreamConfigurationSupported(camera_device_session_hwl, stream_config)) {
721 ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
722 return BAD_VALUE;
723 }
724
725 std::unique_ptr<HalCameraMetadata> characteristics;
726 status_t res =
727 camera_device_session_hwl->GetCameraCharacteristics(&characteristics);
728 if (res != OK) {
729 ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
730 return BAD_VALUE;
731 }
732
733 camera_metadata_ro_entry video_sw_denoise_entry;
734 res = characteristics->Get(VendorTagIds::kVideoSwDenoiseEnabled,
735 &video_sw_denoise_entry);
736 if (res == OK && video_sw_denoise_entry.data.u8[0] == 1) {
737 if (libgooglecamerahal::flags::zsl_video_denoise_in_hwl_two()) {
738 ALOGI("%s: video sw denoise is enabled in HWL", __FUNCTION__);
739 } else {
740 video_sw_denoise_enabled_ = true;
741 ALOGI("%s: video sw denoise is enabled in GCH", __FUNCTION__);
742 }
743 } else {
744 ALOGI("%s: video sw denoise is disabled.", __FUNCTION__);
745 }
746
747 for (auto stream : stream_config.streams) {
748 if (utils::IsPreviewStream(stream)) {
749 hal_preview_stream_id_ = stream.id;
750 break;
751 }
752 }
753 camera_device_session_hwl_ = camera_device_session_hwl;
754 hal_config_ = hal_configured_streams;
755
756 // Create result dispatcher
757 partial_result_count_ = kPartialResult;
758 camera_metadata_ro_entry partial_result_entry;
759 res = characteristics->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
760 &partial_result_entry);
761 if (res == OK) {
762 partial_result_count_ = partial_result_entry.data.i32[0];
763 }
764 result_dispatcher_ = ZslResultDispatcher::Create(
765 partial_result_count_, process_capture_result, notify, stream_config);
766 if (result_dispatcher_ == nullptr) {
767 ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
768 return UNKNOWN_ERROR;
769 }
770
771 internal_stream_manager_ = InternalStreamManager::Create(
772 /*buffer_allocator=*/nullptr, partial_result_count_);
773 if (internal_stream_manager_ == nullptr) {
774 ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
775 return UNKNOWN_ERROR;
776 }
777
778 device_session_notify_ = notify;
779 process_capture_result_ =
780 ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
781 ProcessCaptureResult(std::move(result));
782 });
783 notify_ = NotifyFunc(
784 [this](const NotifyMessage& message) { NotifyHalMessage(message); });
785
786 // Setup and connect realtime process chain
787 res = SetupRealtimeProcessChain(stream_config, process_capture_result_,
788 notify_);
789 if (res != OK) {
790 ALOGE("%s: SetupRealtimeProcessChain fail: %s(%d)", __FUNCTION__,
791 strerror(-res), res);
792 return res;
793 }
794
795 // Setup snapshot process chain
796 res = SetupSnapshotProcessChain(stream_config, process_capture_result_,
797 notify_);
798 if (res != OK) {
799 ALOGE("%s: SetupSnapshotProcessChain fail: %s(%d)", __FUNCTION__,
800 strerror(-res), res);
801 return res;
802 }
803
804 // Realtime and snapshot streams are configured
805 // Start to build pipleline
806 res = BuildPipelines(realtime_process_block_, snapshot_process_block_,
807 hal_configured_streams);
808 if (res != OK) {
809 ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
810 res);
811 return res;
812 }
813
814 res = PurgeHalConfiguredStream(stream_config, hal_configured_streams);
815 if (res != OK) {
816 ALOGE("%s: Removing internal streams from configured stream failed: %s(%d)",
817 __FUNCTION__, strerror(-res), res);
818 return res;
819 }
820
821 if (res != OK) {
822 ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
823 strerror(-res), res);
824 return res;
825 }
826
827 return OK;
828 }
829
ProcessRequest(const CaptureRequest & request)830 status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
831 ATRACE_CALL();
832 bool is_zsl_request = false;
833 bool is_preview_intent = false;
834 camera_metadata_ro_entry entry;
835 if (request.settings != nullptr) {
836 if (request.settings->Get(ANDROID_CONTROL_ENABLE_ZSL, &entry) == OK &&
837 *entry.data.u8 == ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
838 is_zsl_request = true;
839 }
840 if (request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) == OK &&
841 *entry.data.u8 == ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW) {
842 is_preview_intent = true;
843 }
844 }
845 status_t res = result_dispatcher_->AddPendingRequest(request, is_zsl_request);
846 if (res != OK) {
847 ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
848 request.frame_number);
849 return BAD_VALUE;
850 }
851 if (IsSwDenoiseSnapshotCompatible(request)) {
852 res = snapshot_request_processor_->ProcessRequest(request);
853 if (res != OK) {
854 ALOGW(
855 "%s: frame (%d) fall back to real time request for snapshot: %s (%d)",
856 __FUNCTION__, request.frame_number, strerror(-res), res);
857 if (realtime_zsl_result_request_processor_ != nullptr) {
858 realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
859 request.frame_number, request.output_buffers.size(),
860 is_preview_intent);
861 }
862 res = realtime_request_processor_->ProcessRequest(request);
863 }
864 } else {
865 if (realtime_zsl_result_request_processor_ != nullptr) {
866 realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
867 request.frame_number, request.output_buffers.size(),
868 is_preview_intent);
869 }
870
871 res = realtime_request_processor_->ProcessRequest(request);
872 }
873
874 if (res != OK) {
875 ALOGE("%s: ProcessRequest (%d) fail and remove pending request",
876 __FUNCTION__, request.frame_number);
877 result_dispatcher_->RemovePendingRequest(request.frame_number);
878 }
879 return res;
880 }
881
Flush()882 status_t ZslSnapshotCaptureSession::Flush() {
883 ATRACE_CALL();
884 return realtime_request_processor_->Flush();
885 }
886
RepeatingRequestEnd(int32_t frame_number,const std::vector<int32_t> & stream_ids)887 void ZslSnapshotCaptureSession::RepeatingRequestEnd(
888 int32_t frame_number, const std::vector<int32_t>& stream_ids) {
889 ATRACE_CALL();
890 if (realtime_request_processor_ != nullptr) {
891 return realtime_request_processor_->RepeatingRequestEnd(frame_number,
892 stream_ids);
893 }
894 }
895
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)896 void ZslSnapshotCaptureSession::ProcessCaptureResult(
897 std::unique_ptr<CaptureResult> result) {
898 ATRACE_CALL();
899 std::lock_guard<std::mutex> lock(callback_lock_);
900 if (result == nullptr) {
901 return;
902 }
903
904 if (result->result_metadata) {
905 camera_device_session_hwl_->FilterResultMetadata(
906 result->result_metadata.get());
907 }
908
909 status_t res = result_dispatcher_->AddResult(std::move(result));
910 if (res != OK) {
911 ALOGE("%s: fail to AddResult", __FUNCTION__);
912 return;
913 }
914 }
915
NotifyHalMessage(const NotifyMessage & message)916 void ZslSnapshotCaptureSession::NotifyHalMessage(const NotifyMessage& message) {
917 ATRACE_CALL();
918 std::lock_guard<std::mutex> lock(callback_lock_);
919 if (device_session_notify_ == nullptr) {
920 ALOGE("%s: device_session_notify_ is nullptr. Dropping a message.",
921 __FUNCTION__);
922 return;
923 }
924
925 if (message.type == MessageType::kShutter) {
926 status_t res = result_dispatcher_->AddShutter(
927 message.message.shutter.frame_number,
928 message.message.shutter.timestamp_ns,
929 message.message.shutter.readout_timestamp_ns);
930 if (res != OK) {
931 ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
932 message.message.shutter.frame_number, strerror(-res), res);
933 return;
934 }
935 } else if (message.type == MessageType::kError) {
936 status_t res = result_dispatcher_->AddError(message.message.error);
937 if (res != OK) {
938 ALOGE("%s: AddError for frame %u failed: %s (%d).", __FUNCTION__,
939 message.message.error.frame_number, strerror(-res), res);
940 return;
941 }
942 } else {
943 ALOGW("%s: Unsupported message type: %u", __FUNCTION__, message.type);
944 device_session_notify_(message);
945 }
946 }
947
948 } // namespace google_camera_hal
949 } // namespace android
950