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_eligible_snapshot_stream = false;
167 bool has_preview_stream = false;
168 for (const auto& stream : stream_config.streams) {
169 if (stream.is_physical_camera_stream) {
170 ALOGE("%s: support logical camera only", __FUNCTION__);
171 return false;
172 }
173 if (utils::IsJPEGSnapshotStream(stream) ||
174 utils::IsYUVSnapshotStream(stream)) {
175 if (utils::IsSoftwareDenoiseEligibleSnapshotStream(stream)) {
176 has_eligible_snapshot_stream = true;
177 }
178 } else if (utils::IsPreviewStream(stream)) {
179 has_preview_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_eligible_snapshot_stream) {
187 ALOGE("%s: no eligible 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 auto release_thread = std::thread([this]() {
235 ATRACE_NAME("Release snapshot request processor");
236 snapshot_request_processor_ = nullptr;
237 });
238 if (camera_device_session_hwl_ != nullptr) {
239 camera_device_session_hwl_->DestroyPipelines();
240 }
241 // Need to explicitly release SnapshotProcessBlock by releasing
242 // SnapshotRequestProcessor before the lib handle is released.
243 release_thread.join();
244 dlclose(snapshot_process_block_lib_handle_);
245 }
246
BuildPipelines(ProcessBlock * process_block,ProcessBlock * snapshot_process_block,std::vector<HalStream> * hal_configured_streams)247 status_t ZslSnapshotCaptureSession::BuildPipelines(
248 ProcessBlock* process_block, ProcessBlock* snapshot_process_block,
249 std::vector<HalStream>* hal_configured_streams) {
250 ATRACE_CALL();
251 if (process_block == nullptr || hal_configured_streams == nullptr ||
252 snapshot_process_block == nullptr) {
253 ALOGE(
254 "%s: process_block (%p) or hal_configured_streams (%p) or "
255 "snapshot_process_block (%p) is nullptr",
256 __FUNCTION__, process_block, hal_configured_streams,
257 snapshot_process_block);
258 return BAD_VALUE;
259 }
260
261 status_t res;
262
263 std::vector<HalStream> snapshot_hal_configured_streams;
264 res = snapshot_process_block->GetConfiguredHalStreams(
265 &snapshot_hal_configured_streams);
266 if (res != OK) {
267 ALOGE("%s: Getting snapshot HAL streams failed: %s(%d)", __FUNCTION__,
268 strerror(-res), res);
269 return res;
270 }
271
272 for (uint32_t i = 0; i < hal_configured_streams->size(); i++) {
273 if (hal_configured_streams->at(i).id == additional_stream_id_) {
274 // Reserve additional buffer(s).
275 hal_configured_streams->at(i).max_buffers += kAdditionalBufferNumber;
276 // Allocate internal YUV stream buffers
277 res = internal_stream_manager_->AllocateBuffers(
278 hal_configured_streams->at(i),
279 /*additional_num_buffers=*/kAdditionalBufferNumber);
280 if (res != OK) {
281 ALOGE("%s: AllocateBuffers failed.", __FUNCTION__);
282 return UNKNOWN_ERROR;
283 }
284 break;
285 }
286 }
287
288 return OK;
289 }
290
ConfigureStreams(const StreamConfiguration & stream_config,RequestProcessor * request_processor,ProcessBlock * process_block,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,int32_t & additional_stream_id)291 status_t ZslSnapshotCaptureSession::ConfigureStreams(
292 const StreamConfiguration& stream_config,
293 RequestProcessor* request_processor, ProcessBlock* process_block,
294 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
295 int32_t& additional_stream_id) {
296 ATRACE_CALL();
297 if (request_processor == nullptr || process_block == nullptr) {
298 ALOGE("%s: request_processor (%p) or process_block (%p) is nullptr",
299 __FUNCTION__, request_processor, process_block);
300 return BAD_VALUE;
301 }
302 StreamConfiguration process_block_stream_config;
303 // Configure streams for request processor
304 status_t res = request_processor->ConfigureStreams(
305 internal_stream_manager_.get(), stream_config,
306 &process_block_stream_config);
307 if (res != OK) {
308 ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
309 return res;
310 }
311
312 // Check all streams are configured.
313 if (stream_config.streams.size() > process_block_stream_config.streams.size()) {
314 ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
315 __FUNCTION__, stream_config.streams.size(),
316 process_block_stream_config.streams.size());
317 return UNKNOWN_ERROR;
318 }
319 for (auto& stream : stream_config.streams) {
320 bool found = false;
321 for (auto& configured_stream : process_block_stream_config.streams) {
322 if (stream.id == configured_stream.id) {
323 found = true;
324 break;
325 }
326 }
327
328 if (!found) {
329 ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
330 stream.id);
331 return UNKNOWN_ERROR;
332 }
333 }
334
335 for (auto& stream : process_block_stream_config.streams) {
336 bool found = false;
337 for (auto& configured_stream : stream_config.streams) {
338 if (stream.id == configured_stream.id) {
339 found = true;
340 break;
341 }
342 }
343 if (!found) {
344 additional_stream_id = stream.id;
345 break;
346 }
347 }
348
349 if (additional_stream_id == -1) {
350 ALOGE("%s: Configuring stream fail due to wrong additional_stream_id",
351 __FUNCTION__);
352 return UNKNOWN_ERROR;
353 }
354
355 // Create preview result processor. Stream ID is not set at this stage.
356 auto realtime_result_processor = RealtimeZslResultProcessor::Create(
357 internal_stream_manager_.get(), additional_stream_id,
358 HAL_PIXEL_FORMAT_YCBCR_420_888, partial_result_count_);
359 if (realtime_result_processor == nullptr) {
360 ALOGE("%s: Creating RealtimeZslResultProcessor failed.", __FUNCTION__);
361 return UNKNOWN_ERROR;
362 }
363 realtime_result_processor_ = realtime_result_processor.get();
364 realtime_result_processor->SetResultCallback(process_capture_result, notify);
365
366 res = process_block->SetResultProcessor(std::move(realtime_result_processor));
367 if (res != OK) {
368 ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
369 return res;
370 }
371
372 // Configure streams for process block.
373 res = process_block->ConfigureStreams(process_block_stream_config,
374 stream_config);
375 if (res != OK) {
376 ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
377 return res;
378 }
379
380 for (auto& hal_stream : *hal_config_) {
381 if (hal_stream.id == additional_stream_id) {
382 // Set the producer usage so that the buffer will be 64 byte aligned.
383 hal_stream.producer_usage |=
384 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN);
385 }
386 }
387
388 return OK;
389 }
390
ConfigureSnapshotStreams(const StreamConfiguration & stream_config)391 status_t ZslSnapshotCaptureSession::ConfigureSnapshotStreams(
392 const StreamConfiguration& stream_config) {
393 ATRACE_CALL();
394 if (snapshot_process_block_ == nullptr ||
395 snapshot_request_processor_ == nullptr) {
396 ALOGE(
397 "%s: snapshot_process_block_ or snapshot_request_processor_ is nullptr",
398 __FUNCTION__);
399 return BAD_VALUE;
400 }
401
402 StreamConfiguration process_block_stream_config;
403 // Configure streams for request processor
404 status_t res = snapshot_request_processor_->ConfigureStreams(
405 internal_stream_manager_.get(), stream_config,
406 &process_block_stream_config);
407 if (res != OK) {
408 ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
409 return res;
410 }
411
412 // Configure streams for snapshot process block.
413 res = snapshot_process_block_->ConfigureStreams(process_block_stream_config,
414 stream_config);
415 if (res != OK) {
416 ALOGE("%s: Configuring snapshot stream for process block failed.",
417 __FUNCTION__);
418 return res;
419 }
420
421 return OK;
422 }
423
SetupSnapshotProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)424 status_t ZslSnapshotCaptureSession::SetupSnapshotProcessChain(
425 const StreamConfiguration& stream_config,
426 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
427 ATRACE_CALL();
428 if (snapshot_process_block_ != nullptr ||
429 snapshot_result_processor_ != nullptr ||
430 snapshot_request_processor_ != nullptr) {
431 ALOGE(
432 "%s: snapshot_process_block_(%p) or snapshot_result_processor_(%p) or "
433 "snapshot_request_processor_(%p) is/are "
434 "already set",
435 __FUNCTION__, snapshot_process_block_, snapshot_result_processor_,
436 snapshot_request_processor_.get());
437 return BAD_VALUE;
438 }
439
440 std::unique_ptr<ProcessBlock> snapshot_process_block =
441 CreateSnapshotProcessBlock();
442 if (snapshot_process_block == nullptr) {
443 ALOGE("%s: Creating SnapshotProcessBlock failed.", __FUNCTION__);
444 return UNKNOWN_ERROR;
445 }
446 snapshot_process_block_ = snapshot_process_block.get();
447
448 snapshot_request_processor_ = SnapshotRequestProcessor::Create(
449 camera_device_session_hwl_, hwl_session_callback_, additional_stream_id_);
450 if (snapshot_request_processor_ == nullptr) {
451 ALOGE("%s: Creating SnapshotRequestProcessor failed.", __FUNCTION__);
452 return UNKNOWN_ERROR;
453 }
454
455 std::unique_ptr<SnapshotResultProcessor> snapshot_result_processor =
456 SnapshotResultProcessor::Create(internal_stream_manager_.get(),
457 additional_stream_id_);
458 if (snapshot_result_processor == nullptr) {
459 ALOGE("%s: Creating SnapshotResultProcessor failed.", __FUNCTION__);
460 return UNKNOWN_ERROR;
461 }
462 snapshot_result_processor_ = snapshot_result_processor.get();
463
464 status_t res = snapshot_request_processor_->SetProcessBlock(
465 std::move(snapshot_process_block));
466 if (res != OK) {
467 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
468 __FUNCTION__, strerror(-res), res);
469 return res;
470 }
471
472 res = snapshot_process_block_->SetResultProcessor(
473 std::move(snapshot_result_processor));
474
475 snapshot_result_processor_->SetResultCallback(process_capture_result, notify);
476 res = ConfigureSnapshotStreams(stream_config);
477 if (res != OK) {
478 ALOGE("%s: Configuring snapshot stream failed: %s(%d)", __FUNCTION__,
479 strerror(-res), res);
480 return res;
481 }
482 return OK;
483 }
484
SetupRealtimeProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)485 status_t ZslSnapshotCaptureSession::SetupRealtimeProcessChain(
486 const StreamConfiguration& stream_config,
487 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
488 ATRACE_CALL();
489 if (realtime_process_block_ != nullptr ||
490 realtime_result_processor_ != nullptr ||
491 realtime_request_processor_ != nullptr) {
492 ALOGE(
493 "%s: realtime_process_block_(%p) or realtime_result_processor_(%p) or "
494 "realtime_request_processor_(%p) is/are "
495 "already set",
496 __FUNCTION__, realtime_process_block_, realtime_result_processor_,
497 realtime_request_processor_.get());
498 return BAD_VALUE;
499 }
500
501 // Create process block
502 auto realtime_process_block = CaptureSessionWrapperProcessBlock::Create(
503 external_capture_session_entries_, capture_session_entries_,
504 hwl_session_callback_, camera_buffer_allocator_hwl_,
505 camera_device_session_hwl_, hal_config_);
506 if (realtime_process_block == nullptr) {
507 ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
508 return UNKNOWN_ERROR;
509 }
510 realtime_process_block_ = realtime_process_block.get();
511
512 // Create realtime request processor.
513 realtime_request_processor_ = RealtimeZslRequestProcessor::Create(
514 camera_device_session_hwl_, HAL_PIXEL_FORMAT_YCBCR_420_888);
515 if (realtime_request_processor_ == nullptr) {
516 ALOGE("%s: Creating RealtimeZslRequestProcessor failed.", __FUNCTION__);
517 return UNKNOWN_ERROR;
518 }
519
520 // realtime result processor will be created inside ConfigureStreams when the
521 // additional stream id is determined.
522
523 status_t res = realtime_request_processor_->SetProcessBlock(
524 std::move(realtime_process_block));
525 if (res != OK) {
526 ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
527 __FUNCTION__, strerror(-res), res);
528 return res;
529 }
530
531 res = ConfigureStreams(stream_config, realtime_request_processor_.get(),
532 realtime_process_block_, process_capture_result,
533 notify, additional_stream_id_);
534 if (res != OK) {
535 ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
536 res);
537 return res;
538 }
539 return OK;
540 }
541
PurgeHalConfiguredStream(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_configured_streams)542 status_t ZslSnapshotCaptureSession::PurgeHalConfiguredStream(
543 const StreamConfiguration& stream_config,
544 std::vector<HalStream>* hal_configured_streams) {
545 if (hal_configured_streams == nullptr) {
546 ALOGE("%s: HAL configured stream list is null.", __FUNCTION__);
547 return BAD_VALUE;
548 }
549
550 std::set<int32_t> framework_stream_id_set;
551 for (auto& stream : stream_config.streams) {
552 framework_stream_id_set.insert(stream.id);
553 }
554
555 std::vector<HalStream> configured_streams;
556 for (auto& hal_stream : *hal_configured_streams) {
557 if (framework_stream_id_set.find(hal_stream.id) !=
558 framework_stream_id_set.end()) {
559 configured_streams.push_back(hal_stream);
560 }
561 }
562 *hal_configured_streams = configured_streams;
563 return OK;
564 }
565
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)566 ZslSnapshotCaptureSession::ZslSnapshotCaptureSession(
567 const std::vector<ExternalCaptureSessionFactory*>&
568 external_capture_session_entries,
569 const std::vector<CaptureSessionEntryFuncs>& capture_session_entries,
570 HwlSessionCallback hwl_session_callback,
571 CameraBufferAllocatorHwl* camera_buffer_allocator_hwl,
572 CameraDeviceSessionHwl* camera_device_session_hwl)
573 : external_capture_session_entries_(external_capture_session_entries),
574 capture_session_entries_(capture_session_entries),
575 hwl_session_callback_(hwl_session_callback),
576 camera_buffer_allocator_hwl_(camera_buffer_allocator_hwl),
577 camera_device_session_hwl_(camera_device_session_hwl) {
578 }
579
Initialize(CameraDeviceSessionHwl * camera_device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)580 status_t ZslSnapshotCaptureSession::Initialize(
581 CameraDeviceSessionHwl* camera_device_session_hwl,
582 const StreamConfiguration& stream_config,
583 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
584 std::vector<HalStream>* hal_configured_streams) {
585 ATRACE_CALL();
586 if (!IsStreamConfigurationSupported(camera_device_session_hwl, stream_config)) {
587 ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
588 return BAD_VALUE;
589 }
590
591 std::unique_ptr<HalCameraMetadata> characteristics;
592 status_t res =
593 camera_device_session_hwl->GetCameraCharacteristics(&characteristics);
594 if (res != OK) {
595 ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
596 return BAD_VALUE;
597 }
598
599 for (auto stream : stream_config.streams) {
600 if (utils::IsPreviewStream(stream)) {
601 hal_preview_stream_id_ = stream.id;
602 break;
603 }
604 }
605 camera_device_session_hwl_ = camera_device_session_hwl;
606 hal_config_ = hal_configured_streams;
607
608 // Create result dispatcher
609 partial_result_count_ = kPartialResult;
610 camera_metadata_ro_entry partial_result_entry;
611 res = characteristics->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
612 &partial_result_entry);
613 if (res == OK) {
614 partial_result_count_ = partial_result_entry.data.i32[0];
615 }
616 result_dispatcher_ = ZslResultDispatcher::Create(
617 partial_result_count_, process_capture_result, notify);
618 if (result_dispatcher_ == nullptr) {
619 ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
620 return UNKNOWN_ERROR;
621 }
622
623 internal_stream_manager_ = InternalStreamManager::Create(
624 /*buffer_allocator=*/nullptr, partial_result_count_);
625 if (internal_stream_manager_ == nullptr) {
626 ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
627 return UNKNOWN_ERROR;
628 }
629
630 device_session_notify_ = notify;
631 process_capture_result_ =
632 ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
633 ProcessCaptureResult(std::move(result));
634 });
635 notify_ = NotifyFunc(
636 [this](const NotifyMessage& message) { NotifyHalMessage(message); });
637
638 // Setup and connect realtime process chain
639 res = SetupRealtimeProcessChain(stream_config, process_capture_result_,
640 notify_);
641 if (res != OK) {
642 ALOGE("%s: SetupRealtimeProcessChain fail: %s(%d)", __FUNCTION__,
643 strerror(-res), res);
644 return res;
645 }
646
647 // Setup snapshot process chain
648 res = SetupSnapshotProcessChain(stream_config, process_capture_result_,
649 notify_);
650 if (res != OK) {
651 ALOGE("%s: SetupSnapshotProcessChain fail: %s(%d)", __FUNCTION__,
652 strerror(-res), res);
653 return res;
654 }
655
656 // Realtime and snapshot streams are configured
657 // Start to build pipleline
658 res = BuildPipelines(realtime_process_block_, snapshot_process_block_,
659 hal_configured_streams);
660 if (res != OK) {
661 ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
662 res);
663 return res;
664 }
665
666 res = PurgeHalConfiguredStream(stream_config, hal_configured_streams);
667 if (res != OK) {
668 ALOGE("%s: Removing internal streams from configured stream failed: %s(%d)",
669 __FUNCTION__, strerror(-res), res);
670 return res;
671 }
672
673 if (res != OK) {
674 ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
675 strerror(-res), res);
676 return res;
677 }
678
679 return OK;
680 }
681
ProcessRequest(const CaptureRequest & request)682 status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
683 ATRACE_CALL();
684 bool is_zsl_request = false;
685 camera_metadata_ro_entry entry;
686 if (request.settings != nullptr) {
687 if (request.settings->Get(ANDROID_CONTROL_ENABLE_ZSL, &entry) == OK &&
688 *entry.data.u8 == ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
689 is_zsl_request = true;
690 }
691 }
692 status_t res = result_dispatcher_->AddPendingRequest(request, is_zsl_request);
693 if (res != OK) {
694 ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
695 request.frame_number);
696 return BAD_VALUE;
697 }
698 if (IsSwDenoiseSnapshotCompatible(request)) {
699 res = snapshot_request_processor_->ProcessRequest(request);
700 if (res != OK) {
701 ALOGW(
702 "%s: frame (%d) fall back to real time request for snapshot: %s (%d)",
703 __FUNCTION__, request.frame_number, strerror(-res), res);
704 res = realtime_request_processor_->ProcessRequest(request);
705 }
706 } else {
707 res = realtime_request_processor_->ProcessRequest(request);
708 }
709
710 if (res != OK) {
711 ALOGE("%s: ProcessRequest (%d) fail and remove pending request",
712 __FUNCTION__, request.frame_number);
713 result_dispatcher_->RemovePendingRequest(request.frame_number);
714 }
715 return res;
716 }
717
Flush()718 status_t ZslSnapshotCaptureSession::Flush() {
719 ATRACE_CALL();
720 return realtime_request_processor_->Flush();
721 }
722
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)723 void ZslSnapshotCaptureSession::ProcessCaptureResult(
724 std::unique_ptr<CaptureResult> result) {
725 ATRACE_CALL();
726 std::lock_guard<std::mutex> lock(callback_lock_);
727 if (result == nullptr) {
728 return;
729 }
730
731 if (result->result_metadata) {
732 camera_device_session_hwl_->FilterResultMetadata(
733 result->result_metadata.get());
734 }
735
736 status_t res = result_dispatcher_->AddResult(std::move(result));
737 if (res != OK) {
738 ALOGE("%s: fail to AddResult", __FUNCTION__);
739 return;
740 }
741 }
742
NotifyHalMessage(const NotifyMessage & message)743 void ZslSnapshotCaptureSession::NotifyHalMessage(const NotifyMessage& message) {
744 ATRACE_CALL();
745 std::lock_guard<std::mutex> lock(callback_lock_);
746 if (device_session_notify_ == nullptr) {
747 ALOGE("%s: device_session_notify_ is nullptr. Dropping a message.",
748 __FUNCTION__);
749 return;
750 }
751
752 if (message.type == MessageType::kShutter) {
753 status_t res =
754 result_dispatcher_->AddShutter(message.message.shutter.frame_number,
755 message.message.shutter.timestamp_ns);
756 if (res != OK) {
757 ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
758 message.message.shutter.frame_number, strerror(-res), res);
759 return;
760 }
761 } else if (message.type == MessageType::kError) {
762 status_t res = result_dispatcher_->AddError(message.message.error);
763 if (res != OK) {
764 ALOGE("%s: AddError for frame %u failed: %s (%d).", __FUNCTION__,
765 message.message.error.frame_number, strerror(-res), res);
766 return;
767 }
768 } else {
769 ALOGW("%s: Unsupported message type: %u", __FUNCTION__, message.type);
770 device_session_notify_(message);
771 }
772 }
773
774 } // namespace google_camera_hal
775 } // namespace android
776