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_DualIrResultRequestProcessor"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22
23 #include <inttypes.h>
24
25 #include "dual_ir_result_request_processor.h"
26 #include "hal_utils.h"
27
28 namespace android {
29 namespace google_camera_hal {
30
31 std::unique_ptr<DualIrResultRequestProcessor>
Create(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,uint32_t lead_camera_id)32 DualIrResultRequestProcessor::Create(CameraDeviceSessionHwl* device_session_hwl,
33 const StreamConfiguration& stream_config,
34 uint32_t lead_camera_id) {
35 ATRACE_CALL();
36 if (device_session_hwl == nullptr) {
37 ALOGE("%s: device_session_hwl is nullptr.", __FUNCTION__);
38 return nullptr;
39 }
40
41 uint32_t camera_id = device_session_hwl->GetCameraId();
42 auto result_processor = std::unique_ptr<DualIrResultRequestProcessor>(
43 new DualIrResultRequestProcessor(stream_config, camera_id,
44 lead_camera_id));
45 if (result_processor == nullptr) {
46 ALOGE("%s: Creating DualIrResultRequestProcessor failed.", __FUNCTION__);
47 return nullptr;
48 }
49
50 return result_processor;
51 }
52
DualIrResultRequestProcessor(const StreamConfiguration & stream_config,uint32_t logical_camera_id,uint32_t lead_camera_id)53 DualIrResultRequestProcessor::DualIrResultRequestProcessor(
54 const StreamConfiguration& stream_config, uint32_t logical_camera_id,
55 uint32_t lead_camera_id)
56 : kLogicalCameraId(logical_camera_id), kLeadCameraId(lead_camera_id) {
57 ATRACE_CALL();
58 // Initialize stream ID -> camera ID map based on framework's stream
59 // configuration.
60 for (auto& stream : stream_config.streams) {
61 if (stream.is_physical_camera_stream) {
62 stream_camera_ids_[stream.id] = stream.physical_camera_id;
63 } else {
64 stream_camera_ids_[stream.id] = kLogicalCameraId;
65 }
66 }
67 }
68
SetResultCallback(ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)69 void DualIrResultRequestProcessor::SetResultCallback(
70 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
71 ATRACE_CALL();
72 std::lock_guard<std::mutex> lock(callback_lock_);
73 process_capture_result_ = process_capture_result;
74 notify_ = notify;
75 }
76
IsFrameworkPhyiscalStream(int32_t stream_id,uint32_t * physical_camera_id) const77 bool DualIrResultRequestProcessor::IsFrameworkPhyiscalStream(
78 int32_t stream_id, uint32_t* physical_camera_id) const {
79 ATRACE_CALL();
80 auto camera_id_iter = stream_camera_ids_.find(stream_id);
81 if (camera_id_iter == stream_camera_ids_.end()) {
82 ALOGE("%s: Cannot find camera ID for stream %u", __FUNCTION__, stream_id);
83 return false;
84 }
85
86 uint32_t camera_id = camera_id_iter->second;
87 if (camera_id == kLogicalCameraId) {
88 return false;
89 }
90
91 if (physical_camera_id != nullptr) {
92 *physical_camera_id = camera_id;
93 }
94
95 return true;
96 }
97
AddPendingPhysicalCameraMetadata(const ProcessBlockRequest & block_request,std::map<uint32_t,std::unique_ptr<HalCameraMetadata>> * physical_metadata)98 status_t DualIrResultRequestProcessor::AddPendingPhysicalCameraMetadata(
99 const ProcessBlockRequest& block_request,
100 std::map<uint32_t, std::unique_ptr<HalCameraMetadata>>* physical_metadata) {
101 ATRACE_CALL();
102 if (physical_metadata == nullptr) {
103 ALOGE("%s: physical_metadata is nullptr.", __FUNCTION__);
104 return BAD_VALUE;
105 }
106
107 for (auto& buffer : block_request.request.output_buffers) {
108 uint32_t physical_camera_id;
109 if (IsFrameworkPhyiscalStream(buffer.stream_id, &physical_camera_id)) {
110 // Add physical_camera_id to physical_metadata.
111 (*physical_metadata)[physical_camera_id] = nullptr;
112 }
113 }
114
115 return OK;
116 }
117
AddPendingRequests(const std::vector<ProcessBlockRequest> & process_block_requests,const CaptureRequest & remaining_session_request)118 status_t DualIrResultRequestProcessor::AddPendingRequests(
119 const std::vector<ProcessBlockRequest>& process_block_requests,
120 const CaptureRequest& remaining_session_request) {
121 ATRACE_CALL();
122 // This is the last result processor. Sanity check if requests contains
123 // all remaining output buffers.
124 if (!hal_utils::AreAllRemainingBuffersRequested(process_block_requests,
125 remaining_session_request)) {
126 ALOGE("%s: Some output buffers will not be completed.", __FUNCTION__);
127 return BAD_VALUE;
128 }
129
130 // Create new pending result metadata.
131 PendingResultMetadata pending_result_metadata;
132 for (auto& block_request : process_block_requests) {
133 status_t res = AddPendingPhysicalCameraMetadata(
134 block_request, &pending_result_metadata.physical_metadata);
135 if (res != OK) {
136 ALOGE("%s: Failed to fill pending physical camera metadata: %s(%d)",
137 __FUNCTION__, strerror(-res), res);
138 return res;
139 }
140 }
141
142 uint32_t frame_number = process_block_requests[0].request.frame_number;
143
144 std::lock_guard<std::mutex> lock(pending_result_metadata_mutex_);
145 pending_result_metadata_[frame_number] = std::move(pending_result_metadata);
146
147 return OK;
148 }
149
TrySendingResultMetadataLocked(uint32_t frame_number)150 void DualIrResultRequestProcessor::TrySendingResultMetadataLocked(
151 uint32_t frame_number) {
152 ATRACE_CALL();
153 auto pending_result_metadata_iter =
154 pending_result_metadata_.find(frame_number);
155 if (pending_result_metadata_iter == pending_result_metadata_.end()) {
156 ALOGE("%s: Can't find pending result for frame number %u", __FUNCTION__,
157 frame_number);
158 return;
159 }
160
161 // Check if we got result metadata from all cameras for this frame.
162 auto& pending_result_metadata = pending_result_metadata_iter->second;
163 if (pending_result_metadata.metadata == nullptr) {
164 // No metadata for logical camera yet.
165 return;
166 }
167
168 for (auto& [camera_id, metadata] : pending_result_metadata.physical_metadata) {
169 if (metadata == nullptr) {
170 // No metadata for this physical camera yet.
171 return;
172 }
173 }
174
175 // Prepare the result.
176 auto result = std::make_unique<CaptureResult>();
177 result->frame_number = frame_number;
178 result->partial_result = 1;
179 result->result_metadata = std::move(pending_result_metadata.metadata);
180
181 for (auto& [camera_id, metadata] : pending_result_metadata.physical_metadata) {
182 PhysicalCameraMetadata physical_metadata = {
183 .physical_camera_id = camera_id,
184 .metadata = std::move(metadata),
185 };
186
187 result->physical_metadata.push_back(std::move(physical_metadata));
188 }
189
190 process_capture_result_(std::move(result));
191 pending_result_metadata_.erase(pending_result_metadata_iter);
192 }
193
ProcessResultMetadata(uint32_t frame_number,uint32_t physical_camera_id,std::unique_ptr<HalCameraMetadata> result_metadata)194 status_t DualIrResultRequestProcessor::ProcessResultMetadata(
195 uint32_t frame_number, uint32_t physical_camera_id,
196 std::unique_ptr<HalCameraMetadata> result_metadata) {
197 ATRACE_CALL();
198 std::lock_guard<std::mutex> lock(pending_result_metadata_mutex_);
199 auto pending_result_metadata_iter =
200 pending_result_metadata_.find(frame_number);
201 if (pending_result_metadata_iter == pending_result_metadata_.end()) {
202 ALOGE("%s: frame number %u is not expected.", __FUNCTION__, frame_number);
203 return BAD_VALUE;
204 }
205
206 auto& pending_result_metadata = pending_result_metadata_iter->second;
207
208 if (physical_camera_id == kLeadCameraId) {
209 if (pending_result_metadata.metadata != nullptr) {
210 ALOGE("%s: Already received metadata from camera %u for frame %u",
211 __FUNCTION__, physical_camera_id, frame_number);
212 return UNKNOWN_ERROR;
213 }
214
215 // Set lead camera id to multi camera metadata
216 std::string activePhysicalId = std::to_string(kLeadCameraId);
217 if (OK != result_metadata->Set(
218 ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
219 reinterpret_cast<const uint8_t*>(activePhysicalId.c_str()),
220 static_cast<uint32_t>(activePhysicalId.size() + 1))) {
221 ALOGE("Failure in setting active physical camera");
222 }
223
224 // Logical camera's result metadata is a clone of the lead camera's
225 // result metadata.
226 pending_result_metadata.metadata = std::move(result_metadata);
227 }
228
229 // Add the physical result metadata to pending result metadata if needed.
230 auto physical_metadata_iter =
231 pending_result_metadata.physical_metadata.find(physical_camera_id);
232 if (physical_metadata_iter != pending_result_metadata.physical_metadata.end()) {
233 // If the pending result metadata have physical metadata for a physical
234 // camera ID, the physical result metadata is needed.
235 if (physical_metadata_iter->second != nullptr) {
236 ALOGE("%s: Already received result metadata for camera %u for frame %u",
237 __FUNCTION__, physical_camera_id, frame_number);
238 return UNKNOWN_ERROR;
239 }
240
241 if (physical_camera_id == kLeadCameraId) {
242 // If this physical camera is the lead camera, clone the result metadata
243 // from the logical camera's result metadata.
244 physical_metadata_iter->second =
245 HalCameraMetadata::Clone(pending_result_metadata.metadata.get());
246 } else {
247 physical_metadata_iter->second = std::move(result_metadata);
248 }
249 }
250
251 TrySendingResultMetadataLocked(frame_number);
252 return OK;
253 }
254
ProcessResult(ProcessBlockResult block_result)255 void DualIrResultRequestProcessor::ProcessResult(ProcessBlockResult block_result) {
256 ATRACE_CALL();
257 std::lock_guard<std::mutex> lock(callback_lock_);
258 if (block_result.result == nullptr) {
259 ALOGW("%s: Received a nullptr result.", __FUNCTION__);
260 return;
261 }
262
263 if (process_capture_result_ == nullptr) {
264 ALOGE("%s: process_capture_result_ is nullptr. Dropping a result.",
265 __FUNCTION__);
266 return;
267 }
268
269 // Request ID is set to camera ID by DualIrRequestProcessor.
270 uint32_t camera_id = block_result.request_id;
271
272 // Process result metadata separately because there could be two result
273 // metadata (one from each camera).
274 auto result = std::move(block_result.result);
275 if (result->result_metadata != nullptr) {
276 status_t res = ProcessResultMetadata(result->frame_number, camera_id,
277 std::move(result->result_metadata));
278 if (res != OK) {
279 ALOGE("%s: Processing result metadata failed: %s(%d)", __FUNCTION__,
280 strerror(-res), res);
281 // Continue processing rest of the result.
282 }
283 }
284
285 if (result->output_buffers.size() == 0) {
286 // No buffer to send out.
287 return;
288 }
289
290 process_capture_result_(std::move(result));
291 }
292
Notify(const ProcessBlockNotifyMessage & block_message)293 void DualIrResultRequestProcessor::Notify(
294 const ProcessBlockNotifyMessage& block_message) {
295 ATRACE_CALL();
296 std::lock_guard<std::mutex> lock(callback_lock_);
297 if (notify_ == nullptr) {
298 ALOGE("%s: notify_ is nullptr. Dropping a message.", __FUNCTION__);
299 return;
300 }
301
302 const NotifyMessage& message = block_message.message;
303
304 // Request ID is set to camera ID by DualIrRequestProcessor.
305 uint32_t camera_id = block_message.request_id;
306 if (message.type == MessageType::kShutter && camera_id != kLeadCameraId) {
307 // Only send out shutters from the lead camera.
308 return;
309 }
310
311 // TODO(b/129017376): if there are multiple requests for this frame, wait for
312 // all notification to arrive before calling process_capture_result_().
313 notify_(block_message.message);
314 }
315
ConfigureStreams(InternalStreamManager *,const StreamConfiguration &,StreamConfiguration *)316 status_t DualIrResultRequestProcessor::ConfigureStreams(
317 InternalStreamManager* /*internal_stream_manager*/,
318 const StreamConfiguration& /*stream_config*/,
319 StreamConfiguration* /*process_block_stream_config*/) {
320 ATRACE_CALL();
321 // TODO(b/131618554): Implement this function.
322
323 return INVALID_OPERATION;
324 }
325
SetProcessBlock(std::unique_ptr<ProcessBlock>)326 status_t DualIrResultRequestProcessor::SetProcessBlock(
327 std::unique_ptr<ProcessBlock> /*process_block*/) {
328 ATRACE_CALL();
329 // TODO(b/131618554): Implement this function.
330
331 return INVALID_OPERATION;
332 }
333
ProcessRequest(const CaptureRequest &)334 status_t DualIrResultRequestProcessor::ProcessRequest(
335 const CaptureRequest& /*request*/) {
336 ATRACE_CALL();
337 // TODO(b/131618554): Implement this function.
338
339 return INVALID_OPERATION;
340 }
341
Flush()342 status_t DualIrResultRequestProcessor::Flush() {
343 ATRACE_CALL();
344 // TODO(b/131618554): Implement this function.
345
346 return INVALID_OPERATION;
347 }
348
FlushPendingRequests()349 status_t DualIrResultRequestProcessor::FlushPendingRequests() {
350 ATRACE_CALL();
351 return OK;
352 }
353
354 } // namespace google_camera_hal
355 } // namespace android