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