• 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 "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_jpeg_stream = false;
167   bool has_preview_stream = false;
168   bool has_yuv_stream = false;
169   for (const auto& stream : stream_config.streams) {
170     if (stream.is_physical_camera_stream) {
171       ALOGE("%s: support logical camera only", __FUNCTION__);
172       return false;
173     }
174     if (utils::IsJPEGSnapshotStream(stream)) {
175       has_jpeg_stream = true;
176     } else if (utils::IsPreviewStream(stream)) {
177       has_preview_stream = true;
178     } else if (utils::IsYUVSnapshotStream(stream)) {
179       has_yuv_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_jpeg_stream && !has_yuv_stream) {
187     ALOGE("%s: no 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   if (camera_device_session_hwl_ != nullptr) {
235     camera_device_session_hwl_->DestroyPipelines();
236   }
237   // Need to explicitly release SnapshotProcessBlock by releasing
238   // SnapshotRequestProcessor before the lib handle is released.
239   snapshot_request_processor_ = nullptr;
240   dlclose(snapshot_process_block_lib_handle_);
241 }
242 
BuildPipelines(ProcessBlock * process_block,ProcessBlock * snapshot_process_block,std::vector<HalStream> * hal_configured_streams)243 status_t ZslSnapshotCaptureSession::BuildPipelines(
244     ProcessBlock* process_block, ProcessBlock* snapshot_process_block,
245     std::vector<HalStream>* hal_configured_streams) {
246   ATRACE_CALL();
247   if (process_block == nullptr || hal_configured_streams == nullptr ||
248       snapshot_process_block == nullptr) {
249     ALOGE(
250         "%s: process_block (%p) or hal_configured_streams (%p) or "
251         "snapshot_process_block (%p) is nullptr",
252         __FUNCTION__, process_block, hal_configured_streams,
253         snapshot_process_block);
254     return BAD_VALUE;
255   }
256 
257   status_t res;
258 
259   std::vector<HalStream> snapshot_hal_configured_streams;
260   res = snapshot_process_block->GetConfiguredHalStreams(
261       &snapshot_hal_configured_streams);
262   if (res != OK) {
263     ALOGE("%s: Getting snapshot HAL streams failed: %s(%d)", __FUNCTION__,
264           strerror(-res), res);
265     return res;
266   }
267 
268   for (uint32_t i = 0; i < hal_configured_streams->size(); i++) {
269     if (hal_configured_streams->at(i).id == additional_stream_id_) {
270       // Reserve additional buffer(s).
271       hal_configured_streams->at(i).max_buffers += kAdditionalBufferNumber;
272       // Allocate internal YUV stream buffers
273       res = internal_stream_manager_->AllocateBuffers(
274           hal_configured_streams->at(i),
275           /*additional_num_buffers=*/kAdditionalBufferNumber);
276       if (res != OK) {
277         ALOGE("%s: AllocateBuffers failed.", __FUNCTION__);
278         return UNKNOWN_ERROR;
279       }
280       break;
281     }
282   }
283 
284   return OK;
285 }
286 
ConfigureStreams(const StreamConfiguration & stream_config,RequestProcessor * request_processor,ProcessBlock * process_block,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,int32_t & additional_stream_id)287 status_t ZslSnapshotCaptureSession::ConfigureStreams(
288     const StreamConfiguration& stream_config,
289     RequestProcessor* request_processor, ProcessBlock* process_block,
290     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
291     int32_t& additional_stream_id) {
292   ATRACE_CALL();
293   if (request_processor == nullptr || process_block == nullptr) {
294     ALOGE("%s: request_processor (%p) or process_block (%p) is nullptr",
295           __FUNCTION__, request_processor, process_block);
296     return BAD_VALUE;
297   }
298   StreamConfiguration process_block_stream_config;
299   // Configure streams for request processor
300   status_t res = request_processor->ConfigureStreams(
301       internal_stream_manager_.get(), stream_config,
302       &process_block_stream_config);
303   if (res != OK) {
304     ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
305     return res;
306   }
307 
308   // Check all streams are configured.
309   if (stream_config.streams.size() > process_block_stream_config.streams.size()) {
310     ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
311           __FUNCTION__, stream_config.streams.size(),
312           process_block_stream_config.streams.size());
313     return UNKNOWN_ERROR;
314   }
315   for (auto& stream : stream_config.streams) {
316     bool found = false;
317     for (auto& configured_stream : process_block_stream_config.streams) {
318       if (stream.id == configured_stream.id) {
319         found = true;
320         break;
321       }
322     }
323 
324     if (!found) {
325       ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
326             stream.id);
327       return UNKNOWN_ERROR;
328     }
329   }
330 
331   for (auto& stream : process_block_stream_config.streams) {
332     bool found = false;
333     for (auto& configured_stream : stream_config.streams) {
334       if (stream.id == configured_stream.id) {
335         found = true;
336         break;
337       }
338     }
339     if (!found) {
340       additional_stream_id = stream.id;
341       break;
342     }
343   }
344 
345   if (additional_stream_id == -1) {
346     ALOGE("%s: Configuring stream fail due to wrong additional_stream_id",
347           __FUNCTION__);
348     return UNKNOWN_ERROR;
349   }
350 
351   // Create preview result processor. Stream ID is not set at this stage.
352   auto realtime_result_processor = RealtimeZslResultProcessor::Create(
353       internal_stream_manager_.get(), additional_stream_id,
354       HAL_PIXEL_FORMAT_YCBCR_420_888, partial_result_count_);
355   if (realtime_result_processor == nullptr) {
356     ALOGE("%s: Creating RealtimeZslResultProcessor failed.", __FUNCTION__);
357     return UNKNOWN_ERROR;
358   }
359   realtime_result_processor_ = realtime_result_processor.get();
360   realtime_result_processor->SetResultCallback(process_capture_result, notify);
361 
362   res = process_block->SetResultProcessor(std::move(realtime_result_processor));
363   if (res != OK) {
364     ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
365     return res;
366   }
367 
368   // Configure streams for process block.
369   res = process_block->ConfigureStreams(process_block_stream_config,
370                                         stream_config);
371   if (res != OK) {
372     ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
373     return res;
374   }
375 
376   for (auto& hal_stream : *hal_config_) {
377     if (hal_stream.id == additional_stream_id) {
378       // Set the producer usage so that the buffer will be 64 byte aligned.
379       hal_stream.producer_usage |=
380           (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN);
381     }
382   }
383 
384   return OK;
385 }
386 
ConfigureSnapshotStreams(const StreamConfiguration & stream_config)387 status_t ZslSnapshotCaptureSession::ConfigureSnapshotStreams(
388     const StreamConfiguration& stream_config) {
389   ATRACE_CALL();
390   if (snapshot_process_block_ == nullptr ||
391       snapshot_request_processor_ == nullptr) {
392     ALOGE(
393         "%s: snapshot_process_block_ or snapshot_request_processor_ is nullptr",
394         __FUNCTION__);
395     return BAD_VALUE;
396   }
397 
398   StreamConfiguration process_block_stream_config;
399   // Configure streams for request processor
400   status_t res = snapshot_request_processor_->ConfigureStreams(
401       internal_stream_manager_.get(), stream_config,
402       &process_block_stream_config);
403   if (res != OK) {
404     ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
405     return res;
406   }
407 
408   // Configure streams for snapshot process block.
409   res = snapshot_process_block_->ConfigureStreams(process_block_stream_config,
410                                                   stream_config);
411   if (res != OK) {
412     ALOGE("%s: Configuring snapshot stream for process block failed.",
413           __FUNCTION__);
414     return res;
415   }
416 
417   return OK;
418 }
419 
SetupSnapshotProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)420 status_t ZslSnapshotCaptureSession::SetupSnapshotProcessChain(
421     const StreamConfiguration& stream_config,
422     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
423   ATRACE_CALL();
424   if (snapshot_process_block_ != nullptr ||
425       snapshot_result_processor_ != nullptr ||
426       snapshot_request_processor_ != nullptr) {
427     ALOGE(
428         "%s: snapshot_process_block_(%p) or snapshot_result_processor_(%p) or "
429         "snapshot_request_processor_(%p) is/are "
430         "already set",
431         __FUNCTION__, snapshot_process_block_, snapshot_result_processor_,
432         snapshot_request_processor_.get());
433     return BAD_VALUE;
434   }
435 
436   std::unique_ptr<ProcessBlock> snapshot_process_block =
437       CreateSnapshotProcessBlock();
438   if (snapshot_process_block == nullptr) {
439     ALOGE("%s: Creating SnapshotProcessBlock failed.", __FUNCTION__);
440     return UNKNOWN_ERROR;
441   }
442   snapshot_process_block_ = snapshot_process_block.get();
443 
444   snapshot_request_processor_ = SnapshotRequestProcessor::Create(
445       camera_device_session_hwl_, hwl_session_callback_, additional_stream_id_);
446   if (snapshot_request_processor_ == nullptr) {
447     ALOGE("%s: Creating SnapshotRequestProcessor failed.", __FUNCTION__);
448     return UNKNOWN_ERROR;
449   }
450 
451   std::unique_ptr<SnapshotResultProcessor> snapshot_result_processor =
452       SnapshotResultProcessor::Create(internal_stream_manager_.get(),
453                                       additional_stream_id_);
454   if (snapshot_result_processor == nullptr) {
455     ALOGE("%s: Creating SnapshotResultProcessor failed.", __FUNCTION__);
456     return UNKNOWN_ERROR;
457   }
458   snapshot_result_processor_ = snapshot_result_processor.get();
459 
460   status_t res = snapshot_request_processor_->SetProcessBlock(
461       std::move(snapshot_process_block));
462   if (res != OK) {
463     ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
464           __FUNCTION__, strerror(-res), res);
465     return res;
466   }
467 
468   res = snapshot_process_block_->SetResultProcessor(
469       std::move(snapshot_result_processor));
470 
471   snapshot_result_processor_->SetResultCallback(process_capture_result, notify);
472   res = ConfigureSnapshotStreams(stream_config);
473   if (res != OK) {
474     ALOGE("%s: Configuring snapshot stream failed: %s(%d)", __FUNCTION__,
475           strerror(-res), res);
476     return res;
477   }
478   return OK;
479 }
480 
SetupRealtimeProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)481 status_t ZslSnapshotCaptureSession::SetupRealtimeProcessChain(
482     const StreamConfiguration& stream_config,
483     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
484   ATRACE_CALL();
485   if (realtime_process_block_ != nullptr ||
486       realtime_result_processor_ != nullptr ||
487       realtime_request_processor_ != nullptr) {
488     ALOGE(
489         "%s: realtime_process_block_(%p) or realtime_result_processor_(%p) or "
490         "realtime_request_processor_(%p) is/are "
491         "already set",
492         __FUNCTION__, realtime_process_block_, realtime_result_processor_,
493         realtime_request_processor_.get());
494     return BAD_VALUE;
495   }
496 
497   // Create process block
498   auto realtime_process_block = CaptureSessionWrapperProcessBlock::Create(
499       external_capture_session_entries_, capture_session_entries_,
500       hwl_session_callback_, camera_buffer_allocator_hwl_,
501       camera_device_session_hwl_, hal_config_);
502   if (realtime_process_block == nullptr) {
503     ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
504     return UNKNOWN_ERROR;
505   }
506   realtime_process_block_ = realtime_process_block.get();
507 
508   // Create realtime request processor.
509   realtime_request_processor_ = RealtimeZslRequestProcessor::Create(
510       camera_device_session_hwl_, HAL_PIXEL_FORMAT_YCBCR_420_888);
511   if (realtime_request_processor_ == nullptr) {
512     ALOGE("%s: Creating RealtimeZslRequestProcessor failed.", __FUNCTION__);
513     return UNKNOWN_ERROR;
514   }
515 
516   // realtime result processor will be created inside ConfigureStreams when the
517   // additional stream id is determined.
518 
519   status_t res = realtime_request_processor_->SetProcessBlock(
520       std::move(realtime_process_block));
521   if (res != OK) {
522     ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
523           __FUNCTION__, strerror(-res), res);
524     return res;
525   }
526 
527   res = ConfigureStreams(stream_config, realtime_request_processor_.get(),
528                          realtime_process_block_, process_capture_result,
529                          notify, additional_stream_id_);
530   if (res != OK) {
531     ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
532           res);
533     return res;
534   }
535   return OK;
536 }
537 
PurgeHalConfiguredStream(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_configured_streams)538 status_t ZslSnapshotCaptureSession::PurgeHalConfiguredStream(
539     const StreamConfiguration& stream_config,
540     std::vector<HalStream>* hal_configured_streams) {
541   if (hal_configured_streams == nullptr) {
542     ALOGE("%s: HAL configured stream list is null.", __FUNCTION__);
543     return BAD_VALUE;
544   }
545 
546   std::set<int32_t> framework_stream_id_set;
547   for (auto& stream : stream_config.streams) {
548     framework_stream_id_set.insert(stream.id);
549   }
550 
551   std::vector<HalStream> configured_streams;
552   for (auto& hal_stream : *hal_configured_streams) {
553     if (framework_stream_id_set.find(hal_stream.id) !=
554         framework_stream_id_set.end()) {
555       configured_streams.push_back(hal_stream);
556     }
557   }
558   *hal_configured_streams = configured_streams;
559   return OK;
560 }
561 
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)562 ZslSnapshotCaptureSession::ZslSnapshotCaptureSession(
563     const std::vector<ExternalCaptureSessionFactory*>&
564         external_capture_session_entries,
565     const std::vector<CaptureSessionEntryFuncs>& capture_session_entries,
566     HwlSessionCallback hwl_session_callback,
567     CameraBufferAllocatorHwl* camera_buffer_allocator_hwl,
568     CameraDeviceSessionHwl* camera_device_session_hwl)
569     : external_capture_session_entries_(external_capture_session_entries),
570       capture_session_entries_(capture_session_entries),
571       hwl_session_callback_(hwl_session_callback),
572       camera_buffer_allocator_hwl_(camera_buffer_allocator_hwl),
573       camera_device_session_hwl_(camera_device_session_hwl) {
574 }
575 
Initialize(CameraDeviceSessionHwl * camera_device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)576 status_t ZslSnapshotCaptureSession::Initialize(
577     CameraDeviceSessionHwl* camera_device_session_hwl,
578     const StreamConfiguration& stream_config,
579     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
580     std::vector<HalStream>* hal_configured_streams) {
581   ATRACE_CALL();
582   if (!IsStreamConfigurationSupported(camera_device_session_hwl, stream_config)) {
583     ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
584     return BAD_VALUE;
585   }
586 
587   std::unique_ptr<HalCameraMetadata> characteristics;
588   status_t res =
589       camera_device_session_hwl->GetCameraCharacteristics(&characteristics);
590   if (res != OK) {
591     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
592     return BAD_VALUE;
593   }
594 
595   for (auto stream : stream_config.streams) {
596     if (utils::IsPreviewStream(stream)) {
597       hal_preview_stream_id_ = stream.id;
598       break;
599     }
600   }
601   camera_device_session_hwl_ = camera_device_session_hwl;
602   hal_config_ = hal_configured_streams;
603 
604   // Create result dispatcher
605   partial_result_count_ = kPartialResult;
606   camera_metadata_ro_entry partial_result_entry;
607   res = characteristics->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
608                              &partial_result_entry);
609   if (res == OK) {
610     partial_result_count_ = partial_result_entry.data.i32[0];
611   }
612   result_dispatcher_ = ResultDispatcher::Create(partial_result_count_,
613                                                 process_capture_result, notify);
614   if (result_dispatcher_ == nullptr) {
615     ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
616     return UNKNOWN_ERROR;
617   }
618 
619   internal_stream_manager_ = InternalStreamManager::Create(
620       /*buffer_allocator=*/nullptr, partial_result_count_);
621   if (internal_stream_manager_ == nullptr) {
622     ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
623     return UNKNOWN_ERROR;
624   }
625 
626   device_session_notify_ = notify;
627   process_capture_result_ =
628       ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
629         ProcessCaptureResult(std::move(result));
630       });
631   notify_ = NotifyFunc(
632       [this](const NotifyMessage& message) { NotifyHalMessage(message); });
633 
634   // Setup and connect realtime process chain
635   res = SetupRealtimeProcessChain(stream_config, process_capture_result_,
636                                   notify_);
637   if (res != OK) {
638     ALOGE("%s: SetupRealtimeProcessChain fail: %s(%d)", __FUNCTION__,
639           strerror(-res), res);
640     return res;
641   }
642 
643   // Setup snapshot process chain
644   res = SetupSnapshotProcessChain(stream_config, process_capture_result_,
645                                   notify_);
646   if (res != OK) {
647     ALOGE("%s: SetupSnapshotProcessChain fail: %s(%d)", __FUNCTION__,
648           strerror(-res), res);
649     return res;
650   }
651 
652   // Realtime and snapshot streams are configured
653   // Start to build pipleline
654   res = BuildPipelines(realtime_process_block_, snapshot_process_block_,
655                        hal_configured_streams);
656   if (res != OK) {
657     ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
658           res);
659     return res;
660   }
661 
662   res = PurgeHalConfiguredStream(stream_config, hal_configured_streams);
663   if (res != OK) {
664     ALOGE("%s: Removing internal streams from configured stream failed: %s(%d)",
665           __FUNCTION__, strerror(-res), res);
666     return res;
667   }
668 
669   if (res != OK) {
670     ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
671           strerror(-res), res);
672     return res;
673   }
674 
675   return OK;
676 }
677 
ProcessRequest(const CaptureRequest & request)678 status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
679   ATRACE_CALL();
680   status_t res = result_dispatcher_->AddPendingRequest(request);
681   if (res != OK) {
682     ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
683           request.frame_number);
684     return BAD_VALUE;
685   }
686   if (IsSwDenoiseSnapshotCompatible(request)) {
687     res = snapshot_request_processor_->ProcessRequest(request);
688     if (res != OK) {
689       ALOGW(
690           "%s: frame (%d) fall back to real time request for snapshot: %s (%d)",
691           __FUNCTION__, request.frame_number, strerror(-res), res);
692       res = realtime_request_processor_->ProcessRequest(request);
693     }
694   } else {
695     res = realtime_request_processor_->ProcessRequest(request);
696   }
697 
698   if (res != OK) {
699     ALOGE("%s: ProcessRequest (%d) fail and remove pending request",
700           __FUNCTION__, request.frame_number);
701     result_dispatcher_->RemovePendingRequest(request.frame_number);
702   }
703   return res;
704 }
705 
Flush()706 status_t ZslSnapshotCaptureSession::Flush() {
707   ATRACE_CALL();
708   return realtime_request_processor_->Flush();
709 }
710 
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)711 void ZslSnapshotCaptureSession::ProcessCaptureResult(
712     std::unique_ptr<CaptureResult> result) {
713   ATRACE_CALL();
714   std::lock_guard<std::mutex> lock(callback_lock_);
715   if (result == nullptr) {
716     return;
717   }
718 
719   if (result->result_metadata) {
720     camera_device_session_hwl_->FilterResultMetadata(
721         result->result_metadata.get());
722   }
723 
724   status_t res = result_dispatcher_->AddResult(std::move(result));
725   if (res != OK) {
726     ALOGE("%s: fail to AddResult", __FUNCTION__);
727     return;
728   }
729 }
730 
NotifyHalMessage(const NotifyMessage & message)731 void ZslSnapshotCaptureSession::NotifyHalMessage(const NotifyMessage& message) {
732   ATRACE_CALL();
733   std::lock_guard<std::mutex> lock(callback_lock_);
734   if (device_session_notify_ == nullptr) {
735     ALOGE("%s: device_session_notify_ is nullptr. Dropping a message.",
736           __FUNCTION__);
737     return;
738   }
739 
740   if (message.type == MessageType::kShutter) {
741     status_t res =
742         result_dispatcher_->AddShutter(message.message.shutter.frame_number,
743                                        message.message.shutter.timestamp_ns);
744     if (res != OK) {
745       ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
746             message.message.shutter.frame_number, strerror(-res), res);
747       return;
748     }
749   } else if (message.type == MessageType::kError) {
750     status_t res = result_dispatcher_->AddError(message.message.error);
751     if (res != OK) {
752       ALOGE("%s: AddError for frame %u failed: %s (%d).", __FUNCTION__,
753             message.message.error.frame_number, strerror(-res), res);
754       return;
755     }
756   } else {
757     ALOGW("%s: Unsupported message type: %u", __FUNCTION__, message.type);
758     device_session_notify_(message);
759   }
760 }
761 
762 }  // namespace google_camera_hal
763 }  // namespace android
764