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