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