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