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