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_BasicCaptureSession"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "basic_capture_session.h"
21
22 #include <log/log.h>
23 #include <utils/Trace.h>
24
25 #include "basic_request_processor.h"
26 #include "basic_result_processor.h"
27 #include "hal_types.h"
28 #include "realtime_process_block.h"
29
30 namespace android {
31 namespace google_camera_hal {
32
IsStreamConfigurationSupported(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration &)33 bool BasicCaptureSession::IsStreamConfigurationSupported(
34 CameraDeviceSessionHwl* device_session_hwl,
35 const StreamConfiguration& /*stream_config*/) {
36 ATRACE_CALL();
37 if (device_session_hwl == nullptr) {
38 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
39 return false;
40 }
41
42 ALOGD("%s: BasicCaptureSession supports the stream config", __FUNCTION__);
43 return true;
44 }
45
Create(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,ProcessBatchCaptureResultFunc process_batch_capture_result,NotifyFunc notify,HwlSessionCallback,std::vector<HalStream> * hal_configured_streams,CameraBufferAllocatorHwl *)46 std::unique_ptr<CaptureSession> BasicCaptureSession::Create(
47 CameraDeviceSessionHwl* device_session_hwl,
48 const StreamConfiguration& stream_config,
49 ProcessCaptureResultFunc process_capture_result,
50 ProcessBatchCaptureResultFunc process_batch_capture_result,
51 NotifyFunc notify, HwlSessionCallback /*session_callback*/,
52 std::vector<HalStream>* hal_configured_streams,
53 CameraBufferAllocatorHwl* /*camera_allocator_hwl*/) {
54 ATRACE_CALL();
55 auto session = std::unique_ptr<BasicCaptureSession>(new BasicCaptureSession());
56 if (session == nullptr) {
57 ALOGE("%s: Creating BasicCaptureSession failed.", __FUNCTION__);
58 return nullptr;
59 }
60
61 status_t res = session->Initialize(
62 device_session_hwl, stream_config, process_capture_result,
63 process_batch_capture_result, notify, hal_configured_streams);
64 if (res != OK) {
65 ALOGE("%s: Initializing BasicCaptureSession failed: %s (%d).", __FUNCTION__,
66 strerror(-res), res);
67 return nullptr;
68 }
69
70 return session;
71 }
72
~BasicCaptureSession()73 BasicCaptureSession::~BasicCaptureSession() {
74 if (device_session_hwl_ != nullptr) {
75 device_session_hwl_->DestroyPipelines();
76 }
77 }
78
ConfigureStreams(const StreamConfiguration & stream_config,RequestProcessor * request_processor,ProcessBlock * process_block)79 status_t BasicCaptureSession::ConfigureStreams(
80 const StreamConfiguration& stream_config,
81 RequestProcessor* request_processor, ProcessBlock* process_block) {
82 ATRACE_CALL();
83 if (request_processor == nullptr || process_block == nullptr) {
84 ALOGE("%s: request_processor (%p) or process_block (%p) is nullptr",
85 __FUNCTION__, request_processor, process_block);
86 return BAD_VALUE;
87 }
88
89 // Configure streams for request processor
90 StreamConfiguration process_block_stream_config;
91 status_t res = request_processor->ConfigureStreams(
92 internal_stream_manager_.get(), stream_config,
93 &process_block_stream_config);
94 if (res != OK) {
95 ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
96 return res;
97 }
98
99 // Check all streams are configured.
100 if (stream_config.streams.size() !=
101 process_block_stream_config.streams.size()) {
102 ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
103 __FUNCTION__, stream_config.streams.size(),
104 process_block_stream_config.streams.size());
105 return UNKNOWN_ERROR;
106 }
107
108 for (auto& stream : stream_config.streams) {
109 bool found = false;
110 for (auto& configured_stream : process_block_stream_config.streams) {
111 if (stream.id == configured_stream.id) {
112 found = true;
113 break;
114 }
115 }
116
117 if (!found) {
118 ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
119 stream.id);
120 return UNKNOWN_ERROR;
121 }
122 }
123
124 // Configure streams for process block.
125 res = process_block->ConfigureStreams(process_block_stream_config,
126 stream_config);
127 if (res != OK) {
128 ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
129 return res;
130 }
131
132 return OK;
133 }
134
BuildPipelines(ProcessBlock * process_block,std::vector<HalStream> * hal_configured_streams)135 status_t BasicCaptureSession::BuildPipelines(
136 ProcessBlock* process_block,
137 std::vector<HalStream>* hal_configured_streams) {
138 ATRACE_CALL();
139 if (process_block == nullptr || hal_configured_streams == nullptr) {
140 ALOGE("%s: process_block (%p) or hal_configured_streams (%p) is nullptr",
141 __FUNCTION__, process_block, hal_configured_streams);
142 return BAD_VALUE;
143 }
144
145 status_t res = device_session_hwl_->BuildPipelines();
146 if (res != OK) {
147 ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
148 res);
149 return res;
150 }
151
152 res = process_block->GetConfiguredHalStreams(hal_configured_streams);
153 if (res != OK) {
154 ALOGE("%s: Getting HAL streams failed: %s(%d)", __FUNCTION__,
155 strerror(-res), res);
156 return res;
157 }
158
159 return OK;
160 }
161
ConnectProcessChain(RequestProcessor * request_processor,std::unique_ptr<ProcessBlock> process_block,std::unique_ptr<ResultProcessor> result_processor)162 status_t BasicCaptureSession::ConnectProcessChain(
163 RequestProcessor* request_processor,
164 std::unique_ptr<ProcessBlock> process_block,
165 std::unique_ptr<ResultProcessor> result_processor) {
166 ATRACE_CALL();
167 if (request_processor == nullptr) {
168 ALOGE("%s: request_processor is nullptr", __FUNCTION__);
169 return BAD_VALUE;
170 }
171
172 status_t res = process_block->SetResultProcessor(std::move(result_processor));
173 if (res != OK) {
174 ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
175 return res;
176 }
177
178 res = request_processor->SetProcessBlock(std::move(process_block));
179 if (res != OK) {
180 ALOGE("%s: Setting process block for BasicRequestProcessor failed: %s(%d)",
181 __FUNCTION__, strerror(-res), res);
182 return res;
183 }
184
185 return OK;
186 }
187
Initialize(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,ProcessBatchCaptureResultFunc process_batch_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)188 status_t BasicCaptureSession::Initialize(
189 CameraDeviceSessionHwl* device_session_hwl,
190 const StreamConfiguration& stream_config,
191 ProcessCaptureResultFunc process_capture_result,
192 ProcessBatchCaptureResultFunc process_batch_capture_result,
193 NotifyFunc notify, std::vector<HalStream>* hal_configured_streams) {
194 ATRACE_CALL();
195 if (!IsStreamConfigurationSupported(device_session_hwl, stream_config)) {
196 ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
197 return BAD_VALUE;
198 }
199
200 device_session_hwl_ = device_session_hwl;
201 internal_stream_manager_ = InternalStreamManager::Create();
202 if (internal_stream_manager_ == nullptr) {
203 ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
204 return UNKNOWN_ERROR;
205 }
206
207 std::unique_ptr<HalCameraMetadata> characteristics;
208 uint32_t partial_result_count = 1;
209 status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
210 if (res != OK) {
211 ALOGE("GetCameraCharacteristics failed");
212 return BAD_VALUE;
213 }
214 camera_metadata_ro_entry partial_result_entry;
215 res = characteristics->Get(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
216 &partial_result_entry);
217 if (res == OK) {
218 partial_result_count = partial_result_entry.data.i32[0];
219 }
220
221 // Create result dispatcher.
222 std::string result_dispatcher_name =
223 "Cam" + std::to_string(device_session_hwl_->GetCameraId()) +
224 "_ResultDispatcher";
225 result_dispatcher_ =
226 ResultDispatcher::Create(partial_result_count, process_capture_result,
227 process_batch_capture_result, notify,
228 stream_config, result_dispatcher_name);
229 if (result_dispatcher_ == nullptr) {
230 ALOGE("Creating ResultDispatcher failed");
231 return UNKNOWN_ERROR;
232 }
233
234 // Create result processor.
235 auto result_processor = BasicResultProcessor::Create();
236 if (result_processor == nullptr) {
237 ALOGE("%s: Creating BasicResultProcessor failed.", __FUNCTION__);
238 return UNKNOWN_ERROR;
239 }
240
241 auto process_capture_result_cb = [this](std::unique_ptr<CaptureResult> result) {
242 ProcessCaptureResult(std::move(result));
243 };
244 auto notify_cb = [this](const NotifyMessage& message) { Notify(message); };
245 auto process_batch_capture_result_cb =
246 [this](std::vector<std::unique_ptr<CaptureResult>> results) {
247 ProcessBatchCaptureResult(std::move(results));
248 };
249 result_processor->SetResultCallback(process_capture_result_cb, notify_cb,
250 process_batch_capture_result_cb);
251
252 // Create process block.
253 auto process_block = RealtimeProcessBlock::Create(device_session_hwl_);
254 if (process_block == nullptr) {
255 ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
256 return UNKNOWN_ERROR;
257 }
258
259 // Create request processor.
260 request_processor_ = BasicRequestProcessor::Create(device_session_hwl_);
261 if (request_processor_ == nullptr) {
262 ALOGE("%s: Creating BasicRequestProcessor failed.", __FUNCTION__);
263 return UNKNOWN_ERROR;
264 }
265
266 res = ConfigureStreams(stream_config, request_processor_.get(),
267 process_block.get());
268 if (res != OK) {
269 ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
270 res);
271 return res;
272 }
273
274 res = BuildPipelines(process_block.get(), hal_configured_streams);
275 if (res != OK) {
276 ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
277 res);
278 return res;
279 }
280
281 res = ConnectProcessChain(request_processor_.get(), std::move(process_block),
282 std::move(result_processor));
283 if (res != OK) {
284 ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
285 strerror(-res), res);
286 return res;
287 }
288
289 return OK;
290 }
291
ProcessRequest(const CaptureRequest & request)292 status_t BasicCaptureSession::ProcessRequest(const CaptureRequest& request) {
293 ATRACE_CALL();
294 result_dispatcher_->AddPendingRequest(request);
295 return request_processor_->ProcessRequest(request);
296 }
297
Flush()298 status_t BasicCaptureSession::Flush() {
299 ATRACE_CALL();
300 return request_processor_->Flush();
301 }
302
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)303 void BasicCaptureSession::ProcessCaptureResult(
304 std::unique_ptr<CaptureResult> result) {
305 result_dispatcher_->AddResult(std::move(result));
306 }
307
Notify(const NotifyMessage & message)308 void BasicCaptureSession::Notify(const NotifyMessage& message) {
309 if (message.type == MessageType::kShutter) {
310 result_dispatcher_->AddShutter(message.message.shutter.frame_number,
311 message.message.shutter.timestamp_ns,
312 message.message.shutter.readout_timestamp_ns);
313 } else {
314 result_dispatcher_->AddError(message.message.error);
315 }
316 }
317
ProcessBatchCaptureResult(std::vector<std::unique_ptr<CaptureResult>> results)318 void BasicCaptureSession::ProcessBatchCaptureResult(
319 std::vector<std::unique_ptr<CaptureResult>> results) {
320 result_dispatcher_->AddBatchResult(std::move(results));
321 }
322
323 } // namespace google_camera_hal
324 } // namespace android
325