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_DualIrRequestProcessor"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22
23 #include "dual_ir_request_processor.h"
24
25 namespace android {
26 namespace google_camera_hal {
27
Create(CameraDeviceSessionHwl * device_session_hwl,uint32_t lead_ir_camera_id)28 std::unique_ptr<DualIrRequestProcessor> DualIrRequestProcessor::Create(
29 CameraDeviceSessionHwl* device_session_hwl, uint32_t lead_ir_camera_id) {
30 ATRACE_CALL();
31 if (device_session_hwl == nullptr) {
32 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
33 return nullptr;
34 }
35
36 // Check there are two physical cameras.
37 std::vector<uint32_t> camera_ids = device_session_hwl->GetPhysicalCameraIds();
38 if (camera_ids.size() != 2) {
39 ALOGE("%s: Only support two IR cameras but there are %zu cameras.",
40 __FUNCTION__, camera_ids.size());
41 return nullptr;
42 }
43
44 // TODO(b/129017376): Figure out default IR camera ID from static metadata.
45 // Assume the first physical camera is the default for now.
46 auto request_processor = std::unique_ptr<DualIrRequestProcessor>(
47 new DualIrRequestProcessor(lead_ir_camera_id));
48 if (request_processor == nullptr) {
49 ALOGE("%s: Creating DualIrRequestProcessor failed.", __FUNCTION__);
50 return nullptr;
51 }
52
53 return request_processor;
54 }
55
DualIrRequestProcessor(uint32_t lead_camera_id)56 DualIrRequestProcessor::DualIrRequestProcessor(uint32_t lead_camera_id)
57 : kLeadCameraId(lead_camera_id) {
58 }
59
ConfigureStreams(InternalStreamManager *,const StreamConfiguration & stream_config,StreamConfiguration * process_block_stream_config)60 status_t DualIrRequestProcessor::ConfigureStreams(
61 InternalStreamManager* /*internal_stream_manager*/,
62 const StreamConfiguration& stream_config,
63 StreamConfiguration* process_block_stream_config) {
64 ATRACE_CALL();
65 if (process_block_stream_config == nullptr) {
66 ALOGE("%s: process_block_stream_config is nullptr", __FUNCTION__);
67 return BAD_VALUE;
68 }
69
70 process_block_stream_config->streams = stream_config.streams;
71 process_block_stream_config->operation_mode = stream_config.operation_mode;
72 process_block_stream_config->session_params =
73 HalCameraMetadata::Clone(stream_config.session_params.get());
74 process_block_stream_config->stream_config_counter =
75 stream_config.stream_config_counter;
76 process_block_stream_config->log_id = stream_config.log_id;
77
78 for (auto& stream : process_block_stream_config->streams) {
79 // Assign all logical streams to the lead camera.
80 if (!stream.is_physical_camera_stream) {
81 stream.is_physical_camera_stream = true;
82 stream.physical_camera_id = kLeadCameraId;
83 }
84
85 stream_physical_camera_ids_[stream.id] = stream.physical_camera_id;
86 }
87
88 return OK;
89 }
90
SetProcessBlock(std::unique_ptr<ProcessBlock> process_block)91 status_t DualIrRequestProcessor::SetProcessBlock(
92 std::unique_ptr<ProcessBlock> process_block) {
93 ATRACE_CALL();
94 if (process_block == nullptr) {
95 ALOGE("%s: process_block is nullptr", __FUNCTION__);
96 return BAD_VALUE;
97 }
98
99 std::lock_guard<std::mutex> lock(process_block_lock_);
100 if (process_block_ != nullptr) {
101 ALOGE("%s: Already configured.", __FUNCTION__);
102 return ALREADY_EXISTS;
103 }
104
105 process_block_ = std::move(process_block);
106 return OK;
107 }
108
ProcessRequest(const CaptureRequest & request)109 status_t DualIrRequestProcessor::ProcessRequest(const CaptureRequest& request) {
110 ATRACE_CALL();
111 std::lock_guard<std::mutex> lock(process_block_lock_);
112 if (process_block_ == nullptr) {
113 ALOGE("%s: Not configured yet.", __FUNCTION__);
114 return NO_INIT;
115 }
116
117 uint32_t frame_number = request.frame_number;
118
119 // Create one physical request for each physical camera.
120 // Map from camera_id to the camera's request.
121 std::map<uint32_t, CaptureRequest> requests;
122
123 for (auto& buffer : request.output_buffers) {
124 uint32_t camera_id = stream_physical_camera_ids_[buffer.stream_id];
125 CaptureRequest* physical_request = nullptr;
126
127 auto request_iter = requests.find(camera_id);
128 if (request_iter == requests.end()) {
129 physical_request = &requests[camera_id];
130 physical_request->frame_number = frame_number;
131 // TODO: Combine physical camera settings?
132 physical_request->settings =
133 HalCameraMetadata::Clone(request.settings.get());
134 } else {
135 physical_request = &request_iter->second;
136 }
137 physical_request->output_buffers.push_back(buffer);
138 }
139
140 // Construct block requests.
141 std::vector<ProcessBlockRequest> block_requests;
142 for (auto& [camera_id, physical_request] : requests) {
143 ProcessBlockRequest block_request = {
144 .request_id = camera_id,
145 .request = std::move(physical_request),
146 };
147
148 block_requests.push_back(std::move(block_request));
149 }
150
151 return process_block_->ProcessRequests(block_requests, request);
152 }
153
Flush()154 status_t DualIrRequestProcessor::Flush() {
155 ATRACE_CALL();
156 std::lock_guard<std::mutex> lock(process_block_lock_);
157 if (process_block_ == nullptr) {
158 return OK;
159 }
160
161 return process_block_->Flush();
162 }
163
164 } // namespace google_camera_hal
165 } // namespace android