• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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