1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "camera_util.h"
17 #include "media_log.h"
18 #include "surface.h"
19 #include "ipc_skeleton.h"
20 #include "hcapture_session.h"
21
22 namespace OHOS {
23 namespace CameraStandard {
24 static std::map<int32_t, sptr<HCaptureSession>> session_;
HCaptureSession(sptr<HCameraHostManager> cameraHostManager,sptr<StreamOperatorCallback> streamOperatorCb)25 HCaptureSession::HCaptureSession(sptr<HCameraHostManager> cameraHostManager,
26 sptr<StreamOperatorCallback> streamOperatorCb)
27 : cameraHostManager_(cameraHostManager), streamOperatorCallback_(streamOperatorCb),
28 sessionCallback_(nullptr)
29 {
30 std::map<int32_t, sptr<HCaptureSession>>::iterator it;
31 pid_ = IPCSkeleton::GetCallingPid();
32 uid_ = IPCSkeleton::GetCallingUid();
33 sessionState_.insert(std::make_pair(CaptureSessionState::SESSION_INIT, "Init"));
34 sessionState_.insert(std::make_pair(CaptureSessionState::SESSION_CONFIG_INPROGRESS, "Config_In-progress"));
35 sessionState_.insert(std::make_pair(CaptureSessionState::SESSION_CONFIG_COMMITTED, "Committed"));
36
37 MEDIA_DEBUG_LOG("HCaptureSession: camera stub services(%{public}zu) pid(%{public}d).", session_.size(), pid_);
38 it = session_.find(pid_);
39 if (it != session_.end()) {
40 MEDIA_ERR_LOG("HCaptureSession::HCaptureSession doesn't support multiple sessions per pid");
41 } else {
42 session_[pid_] = this;
43 }
44 MEDIA_DEBUG_LOG("HCaptureSession: camera stub services(%{public}zu).", session_.size());
45 }
46
~HCaptureSession()47 HCaptureSession::~HCaptureSession()
48 {}
49
BeginConfig()50 int32_t HCaptureSession::BeginConfig()
51 {
52 if (curState_ == CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
53 MEDIA_ERR_LOG("HCaptureSession::BeginConfig Already in config inprogress state!");
54 return CAMERA_INVALID_STATE;
55 }
56 prevState_ = curState_;
57 curState_ = CaptureSessionState::SESSION_CONFIG_INPROGRESS;
58 tempCameraDevices_.clear();
59 tempStreamCaptures_.clear();
60 tempStreamRepeats_.clear();
61 deletedStreamIds_.clear();
62 return CAMERA_OK;
63 }
64
AddInput(sptr<ICameraDeviceService> cameraDevice)65 int32_t HCaptureSession::AddInput(sptr<ICameraDeviceService> cameraDevice)
66 {
67 sptr<HCameraDevice> localCameraDevice = nullptr;
68
69 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
70 MEDIA_ERR_LOG("HCaptureSession::AddInput Need to call BeginConfig before adding input");
71 return CAMERA_INVALID_STATE;
72 }
73 if (cameraDevice == nullptr) {
74 MEDIA_ERR_LOG("HCaptureSession::AddInput cameraDevice is null");
75 return CAMERA_INVALID_ARG;
76 }
77 if (!tempCameraDevices_.empty() || (cameraDevice_ != nullptr && !cameraDevice_->IsReleaseCameraDevice())) {
78 MEDIA_ERR_LOG("HCaptureSession::AddInput Only one input is supported");
79 return CAMERA_INVALID_SESSION_CFG;
80 }
81 localCameraDevice = static_cast<HCameraDevice*>(cameraDevice.GetRefPtr());
82 if (cameraDevice_ == localCameraDevice) {
83 cameraDevice_->SetReleaseCameraDevice(false);
84 } else {
85 tempCameraDevices_.emplace_back(localCameraDevice);
86 }
87 return CAMERA_OK;
88 }
89
AddOutput(sptr<IStreamRepeat> streamRepeat)90 int32_t HCaptureSession::AddOutput(sptr<IStreamRepeat> streamRepeat)
91 {
92 sptr<HStreamRepeat> localStreamRepeat = nullptr;
93
94 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
95 MEDIA_ERR_LOG("HCaptureSession::AddOutput Need to call BeginConfig before adding output");
96 return CAMERA_INVALID_STATE;
97 }
98 // Temp hack to fix the library linking issue
99 sptr<Surface> captureSurface = Surface::CreateSurfaceAsConsumer();
100 if (streamRepeat == nullptr) {
101 MEDIA_ERR_LOG("HCaptureSession::AddOutput streamRepeat is null");
102 return CAMERA_INVALID_ARG;
103 }
104 localStreamRepeat = static_cast<HStreamRepeat *>(streamRepeat.GetRefPtr());
105 if (std::find(tempStreamRepeats_.begin(), tempStreamRepeats_.end(), localStreamRepeat) != tempStreamRepeats_.end()
106 || std::find(streamRepeats_.begin(), streamRepeats_.end(), localStreamRepeat) != streamRepeats_.end()) {
107 MEDIA_ERR_LOG("HCaptureSession::AddOutput Adding same output multiple times");
108 return CAMERA_INVALID_SESSION_CFG;
109 }
110 localStreamRepeat->SetReleaseStream(false);
111 tempStreamRepeats_.emplace_back(localStreamRepeat);
112 return CAMERA_OK;
113 }
114
AddOutput(sptr<IStreamCapture> streamCapture)115 int32_t HCaptureSession::AddOutput(sptr<IStreamCapture> streamCapture)
116 {
117 sptr<HStreamCapture> lStreamCapture = nullptr;
118
119 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
120 MEDIA_ERR_LOG("HCaptureSession::AddOutput Need to call BeginConfig before adding output");
121 return CAMERA_INVALID_STATE;
122 }
123 if (streamCapture == nullptr) {
124 MEDIA_ERR_LOG("HCaptureSession::AddOutput streamCapture is null");
125 return CAMERA_INVALID_ARG;
126 }
127 lStreamCapture = static_cast<HStreamCapture*>(streamCapture.GetRefPtr());
128 if (std::find(tempStreamCaptures_.begin(), tempStreamCaptures_.end(), lStreamCapture) != tempStreamCaptures_.end()
129 || std::find(streamCaptures_.begin(), streamCaptures_.end(), lStreamCapture) != streamCaptures_.end()) {
130 MEDIA_ERR_LOG("HCaptureSession::AddOutput Adding same output multiple times");
131 return CAMERA_INVALID_SESSION_CFG;
132 }
133 lStreamCapture->SetReleaseStream(false);
134 tempStreamCaptures_.emplace_back(lStreamCapture);
135 return CAMERA_OK;
136 }
137
RemoveInput(sptr<ICameraDeviceService> cameraDevice)138 int32_t HCaptureSession::RemoveInput(sptr<ICameraDeviceService> cameraDevice)
139 {
140 sptr<HCameraDevice> localCameraDevice;
141
142 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
143 MEDIA_ERR_LOG("HCaptureSession::RemoveInput Need to call BeginConfig before removing input");
144 return CAMERA_INVALID_STATE;
145 }
146 if (cameraDevice == nullptr) {
147 MEDIA_ERR_LOG("HCaptureSession::RemoveInput cameraDevice is null");
148 return CAMERA_INVALID_ARG;
149 }
150 localCameraDevice = static_cast<HCameraDevice*>(cameraDevice.GetRefPtr());
151 auto it = std::find(tempCameraDevices_.begin(), tempCameraDevices_.end(), localCameraDevice);
152 if (it != tempCameraDevices_.end()) {
153 tempCameraDevices_.erase(it);
154 } else if (cameraDevice_ == localCameraDevice) {
155 cameraDevice_->SetReleaseCameraDevice(true);
156 } else {
157 MEDIA_ERR_LOG("HCaptureSession::RemoveInput Invalid camera device");
158 return CAMERA_INVALID_SESSION_CFG;
159 }
160 return CAMERA_OK;
161 }
162
RemoveOutput(sptr<IStreamRepeat> streamRepeat)163 int32_t HCaptureSession::RemoveOutput(sptr<IStreamRepeat> streamRepeat)
164 {
165 sptr<HStreamRepeat> lStreamRepeat = nullptr;
166
167 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
168 MEDIA_ERR_LOG("HCaptureSession::RemoveOutput Need to call BeginConfig before removing output");
169 return CAMERA_INVALID_STATE;
170 }
171 if (streamRepeat == nullptr) {
172 MEDIA_ERR_LOG("HCaptureSession::RemoveOutput streamRepeat is null");
173 return CAMERA_INVALID_ARG;
174 }
175 lStreamRepeat = static_cast<HStreamRepeat *>(streamRepeat.GetRefPtr());
176 auto it = std::find(tempStreamRepeats_.begin(), tempStreamRepeats_.end(), lStreamRepeat);
177 if (it != tempStreamRepeats_.end()) {
178 tempStreamRepeats_.erase(it);
179 } else {
180 it = std::find(streamRepeats_.begin(), streamRepeats_.end(), lStreamRepeat);
181 if (it != streamRepeats_.end()) {
182 if (!lStreamRepeat->IsReleaseStream()) {
183 deletedStreamIds_.emplace_back(lStreamRepeat->GetStreamId());
184 lStreamRepeat->SetReleaseStream(true);
185 }
186 } else {
187 MEDIA_ERR_LOG("HCaptureSession::RemoveOutput Invalid output");
188 return CAMERA_INVALID_SESSION_CFG;
189 }
190 }
191 return CAMERA_OK;
192 }
193
RemoveOutput(sptr<IStreamCapture> streamCapture)194 int32_t HCaptureSession::RemoveOutput(sptr<IStreamCapture> streamCapture)
195 {
196 sptr<HStreamCapture> lStreamCapture = nullptr;
197
198 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
199 MEDIA_ERR_LOG("HCaptureSession::RemoveOutput Need to call BeginConfig before removing output");
200 return CAMERA_INVALID_STATE;
201 }
202 if (streamCapture == nullptr) {
203 MEDIA_ERR_LOG("HCaptureSession::RemoveOutput streamCapture is null");
204 return CAMERA_INVALID_ARG;
205 }
206 lStreamCapture = static_cast<HStreamCapture *>(streamCapture.GetRefPtr());
207 auto it = std::find(tempStreamCaptures_.begin(), tempStreamCaptures_.end(), lStreamCapture);
208 if (it != tempStreamCaptures_.end()) {
209 tempStreamCaptures_.erase(it);
210 } else {
211 it = std::find(streamCaptures_.begin(), streamCaptures_.end(), lStreamCapture);
212 if (it != streamCaptures_.end()) {
213 if (!lStreamCapture->IsReleaseStream()) {
214 deletedStreamIds_.emplace_back(lStreamCapture->GetStreamId());
215 lStreamCapture->SetReleaseStream(true);
216 }
217 } else {
218 MEDIA_ERR_LOG("HCaptureSession::RemoveOutput Invalid output");
219 return CAMERA_INVALID_SESSION_CFG;
220 }
221 }
222 return CAMERA_OK;
223 }
224
ValidateSessionInputs()225 int32_t HCaptureSession::ValidateSessionInputs()
226 {
227 if (tempCameraDevices_.empty() && (cameraDevice_ == nullptr || cameraDevice_->IsReleaseCameraDevice())) {
228 MEDIA_ERR_LOG("HCaptureSession::ValidateSessionInputs No inputs present");
229 return CAMERA_INVALID_SESSION_CFG;
230 }
231 return CAMERA_OK;
232 }
233
ValidateSessionOutputs()234 int32_t HCaptureSession::ValidateSessionOutputs()
235 {
236 uint32_t currentOutputCnt = streamCaptures_.size() + streamRepeats_.size();
237 uint32_t newOutputCnt = tempStreamCaptures_.size() + tempStreamRepeats_.size();
238 if (newOutputCnt + currentOutputCnt - deletedStreamIds_.size() == 0) {
239 MEDIA_ERR_LOG("HCaptureSession::ValidateSessionOutputs No outputs present");
240 return CAMERA_INVALID_SESSION_CFG;
241 }
242 return CAMERA_OK;
243 }
244
GetCameraDevice(sptr<HCameraDevice> & device)245 int32_t HCaptureSession::GetCameraDevice(sptr<HCameraDevice> &device)
246 {
247 int32_t rc;
248 sptr<HCameraDevice> camDevice;
249 sptr<Camera::IStreamOperator> streamOperator;
250
251 if (cameraDevice_ != nullptr && !cameraDevice_->IsReleaseCameraDevice()) {
252 MEDIA_DEBUG_LOG("HCaptureSession::GetCameraDevice Camera device has not changed");
253 device = cameraDevice_;
254 return CAMERA_OK;
255 }
256 camDevice = tempCameraDevices_[0];
257 rc = camDevice->Open();
258 if (rc != CAMERA_OK) {
259 MEDIA_ERR_LOG("HCaptureSession::GetCameraDevice Failed to open camera, rc: %{public}d", rc);
260 return rc;
261 }
262 rc = camDevice->GetStreamOperator(streamOperatorCallback_, streamOperator);
263 if (rc != CAMERA_OK) {
264 MEDIA_ERR_LOG("HCaptureSession::GetCameraDevice GetStreamOperator returned %{public}d", rc);
265 camDevice->Close();
266 return rc;
267 }
268 device = camDevice;
269 return rc;
270 }
271
GetCurrentStreamInfos(sptr<HCameraDevice> & device,std::shared_ptr<Camera::CameraMetadata> & deviceSettings,std::vector<std::shared_ptr<Camera::StreamInfo>> & streamInfos)272 int32_t HCaptureSession::GetCurrentStreamInfos(sptr<HCameraDevice> &device,
273 std::shared_ptr<Camera::CameraMetadata> &deviceSettings,
274 std::vector<std::shared_ptr<Camera::StreamInfo>> &streamInfos)
275 {
276 int32_t rc;
277 int32_t streamId = streamId_;
278 bool isNeedLink;
279 std::shared_ptr<Camera::StreamInfo> curStreamInfo;
280 sptr<Camera::IStreamOperator> streamOperator;
281 sptr<HStreamCapture> curStreamCapture;
282 sptr<HStreamRepeat> curStreamRepeat;
283
284 streamOperator = device->GetStreamOperator();
285 isNeedLink = (device != cameraDevice_);
286 for (auto item = streamCaptures_.begin(); item != streamCaptures_.end(); ++item) {
287 curStreamCapture = *item;
288 if (curStreamCapture->IsReleaseStream()) {
289 continue;
290 }
291 if (isNeedLink) {
292 rc = curStreamCapture->LinkInput(streamOperator, deviceSettings, streamId);
293 if (rc != CAMERA_OK) {
294 MEDIA_ERR_LOG("HCaptureSession::GetCurrentStreamInfos() Failed to link Output, %{public}d", rc);
295 return rc;
296 }
297 streamId++;
298 }
299 curStreamInfo = std::make_shared<Camera::StreamInfo>();
300 curStreamCapture->SetStreamInfo(curStreamInfo);
301 streamInfos.push_back(curStreamInfo);
302 }
303 for (auto item = streamRepeats_.begin(); item != streamRepeats_.end(); ++item) {
304 curStreamRepeat = *item;
305 if (curStreamRepeat->IsReleaseStream()) {
306 continue;
307 }
308 if (isNeedLink) {
309 rc = curStreamRepeat->LinkInput(streamOperator, deviceSettings, streamId);
310 if (rc != CAMERA_OK) {
311 MEDIA_ERR_LOG("HCaptureSession::GetCurrentStreamInfos() Failed to link Output, %{public}d", rc);
312 return rc;
313 }
314 streamId++;
315 }
316 curStreamInfo = std::make_shared<Camera::StreamInfo>();
317 curStreamRepeat->SetStreamInfo(curStreamInfo);
318 streamInfos.push_back(curStreamInfo);
319 }
320
321 if (streamId != streamId_) {
322 streamId_ = streamId;
323 }
324 return CAMERA_OK;
325 }
326
CreateAndCommitStreams(sptr<HCameraDevice> & device,std::shared_ptr<Camera::CameraMetadata> & deviceSettings,std::vector<std::shared_ptr<Camera::StreamInfo>> & streamInfos)327 int32_t HCaptureSession::CreateAndCommitStreams(sptr<HCameraDevice> &device,
328 std::shared_ptr<Camera::CameraMetadata> &deviceSettings,
329 std::vector<std::shared_ptr<Camera::StreamInfo>> &streamInfos)
330 {
331 Camera::CamRetCode hdiRc = Camera::NO_ERROR;
332 std::vector<int32_t> streamIds;
333 std::shared_ptr<Camera::StreamInfo> curStreamInfo;
334 sptr<Camera::IStreamOperator> streamOperator;
335
336 streamOperator = device->GetStreamOperator();
337 if (!streamInfos.empty()) {
338 hdiRc = streamOperator->CreateStreams(streamInfos);
339 } else {
340 MEDIA_INFO_LOG("HCaptureSession::CreateAndCommitStreams(), No new streams to create");
341 }
342 if (hdiRc == Camera::NO_ERROR) {
343 hdiRc = streamOperator->CommitStreams(Camera::NORMAL, deviceSettings);
344 if (hdiRc != Camera::NO_ERROR) {
345 MEDIA_ERR_LOG("HCaptureSession::CreateAndCommitStreams(), Failed to commit %{public}d", hdiRc);
346 for (auto item = streamInfos.begin(); item != streamInfos.end(); ++item) {
347 curStreamInfo = *item;
348 streamIds.emplace_back(curStreamInfo->streamId_);
349 }
350 if (!streamIds.empty() && streamOperator->ReleaseStreams(streamIds) != Camera::NO_ERROR) {
351 MEDIA_ERR_LOG("HCaptureSession::CreateAndCommitStreams(), Failed to release streams");
352 }
353 }
354 }
355 return HdiToServiceError(hdiRc);
356 }
357
CheckAndCommitStreams(sptr<HCameraDevice> & device,std::shared_ptr<Camera::CameraMetadata> & deviceSettings,std::vector<std::shared_ptr<Camera::StreamInfo>> & allStreamInfos,std::vector<std::shared_ptr<Camera::StreamInfo>> & newStreamInfos)358 int32_t HCaptureSession::CheckAndCommitStreams(sptr<HCameraDevice> &device,
359 std::shared_ptr<Camera::CameraMetadata> &deviceSettings,
360 std::vector<std::shared_ptr<Camera::StreamInfo>> &allStreamInfos,
361 std::vector<std::shared_ptr<Camera::StreamInfo>> &newStreamInfos)
362 {
363 #ifndef BALTIMORE_CAMERA
364 Camera::CamRetCode hdiRc = Camera::NO_ERROR;
365 Camera::StreamSupportType supportType = Camera::DYNAMIC_SUPPORTED;
366
367 hdiRc = device->GetStreamOperator()->IsStreamsSupported(Camera::NORMAL, deviceSettings,
368 allStreamInfos, supportType);
369 if (hdiRc != Camera::NO_ERROR) {
370 MEDIA_ERR_LOG("HCaptureSession::CheckAndCommitStreams(), Error from HDI: %{public}d", hdiRc);
371 return HdiToServiceError(hdiRc);
372 } else if (supportType != Camera::DYNAMIC_SUPPORTED) {
373 MEDIA_ERR_LOG("HCaptureSession::CheckAndCommitStreams(), Config not supported %{public}d", supportType);
374 return CAMERA_UNSUPPORTED;
375 }
376 #endif
377 return CreateAndCommitStreams(device, deviceSettings, newStreamInfos);
378 }
379
DeleteReleasedStream()380 void HCaptureSession::DeleteReleasedStream()
381 {
382 sptr<HStreamCapture> curStreamCapture;
383 sptr<HStreamRepeat> curStreamRepeat;
384
385 for (auto item = streamCaptures_.begin(); item != streamCaptures_.end(); ++item) {
386 curStreamCapture = *item;
387 if (curStreamCapture->IsReleaseStream()) {
388 curStreamCapture->Release();
389 streamCaptures_.erase(item--);
390 }
391 }
392 for (auto item = streamRepeats_.begin(); item != streamRepeats_.end(); ++item) {
393 curStreamRepeat = *item;
394 if (curStreamRepeat->IsReleaseStream()) {
395 curStreamRepeat->Release();
396 streamRepeats_.erase(item--);
397 }
398 }
399 }
400
RestorePreviousState(sptr<HCameraDevice> & device,bool isCreateReleaseStreams)401 void HCaptureSession::RestorePreviousState(sptr<HCameraDevice> &device, bool isCreateReleaseStreams)
402 {
403 std::vector<std::shared_ptr<Camera::StreamInfo>> streamInfos;
404 std::shared_ptr<Camera::StreamInfo> streamInfo;
405 std::shared_ptr<Camera::CameraMetadata> settings;
406 sptr<HStreamCapture> curStreamCapture;
407 sptr<HStreamRepeat> curStreamRepeat;
408
409 MEDIA_DEBUG_LOG("HCaptureSession::RestorePreviousState, Restore to previous state");
410
411 for (auto item = streamCaptures_.begin(); item != streamCaptures_.end(); ++item) {
412 curStreamCapture = *item;
413 if (isCreateReleaseStreams && curStreamCapture->IsReleaseStream()) {
414 streamInfo = std::make_shared<Camera::StreamInfo>();
415 curStreamCapture->SetStreamInfo(streamInfo);
416 streamInfos.push_back(streamInfo);
417 }
418 curStreamCapture->SetReleaseStream(false);
419 }
420 for (auto item = streamRepeats_.begin(); item != streamRepeats_.end(); ++item) {
421 curStreamRepeat = *item;
422 if (isCreateReleaseStreams && curStreamRepeat->IsReleaseStream()) {
423 streamInfo = std::make_shared<Camera::StreamInfo>();
424 curStreamRepeat->SetStreamInfo(streamInfo);
425 streamInfos.push_back(streamInfo);
426 }
427 curStreamRepeat->SetReleaseStream(false);
428 }
429
430 for (auto item = tempStreamCaptures_.begin(); item != tempStreamCaptures_.end(); ++item) {
431 curStreamCapture = *item;
432 curStreamCapture->Release();
433 }
434 tempStreamCaptures_.clear();
435 for (auto item = tempStreamRepeats_.begin(); item != tempStreamRepeats_.end(); ++item) {
436 curStreamRepeat = *item;
437 curStreamRepeat->Release();
438 }
439 tempStreamRepeats_.clear();
440 deletedStreamIds_.clear();
441 tempCameraDevices_.clear();
442 if (device != nullptr) {
443 device->SetReleaseCameraDevice(false);
444 if (isCreateReleaseStreams) {
445 settings = device->GetSettings();
446 if (settings != nullptr) {
447 CreateAndCommitStreams(device, settings, streamInfos);
448 }
449 }
450 }
451 curState_ = prevState_;
452 }
453
UpdateSessionConfig(sptr<HCameraDevice> & device)454 void HCaptureSession::UpdateSessionConfig(sptr<HCameraDevice> &device)
455 {
456 DeleteReleasedStream();
457 deletedStreamIds_.clear();
458 for (auto item = tempStreamCaptures_.begin(); item != tempStreamCaptures_.end(); ++item) {
459 streamCaptures_.emplace_back(*item);
460 }
461 tempStreamCaptures_.clear();
462 for (auto item = tempStreamRepeats_.begin(); item != tempStreamRepeats_.end(); ++item) {
463 streamRepeats_.emplace_back(*item);
464 }
465 tempStreamRepeats_.clear();
466 streamOperatorCallback_->SetCaptureSession(this);
467 cameraDevice_ = device;
468 curState_ = CaptureSessionState::SESSION_CONFIG_COMMITTED;
469 return;
470 }
471
HandleCaptureOuputsConfig(sptr<HCameraDevice> & device)472 int32_t HCaptureSession::HandleCaptureOuputsConfig(sptr<HCameraDevice> &device)
473 {
474 int32_t rc;
475 int32_t streamId;
476 std::vector<std::shared_ptr<Camera::StreamInfo>> newStreamInfos;
477 std::vector<std::shared_ptr<Camera::StreamInfo>> allStreamInfos;
478 std::shared_ptr<Camera::StreamInfo> curStreamInfo;
479 std::shared_ptr<Camera::CameraMetadata> settings;
480 sptr<Camera::IStreamOperator> streamOperator;
481 sptr<HStreamCapture> curStreamCapture;
482 sptr<HStreamRepeat> curStreamRepeat;
483
484 settings = device->GetSettings();
485 if (settings == nullptr) {
486 return CAMERA_UNKNOWN_ERROR;
487 }
488
489 rc = GetCurrentStreamInfos(device, settings, allStreamInfos);
490 if (rc != CAMERA_OK) {
491 MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() Failed to get streams info, %{public}d", rc);
492 return rc;
493 }
494
495 if (cameraDevice_ != device) {
496 newStreamInfos = allStreamInfos;
497 }
498
499 streamOperator = device->GetStreamOperator();
500 streamId = streamId_;
501 for (auto item = tempStreamCaptures_.begin(); item != tempStreamCaptures_.end(); ++item) {
502 curStreamCapture = *item;
503 rc = curStreamCapture->LinkInput(streamOperator, settings, streamId);
504 if (rc != CAMERA_OK) {
505 MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() Failed to link Output, %{public}d", rc);
506 return rc;
507 }
508 curStreamInfo = std::make_shared<Camera::StreamInfo>();
509 curStreamCapture->SetStreamInfo(curStreamInfo);
510 newStreamInfos.push_back(curStreamInfo);
511 allStreamInfos.push_back(curStreamInfo);
512 streamId++;
513 }
514 for (auto item = tempStreamRepeats_.begin(); item != tempStreamRepeats_.end(); ++item) {
515 curStreamRepeat = *item;
516 rc = curStreamRepeat->LinkInput(streamOperator, settings, streamId);
517 if (rc != CAMERA_OK) {
518 MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() Failed to link Output, %{public}d", rc);
519 return rc;
520 }
521 curStreamInfo = std::make_shared<Camera::StreamInfo>();
522 curStreamRepeat->SetStreamInfo(curStreamInfo);
523 newStreamInfos.push_back(curStreamInfo);
524 allStreamInfos.push_back(curStreamInfo);
525 streamId++;
526 }
527
528 rc = CheckAndCommitStreams(device, settings, allStreamInfos, newStreamInfos);
529 if (rc == CAMERA_OK) {
530 streamId_ = streamId;
531 }
532 return rc;
533 }
534
CommitConfig()535 int32_t HCaptureSession::CommitConfig()
536 {
537 int32_t rc;
538 sptr<HCameraDevice> device = nullptr;
539
540 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
541 MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Need to call BeginConfig before committing configuration");
542 return CAMERA_INVALID_STATE;
543 }
544
545 rc = ValidateSessionInputs();
546 if (rc != CAMERA_OK) {
547 return rc;
548 }
549 rc = ValidateSessionOutputs();
550 if (rc != CAMERA_OK) {
551 return rc;
552 }
553
554 rc = GetCameraDevice(device);
555 if ((rc == CAMERA_OK) && (device == cameraDevice_) && !deletedStreamIds_.empty()) {
556 rc = HdiToServiceError(device->GetStreamOperator()->ReleaseStreams(deletedStreamIds_));
557 }
558
559 if (rc != CAMERA_OK) {
560 MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Failed to commit config. rc: %{public}d", rc);
561 if (device != nullptr && device != cameraDevice_) {
562 device->Close();
563 }
564 RestorePreviousState(cameraDevice_, false);
565 return rc;
566 }
567
568 rc = HandleCaptureOuputsConfig(device);
569 if (rc != CAMERA_OK) {
570 MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Failed to commit config. rc: %{public}d", rc);
571 if (device != nullptr && device != cameraDevice_) {
572 device->Close();
573 }
574 RestorePreviousState(cameraDevice_, !deletedStreamIds_.empty());
575 return rc;
576 }
577 if (cameraDevice_ != nullptr && device != cameraDevice_) {
578 cameraDevice_->Close();
579 cameraDevice_ = nullptr;
580 }
581 UpdateSessionConfig(device);
582 return rc;
583 }
584
Start()585 int32_t HCaptureSession::Start()
586 {
587 int32_t rc = CAMERA_INVALID_STATE;
588 sptr<HStreamRepeat> curStreamRepeat;
589
590 if (curState_ != CaptureSessionState::SESSION_CONFIG_COMMITTED) {
591 return rc;
592 }
593 for (auto item = streamRepeats_.begin(); item != streamRepeats_.end(); ++item) {
594 curStreamRepeat = *item;
595 if (!curStreamRepeat->IsVideo()) {
596 rc = curStreamRepeat->Start();
597 if (rc != CAMERA_OK) {
598 MEDIA_ERR_LOG("HCaptureSession::Start(), Failed to start preview, rc: %{public}d", rc);
599 break;
600 }
601 }
602 }
603 return rc;
604 }
605
Stop()606 int32_t HCaptureSession::Stop()
607 {
608 int32_t rc = CAMERA_INVALID_STATE;
609 sptr<HStreamRepeat> curStreamRepeat;
610
611 if (curState_ != CaptureSessionState::SESSION_CONFIG_COMMITTED) {
612 return rc;
613 }
614
615 for (auto item = streamRepeats_.begin(); item != streamRepeats_.end(); ++item) {
616 curStreamRepeat = *item;
617 if (!curStreamRepeat->IsVideo()) {
618 rc = curStreamRepeat->Stop();
619 if (rc != CAMERA_OK) {
620 MEDIA_ERR_LOG("HCaptureSession::Stop(), Failed to stop preview, rc: %{public}d", rc);
621 break;
622 }
623 }
624 }
625 return rc;
626 }
627
ClearCaptureSession(pid_t pid)628 void HCaptureSession::ClearCaptureSession(pid_t pid)
629 {
630 MEDIA_DEBUG_LOG("ClearCaptureSession: camera stub services(%{public}zu) pid(%{public}d).", session_.size(), pid);
631 auto it = session_.find(pid);
632 if (it != session_.end()) {
633 session_.erase(it);
634 }
635 MEDIA_DEBUG_LOG("ClearCaptureSession: camera stub services(%{public}zu).", session_.size());
636 }
637
ReleaseStreams()638 void HCaptureSession::ReleaseStreams()
639 {
640 std::vector<int32_t> streamIds;
641 sptr<HStreamCapture> curStreamCapture;
642 sptr<HStreamRepeat> curStreamRepeat;
643
644 for (auto item = streamRepeats_.begin(); item != streamRepeats_.end(); ++item) {
645 curStreamRepeat = *item;
646 streamIds.emplace_back(curStreamRepeat->GetStreamId());
647 curStreamRepeat->Release();
648 }
649 streamRepeats_.clear();
650 HStreamRepeat::ResetCaptureIds();
651 for (auto item = streamCaptures_.begin(); item != streamCaptures_.end(); ++item) {
652 curStreamCapture = *item;
653 streamIds.emplace_back(curStreamCapture->GetStreamId());
654 curStreamCapture->Release();
655 }
656 streamCaptures_.clear();
657 HStreamCapture::ResetCaptureId();
658 if ((cameraDevice_ != nullptr) && (cameraDevice_->GetStreamOperator() != nullptr) && !streamIds.empty()) {
659 cameraDevice_->GetStreamOperator()->ReleaseStreams(streamIds);
660 }
661 }
662
Release(pid_t pid)663 int32_t HCaptureSession::Release(pid_t pid)
664 {
665 ClearCaptureSession(pid);
666 ReleaseStreams();
667 if (streamOperatorCallback_ != nullptr) {
668 streamOperatorCallback_->SetCaptureSession(nullptr);
669 streamOperatorCallback_ = nullptr;
670 }
671 if (cameraDevice_ != nullptr) {
672 cameraDevice_->Close();
673 cameraDevice_ = nullptr;
674 }
675 return CAMERA_OK;
676 }
677
DestroyStubObjectForPid(pid_t pid)678 void HCaptureSession::DestroyStubObjectForPid(pid_t pid)
679 {
680 MEDIA_DEBUG_LOG("camera stub services(%{public}zu) pid(%{public}d).", session_.size(), pid);
681 sptr<HCaptureSession> session;
682
683 auto it = session_.find(pid);
684 if (it != session_.end()) {
685 session = it->second;
686 session->Release(pid);
687 }
688 MEDIA_DEBUG_LOG("camera stub services(%{public}zu).", session_.size());
689 }
690
SetCallback(sptr<ICaptureSessionCallback> & callback)691 int32_t HCaptureSession::SetCallback(sptr<ICaptureSessionCallback> &callback)
692 {
693 if (callback == nullptr) {
694 MEDIA_ERR_LOG("HCaptureSession::SetCallback callback is null");
695 return CAMERA_INVALID_ARG;
696 }
697
698 sessionCallback_ = callback;
699 return CAMERA_OK;
700 }
701
GetSessionState()702 std::string HCaptureSession::GetSessionState()
703 {
704 std::map<CaptureSessionState, std::string>::const_iterator iter =
705 sessionState_.find(curState_);
706 if (iter != sessionState_.end()) {
707 return iter->second;
708 }
709 return nullptr;
710 }
711
CameraSessionSummary(std::string & dumpString)712 void HCaptureSession::CameraSessionSummary(std::string& dumpString)
713 {
714 dumpString += "# Number of Camera clients:[" + std::to_string(session_.size()) + "]:\n";
715 }
716
dumpSessions(std::string & dumpString)717 void HCaptureSession::dumpSessions(std::string& dumpString)
718 {
719 for (auto it = session_.begin(); it != session_.end(); it++) {
720 sptr<HCaptureSession> session = it->second;
721 dumpString += "No. of sessions for client:[" + std::to_string(1) + "]:\n";
722 session->dumpSessionInfo(dumpString);
723 }
724 }
725
dumpSessionInfo(std::string & dumpString)726 void HCaptureSession::dumpSessionInfo(std::string& dumpString)
727 {
728 sptr<HStreamCapture> streamCaptures;
729
730 dumpString += "Client pid:[" + std::to_string(pid_)
731 + "] Client uid:[" + std::to_string(uid_) + "]:\n";
732 dumpString += "session state:[" + GetSessionState() + "]:\n";
733 if (cameraDevice_ != nullptr) {
734 dumpString += "session Camera Id:[" + cameraDevice_->GetCameraId() + "]:\n";
735 dumpString += "session Camera release status:["
736 + std::to_string(cameraDevice_->IsReleaseCameraDevice()) + "]:\n";
737 }
738 if (streamCaptures_.size()) {
739 sptr<HStreamCapture> curStreamCapture;
740 for (auto item = streamCaptures_.begin(); item != streamCaptures_.end(); ++item) {
741 curStreamCapture = *item;
742 dumpString += "stream capture:\nrelease status:["
743 + std::to_string(curStreamCapture->IsReleaseStream()) + "]:\n";
744 curStreamCapture->dumpCaptureStreamInfo(dumpString);
745 }
746 }
747 if (streamRepeats_.size()) {
748 sptr<HStreamRepeat> curStreamRepeat = nullptr;
749 for (auto item = streamRepeats_.begin(); item != streamRepeats_.end(); ++item) {
750 curStreamRepeat = *item;
751 dumpString += "stream repeat:\nrelease status:["
752 + std::to_string(curStreamRepeat->IsReleaseStream()) + "]:\n";
753 curStreamRepeat->dumpRepeatStreamInfo(dumpString);
754 }
755 }
756 }
757
StreamOperatorCallback(sptr<HCaptureSession> session)758 StreamOperatorCallback::StreamOperatorCallback(sptr<HCaptureSession> session)
759 {
760 captureSession_ = session;
761 }
762
GetStreamRepeatByStreamID(int32_t streamId)763 sptr<HStreamRepeat> StreamOperatorCallback::GetStreamRepeatByStreamID(int32_t streamId)
764 {
765 sptr<HStreamRepeat> curStreamRepeat;
766 sptr<HStreamRepeat> result = nullptr;
767
768 if (captureSession_ != nullptr) {
769 for (auto item = captureSession_->streamRepeats_.begin();
770 item != captureSession_->streamRepeats_.end(); ++item) {
771 curStreamRepeat = *item;
772 if (curStreamRepeat->GetStreamId() == streamId) {
773 result = curStreamRepeat;
774 break;
775 }
776 }
777 }
778 return result;
779 }
780
GetStreamCaptureByStreamID(int32_t streamId)781 sptr<HStreamCapture> StreamOperatorCallback::GetStreamCaptureByStreamID(int32_t streamId)
782 {
783 sptr<HStreamCapture> curStreamCapture;
784 sptr<HStreamCapture> result = nullptr;
785
786 if (captureSession_ != nullptr) {
787 for (auto item = captureSession_->streamCaptures_.begin();
788 item != captureSession_->streamCaptures_.end(); ++item) {
789 curStreamCapture = *item;
790 if (curStreamCapture->GetStreamId() == streamId) {
791 result = curStreamCapture;
792 break;
793 }
794 }
795 }
796 return result;
797 }
798
799
OnCaptureStarted(int32_t captureId,const std::vector<int32_t> & streamIds)800 void StreamOperatorCallback::OnCaptureStarted(int32_t captureId,
801 const std::vector<int32_t> &streamIds)
802 {
803 sptr<HStreamCapture> curStreamCapture;
804 sptr<HStreamRepeat> curStreamRepeat;
805
806 for (auto item = streamIds.begin(); item != streamIds.end(); ++item) {
807 curStreamRepeat = GetStreamRepeatByStreamID(*item);
808 if (curStreamRepeat != nullptr) {
809 curStreamRepeat->OnFrameStarted();
810 } else {
811 curStreamCapture = GetStreamCaptureByStreamID(*item);
812 if (curStreamCapture != nullptr) {
813 curStreamCapture->OnCaptureStarted(captureId);
814 } else {
815 MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureStarted StreamId: %{public}d not found", *item);
816 }
817 }
818 }
819 }
820
OnCaptureEnded(int32_t captureId,const std::vector<std::shared_ptr<Camera::CaptureEndedInfo>> & info)821 void StreamOperatorCallback::OnCaptureEnded(int32_t captureId,
822 const std::vector<std::shared_ptr<Camera::CaptureEndedInfo>> &info)
823 {
824 sptr<HStreamCapture> curStreamCapture;
825 sptr<HStreamRepeat> curStreamRepeat;
826 std::shared_ptr<Camera::CaptureEndedInfo> captureInfo = nullptr;
827
828 for (auto item = info.begin(); item != info.end(); ++item) {
829 captureInfo = *item;
830 curStreamRepeat = GetStreamRepeatByStreamID(captureInfo->streamId_);
831 if (curStreamRepeat != nullptr) {
832 curStreamRepeat->OnFrameEnded(captureInfo->frameCount_);
833 } else {
834 curStreamCapture = GetStreamCaptureByStreamID(captureInfo->streamId_);
835 if (curStreamCapture != nullptr) {
836 curStreamCapture->OnCaptureEnded(captureId, captureInfo->frameCount_);
837 } else {
838 MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureEnded StreamId: %{public}d not found."
839 " Framecount: %{public}d", captureInfo->streamId_, captureInfo->frameCount_);
840 }
841 }
842 }
843 }
844
OnCaptureError(int32_t captureId,const std::vector<std::shared_ptr<Camera::CaptureErrorInfo>> & info)845 void StreamOperatorCallback::OnCaptureError(int32_t captureId,
846 const std::vector<std::shared_ptr<Camera::CaptureErrorInfo>> &info)
847 {
848 sptr<HStreamCapture> curStreamCapture;
849 sptr<HStreamRepeat> curStreamRepeat;
850 std::shared_ptr<Camera::CaptureErrorInfo> errInfo = nullptr;
851
852 for (auto item = info.begin(); item != info.end(); ++item) {
853 errInfo = *item;
854 curStreamRepeat = GetStreamRepeatByStreamID(errInfo->streamId_);
855 if (curStreamRepeat != nullptr) {
856 curStreamRepeat->OnFrameError(errInfo->error_);
857 } else {
858 curStreamCapture = GetStreamCaptureByStreamID(errInfo->streamId_);
859 if (curStreamCapture != nullptr) {
860 curStreamCapture->OnCaptureError(captureId, errInfo->error_);
861 } else {
862 MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureError StreamId: %{public}d not found."
863 " Error: %{public}d", errInfo->streamId_, errInfo->error_);
864 }
865 }
866 }
867 }
868
OnFrameShutter(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)869 void StreamOperatorCallback::OnFrameShutter(int32_t captureId,
870 const std::vector<int32_t> &streamIds, uint64_t timestamp)
871 {
872 sptr<HStreamCapture> curStreamCapture;
873
874 for (auto item = streamIds.begin(); item != streamIds.end(); ++item) {
875 curStreamCapture = GetStreamCaptureByStreamID(*item);
876 if (curStreamCapture != nullptr) {
877 curStreamCapture->OnFrameShutter(captureId, timestamp);
878 } else {
879 MEDIA_ERR_LOG("StreamOperatorCallback::OnFrameShutter StreamId: %{public}d not found", *item);
880 }
881 }
882 }
883
SetCaptureSession(sptr<HCaptureSession> captureSession)884 void StreamOperatorCallback::SetCaptureSession(sptr<HCaptureSession> captureSession)
885 {
886 captureSession_ = captureSession;
887 }
888 } // namespace CameraStandard
889 } // namespace OHOS
890