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