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
77 for (auto& stream : process_block_stream_config->streams) {
78 // Assign all logical streams to the lead camera.
79 if (!stream.is_physical_camera_stream) {
80 stream.is_physical_camera_stream = true;
81 stream.physical_camera_id = kLeadCameraId;
82 }
83
84 stream_physical_camera_ids_[stream.id] = stream.physical_camera_id;
85 }
86
87 return OK;
88 }
89
SetProcessBlock(std::unique_ptr<ProcessBlock> process_block)90 status_t DualIrRequestProcessor::SetProcessBlock(
91 std::unique_ptr<ProcessBlock> process_block) {
92 ATRACE_CALL();
93 if (process_block == nullptr) {
94 ALOGE("%s: process_block is nullptr", __FUNCTION__);
95 return BAD_VALUE;
96 }
97
98 std::lock_guard<std::mutex> lock(process_block_lock_);
99 if (process_block_ != nullptr) {
100 ALOGE("%s: Already configured.", __FUNCTION__);
101 return ALREADY_EXISTS;
102 }
103
104 process_block_ = std::move(process_block);
105 return OK;
106 }
107
ProcessRequest(const CaptureRequest & request)108 status_t DualIrRequestProcessor::ProcessRequest(const CaptureRequest& request) {
109 ATRACE_CALL();
110 std::lock_guard<std::mutex> lock(process_block_lock_);
111 if (process_block_ == nullptr) {
112 ALOGE("%s: Not configured yet.", __FUNCTION__);
113 return NO_INIT;
114 }
115
116 uint32_t frame_number = request.frame_number;
117
118 // Create one physical request for each physical camera.
119 // Map from camera_id to the camera's request.
120 std::map<uint32_t, CaptureRequest> requests;
121
122 for (auto& buffer : request.output_buffers) {
123 uint32_t camera_id = stream_physical_camera_ids_[buffer.stream_id];
124 CaptureRequest* physical_request = nullptr;
125
126 auto request_iter = requests.find(camera_id);
127 if (request_iter == requests.end()) {
128 physical_request = &requests[camera_id];
129 physical_request->frame_number = frame_number;
130 // TODO: Combine physical camera settings?
131 physical_request->settings =
132 HalCameraMetadata::Clone(request.settings.get());
133 } else {
134 physical_request = &request_iter->second;
135 }
136 physical_request->output_buffers.push_back(buffer);
137 }
138
139 // Construct block requests.
140 std::vector<ProcessBlockRequest> block_requests;
141 for (auto& [camera_id, physical_request] : requests) {
142 ProcessBlockRequest block_request = {
143 .request_id = camera_id,
144 .request = std::move(physical_request),
145 };
146
147 block_requests.push_back(std::move(block_request));
148 }
149
150 return process_block_->ProcessRequests(block_requests, request);
151 }
152
Flush()153 status_t DualIrRequestProcessor::Flush() {
154 ATRACE_CALL();
155 std::lock_guard<std::mutex> lock(process_block_lock_);
156 if (process_block_ == nullptr) {
157 return OK;
158 }
159
160 return process_block_->Flush();
161 }
162
163 } // namespace google_camera_hal
164 } // namespace android