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