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 *
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 "ipp_node.h"
17
18 namespace OHOS::Camera {
IppNode(const std::string & name,const std::string & type)19 IppNode::IppNode(const std::string& name, const std::string& type)
20 : NodeBase(name, type)
21 {
22 }
23
~IppNode()24 IppNode::~IppNode() {}
25
Init(const int32_t streamId)26 RetCode IppNode::Init(const int32_t streamId)
27 {
28 (void)streamId;
29 // initialize algo plugin
30 if (offlineMode_.load()) {
31 return RC_OK;
32 }
33 algoPluginManager_ = std::make_shared<AlgoPluginManager>();
34 if (algoPluginManager_ == nullptr) {
35 CAMERA_LOGE("create AlgoPluginManager failed");
36 return RC_ERROR;
37 }
38 RetCode ret = algoPluginManager_->LoadPlugin();
39 if (ret != RC_OK) {
40 CAMERA_LOGE("load plugin failed.");
41 return RC_ERROR;
42 }
43 return RC_OK;
44 }
45
Start(const int32_t streamId)46 RetCode IppNode::Start(const int32_t streamId)
47 {
48 NodeBase::Start(streamId);
49 // start offline stream process thread
50 if (offlineMode_.load()) {
51 return RC_OK;
52 }
53 algoPlugin_ = algoPluginManager_->GetAlgoPlugin(IPP_ALGO_MODE_NORMAL);
54 StartProcess();
55 return RC_OK;
56 }
57
Flush(const int32_t streamId)58 RetCode IppNode::Flush(const int32_t streamId)
59 {
60 if (offlineMode_.load()) {
61 return RC_OK;
62 }
63
64 algoPlugin_->Flush();
65 NodeBase::Flush(streamId);
66 return RC_OK;
67 }
68
Stop(const int32_t streamId)69 RetCode IppNode::Stop(const int32_t streamId)
70 {
71 // stop offline stream process thread
72 if (offlineMode_.load()) {
73 return RC_OK;
74 }
75 algoPlugin_->Stop();
76
77 StopProcess();
78 NodeBase::Stop(streamId);
79 return RC_OK;
80 }
81
Config(const int32_t streamId,const CaptureMeta & meta)82 RetCode IppNode::Config(const int32_t streamId, const CaptureMeta& meta)
83 {
84 (void)streamId;
85 (void)meta;
86 // configure algo
87 // NodeBase::Configure
88 if (offlineMode_.load()) {
89 return RC_OK;
90 }
91
92 return RC_OK;
93 }
94
DeliverBuffer(std::shared_ptr<IBuffer> & buffer)95 void IppNode::DeliverBuffer(std::shared_ptr<IBuffer>& buffer)
96 {
97 std::vector<std::shared_ptr<IBuffer>> cache;
98 cache.emplace_back(buffer);
99
100 ReceiveCache(cache);
101 return;
102 }
103
DeliverBuffers(std::vector<std::shared_ptr<IBuffer>> & buffers)104 void IppNode::DeliverBuffers(std::vector<std::shared_ptr<IBuffer>>& buffers)
105 {
106 std::vector<std::shared_ptr<IBuffer>> cache;
107 for (auto it : buffers) {
108 cache.emplace_back(it);
109 }
110
111 ReceiveCache(cache);
112 return;
113 }
114
ProcessCache(std::vector<std::shared_ptr<IBuffer>> & buffers)115 void IppNode::ProcessCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
116 {
117 // process buffers with algorithm
118 std::shared_ptr<IBuffer> outBuffer = nullptr;
119 RetCode ret = GetOutputBuffer(buffers, outBuffer);
120 if (ret != RC_OK) {
121 CAMERA_LOGE("fatal error, can't get output buffer, ipp will do nothing.");
122 return;
123 }
124 std::shared_ptr<CameraMetadata> meta = nullptr;
125 if (algoPlugin_ != nullptr) {
126 CAMERA_LOGV("process buffers with algo, input buffer count = %{public}u.", buffers.size());
127 algoPlugin_->Process(outBuffer, buffers, meta);
128 }
129
130 std::shared_ptr<IBuffer> algoProduct = nullptr;
131 std::vector<std::shared_ptr<IBuffer>> recycleBuffers{};
132 ClassifyOutputBuffer(outBuffer, buffers, algoProduct, recycleBuffers);
133
134 DeliverAlgoProductBuffer(algoProduct);
135 DeliverCache(recycleBuffers);
136 CAMERA_LOGV("process algo completed.");
137 return;
138 }
139
DeliverCache(std::vector<std::shared_ptr<IBuffer>> & buffers)140 void IppNode::DeliverCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
141 {
142 OfflinePipeline::DeliverCacheCheck(buffers);
143 }
144
DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>> & buffers)145 void IppNode::DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
146 {
147 std::shared_ptr<IBuffer> outBuffer = nullptr;
148 RetCode ret = GetOutputBuffer(buffers, outBuffer);
149 if (ret != RC_OK) {
150 CAMERA_LOGE("fatal error, can't return buffer.");
151 return;
152 }
153
154 std::shared_ptr<IBuffer> algoProduct = nullptr;
155 std::vector<std::shared_ptr<IBuffer>> recycleBuffers{};
156 ClassifyOutputBuffer(outBuffer, buffers, algoProduct, recycleBuffers);
157 if (algoProduct == nullptr) {
158 return;
159 }
160 DeliverAlgoProductBuffer(algoProduct);
161 DeliverCache(recycleBuffers);
162
163 return;
164 }
165
GetOutputBuffer(std::vector<std::shared_ptr<IBuffer>> & buffers,std::shared_ptr<IBuffer> & outBuffer)166 RetCode IppNode::GetOutputBuffer(std::vector<std::shared_ptr<IBuffer>>& buffers, std::shared_ptr<IBuffer>& outBuffer)
167 {
168 auto outPort = GetOutPortById(0);
169 if (outPort == nullptr) {
170 CAMERA_LOGE("fatal error, can't get out port.");
171 return RC_ERROR;
172 }
173
174 PortFormat format {};
175 outPort->GetFormat(format);
176 auto id = format.bufferPoolId_;
177 for (auto it : buffers) {
178 if (id == it->GetPoolId()) {
179 outBuffer = nullptr;
180 return RC_OK;
181 }
182 }
183
184 auto bufferManager = BufferManager::GetInstance();
185 if (bufferManager == nullptr) {
186 CAMERA_LOGE("fatal error, can't get buffer manager.");
187 return RC_ERROR;
188 }
189 auto bufferPool = bufferManager->GetBufferPool(id);
190 if (bufferPool == nullptr) {
191 CAMERA_LOGE("fatal error, can't get buffer pool.");
192 return RC_ERROR;
193 }
194
195 outBuffer = bufferPool->AcquireBuffer(-1);
196
197 return RC_OK;
198 }
199
DeliverAlgoProductBuffer(std::shared_ptr<IBuffer> & result)200 void IppNode::DeliverAlgoProductBuffer(std::shared_ptr<IBuffer>& result)
201 {
202 if (offlineMode_.load()) {
203 CAMERA_LOGV("deliver buffer to offline stream");
204 DeliverOfflineBuffer(result);
205 } else {
206 std::shared_ptr<IPort> outPort = GetOutPortById(0);
207 if (outPort == nullptr) {
208 CAMERA_LOGE("can't find out port, deliver algo product failed.");
209 return;
210 }
211 outPort->DeliverBuffer(result);
212 }
213
214 return;
215 }
216
ClassifyOutputBuffer(std::shared_ptr<IBuffer> & outBuffer,std::vector<std::shared_ptr<IBuffer>> & inBuffers,std::shared_ptr<IBuffer> & product,std::vector<std::shared_ptr<IBuffer>> & recycleBuffers)217 void IppNode::ClassifyOutputBuffer(std::shared_ptr<IBuffer>& outBuffer,
218 std::vector<std::shared_ptr<IBuffer>>& inBuffers,
219 std::shared_ptr<IBuffer>& product,
220 std::vector<std::shared_ptr<IBuffer>>& recycleBuffers)
221 {
222 if (outBuffer != nullptr) {
223 product = outBuffer;
224 recycleBuffers = inBuffers;
225 return;
226 }
227 auto outPort = GetOutPortById(0);
228 if (outPort == nullptr) {
229 CAMERA_LOGE("fatal error, can't get out port.");
230 return;
231 }
232
233 PortFormat format {};
234 outPort->GetFormat(format);
235 auto id = format.bufferPoolId_;
236 auto it = std::find_if(inBuffers.begin(), inBuffers.end(),
237 [&id](const std::shared_ptr<IBuffer>& buffer) { return buffer->GetPoolId() == id; });
238 if (it == inBuffers.end()) {
239 CAMERA_LOGE("fatal error, outBuffer should be null.");
240 return;
241 }
242 product = *it;
243 inBuffers.erase(it);
244 recycleBuffers = inBuffers;
245 product->SetCaptureId(inBuffers[0]->GetCaptureId());
246 product->SetBufferStatus(inBuffers[0]->GetBufferStatus());
247 return;
248 }
249 REGISTERNODE(IppNode, {"ipp"});
250 } // namespace OHOS::Camera
251