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 /*notify_batch=*/nullptr);
449
450 res = process_block->SetResultProcessor(std::move(realtime_result_processor));
451 if (res != OK) {
452 ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
453 return res;
454 }
455
456 // Configure streams for process block.
457 res = process_block->ConfigureStreams(process_block_stream_config,
458 stream_config);
459 if (res != OK) {
460 ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
461 return res;
462 }
463
464 for (auto& hal_stream : *hal_config_) {
465 if (hal_stream.id == additional_stream_id) {
466 // Set the producer usage so that the buffer will be 64 byte aligned.
467 hal_stream.producer_usage |=
468 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN);
469 }
470 }
471
472 if (video_sw_denoise_enabled_) {
473 StreamConfiguration denoise_process_block_stream_config;
474 // Configure streams for request processor
475 res = realtime_zsl_result_request_processor_->ConfigureStreams(
476 internal_stream_manager_.get(), stream_config,
477 &denoise_process_block_stream_config);
478
479 if (res != OK) {
480 ALOGE(
481 "%s: Configuring stream for process block "
482 "(RealtimeZslResultRequestProcessor) failed.",
483 __FUNCTION__);
484 return res;
485 }
486
487 std::unique_ptr<ProcessBlock> denoise_processor =
488 CreateDenoiseProcessBlock();
489 // Create preview result processor. Stream ID is not set at this stage.
490 auto basic_result_processor = BasicResultProcessor::Create();
491 if (basic_result_processor == nullptr) {
492 ALOGE("%s: Creating BasicResultProcessor failed.", __FUNCTION__);
493 return UNKNOWN_ERROR;
494 }
495 basic_result_processor_ = basic_result_processor.get();
496 basic_result_processor->SetResultCallback(
497 process_capture_result, notify,
498 /*process_batch_capture_result=*/nullptr, /*notify_batch=*/nullptr);
499
500 res =
501 denoise_processor->SetResultProcessor(std::move(basic_result_processor));
502 if (res != OK) {
503 ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
504 return res;
505 }
506
507 // Configure streams for process block.
508 res = denoise_processor->ConfigureStreams(
509 denoise_process_block_stream_config, stream_config);
510 if (res != OK) {
511 ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
512 return res;
513 }
514
515 res = realtime_zsl_result_request_processor_->SetProcessBlock(
516 std::move(denoise_processor));
517 if (res != OK) {
518 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
519 __FUNCTION__, strerror(-res), res);
520 return res;
521 }
522 }
523
524 return OK;
525 }
526
ConfigureSnapshotStreams(const StreamConfiguration & stream_config)527 status_t ZslSnapshotCaptureSession::ConfigureSnapshotStreams(
528 const StreamConfiguration& stream_config) {
529 ATRACE_CALL();
530 if (snapshot_process_block_ == nullptr ||
531 snapshot_request_processor_ == nullptr) {
532 ALOGE(
533 "%s: snapshot_process_block_ or snapshot_request_processor_ is nullptr",
534 __FUNCTION__);
535 return BAD_VALUE;
536 }
537
538 StreamConfiguration process_block_stream_config;
539 // Configure streams for request processor
540 status_t res = snapshot_request_processor_->ConfigureStreams(
541 internal_stream_manager_.get(), stream_config,
542 &process_block_stream_config);
543 if (res != OK) {
544 ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
545 return res;
546 }
547
548 // Configure streams for snapshot process block.
549 res = snapshot_process_block_->ConfigureStreams(process_block_stream_config,
550 stream_config);
551 if (res != OK) {
552 ALOGE("%s: Configuring snapshot stream for process block failed.",
553 __FUNCTION__);
554 return res;
555 }
556
557 return OK;
558 }
559
SetupSnapshotProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)560 status_t ZslSnapshotCaptureSession::SetupSnapshotProcessChain(
561 const StreamConfiguration& stream_config,
562 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
563 ATRACE_CALL();
564 if (snapshot_process_block_ != nullptr ||
565 snapshot_result_processor_ != nullptr ||
566 snapshot_request_processor_ != nullptr) {
567 ALOGE(
568 "%s: snapshot_process_block_(%p) or snapshot_result_processor_(%p) or "
569 "snapshot_request_processor_(%p) is/are "
570 "already set",
571 __FUNCTION__, snapshot_process_block_, snapshot_result_processor_,
572 snapshot_request_processor_.get());
573 return BAD_VALUE;
574 }
575
576 std::unique_ptr<ProcessBlock> snapshot_process_block =
577 CreateSnapshotProcessBlock();
578 if (snapshot_process_block == nullptr) {
579 ALOGE("%s: Creating SnapshotProcessBlock failed.", __FUNCTION__);
580 return UNKNOWN_ERROR;
581 }
582 snapshot_process_block_ = snapshot_process_block.get();
583
584 snapshot_request_processor_ = SnapshotRequestProcessor::Create(
585 camera_device_session_hwl_, hwl_session_callback_, additional_stream_id_);
586 if (snapshot_request_processor_ == nullptr) {
587 ALOGE("%s: Creating SnapshotRequestProcessor failed.", __FUNCTION__);
588 return UNKNOWN_ERROR;
589 }
590
591 std::unique_ptr<SnapshotResultProcessor> snapshot_result_processor =
592 SnapshotResultProcessor::Create(internal_stream_manager_.get(),
593 additional_stream_id_);
594 if (snapshot_result_processor == nullptr) {
595 ALOGE("%s: Creating SnapshotResultProcessor failed.", __FUNCTION__);
596 return UNKNOWN_ERROR;
597 }
598 snapshot_result_processor_ = snapshot_result_processor.get();
599
600 status_t res = snapshot_request_processor_->SetProcessBlock(
601 std::move(snapshot_process_block));
602 if (res != OK) {
603 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
604 __FUNCTION__, strerror(-res), res);
605 return res;
606 }
607
608 res = snapshot_process_block_->SetResultProcessor(
609 std::move(snapshot_result_processor));
610
611 snapshot_result_processor_->SetResultCallback(
612 process_capture_result, notify, /*process_batch_capture_result=*/nullptr,
613 /*notify_batch=*/nullptr);
614 res = ConfigureSnapshotStreams(stream_config);
615 if (res != OK) {
616 ALOGE("%s: Configuring snapshot stream failed: %s(%d)", __FUNCTION__,
617 strerror(-res), res);
618 return res;
619 }
620 return OK;
621 }
622
SetupRealtimeProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)623 status_t ZslSnapshotCaptureSession::SetupRealtimeProcessChain(
624 const StreamConfiguration& stream_config,
625 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
626 ATRACE_CALL();
627 if (realtime_process_block_ != nullptr ||
628 realtime_request_processor_ != nullptr) {
629 ALOGE(
630 "%s: realtime_process_block_(%p) or realtime_request_processor_(%p) "
631 "is/are already set",
632 __FUNCTION__, realtime_process_block_,
633 realtime_request_processor_.get());
634 return BAD_VALUE;
635 }
636
637 // Create process block
638 auto realtime_process_block = CaptureSessionWrapperProcessBlock::Create(
639 external_capture_session_entries_, capture_session_entries_,
640 hwl_session_callback_, camera_buffer_allocator_hwl_,
641 camera_device_session_hwl_, hal_config_);
642 if (realtime_process_block == nullptr) {
643 ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
644 return UNKNOWN_ERROR;
645 }
646 realtime_process_block_ = realtime_process_block.get();
647
648 // Create realtime request processor.
649 realtime_request_processor_ = RealtimeZslRequestProcessor::Create(
650 camera_device_session_hwl_, HAL_PIXEL_FORMAT_YCBCR_420_888);
651 if (realtime_request_processor_ == nullptr) {
652 ALOGE("%s: Creating RealtimeZslRequestProcessor failed.", __FUNCTION__);
653 return UNKNOWN_ERROR;
654 }
655
656 // realtime result processor will be created inside ConfigureStreams when the
657 // additional stream id is determined.
658
659 status_t res = realtime_request_processor_->SetProcessBlock(
660 std::move(realtime_process_block));
661 if (res != OK) {
662 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
663 __FUNCTION__, strerror(-res), res);
664 return res;
665 }
666
667 res = ConfigureStreams(stream_config, realtime_request_processor_.get(),
668 realtime_process_block_, process_capture_result,
669 notify, additional_stream_id_);
670 if (res != OK) {
671 ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
672 res);
673 return res;
674 }
675 return OK;
676 }
677
PurgeHalConfiguredStream(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_configured_streams)678 status_t ZslSnapshotCaptureSession::PurgeHalConfiguredStream(
679 const StreamConfiguration& stream_config,
680 std::vector<HalStream>* hal_configured_streams) {
681 if (hal_configured_streams == nullptr) {
682 ALOGE("%s: HAL configured stream list is null.", __FUNCTION__);
683 return BAD_VALUE;
684 }
685
686 std::set<int32_t> framework_stream_id_set;
687 for (auto& stream : stream_config.streams) {
688 framework_stream_id_set.insert(stream.id);
689 }
690
691 std::vector<HalStream> configured_streams;
692 for (auto& hal_stream : *hal_configured_streams) {
693 if (framework_stream_id_set.find(hal_stream.id) !=
694 framework_stream_id_set.end()) {
695 configured_streams.push_back(hal_stream);
696 }
697 }
698 *hal_configured_streams = configured_streams;
699 return OK;
700 }
701
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)702 ZslSnapshotCaptureSession::ZslSnapshotCaptureSession(
703 const std::vector<ExternalCaptureSessionFactory*>&
704 external_capture_session_entries,
705 const std::vector<CaptureSessionEntryFuncs>& capture_session_entries,
706 HwlSessionCallback hwl_session_callback,
707 CameraBufferAllocatorHwl* camera_buffer_allocator_hwl,
708 CameraDeviceSessionHwl* camera_device_session_hwl)
709 : external_capture_session_entries_(external_capture_session_entries),
710 capture_session_entries_(capture_session_entries),
711 hwl_session_callback_(hwl_session_callback),
712 camera_buffer_allocator_hwl_(camera_buffer_allocator_hwl),
713 camera_device_session_hwl_(camera_device_session_hwl) {
714 }
715
Initialize(CameraDeviceSessionHwl * camera_device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)716 status_t ZslSnapshotCaptureSession::Initialize(
717 CameraDeviceSessionHwl* camera_device_session_hwl,
718 const StreamConfiguration& stream_config,
719 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
720 std::vector<HalStream>* hal_configured_streams) {
721 ATRACE_CALL();
722 if (!IsStreamConfigurationSupported(camera_device_session_hwl, stream_config)) {
723 ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
724 return BAD_VALUE;
725 }
726
727 std::unique_ptr<HalCameraMetadata> characteristics;
728 status_t res =
729 camera_device_session_hwl->GetCameraCharacteristics(&characteristics);
730 if (res != OK) {
731 ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
732 return BAD_VALUE;
733 }
734
735 camera_metadata_ro_entry video_sw_denoise_entry;
736 res = characteristics->Get(VendorTagIds::kVideoSwDenoiseEnabled,
737 &video_sw_denoise_entry);
738 if (res == OK && video_sw_denoise_entry.data.u8[0] == 1) {
739 if (libgooglecamerahal::flags::zsl_video_denoise_in_hwl_two()) {
740 ALOGI("%s: video sw denoise is enabled in HWL", __FUNCTION__);
741 } else {
742 video_sw_denoise_enabled_ = true;
743 ALOGI("%s: video sw denoise is enabled in GCH", __FUNCTION__);
744 }
745 } else {
746 ALOGI("%s: video sw denoise is disabled.", __FUNCTION__);
747 }
748
749 for (auto stream : stream_config.streams) {
750 if (utils::IsPreviewStream(stream)) {
751 hal_preview_stream_id_ = stream.id;
752 break;
753 }
754 }
755 camera_device_session_hwl_ = camera_device_session_hwl;
756 hal_config_ = hal_configured_streams;
757
758 // Create result dispatcher
759 partial_result_count_ = kPartialResult;
760 camera_metadata_ro_entry partial_result_entry;
761 res = characteristics->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
762 &partial_result_entry);
763 if (res == OK) {
764 partial_result_count_ = partial_result_entry.data.i32[0];
765 }
766 result_dispatcher_ = ZslResultDispatcher::Create(
767 partial_result_count_, process_capture_result, notify, stream_config);
768 if (result_dispatcher_ == nullptr) {
769 ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
770 return UNKNOWN_ERROR;
771 }
772
773 internal_stream_manager_ = InternalStreamManager::Create(
774 /*buffer_allocator=*/nullptr, partial_result_count_);
775 if (internal_stream_manager_ == nullptr) {
776 ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
777 return UNKNOWN_ERROR;
778 }
779
780 device_session_notify_ = notify;
781 process_capture_result_ =
782 ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
783 ProcessCaptureResult(std::move(result));
784 });
785 notify_ = NotifyFunc(
786 [this](const NotifyMessage& message) { NotifyHalMessage(message); });
787
788 // Setup and connect realtime process chain
789 res = SetupRealtimeProcessChain(stream_config, process_capture_result_,
790 notify_);
791 if (res != OK) {
792 ALOGE("%s: SetupRealtimeProcessChain fail: %s(%d)", __FUNCTION__,
793 strerror(-res), res);
794 return res;
795 }
796
797 // Setup snapshot process chain
798 res = SetupSnapshotProcessChain(stream_config, process_capture_result_,
799 notify_);
800 if (res != OK) {
801 ALOGE("%s: SetupSnapshotProcessChain fail: %s(%d)", __FUNCTION__,
802 strerror(-res), res);
803 return res;
804 }
805
806 // Realtime and snapshot streams are configured
807 // Start to build pipleline
808 res = BuildPipelines(realtime_process_block_, snapshot_process_block_,
809 hal_configured_streams);
810 if (res != OK) {
811 ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
812 res);
813 return res;
814 }
815
816 res = PurgeHalConfiguredStream(stream_config, hal_configured_streams);
817 if (res != OK) {
818 ALOGE("%s: Removing internal streams from configured stream failed: %s(%d)",
819 __FUNCTION__, strerror(-res), res);
820 return res;
821 }
822
823 if (res != OK) {
824 ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
825 strerror(-res), res);
826 return res;
827 }
828
829 return OK;
830 }
831
ProcessRequest(const CaptureRequest & request)832 status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
833 ATRACE_CALL();
834 bool is_zsl_request = false;
835 bool is_preview_intent = false;
836 camera_metadata_ro_entry entry;
837 if (request.settings != nullptr) {
838 if (request.settings->Get(ANDROID_CONTROL_ENABLE_ZSL, &entry) == OK &&
839 *entry.data.u8 == ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
840 is_zsl_request = true;
841 }
842 if (request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) == OK &&
843 *entry.data.u8 == ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW) {
844 is_preview_intent = true;
845 }
846 }
847 status_t res = result_dispatcher_->AddPendingRequest(request, is_zsl_request);
848 if (res != OK) {
849 ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
850 request.frame_number);
851 return BAD_VALUE;
852 }
853 if (IsSwDenoiseSnapshotCompatible(request)) {
854 res = snapshot_request_processor_->ProcessRequest(request);
855 if (res != OK) {
856 ALOGW(
857 "%s: frame (%d) fall back to real time request for snapshot: %s (%d)",
858 __FUNCTION__, request.frame_number, strerror(-res), res);
859 if (realtime_zsl_result_request_processor_ != nullptr) {
860 realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
861 request.frame_number, request.output_buffers.size(),
862 is_preview_intent);
863 }
864 res = realtime_request_processor_->ProcessRequest(request);
865 }
866 } else {
867 if (realtime_zsl_result_request_processor_ != nullptr) {
868 realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
869 request.frame_number, request.output_buffers.size(),
870 is_preview_intent);
871 }
872
873 res = realtime_request_processor_->ProcessRequest(request);
874 }
875
876 if (res != OK) {
877 ALOGE("%s: ProcessRequest (%d) fail and remove pending request",
878 __FUNCTION__, request.frame_number);
879 result_dispatcher_->RemovePendingRequest(request.frame_number);
880 }
881 return res;
882 }
883
Flush()884 status_t ZslSnapshotCaptureSession::Flush() {
885 ATRACE_CALL();
886 return realtime_request_processor_->Flush();
887 }
888
RepeatingRequestEnd(int32_t frame_number,const std::vector<int32_t> & stream_ids)889 void ZslSnapshotCaptureSession::RepeatingRequestEnd(
890 int32_t frame_number, const std::vector<int32_t>& stream_ids) {
891 ATRACE_CALL();
892 if (realtime_request_processor_ != nullptr) {
893 return realtime_request_processor_->RepeatingRequestEnd(frame_number,
894 stream_ids);
895 }
896 }
897
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)898 void ZslSnapshotCaptureSession::ProcessCaptureResult(
899 std::unique_ptr<CaptureResult> result) {
900 ATRACE_CALL();
901 std::lock_guard<std::mutex> lock(callback_lock_);
902 if (result == nullptr) {
903 return;
904 }
905
906 if (result->result_metadata) {
907 camera_device_session_hwl_->FilterResultMetadata(
908 result->result_metadata.get());
909 }
910
911 status_t res = result_dispatcher_->AddResult(std::move(result));
912 if (res != OK) {
913 ALOGE("%s: fail to AddResult", __FUNCTION__);
914 return;
915 }
916 }
917
NotifyHalMessage(const NotifyMessage & message)918 void ZslSnapshotCaptureSession::NotifyHalMessage(const NotifyMessage& message) {
919 ATRACE_CALL();
920 std::lock_guard<std::mutex> lock(callback_lock_);
921 if (device_session_notify_ == nullptr) {
922 ALOGE("%s: device_session_notify_ is nullptr. Dropping a message.",
923 __FUNCTION__);
924 return;
925 }
926
927 if (message.type == MessageType::kShutter) {
928 status_t res = result_dispatcher_->AddShutter(message.message.shutter);
929 if (res != OK) {
930 ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
931 message.message.shutter.frame_number, strerror(-res), res);
932 return;
933 }
934 } else if (message.type == MessageType::kError) {
935 status_t res = result_dispatcher_->AddError(message.message.error);
936 if (res != OK) {
937 ALOGE("%s: AddError for frame %u failed: %s (%d).", __FUNCTION__,
938 message.message.error.frame_number, strerror(-res), res);
939 return;
940 }
941 } else {
942 ALOGW("%s: Unsupported message type: %u", __FUNCTION__, message.type);
943 device_session_notify_(message);
944 }
945 }
946
947 } // namespace google_camera_hal
948 } // namespace android
949