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