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