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 <log/log.h>
21 #include <utils/Trace.h>
22
23 #include "basic_capture_session.h"
24 #include "basic_request_processor.h"
25 #include "basic_result_processor.h"
26 #include "realtime_process_block.h"
27
28 namespace android {
29 namespace google_camera_hal {
30
IsStreamConfigurationSupported(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration &)31 bool BasicCaptureSession::IsStreamConfigurationSupported(
32 CameraDeviceSessionHwl* device_session_hwl,
33 const StreamConfiguration& /*stream_config*/) {
34 ATRACE_CALL();
35 if (device_session_hwl == nullptr) {
36 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
37 return false;
38 }
39
40 ALOGD("%s: BasicCaptureSession supports the stream config", __FUNCTION__);
41 return true;
42 }
43
Create(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,HwlSessionCallback,std::vector<HalStream> * hal_configured_streams,CameraBufferAllocatorHwl *)44 std::unique_ptr<CaptureSession> BasicCaptureSession::Create(
45 CameraDeviceSessionHwl* device_session_hwl,
46 const StreamConfiguration& stream_config,
47 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
48 HwlSessionCallback /*session_callback*/,
49 std::vector<HalStream>* hal_configured_streams,
50 CameraBufferAllocatorHwl* /*camera_allocator_hwl*/) {
51 ATRACE_CALL();
52 auto session = std::unique_ptr<BasicCaptureSession>(new BasicCaptureSession());
53 if (session == nullptr) {
54 ALOGE("%s: Creating BasicCaptureSession failed.", __FUNCTION__);
55 return nullptr;
56 }
57
58 status_t res = session->Initialize(device_session_hwl, stream_config,
59 process_capture_result, notify,
60 hal_configured_streams);
61 if (res != OK) {
62 ALOGE("%s: Initializing BasicCaptureSession failed: %s (%d).", __FUNCTION__,
63 strerror(-res), res);
64 return nullptr;
65 }
66
67 return session;
68 }
69
~BasicCaptureSession()70 BasicCaptureSession::~BasicCaptureSession() {
71 if (device_session_hwl_ != nullptr) {
72 device_session_hwl_->DestroyPipelines();
73 }
74 }
75
ConfigureStreams(const StreamConfiguration & stream_config,RequestProcessor * request_processor,ProcessBlock * process_block)76 status_t BasicCaptureSession::ConfigureStreams(
77 const StreamConfiguration& stream_config,
78 RequestProcessor* request_processor, ProcessBlock* process_block) {
79 ATRACE_CALL();
80 if (request_processor == nullptr || process_block == nullptr) {
81 ALOGE("%s: request_processor (%p) or process_block (%p) is nullptr",
82 __FUNCTION__, request_processor, process_block);
83 return BAD_VALUE;
84 }
85
86 // Configure streams for request processor
87 StreamConfiguration process_block_stream_config;
88 status_t res = request_processor->ConfigureStreams(
89 internal_stream_manager_.get(), stream_config,
90 &process_block_stream_config);
91 if (res != OK) {
92 ALOGE("%s: Configuring stream for request processor failed.", __FUNCTION__);
93 return res;
94 }
95
96 // Check all streams are configured.
97 if (stream_config.streams.size() !=
98 process_block_stream_config.streams.size()) {
99 ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
100 __FUNCTION__, stream_config.streams.size(),
101 process_block_stream_config.streams.size());
102 return UNKNOWN_ERROR;
103 }
104
105 for (auto& stream : stream_config.streams) {
106 bool found = false;
107 for (auto& configured_stream : process_block_stream_config.streams) {
108 if (stream.id == configured_stream.id) {
109 found = true;
110 break;
111 }
112 }
113
114 if (!found) {
115 ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
116 stream.id);
117 return UNKNOWN_ERROR;
118 }
119 }
120
121 // Configure streams for process block.
122 res = process_block->ConfigureStreams(process_block_stream_config,
123 stream_config);
124 if (res != OK) {
125 ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
126 return res;
127 }
128
129 return OK;
130 }
131
BuildPipelines(ProcessBlock * process_block,std::vector<HalStream> * hal_configured_streams)132 status_t BasicCaptureSession::BuildPipelines(
133 ProcessBlock* process_block,
134 std::vector<HalStream>* hal_configured_streams) {
135 ATRACE_CALL();
136 if (process_block == nullptr || hal_configured_streams == nullptr) {
137 ALOGE("%s: process_block (%p) or hal_configured_streams (%p) is nullptr",
138 __FUNCTION__, process_block, hal_configured_streams);
139 return BAD_VALUE;
140 }
141
142 status_t res = device_session_hwl_->BuildPipelines();
143 if (res != OK) {
144 ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
145 res);
146 return res;
147 }
148
149 res = process_block->GetConfiguredHalStreams(hal_configured_streams);
150 if (res != OK) {
151 ALOGE("%s: Getting HAL streams failed: %s(%d)", __FUNCTION__,
152 strerror(-res), res);
153 return res;
154 }
155
156 return OK;
157 }
158
ConnectProcessChain(RequestProcessor * request_processor,std::unique_ptr<ProcessBlock> process_block,std::unique_ptr<ResultProcessor> result_processor)159 status_t BasicCaptureSession::ConnectProcessChain(
160 RequestProcessor* request_processor,
161 std::unique_ptr<ProcessBlock> process_block,
162 std::unique_ptr<ResultProcessor> result_processor) {
163 ATRACE_CALL();
164 if (request_processor == nullptr) {
165 ALOGE("%s: request_processor is nullptr", __FUNCTION__);
166 return BAD_VALUE;
167 }
168
169 status_t res = process_block->SetResultProcessor(std::move(result_processor));
170 if (res != OK) {
171 ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
172 return res;
173 }
174
175 res = request_processor->SetProcessBlock(std::move(process_block));
176 if (res != OK) {
177 ALOGE("%s: Setting process block for BasicRequestProcessor failed: %s(%d)",
178 __FUNCTION__, strerror(-res), res);
179 return res;
180 }
181
182 return OK;
183 }
184
Initialize(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)185 status_t BasicCaptureSession::Initialize(
186 CameraDeviceSessionHwl* device_session_hwl,
187 const StreamConfiguration& stream_config,
188 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
189 std::vector<HalStream>* hal_configured_streams) {
190 ATRACE_CALL();
191 if (!IsStreamConfigurationSupported(device_session_hwl, stream_config)) {
192 ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
193 return BAD_VALUE;
194 }
195
196 device_session_hwl_ = device_session_hwl;
197 internal_stream_manager_ = InternalStreamManager::Create();
198 if (internal_stream_manager_ == nullptr) {
199 ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
200 return UNKNOWN_ERROR;
201 }
202
203 // Create result processor.
204 auto result_processor = BasicResultProcessor::Create();
205 if (result_processor == nullptr) {
206 ALOGE("%s: Creating BasicResultProcessor failed.", __FUNCTION__);
207 return UNKNOWN_ERROR;
208 }
209
210 result_processor->SetResultCallback(process_capture_result, notify);
211
212 // Create process block.
213 auto process_block = RealtimeProcessBlock::Create(device_session_hwl_);
214 if (process_block == nullptr) {
215 ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
216 return UNKNOWN_ERROR;
217 }
218
219 // Create request processor.
220 request_processor_ = BasicRequestProcessor::Create(device_session_hwl_);
221 if (request_processor_ == nullptr) {
222 ALOGE("%s: Creating BasicRequestProcessor failed.", __FUNCTION__);
223 return UNKNOWN_ERROR;
224 }
225
226 status_t res = ConfigureStreams(stream_config, request_processor_.get(),
227 process_block.get());
228 if (res != OK) {
229 ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
230 res);
231 return res;
232 }
233
234 res = BuildPipelines(process_block.get(), hal_configured_streams);
235 if (res != OK) {
236 ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
237 res);
238 return res;
239 }
240
241 res = ConnectProcessChain(request_processor_.get(), std::move(process_block),
242 std::move(result_processor));
243 if (res != OK) {
244 ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
245 strerror(-res), res);
246 return res;
247 }
248
249 return OK;
250 }
251
ProcessRequest(const CaptureRequest & request)252 status_t BasicCaptureSession::ProcessRequest(const CaptureRequest& request) {
253 ATRACE_CALL();
254 return request_processor_->ProcessRequest(request);
255 }
256
Flush()257 status_t BasicCaptureSession::Flush() {
258 ATRACE_CALL();
259 return request_processor_->Flush();
260 }
261
262 } // namespace google_camera_hal
263 } // namespace android
264