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