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