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(
446       process_capture_result, notify, /*process_batch_capture_result=*/nullptr);
447 
448   res = process_block->SetResultProcessor(std::move(realtime_result_processor));
449   if (res != OK) {
450     ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
451     return res;
452   }
453 
454   // Configure streams for process block.
455   res = process_block->ConfigureStreams(process_block_stream_config,
456                                         stream_config);
457   if (res != OK) {
458     ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
459     return res;
460   }
461 
462   for (auto& hal_stream : *hal_config_) {
463     if (hal_stream.id == additional_stream_id) {
464       // Set the producer usage so that the buffer will be 64 byte aligned.
465       hal_stream.producer_usage |=
466           (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN);
467     }
468   }
469 
470   if (video_sw_denoise_enabled_) {
471     StreamConfiguration denoise_process_block_stream_config;
472     // Configure streams for request processor
473     res = realtime_zsl_result_request_processor_->ConfigureStreams(
474         internal_stream_manager_.get(), stream_config,
475         &denoise_process_block_stream_config);
476 
477     if (res != OK) {
478       ALOGE(
479           "%s: Configuring stream for process block "
480           "(RealtimeZslResultRequestProcessor) failed.",
481           __FUNCTION__);
482       return res;
483     }
484 
485     std::unique_ptr<ProcessBlock> denoise_processor =
486         CreateDenoiseProcessBlock();
487     // Create preview result processor. Stream ID is not set at this stage.
488     auto basic_result_processor = BasicResultProcessor::Create();
489     if (basic_result_processor == nullptr) {
490       ALOGE("%s: Creating BasicResultProcessor failed.", __FUNCTION__);
491       return UNKNOWN_ERROR;
492     }
493     basic_result_processor_ = basic_result_processor.get();
494     basic_result_processor->SetResultCallback(
495         process_capture_result, notify,
496         /*process_batch_capture_result=*/nullptr);
497 
498     res =
499         denoise_processor->SetResultProcessor(std::move(basic_result_processor));
500     if (res != OK) {
501       ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
502       return res;
503     }
504 
505     // Configure streams for process block.
506     res = denoise_processor->ConfigureStreams(
507         denoise_process_block_stream_config, stream_config);
508     if (res != OK) {
509       ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
510       return res;
511     }
512 
513     res = realtime_zsl_result_request_processor_->SetProcessBlock(
514         std::move(denoise_processor));
515     if (res != OK) {
516       ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
517             __FUNCTION__, strerror(-res), res);
518       return res;
519     }
520   }
521 
522   return OK;
523 }
524 
ConfigureSnapshotStreams(const StreamConfiguration & stream_config)525 status_t ZslSnapshotCaptureSession::ConfigureSnapshotStreams(
526     const StreamConfiguration& stream_config) {
527   ATRACE_CALL();
528   if (snapshot_process_block_ == nullptr ||
529       snapshot_request_processor_ == nullptr) {
530     ALOGE(
531         "%s: snapshot_process_block_ or snapshot_request_processor_ is nullptr",
532         __FUNCTION__);
533     return BAD_VALUE;
534   }
535 
536   StreamConfiguration process_block_stream_config;
537   // Configure streams for request processor
538   status_t res = snapshot_request_processor_->ConfigureStreams(
539       internal_stream_manager_.get(), stream_config,
540       &process_block_stream_config);
541   if (res != OK) {
542     ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
543     return res;
544   }
545 
546   // Configure streams for snapshot process block.
547   res = snapshot_process_block_->ConfigureStreams(process_block_stream_config,
548                                                   stream_config);
549   if (res != OK) {
550     ALOGE("%s: Configuring snapshot stream for process block failed.",
551           __FUNCTION__);
552     return res;
553   }
554 
555   return OK;
556 }
557 
SetupSnapshotProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)558 status_t ZslSnapshotCaptureSession::SetupSnapshotProcessChain(
559     const StreamConfiguration& stream_config,
560     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
561   ATRACE_CALL();
562   if (snapshot_process_block_ != nullptr ||
563       snapshot_result_processor_ != nullptr ||
564       snapshot_request_processor_ != nullptr) {
565     ALOGE(
566         "%s: snapshot_process_block_(%p) or snapshot_result_processor_(%p) or "
567         "snapshot_request_processor_(%p) is/are "
568         "already set",
569         __FUNCTION__, snapshot_process_block_, snapshot_result_processor_,
570         snapshot_request_processor_.get());
571     return BAD_VALUE;
572   }
573 
574   std::unique_ptr<ProcessBlock> snapshot_process_block =
575       CreateSnapshotProcessBlock();
576   if (snapshot_process_block == nullptr) {
577     ALOGE("%s: Creating SnapshotProcessBlock failed.", __FUNCTION__);
578     return UNKNOWN_ERROR;
579   }
580   snapshot_process_block_ = snapshot_process_block.get();
581 
582   snapshot_request_processor_ = SnapshotRequestProcessor::Create(
583       camera_device_session_hwl_, hwl_session_callback_, additional_stream_id_);
584   if (snapshot_request_processor_ == nullptr) {
585     ALOGE("%s: Creating SnapshotRequestProcessor failed.", __FUNCTION__);
586     return UNKNOWN_ERROR;
587   }
588 
589   std::unique_ptr<SnapshotResultProcessor> snapshot_result_processor =
590       SnapshotResultProcessor::Create(internal_stream_manager_.get(),
591                                       additional_stream_id_);
592   if (snapshot_result_processor == nullptr) {
593     ALOGE("%s: Creating SnapshotResultProcessor failed.", __FUNCTION__);
594     return UNKNOWN_ERROR;
595   }
596   snapshot_result_processor_ = snapshot_result_processor.get();
597 
598   status_t res = snapshot_request_processor_->SetProcessBlock(
599       std::move(snapshot_process_block));
600   if (res != OK) {
601     ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
602           __FUNCTION__, strerror(-res), res);
603     return res;
604   }
605 
606   res = snapshot_process_block_->SetResultProcessor(
607       std::move(snapshot_result_processor));
608 
609   snapshot_result_processor_->SetResultCallback(
610       process_capture_result, notify, /*process_batch_capture_result=*/nullptr);
611   res = ConfigureSnapshotStreams(stream_config);
612   if (res != OK) {
613     ALOGE("%s: Configuring snapshot stream failed: %s(%d)", __FUNCTION__,
614           strerror(-res), res);
615     return res;
616   }
617   return OK;
618 }
619 
SetupRealtimeProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)620 status_t ZslSnapshotCaptureSession::SetupRealtimeProcessChain(
621     const StreamConfiguration& stream_config,
622     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
623   ATRACE_CALL();
624   if (realtime_process_block_ != nullptr ||
625       realtime_request_processor_ != nullptr) {
626     ALOGE(
627         "%s: realtime_process_block_(%p) or realtime_request_processor_(%p) "
628         "is/are already set",
629         __FUNCTION__, realtime_process_block_,
630         realtime_request_processor_.get());
631     return BAD_VALUE;
632   }
633 
634   // Create process block
635   auto realtime_process_block = CaptureSessionWrapperProcessBlock::Create(
636       external_capture_session_entries_, capture_session_entries_,
637       hwl_session_callback_, camera_buffer_allocator_hwl_,
638       camera_device_session_hwl_, hal_config_);
639   if (realtime_process_block == nullptr) {
640     ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
641     return UNKNOWN_ERROR;
642   }
643   realtime_process_block_ = realtime_process_block.get();
644 
645   // Create realtime request processor.
646   realtime_request_processor_ = RealtimeZslRequestProcessor::Create(
647       camera_device_session_hwl_, HAL_PIXEL_FORMAT_YCBCR_420_888);
648   if (realtime_request_processor_ == nullptr) {
649     ALOGE("%s: Creating RealtimeZslRequestProcessor failed.", __FUNCTION__);
650     return UNKNOWN_ERROR;
651   }
652 
653   // realtime result processor will be created inside ConfigureStreams when the
654   // additional stream id is determined.
655 
656   status_t res = realtime_request_processor_->SetProcessBlock(
657       std::move(realtime_process_block));
658   if (res != OK) {
659     ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
660           __FUNCTION__, strerror(-res), res);
661     return res;
662   }
663 
664   res = ConfigureStreams(stream_config, realtime_request_processor_.get(),
665                          realtime_process_block_, process_capture_result,
666                          notify, additional_stream_id_);
667   if (res != OK) {
668     ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
669           res);
670     return res;
671   }
672   return OK;
673 }
674 
PurgeHalConfiguredStream(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_configured_streams)675 status_t ZslSnapshotCaptureSession::PurgeHalConfiguredStream(
676     const StreamConfiguration& stream_config,
677     std::vector<HalStream>* hal_configured_streams) {
678   if (hal_configured_streams == nullptr) {
679     ALOGE("%s: HAL configured stream list is null.", __FUNCTION__);
680     return BAD_VALUE;
681   }
682 
683   std::set<int32_t> framework_stream_id_set;
684   for (auto& stream : stream_config.streams) {
685     framework_stream_id_set.insert(stream.id);
686   }
687 
688   std::vector<HalStream> configured_streams;
689   for (auto& hal_stream : *hal_configured_streams) {
690     if (framework_stream_id_set.find(hal_stream.id) !=
691         framework_stream_id_set.end()) {
692       configured_streams.push_back(hal_stream);
693     }
694   }
695   *hal_configured_streams = configured_streams;
696   return OK;
697 }
698 
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)699 ZslSnapshotCaptureSession::ZslSnapshotCaptureSession(
700     const std::vector<ExternalCaptureSessionFactory*>&
701         external_capture_session_entries,
702     const std::vector<CaptureSessionEntryFuncs>& capture_session_entries,
703     HwlSessionCallback hwl_session_callback,
704     CameraBufferAllocatorHwl* camera_buffer_allocator_hwl,
705     CameraDeviceSessionHwl* camera_device_session_hwl)
706     : external_capture_session_entries_(external_capture_session_entries),
707       capture_session_entries_(capture_session_entries),
708       hwl_session_callback_(hwl_session_callback),
709       camera_buffer_allocator_hwl_(camera_buffer_allocator_hwl),
710       camera_device_session_hwl_(camera_device_session_hwl) {
711 }
712 
Initialize(CameraDeviceSessionHwl * camera_device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)713 status_t ZslSnapshotCaptureSession::Initialize(
714     CameraDeviceSessionHwl* camera_device_session_hwl,
715     const StreamConfiguration& stream_config,
716     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
717     std::vector<HalStream>* hal_configured_streams) {
718   ATRACE_CALL();
719   if (!IsStreamConfigurationSupported(camera_device_session_hwl, stream_config)) {
720     ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
721     return BAD_VALUE;
722   }
723 
724   std::unique_ptr<HalCameraMetadata> characteristics;
725   status_t res =
726       camera_device_session_hwl->GetCameraCharacteristics(&characteristics);
727   if (res != OK) {
728     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
729     return BAD_VALUE;
730   }
731 
732   camera_metadata_ro_entry video_sw_denoise_entry;
733   res = characteristics->Get(VendorTagIds::kVideoSwDenoiseEnabled,
734                              &video_sw_denoise_entry);
735   if (res == OK && video_sw_denoise_entry.data.u8[0] == 1) {
736     video_sw_denoise_enabled_ = true;
737     ALOGI("%s: video sw denoise is enabled.", __FUNCTION__);
738   } else {
739     ALOGI("%s: video sw denoise is disabled.", __FUNCTION__);
740   }
741 
742   for (auto stream : stream_config.streams) {
743     if (utils::IsPreviewStream(stream)) {
744       hal_preview_stream_id_ = stream.id;
745       break;
746     }
747   }
748   camera_device_session_hwl_ = camera_device_session_hwl;
749   hal_config_ = hal_configured_streams;
750 
751   // Create result dispatcher
752   partial_result_count_ = kPartialResult;
753   camera_metadata_ro_entry partial_result_entry;
754   res = characteristics->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
755                              &partial_result_entry);
756   if (res == OK) {
757     partial_result_count_ = partial_result_entry.data.i32[0];
758   }
759   result_dispatcher_ = ZslResultDispatcher::Create(
760       partial_result_count_, process_capture_result, notify, stream_config);
761   if (result_dispatcher_ == nullptr) {
762     ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
763     return UNKNOWN_ERROR;
764   }
765 
766   internal_stream_manager_ = InternalStreamManager::Create(
767       /*buffer_allocator=*/nullptr, partial_result_count_);
768   if (internal_stream_manager_ == nullptr) {
769     ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
770     return UNKNOWN_ERROR;
771   }
772 
773   device_session_notify_ = notify;
774   process_capture_result_ =
775       ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
776         ProcessCaptureResult(std::move(result));
777       });
778   notify_ = NotifyFunc(
779       [this](const NotifyMessage& message) { NotifyHalMessage(message); });
780 
781   // Setup and connect realtime process chain
782   res = SetupRealtimeProcessChain(stream_config, process_capture_result_,
783                                   notify_);
784   if (res != OK) {
785     ALOGE("%s: SetupRealtimeProcessChain fail: %s(%d)", __FUNCTION__,
786           strerror(-res), res);
787     return res;
788   }
789 
790   // Setup snapshot process chain
791   res = SetupSnapshotProcessChain(stream_config, process_capture_result_,
792                                   notify_);
793   if (res != OK) {
794     ALOGE("%s: SetupSnapshotProcessChain fail: %s(%d)", __FUNCTION__,
795           strerror(-res), res);
796     return res;
797   }
798 
799   // Realtime and snapshot streams are configured
800   // Start to build pipleline
801   res = BuildPipelines(realtime_process_block_, snapshot_process_block_,
802                        hal_configured_streams);
803   if (res != OK) {
804     ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
805           res);
806     return res;
807   }
808 
809   res = PurgeHalConfiguredStream(stream_config, hal_configured_streams);
810   if (res != OK) {
811     ALOGE("%s: Removing internal streams from configured stream failed: %s(%d)",
812           __FUNCTION__, strerror(-res), res);
813     return res;
814   }
815 
816   if (res != OK) {
817     ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
818           strerror(-res), res);
819     return res;
820   }
821 
822   return OK;
823 }
824 
ProcessRequest(const CaptureRequest & request)825 status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
826   ATRACE_CALL();
827   bool is_zsl_request = false;
828   bool is_preview_intent = false;
829   camera_metadata_ro_entry entry;
830   if (request.settings != nullptr) {
831     if (request.settings->Get(ANDROID_CONTROL_ENABLE_ZSL, &entry) == OK &&
832         *entry.data.u8 == ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
833       is_zsl_request = true;
834     }
835     if (request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) == OK &&
836         *entry.data.u8 == ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW) {
837       is_preview_intent = true;
838     }
839   }
840   status_t res = result_dispatcher_->AddPendingRequest(request, is_zsl_request);
841   if (res != OK) {
842     ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
843           request.frame_number);
844     return BAD_VALUE;
845   }
846   if (IsSwDenoiseSnapshotCompatible(request)) {
847     res = snapshot_request_processor_->ProcessRequest(request);
848     if (res != OK) {
849       ALOGW(
850           "%s: frame (%d) fall back to real time request for snapshot: %s (%d)",
851           __FUNCTION__, request.frame_number, strerror(-res), res);
852       if (realtime_zsl_result_request_processor_ != nullptr) {
853         realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
854             request.frame_number, request.output_buffers.size(),
855             is_preview_intent);
856       }
857       res = realtime_request_processor_->ProcessRequest(request);
858     }
859   } else {
860     if (realtime_zsl_result_request_processor_ != nullptr) {
861       realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
862           request.frame_number, request.output_buffers.size(),
863           is_preview_intent);
864     }
865 
866     res = realtime_request_processor_->ProcessRequest(request);
867   }
868 
869   if (res != OK) {
870     ALOGE("%s: ProcessRequest (%d) fail and remove pending request",
871           __FUNCTION__, request.frame_number);
872     result_dispatcher_->RemovePendingRequest(request.frame_number);
873   }
874   return res;
875 }
876 
Flush()877 status_t ZslSnapshotCaptureSession::Flush() {
878   ATRACE_CALL();
879   return realtime_request_processor_->Flush();
880 }
881 
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)882 void ZslSnapshotCaptureSession::ProcessCaptureResult(
883     std::unique_ptr<CaptureResult> result) {
884   ATRACE_CALL();
885   std::lock_guard<std::mutex> lock(callback_lock_);
886   if (result == nullptr) {
887     return;
888   }
889 
890   if (result->result_metadata) {
891     camera_device_session_hwl_->FilterResultMetadata(
892         result->result_metadata.get());
893   }
894 
895   status_t res = result_dispatcher_->AddResult(std::move(result));
896   if (res != OK) {
897     ALOGE("%s: fail to AddResult", __FUNCTION__);
898     return;
899   }
900 }
901 
NotifyHalMessage(const NotifyMessage & message)902 void ZslSnapshotCaptureSession::NotifyHalMessage(const NotifyMessage& message) {
903   ATRACE_CALL();
904   std::lock_guard<std::mutex> lock(callback_lock_);
905   if (device_session_notify_ == nullptr) {
906     ALOGE("%s: device_session_notify_ is nullptr. Dropping a message.",
907           __FUNCTION__);
908     return;
909   }
910 
911   if (message.type == MessageType::kShutter) {
912     status_t res = result_dispatcher_->AddShutter(
913         message.message.shutter.frame_number,
914         message.message.shutter.timestamp_ns,
915         message.message.shutter.readout_timestamp_ns);
916     if (res != OK) {
917       ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
918             message.message.shutter.frame_number, strerror(-res), res);
919       return;
920     }
921   } else if (message.type == MessageType::kError) {
922     status_t res = result_dispatcher_->AddError(message.message.error);
923     if (res != OK) {
924       ALOGE("%s: AddError for frame %u failed: %s (%d).", __FUNCTION__,
925             message.message.error.frame_number, strerror(-res), res);
926       return;
927     }
928   } else {
929     ALOGW("%s: Unsupported message type: %u", __FUNCTION__, message.type);
930     device_session_notify_(message);
931   }
932 }
933 
934 }  // namespace google_camera_hal
935 }  // namespace android
936