1 /*
2  * Copyright (C) 2019 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 #define LOG_TAG "GCH_HdrplusCaptureSession"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "hdrplus_capture_session.h"
21 
22 #include <cutils/properties.h>
23 #include <inttypes.h>
24 #include <log/log.h>
25 #include <utils/Trace.h>
26 
27 #include <set>
28 
29 #include "hal_utils.h"
30 #include "hdrplus_process_block.h"
31 #include "hdrplus_request_processor.h"
32 #include "hdrplus_result_processor.h"
33 #include "realtime_process_block.h"
34 #include "realtime_zsl_request_processor.h"
35 #include "realtime_zsl_result_processor.h"
36 #include "vendor_tag_defs.h"
37 
38 namespace android {
39 namespace google_camera_hal {
IsStreamConfigurationSupported(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config)40 bool HdrplusCaptureSession::IsStreamConfigurationSupported(
41     CameraDeviceSessionHwl* device_session_hwl,
42     const StreamConfiguration& stream_config) {
43   ATRACE_CALL();
44   if (device_session_hwl == nullptr) {
45     ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
46     return false;
47   }
48 
49   uint32_t num_physical_cameras =
50       device_session_hwl->GetPhysicalCameraIds().size();
51   if (num_physical_cameras > 1) {
52     ALOGD("%s: HdrplusCaptureSession doesn't support %u physical cameras",
53           __FUNCTION__, num_physical_cameras);
54     return false;
55   }
56 
57   std::unique_ptr<HalCameraMetadata> characteristics;
58   status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
59   if (res != OK) {
60     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
61     return BAD_VALUE;
62   }
63 
64   if (hal_utils::IsStreamHdrplusCompatible(stream_config,
65                                            characteristics.get()) == false) {
66     return false;
67   }
68 
69   if (!hal_utils::IsBayerCamera(characteristics.get())) {
70     ALOGD("%s: camera %d is not a bayer camera", __FUNCTION__,
71           device_session_hwl->GetCameraId());
72     return false;
73   }
74 
75   ALOGI("%s: HDR+ is enabled", __FUNCTION__);
76   ALOGD("%s: HdrplusCaptureSession supports the stream config", __FUNCTION__);
77   return true;
78 }
79 
Create(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,ProcessBatchCaptureResultFunc,NotifyFunc notify,HwlSessionCallback,std::vector<HalStream> * hal_configured_streams,CameraBufferAllocatorHwl *)80 std::unique_ptr<HdrplusCaptureSession> HdrplusCaptureSession::Create(
81     CameraDeviceSessionHwl* device_session_hwl,
82     const StreamConfiguration& stream_config,
83     ProcessCaptureResultFunc process_capture_result,
84     ProcessBatchCaptureResultFunc /*process_batch_capture_result*/,
85     NotifyFunc notify, HwlSessionCallback /*session_callback*/,
86     std::vector<HalStream>* hal_configured_streams,
87     CameraBufferAllocatorHwl* /*camera_allocator_hwl*/) {
88   ATRACE_CALL();
89   auto session =
90       std::unique_ptr<HdrplusCaptureSession>(new HdrplusCaptureSession());
91   if (session == nullptr) {
92     ALOGE("%s: Creating HdrplusCaptureSession failed.", __FUNCTION__);
93     return nullptr;
94   }
95 
96   status_t res = session->Initialize(device_session_hwl, stream_config,
97                                      process_capture_result, notify,
98                                      hal_configured_streams);
99   if (res != OK) {
100     ALOGE("%s: Initializing HdrplusCaptureSession failed: %s (%d).",
101           __FUNCTION__, strerror(-res), res);
102     return nullptr;
103   }
104 
105   return session;
106 }
107 
~HdrplusCaptureSession()108 HdrplusCaptureSession::~HdrplusCaptureSession() {
109   ATRACE_CALL();
110   if (device_session_hwl_ != nullptr) {
111     device_session_hwl_->DestroyPipelines();
112   }
113 }
114 
ConfigureStreams(const StreamConfiguration & stream_config,RequestProcessor * request_processor,ProcessBlock * process_block,int32_t * raw_stream_id)115 status_t HdrplusCaptureSession::ConfigureStreams(
116     const StreamConfiguration& stream_config,
117     RequestProcessor* request_processor, ProcessBlock* process_block,
118     int32_t* raw_stream_id) {
119   ATRACE_CALL();
120   if (request_processor == nullptr || process_block == nullptr ||
121       raw_stream_id == nullptr) {
122     ALOGE(
123         "%s: request_processor (%p) or process_block (%p) is nullptr or "
124         "raw_stream_id (%p) is nullptr",
125         __FUNCTION__, request_processor, process_block, raw_stream_id);
126     return BAD_VALUE;
127   }
128 
129   StreamConfiguration process_block_stream_config;
130   // Configure streams for request processor
131   status_t res = request_processor->ConfigureStreams(
132       internal_stream_manager_.get(), stream_config,
133       &process_block_stream_config);
134   if (res != OK) {
135     ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
136     return res;
137   }
138 
139   // Check all streams are configured.
140   if (stream_config.streams.size() > process_block_stream_config.streams.size()) {
141     ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
142           __FUNCTION__, stream_config.streams.size(),
143           process_block_stream_config.streams.size());
144     return UNKNOWN_ERROR;
145   }
146 
147   for (auto& stream : stream_config.streams) {
148     bool found = false;
149     for (auto& configured_stream : process_block_stream_config.streams) {
150       if (stream.id == configured_stream.id) {
151         found = true;
152         break;
153       }
154     }
155 
156     if (!found) {
157       ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
158             stream.id);
159       return UNKNOWN_ERROR;
160     }
161   }
162 
163   for (auto& configured_stream : process_block_stream_config.streams) {
164     if (configured_stream.format == kHdrplusRawFormat) {
165       *raw_stream_id = configured_stream.id;
166       break;
167     }
168   }
169 
170   if (*raw_stream_id == -1) {
171     ALOGE("%s: Configuring stream fail due to wrong raw_stream_id",
172           __FUNCTION__);
173     return UNKNOWN_ERROR;
174   }
175 
176   // Configure streams for process block.
177   res = process_block->ConfigureStreams(process_block_stream_config,
178                                         stream_config);
179   if (res != OK) {
180     ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
181     return res;
182   }
183 
184   return OK;
185 }
186 
ConfigureHdrplusStreams(const StreamConfiguration & stream_config,RequestProcessor * hdrplus_request_processor,ProcessBlock * hdrplus_process_block)187 status_t HdrplusCaptureSession::ConfigureHdrplusStreams(
188     const StreamConfiguration& stream_config,
189     RequestProcessor* hdrplus_request_processor,
190     ProcessBlock* hdrplus_process_block) {
191   ATRACE_CALL();
192   if (hdrplus_process_block == nullptr || hdrplus_request_processor == nullptr) {
193     ALOGE("%s: hdrplus_process_block or hdrplus_request_processor is nullptr",
194           __FUNCTION__);
195     return BAD_VALUE;
196   }
197 
198   StreamConfiguration process_block_stream_config;
199   // Configure streams for request processor
200   status_t res = hdrplus_request_processor->ConfigureStreams(
201       internal_stream_manager_.get(), stream_config,
202       &process_block_stream_config);
203   if (res != OK) {
204     ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
205     return res;
206   }
207 
208   // Check all streams are configured.
209   if (stream_config.streams.size() > process_block_stream_config.streams.size()) {
210     ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
211           __FUNCTION__, stream_config.streams.size(),
212           process_block_stream_config.streams.size());
213     return UNKNOWN_ERROR;
214   }
215 
216   for (auto& stream : stream_config.streams) {
217     bool found = false;
218     for (auto& configured_stream : process_block_stream_config.streams) {
219       if (stream.id == configured_stream.id) {
220         found = true;
221         break;
222       }
223     }
224 
225     if (!found) {
226       ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
227             stream.id);
228       return UNKNOWN_ERROR;
229     }
230   }
231 
232   // Configure streams for HDR+ process block.
233   res = hdrplus_process_block->ConfigureStreams(process_block_stream_config,
234                                                 stream_config);
235   if (res != OK) {
236     ALOGE("%s: Configuring hdrplus stream for process block failed.",
237           __FUNCTION__);
238     return res;
239   }
240 
241   return OK;
242 }
243 
BuildPipelines(ProcessBlock * process_block,ProcessBlock * hdrplus_process_block,std::vector<HalStream> * hal_configured_streams)244 status_t HdrplusCaptureSession::BuildPipelines(
245     ProcessBlock* process_block, ProcessBlock* hdrplus_process_block,
246     std::vector<HalStream>* hal_configured_streams) {
247   ATRACE_CALL();
248   if (process_block == nullptr || hal_configured_streams == nullptr) {
249     ALOGE("%s: process_block (%p) or hal_configured_streams (%p) is nullptr",
250           __FUNCTION__, process_block, hal_configured_streams);
251     return BAD_VALUE;
252   }
253 
254   status_t res = device_session_hwl_->BuildPipelines();
255   if (res != OK) {
256     ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
257           res);
258     return res;
259   }
260 
261   res = process_block->GetConfiguredHalStreams(hal_configured_streams);
262   if (res != OK) {
263     ALOGE("%s: Getting HAL streams failed: %s(%d)", __FUNCTION__,
264           strerror(-res), res);
265     return res;
266   }
267 
268   std::vector<HalStream> hdrplus_hal_configured_streams;
269   res = hdrplus_process_block->GetConfiguredHalStreams(
270       &hdrplus_hal_configured_streams);
271   if (res != OK) {
272     ALOGE("%s: Getting HDR+ HAL streams failed: %s(%d)", __FUNCTION__,
273           strerror(-res), res);
274     return res;
275   }
276 
277   // Combine realtime and HDR+ hal stream.
278   // Only usage of internal raw stream is different, so combine usage directly
279   uint64_t consumer_usage = 0;
280   for (uint32_t i = 0; i < hdrplus_hal_configured_streams.size(); i++) {
281     if (hdrplus_hal_configured_streams[i].override_format == kHdrplusRawFormat) {
282       consumer_usage = hdrplus_hal_configured_streams[i].consumer_usage;
283       break;
284     }
285   }
286 
287   for (uint32_t i = 0; i < hal_configured_streams->size(); i++) {
288     if (hal_configured_streams->at(i).override_format == kHdrplusRawFormat) {
289       hal_configured_streams->at(i).consumer_usage = consumer_usage;
290       if (hal_configured_streams->at(i).max_buffers < kRawMinBufferCount) {
291         hal_configured_streams->at(i).max_buffers = kRawMinBufferCount;
292       }
293       // Allocate internal raw stream buffers
294       uint32_t additional_num_buffers =
295           (hal_configured_streams->at(i).max_buffers >= kRawBufferCount)
296               ? 0
297               : (kRawBufferCount - hal_configured_streams->at(i).max_buffers);
298       res = internal_stream_manager_->AllocateBuffers(
299           hal_configured_streams->at(i), additional_num_buffers);
300       if (res != OK) {
301         ALOGE("%s: AllocateBuffers failed.", __FUNCTION__);
302         return UNKNOWN_ERROR;
303       }
304       break;
305     }
306   }
307 
308   return OK;
309 }
310 
ConnectProcessChain(RequestProcessor * request_processor,std::unique_ptr<ProcessBlock> process_block,std::unique_ptr<ResultProcessor> result_processor)311 status_t HdrplusCaptureSession::ConnectProcessChain(
312     RequestProcessor* request_processor,
313     std::unique_ptr<ProcessBlock> process_block,
314     std::unique_ptr<ResultProcessor> result_processor) {
315   ATRACE_CALL();
316   if (request_processor == nullptr) {
317     ALOGE("%s: request_processor is nullptr", __FUNCTION__);
318     return BAD_VALUE;
319   }
320 
321   status_t res = process_block->SetResultProcessor(std::move(result_processor));
322   if (res != OK) {
323     ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
324     return res;
325   }
326 
327   res = request_processor->SetProcessBlock(std::move(process_block));
328   if (res != OK) {
329     ALOGE(
330         "%s: Setting process block for HdrplusRequestProcessor failed: %s(%d)",
331         __FUNCTION__, strerror(-res), res);
332     return res;
333   }
334 
335   return OK;
336 }
337 
SetupRealtimeProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::unique_ptr<ProcessBlock> * realtime_process_block,std::unique_ptr<ResultProcessor> * realtime_result_processor,int32_t * raw_stream_id)338 status_t HdrplusCaptureSession::SetupRealtimeProcessChain(
339     const StreamConfiguration& stream_config,
340     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
341     std::unique_ptr<ProcessBlock>* realtime_process_block,
342     std::unique_ptr<ResultProcessor>* realtime_result_processor,
343     int32_t* raw_stream_id) {
344   ATRACE_CALL();
345   if (realtime_process_block == nullptr ||
346       realtime_result_processor == nullptr || raw_stream_id == nullptr) {
347     ALOGE(
348         "%s: realtime_process_block(%p) or realtime_result_processor(%p) or "
349         "raw_stream_id(%p) is nullptr",
350         __FUNCTION__, realtime_process_block, realtime_result_processor,
351         raw_stream_id);
352     return BAD_VALUE;
353   }
354   // Create realtime process block.
355   auto process_block = RealtimeProcessBlock::Create(device_session_hwl_);
356   if (process_block == nullptr) {
357     ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
358     return UNKNOWN_ERROR;
359   }
360 
361   // Create realtime request processor.
362   request_processor_ = RealtimeZslRequestProcessor::Create(
363       device_session_hwl_, HAL_PIXEL_FORMAT_RAW10);
364   if (request_processor_ == nullptr) {
365     ALOGE("%s: Creating RealtimeZslsRequestProcessor failed.", __FUNCTION__);
366     return UNKNOWN_ERROR;
367   }
368 
369   status_t res = ConfigureStreams(stream_config, request_processor_.get(),
370                                   process_block.get(), raw_stream_id);
371   if (res != OK) {
372     ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
373           res);
374     return res;
375   }
376 
377   // Create realtime result processor.
378   auto result_processor = RealtimeZslResultProcessor::Create(
379       internal_stream_manager_.get(), *raw_stream_id, HAL_PIXEL_FORMAT_RAW10);
380   if (result_processor == nullptr) {
381     ALOGE("%s: Creating RealtimeZslResultProcessor failed.", __FUNCTION__);
382     return UNKNOWN_ERROR;
383   }
384   result_processor->SetResultCallback(process_capture_result, notify,
385                                       /*process_batch_capture_result=*/nullptr);
386 
387   *realtime_process_block = std::move(process_block);
388   *realtime_result_processor = std::move(result_processor);
389 
390   return OK;
391 }
392 
SetupHdrplusProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::unique_ptr<ProcessBlock> * hdrplus_process_block,std::unique_ptr<ResultProcessor> * hdrplus_result_processor,int32_t raw_stream_id)393 status_t HdrplusCaptureSession::SetupHdrplusProcessChain(
394     const StreamConfiguration& stream_config,
395     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
396     std::unique_ptr<ProcessBlock>* hdrplus_process_block,
397     std::unique_ptr<ResultProcessor>* hdrplus_result_processor,
398     int32_t raw_stream_id) {
399   ATRACE_CALL();
400   if (hdrplus_process_block == nullptr || hdrplus_result_processor == nullptr) {
401     ALOGE(
402         "%s: hdrplus_process_block(%p) or hdrplus_result_processor(%p) is "
403         "nullptr",
404         __FUNCTION__, hdrplus_process_block, hdrplus_result_processor);
405     return BAD_VALUE;
406   }
407 
408   // Create hdrplus process block.
409   auto process_block = HdrplusProcessBlock::Create(
410       device_session_hwl_, device_session_hwl_->GetCameraId());
411   if (process_block == nullptr) {
412     ALOGE("%s: Creating HdrplusProcessBlock failed.", __FUNCTION__);
413     return UNKNOWN_ERROR;
414   }
415 
416   // Create hdrplus request processor.
417   hdrplus_request_processor_ = HdrplusRequestProcessor::Create(
418       device_session_hwl_, raw_stream_id, device_session_hwl_->GetCameraId());
419   if (hdrplus_request_processor_ == nullptr) {
420     ALOGE("%s: Creating HdrplusRequestProcessor failed.", __FUNCTION__);
421     return UNKNOWN_ERROR;
422   }
423 
424   // Create hdrplus result processor.
425   auto result_processor = HdrplusResultProcessor::Create(
426       internal_stream_manager_.get(), raw_stream_id);
427   if (result_processor == nullptr) {
428     ALOGE("%s: Creating HdrplusResultProcessor failed.", __FUNCTION__);
429     return UNKNOWN_ERROR;
430   }
431   result_processor->SetResultCallback(process_capture_result, notify,
432                                       /*process_batch_capture_result=*/nullptr);
433 
434   status_t res = ConfigureHdrplusStreams(
435       stream_config, hdrplus_request_processor_.get(), process_block.get());
436   if (res != OK) {
437     ALOGE("%s: Configuring hdrplus stream failed: %s(%d)", __FUNCTION__,
438           strerror(-res), res);
439     return res;
440   }
441 
442   *hdrplus_process_block = std::move(process_block);
443   *hdrplus_result_processor = std::move(result_processor);
444 
445   return OK;
446 }
447 
Initialize(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)448 status_t HdrplusCaptureSession::Initialize(
449     CameraDeviceSessionHwl* device_session_hwl,
450     const StreamConfiguration& stream_config,
451     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
452     std::vector<HalStream>* hal_configured_streams) {
453   ATRACE_CALL();
454   if (!IsStreamConfigurationSupported(device_session_hwl, stream_config)) {
455     ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
456     return BAD_VALUE;
457   }
458 
459   std::unique_ptr<HalCameraMetadata> characteristics;
460   status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
461   if (res != OK) {
462     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
463     return BAD_VALUE;
464   }
465 
466   camera_metadata_ro_entry entry;
467   res = characteristics->Get(VendorTagIds::kHdrUsageMode, &entry);
468   if (res == OK) {
469     hdr_mode_ = static_cast<HdrMode>(entry.data.u8[0]);
470   }
471 
472   for (auto stream : stream_config.streams) {
473     if (utils::IsPreviewStream(stream)) {
474       hal_preview_stream_id_ = stream.id;
475       break;
476     }
477   }
478   device_session_hwl_ = device_session_hwl;
479   internal_stream_manager_ = InternalStreamManager::Create();
480   if (internal_stream_manager_ == nullptr) {
481     ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
482     return UNKNOWN_ERROR;
483   }
484 
485   // Create result dispatcher
486   result_dispatcher_ =
487       ResultDispatcher::Create(kPartialResult, process_capture_result,
488                                /*process_batch_capture_result=*/nullptr, notify,
489                                stream_config, "HdrplusDispatcher");
490   if (result_dispatcher_ == nullptr) {
491     ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
492     return UNKNOWN_ERROR;
493   }
494 
495   device_session_notify_ = notify;
496   process_capture_result_ =
497       ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
498         ProcessCaptureResult(std::move(result));
499       });
500   notify_ = NotifyFunc(
501       [this](const NotifyMessage& message) { NotifyHalMessage(message); });
502 
503   // Setup realtime process chain
504   int32_t raw_stream_id = -1;
505   std::unique_ptr<ProcessBlock> realtime_process_block;
506   std::unique_ptr<ResultProcessor> realtime_result_processor;
507 
508   res = SetupRealtimeProcessChain(stream_config, process_capture_result_,
509                                   notify_, &realtime_process_block,
510                                   &realtime_result_processor, &raw_stream_id);
511   if (res != OK) {
512     ALOGE("%s: SetupRealtimeProcessChain fail: %s(%d)", __FUNCTION__,
513           strerror(-res), res);
514     return res;
515   }
516 
517   // Setup hdrplus process chain
518   std::unique_ptr<ProcessBlock> hdrplus_process_block;
519   std::unique_ptr<ResultProcessor> hdrplus_result_processor;
520 
521   res = SetupHdrplusProcessChain(stream_config, process_capture_result_,
522                                  notify_, &hdrplus_process_block,
523                                  &hdrplus_result_processor, raw_stream_id);
524   if (res != OK) {
525     ALOGE("%s: SetupHdrplusProcessChain fail: %s(%d)", __FUNCTION__,
526           strerror(-res), res);
527     return res;
528   }
529 
530   // Realtime and HDR+ streams are configured
531   // Start to build pipleline
532   res = BuildPipelines(realtime_process_block.get(),
533                        hdrplus_process_block.get(), hal_configured_streams);
534   if (res != OK) {
535     ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
536           res);
537     return res;
538   }
539 
540   res = PurgeHalConfiguredStream(stream_config, hal_configured_streams);
541   if (res != OK) {
542     ALOGE("%s: Removing internal streams from configured stream failed: %s(%d)",
543           __FUNCTION__, strerror(-res), res);
544     return res;
545   }
546 
547   // Connect realtime process chain
548   res = ConnectProcessChain(request_processor_.get(),
549                             std::move(realtime_process_block),
550                             std::move(realtime_result_processor));
551   if (res != OK) {
552     ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
553           strerror(-res), res);
554     return res;
555   }
556 
557   // Connect HDR+ process chain
558   res = ConnectProcessChain(hdrplus_request_processor_.get(),
559                             std::move(hdrplus_process_block),
560                             std::move(hdrplus_result_processor));
561   if (res != OK) {
562     ALOGE("%s: Connecting HDR+ process chain failed: %s(%d)", __FUNCTION__,
563           strerror(-res), res);
564     return res;
565   }
566 
567   return OK;
568 }
569 
ProcessRequest(const CaptureRequest & request)570 status_t HdrplusCaptureSession::ProcessRequest(const CaptureRequest& request) {
571   ATRACE_CALL();
572   bool is_hdrplus_request =
573       hal_utils::IsRequestHdrplusCompatible(request, hal_preview_stream_id_);
574 
575   status_t res = result_dispatcher_->AddPendingRequest(request);
576   if (res != OK) {
577     ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
578           request.frame_number);
579     return BAD_VALUE;
580   }
581 
582   if (is_hdrplus_request) {
583     ALOGI("%s: hdrplus snapshot (%d), output stream size:%zu", __FUNCTION__,
584           request.frame_number, request.output_buffers.size());
585     res = hdrplus_request_processor_->ProcessRequest(request);
586     if (res != OK) {
587       ALOGI("%s: hdrplus snapshot frame(%d) request to realtime process",
588             __FUNCTION__, request.frame_number);
589       res = request_processor_->ProcessRequest(request);
590     }
591   } else {
592     res = request_processor_->ProcessRequest(request);
593   }
594 
595   if (res != OK) {
596     ALOGE("%s: ProcessRequest (%d) fail and remove pending request",
597           __FUNCTION__, request.frame_number);
598     result_dispatcher_->RemovePendingRequest(request.frame_number);
599   }
600   return res;
601 }
602 
Flush()603 status_t HdrplusCaptureSession::Flush() {
604   ATRACE_CALL();
605   return request_processor_->Flush();
606 }
607 
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)608 void HdrplusCaptureSession::ProcessCaptureResult(
609     std::unique_ptr<CaptureResult> result) {
610   ATRACE_CALL();
611   std::lock_guard<std::mutex> lock(callback_lock_);
612   if (result == nullptr) {
613     return;
614   }
615 
616   if (result->result_metadata && hdr_mode_ != HdrMode::kHdrplusMode) {
617     device_session_hwl_->FilterResultMetadata(result->result_metadata.get());
618   }
619 
620   status_t res = result_dispatcher_->AddResult(std::move(result));
621   if (res != OK) {
622     ALOGE("%s: fail to AddResult", __FUNCTION__);
623     return;
624   }
625 }
626 
PurgeHalConfiguredStream(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_configured_streams)627 status_t HdrplusCaptureSession::PurgeHalConfiguredStream(
628     const StreamConfiguration& stream_config,
629     std::vector<HalStream>* hal_configured_streams) {
630   if (hal_configured_streams == nullptr) {
631     ALOGE("%s: HAL configured stream list is null.", __FUNCTION__);
632     return BAD_VALUE;
633   }
634 
635   std::set<int32_t> framework_stream_id_set;
636   for (auto& stream : stream_config.streams) {
637     framework_stream_id_set.insert(stream.id);
638   }
639 
640   std::vector<HalStream> configured_streams;
641   for (auto& hal_stream : *hal_configured_streams) {
642     if (framework_stream_id_set.find(hal_stream.id) !=
643         framework_stream_id_set.end()) {
644       configured_streams.push_back(hal_stream);
645     }
646   }
647   *hal_configured_streams = configured_streams;
648   return OK;
649 }
650 
NotifyHalMessage(const NotifyMessage & message)651 void HdrplusCaptureSession::NotifyHalMessage(const NotifyMessage& message) {
652   ATRACE_CALL();
653   std::lock_guard<std::mutex> lock(callback_lock_);
654   if (device_session_notify_ == nullptr) {
655     ALOGE("%s: device_session_notify_ is nullptr. Dropping a message.",
656           __FUNCTION__);
657     return;
658   }
659 
660   if (message.type == MessageType::kShutter) {
661     status_t res = result_dispatcher_->AddShutter(
662         message.message.shutter.frame_number,
663         message.message.shutter.timestamp_ns,
664         message.message.shutter.readout_timestamp_ns);
665     if (res != OK) {
666       ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
667             message.message.shutter.frame_number, strerror(-res), res);
668       return;
669     }
670   } else if (message.type == MessageType::kError) {
671     status_t res = result_dispatcher_->AddError(message.message.error);
672     if (res != OK) {
673       ALOGE("%s: AddError for frame %u failed: %s (%d).", __FUNCTION__,
674             message.message.error.frame_number, strerror(-res), res);
675       return;
676     }
677   } else {
678     ALOGW("%s: Unsupported message type: %u", __FUNCTION__, message.type);
679     device_session_notify_(message);
680   }
681 }
682 }  // namespace google_camera_hal
683 }  // namespace android
684