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