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