1 /*
2 * Copyright (c) 2021 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 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
12 */
13
14 #include "stream_pipeline_core.h"
15 #include "idevice_manager.h"
16 #include "ipp_node.h"
17 #include "camera_hal_hisysevent.h"
18
19 namespace OHOS::Camera {
Init(const std::string & cameraId)20 RetCode StreamPipelineCore::Init(const std::string &cameraId)
21 {
22 strategy_ = StreamPipelineStrategy::Create(context_->streamMgr_);
23 builder_ = StreamPipelineBuilder::Create(context_->streamMgr_);
24 dispatcher_ = StreamPipelineDispatcher::Create();
25 cameraId_ = cameraId;
26 return RC_OK;
27 }
28
PreConfig(const ModeMeta & meta)29 RetCode StreamPipelineCore::PreConfig(const ModeMeta& meta)
30 {
31 auto deviceManager = IDeviceManager::GetInstance();
32 CHECK_IF_PTR_NULL_RETURN_VALUE(deviceManager, RC_ERROR);
33
34 std::vector<DeviceStreamSetting> settings = {};
35 std::vector<int32_t> ids = {};
36 context_->streamMgr_->GetStreamIds(ids);
37 for (auto i : ids) {
38 auto info = context_->streamMgr_->GetStreamInfo(i);
39 DeviceStreamSetting setting = {info.streamId_, info.bufferCount_, info.width_, info.height_,
40 info.format_, info.usage_, static_cast<CameraEncodeType>(info.encodeType_)};
41 settings.emplace_back(setting);
42 }
43 return deviceManager->PreConfig(meta, settings);
44 }
45
CreatePipeline(const int32_t & mode)46 RetCode StreamPipelineCore::CreatePipeline(const int32_t& mode)
47 {
48 std::lock_guard<std::recursive_mutex> l(mutex_);
49 std::shared_ptr<PipelineSpec> spec = strategy_->GeneratePipelineSpec(mode);
50 if (spec == nullptr) {
51 CameraHalHisysevent::WriteFaultHisysEvent(CameraHalHisysevent::GetEventName(CREATE_PIPELINE_ERROR),
52 CameraHalHisysevent::CreateMsg("CreatePipeline GeneratePipelineSpec failed mode:%d", mode));
53 return RC_ERROR;
54 }
55 std::shared_ptr<Pipeline> pipeline = builder_->Build(spec, cameraId_);
56 if (pipeline == nullptr) {
57 CameraHalHisysevent::WriteFaultHisysEvent(CameraHalHisysevent::GetEventName(CREATE_PIPELINE_ERROR),
58 CameraHalHisysevent::CreateMsg("CreatePipeline Build failed mode:%d", mode));
59 return RC_ERROR;
60 }
61 return dispatcher_->Update(pipeline);
62 }
63
DestroyPipeline(const std::vector<int> & streamIds)64 RetCode StreamPipelineCore::DestroyPipeline(const std::vector<int>& streamIds)
65 {
66 std::lock_guard<std::recursive_mutex> l(mutex_);
67 RetCode re = RC_OK;
68 for (const auto& it : streamIds) {
69 re = dispatcher_->Destroy(it) | re;
70 re = builder_->Destroy(it) | re;
71 re = strategy_->Destroy(it) | re;
72 }
73 return re;
74 }
75
Prepare(const std::vector<int> & streamIds)76 RetCode StreamPipelineCore::Prepare(const std::vector<int>& streamIds)
77 {
78 std::lock_guard<std::recursive_mutex> l(mutex_);
79 RetCode re = RC_OK;
80 for (const auto& it : streamIds) {
81 re = dispatcher_->Prepare(it) | re;
82 }
83 return re;
84 }
85
Start(const std::vector<int> & streamIds)86 RetCode StreamPipelineCore::Start(const std::vector<int>& streamIds)
87 {
88 std::lock_guard<std::recursive_mutex> l(mutex_);
89 RetCode re = RC_OK;
90 for (const auto& it : streamIds) {
91 re = dispatcher_->Start(it) | re;
92 }
93 return re;
94 }
95
SetCallback(const MetaDataCb cb)96 RetCode StreamPipelineCore::SetCallback(const MetaDataCb cb)
97 {
98 CAMERA_LOGE("StreamPipelineCore %{public}s: line: %{public}d", __FUNCTION__, __LINE__);
99 std::lock_guard<std::recursive_mutex> l(mutex_);
100 RetCode re = RC_OK;
101 dispatcher_->SetCallback(cb);
102 return re;
103 }
104
Stop(const std::vector<int> & streamIds)105 RetCode StreamPipelineCore::Stop(const std::vector<int>& streamIds)
106 {
107 RetCode re = RC_OK;
108 for (const auto& it : streamIds) {
109 CAMERA_LOGV("stop stream %{public}d begin", it);
110 re = dispatcher_->Stop(it) | re;
111 CAMERA_LOGV("stop stream %{public}d end", it);
112 }
113 return re;
114 }
115
Config(const std::vector<int> & streamIds,const CaptureMeta & meta)116 RetCode StreamPipelineCore::Config(const std::vector<int>& streamIds, const CaptureMeta& meta)
117 {
118 std::lock_guard<std::recursive_mutex> l(mutex_);
119 RetCode re = RC_OK;
120 for (const auto& it : streamIds) {
121 re = dispatcher_->Config(it, meta) | re;
122 }
123 return re;
124 }
125
Capture(const std::vector<int> & streamIds,const int32_t captureId)126 RetCode StreamPipelineCore::Capture(const std::vector<int>& streamIds, const int32_t captureId)
127 {
128 CAMERA_LOGI("StreamPipelineCore::Capture %{public}s", cameraId_.c_str());
129 std::lock_guard<std::recursive_mutex> l(mutex_);
130 RetCode re = RC_OK;
131 for (const auto& it : streamIds) {
132 re = dispatcher_->Capture(it, captureId) | re;
133 }
134 return re;
135 }
136
CancelCapture(const std::vector<int> & streamIds)137 RetCode StreamPipelineCore::CancelCapture(const std::vector<int>& streamIds)
138 {
139 std::lock_guard<std::recursive_mutex> l(mutex_);
140 RetCode re = RC_OK;
141 for (const auto& it : streamIds) {
142 re = dispatcher_->CancelCapture(it) | re;
143 }
144 return re;
145 }
146
Flush(const std::vector<int> & streamIds)147 RetCode StreamPipelineCore::Flush(const std::vector<int>& streamIds)
148 {
149 std::lock_guard<std::recursive_mutex> l(mutex_);
150 RetCode re = RC_OK;
151 for (const auto& it : streamIds) {
152 CAMERA_LOGV("flush stream %{public}d begin", it);
153 re = dispatcher_->Flush(it) | re;
154 CAMERA_LOGV("flush stream %{public}d end", it);
155 }
156 return re;
157 }
158
GetOfflinePipeline(const int32_t id)159 std::shared_ptr<OfflinePipeline> StreamPipelineCore::GetOfflinePipeline(const int32_t id)
160 {
161 std::lock_guard<std::recursive_mutex> l(mutex_);
162 std::shared_ptr<INode> node = dispatcher_->GetNode(id, "ipp");
163 return std::static_pointer_cast<IppNode>(node);
164 }
165
GetCurrentMode() const166 VdiOperationMode StreamPipelineCore::GetCurrentMode() const
167 {
168 return mode_;
169 }
170
CheckStreamsSupported(VdiOperationMode mode,const ModeMeta & meta,const std::vector<StreamConfiguration> & configs)171 DynamicStreamSwitchMode StreamPipelineCore::CheckStreamsSupported(VdiOperationMode mode,
172 const ModeMeta& meta,
173 const std::vector<StreamConfiguration>& configs)
174 {
175 // check metadata
176 CHECK_IF_PTR_NULL_RETURN_VALUE(meta, DYNAMIC_STREAM_SWITCH_NOT_SUPPORT);
177 CHECK_IF_EQUAL_RETURN_VALUE(configs.empty(), true, DYNAMIC_STREAM_SWITCH_NOT_SUPPORT);
178
179 std::vector<DeviceStreamSetting> settings = {};
180 std::vector<int32_t> ids = {};
181 context_->streamMgr_->GetStreamIds(ids);
182
183 std::vector<int32_t> types = {};
184 std::transform(configs.begin(), configs.end(), std::back_inserter(types),
185 [](auto &it) { return static_cast<std::underlying_type<VdiStreamIntent>::type>(it.type); });
186 std::sort(types.begin(), types.end(), [](const int32_t& f, const int32_t& n) { return f < n; });
187
188 bool isSupport = strategy_->CheckPipelineSpecExist(mode, types) == RC_OK ? true : false;
189 if (isSupport && !ids.empty()) {
190 return DYNAMIC_STREAM_SWITCH_NEED_INNER_RESTART;
191 } else if (isSupport && ids.empty()) {
192 return DYNAMIC_STREAM_SWITCH_SUPPORT;
193 } else {
194 return DYNAMIC_STREAM_SWITCH_NOT_SUPPORT;
195 }
196
197 return DYNAMIC_STREAM_SWITCH_NOT_SUPPORT;
198 }
199
Create(const std::shared_ptr<NodeContext> & c)200 std::shared_ptr<IStreamPipelineCore> IStreamPipelineCore::Create(const std::shared_ptr<NodeContext>& c)
201 {
202 return std::make_shared<StreamPipelineCore>(c);
203 }
204 } // namespace OHOS::Camera
205