• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef HPAE_NODE_H
17 #define HPAE_NODE_H
18 #include <memory>
19 #include <stdint.h>
20 #include <unordered_map>
21 #include <vector>
22 #include <set>
23 #include <sstream>
24 #include "hpae_pcm_buffer.h"
25 #include "hpae_define.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 namespace HPAE {
30 static constexpr uint32_t MIN_START_NODE_ID = 100;
31 
32 class HpaeNode : public std::enable_shared_from_this<HpaeNode> {
33 public:
HpaeNode()34     HpaeNode()
35     {
36 #ifdef ENABLE_HIDUMP_DFX
37         nodeInfo_.nodeId = GenerateHpaeNodeId();
38 #endif
39     }
40 
~HpaeNode()41     virtual ~HpaeNode() {};
42 
HpaeNode(HpaeNodeInfo & nodeInfo)43     HpaeNode(HpaeNodeInfo& nodeInfo) : nodeInfo_(nodeInfo)
44     {
45 #ifdef ENABLE_HIDUMP_DFX
46         nodeInfo_.nodeId = GenerateHpaeNodeId();
47 #endif
48     }
49 
50     virtual void DoProcess() = 0;
Enqueue(HpaePcmBuffer * buffer)51     virtual void Enqueue(HpaePcmBuffer* buffer) {};
52     // for process node
53     virtual bool Reset() = 0;
54     virtual bool ResetAll() = 0;
55 
GetNodeInfo()56     virtual HpaeNodeInfo& GetNodeInfo()
57     {
58         return nodeInfo_;
59     }
60 
SetNodeInfo(HpaeNodeInfo & nodeInfo)61     virtual void SetNodeInfo(HpaeNodeInfo& nodeInfo)
62     {
63         nodeInfo_ = nodeInfo;
64     }
65 
SetNodeId(uint32_t nodeId)66     virtual void SetNodeId(uint32_t nodeId)
67     {
68         nodeInfo_.nodeId = nodeId;
69     }
70 
SetNodeName(std::string nodeName)71     virtual void SetNodeName(std::string nodeName)
72     {
73         nodeInfo_.nodeName = nodeName;
74     }
75 
GetSampleRate()76     virtual AudioSamplingRate GetSampleRate()
77     {
78         return nodeInfo_.samplingRate;
79     }
80 
GetBitWidth()81     virtual AudioSampleFormat GetBitWidth()
82     {
83         return nodeInfo_.format;
84     }
85 
GetChannelCount()86     virtual AudioChannel GetChannelCount()
87     {
88         return nodeInfo_.channels;
89     }
90 
GetChannelLayout()91     virtual AudioChannelLayout GetChannelLayout()
92     {
93         return nodeInfo_.channelLayout;
94     }
95 
GetFrameLen()96     virtual size_t GetFrameLen()
97     {
98         return nodeInfo_.frameLen;
99     }
100 
GetNodeId()101     virtual uint32_t GetNodeId()
102     {
103         return nodeInfo_.nodeId;
104     }
105 
GetSessionId()106     virtual uint32_t GetSessionId()
107     {
108         return nodeInfo_.sessionId;
109     }
110 
GetStreamType()111     virtual AudioStreamType GetStreamType()
112     {
113         return nodeInfo_.streamType;
114     }
115 
GetSceneType()116     virtual HpaeProcessorType GetSceneType()
117     {
118         return nodeInfo_.sceneType;
119     }
120 
GetDeviceClass()121     virtual std::string GetDeviceClass()
122     {
123         return nodeInfo_.deviceClass;
124     }
125 
GetDeviceNetId()126     virtual std::string GetDeviceNetId()
127     {
128         return nodeInfo_.deviceNetId;
129     }
130 
GetNodeName()131     virtual std::string GetNodeName()
132     {
133         return nodeInfo_.nodeName;
134     }
135 
GetNodeStatusCallback()136     virtual std::weak_ptr<INodeCallback> GetNodeStatusCallback()
137     {
138         return nodeInfo_.statusCallback;
139     }
140 
GetTraceInfo()141     virtual std::string GetTraceInfo()
142     {
143         std::ostringstream oss;
144         oss << "rate[" << nodeInfo_.samplingRate << "]_"
145             << "ch[" << static_cast<int32_t>(nodeInfo_.channels) << "]_"
146             << "len[" << nodeInfo_.frameLen << "]_"
147             << "bit[" << static_cast<int32_t>(nodeInfo_.format) << "]";
148         return oss.str();
149     }
150 private:
GenerateHpaeNodeId()151     static uint32_t GenerateHpaeNodeId()
152     {
153         std::lock_guard<std::mutex> lock(nodeIdCounterMutex_);
154         if (nodeIdCounter_ == std::numeric_limits<uint32_t>::max()) {
155             nodeIdCounter_ = MIN_START_NODE_ID;
156         } else {
157             ++nodeIdCounter_;
158         }
159         return nodeIdCounter_;
160     }
161 
162 private:
163     HpaeNodeInfo nodeInfo_;
164     inline static std::mutex nodeIdCounterMutex_;
165     inline static uint32_t nodeIdCounter_ = MIN_START_NODE_ID;
166 };
167 
168 template <typename T>
169 class InputPort;
170 
171 template <typename T>
172 class OutputPort {
173 public:
OutputPort(HpaeNode * node)174     explicit OutputPort(HpaeNode *node) : hpaeNode_(node)
175     {}
176     void WriteDataToOutput(T data, HpaeBufferType bufferType = HPAE_BUFFER_TYPE_DEFAULT);
177     OutputPort(const OutputPort &that) = delete;
178     T PullOutputData();
179     void AddInput(InputPort<T> *input);
180     void AddInput(InputPort<T> *input, const std::shared_ptr<HpaeNode> &node);
181     bool RemoveInput(InputPort<T> *input, HpaeBufferType bufferType = HPAE_BUFFER_TYPE_DEFAULT);
182     size_t GetInputNum() const;
183 private:
184     std::set<InputPort<T>*> inputPortSet_;
185     std::vector<T> outputData_;
186     HpaeNode *hpaeNode_;
187     std::unordered_map<InputPort<T>*, std::shared_ptr<HpaeNode>> coInputPorts_;
188 };
189 
190 template <typename OutputType>
191 class OutputNode : virtual public HpaeNode {
192 public:
~OutputNode()193     virtual ~OutputNode()
194     {}
195     virtual std::shared_ptr<HpaeNode> GetSharedInstance() = 0;
GetSharedInstance(HpaeNodeInfo & nodeInfo)196     virtual std::shared_ptr<HpaeNode> GetSharedInstance(HpaeNodeInfo &nodeInfo) { return nullptr; }
197     virtual OutputPort<OutputType>* GetOutputPort() = 0;
198     virtual OutputPort<OutputType>* GetOutputPort(HpaeNodeInfo &nodeInfo, bool isDisConnect = false) { return nullptr; }
GetOutputPortBufferType(HpaeNodeInfo & nodeInfo)199     virtual HpaeSourceBufferType GetOutputPortBufferType(HpaeNodeInfo &nodeInfo)
200         { return HPAE_SOURCE_BUFFER_TYPE_DEFAULT; }
201 };
202 
203 template <typename InputType>
204 class InputNode : virtual public HpaeNode {
205 public:
~InputNode()206     virtual ~InputNode()
207     {}
208     virtual void Connect(const std::shared_ptr<OutputNode<InputType>> &preNode) = 0;
ConnectWithInfo(const std::shared_ptr<OutputNode<InputType>> & preNode,HpaeNodeInfo & nodeInfo)209     virtual void ConnectWithInfo(const std::shared_ptr<OutputNode<InputType>> &preNode, HpaeNodeInfo &nodeInfo) {}
210     virtual void DisConnect(const std::shared_ptr<OutputNode<InputType>> &preNode) = 0;
DisConnectWithInfo(const std::shared_ptr<OutputNode<InputType>> & preNode,HpaeNodeInfo & nodeInfo)211     virtual void DisConnectWithInfo(const std::shared_ptr<OutputNode<InputType>> &preNode, HpaeNodeInfo &nodeInfo) {}
212 };
213 
214 template <typename T>
215 class InputPort {
216 public:
InputPort()217     InputPort()
218     {}
219     ~InputPort();
220     std::vector<T>& ReadPreOutputData();
221 
222     void Connect(const std::shared_ptr<HpaeNode>& node, OutputPort<T>* output,
223         HpaeBufferType bufferType = HPAE_BUFFER_TYPE_DEFAULT);
224 
225     void DisConnect(OutputPort<T>* output, HpaeBufferType bufferType = HPAE_BUFFER_TYPE_DEFAULT);
226 
227     size_t GetPreOutputNum() const;
228 
229     const std::unordered_map<OutputPort<T> *, std::shared_ptr<HpaeNode>>& GetPreOutputMap();
230 
231     bool CheckIfDisConnected(OutputPort<T>* output);
232 
233     InputPort(const InputPort &that) = delete;
234 
235     void AddPreOutput(const std::shared_ptr<HpaeNode> &node, OutputPort<T>* output);
236     void RemovePreOutput(OutputPort<T>* output);
237 private:
238     std::unordered_map<OutputPort<T>*, std::shared_ptr<HpaeNode>> outputPorts_;
239     std::vector<T> inputData_;
240 };
241 
242 template <class T>
~InputPort()243 InputPort<T>::~InputPort()
244 {
245     for (auto &o : outputPorts_) {
246         o.first->RemoveInput(this);
247     }
248 }
249 
250 template <class T>
ReadPreOutputData()251 std::vector<T>& InputPort<T>::ReadPreOutputData()
252 {
253     inputData_.clear();
254     for (auto &o : outputPorts_) {
255         T pcmData = o.first->PullOutputData();
256         if (pcmData != nullptr) {
257             inputData_.emplace_back(std::move(pcmData));
258         }
259     }
260     return inputData_;
261 }
262 
263 template <class T>
Connect(const std::shared_ptr<HpaeNode> & node,OutputPort<T> * output,HpaeBufferType bufferType)264 void InputPort<T>::Connect(const std::shared_ptr<HpaeNode> &node, OutputPort<T>* output, HpaeBufferType bufferType)
265 {
266     // for default type
267     if (bufferType == HPAE_BUFFER_TYPE_DEFAULT) {
268         if (output) {
269             output->AddInput(this);
270         }
271         AddPreOutput(node, output);
272         return;
273     }
274     // for cobuffer type
275     if (bufferType == HPAE_BUFFER_TYPE_COBUFFER) {
276         if (output) {
277             output->AddInput(this, node);
278         }
279         AddPreOutput(node, output);
280         return;
281     }
282     return;
283 }
284 
285 template <class T>
DisConnect(OutputPort<T> * output,HpaeBufferType bufferType)286 void InputPort<T>::DisConnect(OutputPort<T>* output, HpaeBufferType bufferType)
287 {
288     if (output) {
289         output->RemoveInput(this, bufferType);
290     }
291     RemovePreOutput(output);
292 }
293 
294 template <class T>
GetPreOutputNum()295 size_t InputPort<T>::GetPreOutputNum() const
296 {
297     return outputPorts_.size();
298 }
299 
300 template <class T>
GetPreOutputMap()301 const std::unordered_map<OutputPort<T> *, std::shared_ptr<HpaeNode>>& InputPort<T>::GetPreOutputMap()
302 {
303     return outputPorts_;
304 }
305 
306 template <class T>
CheckIfDisConnected(OutputPort<T> * output)307 bool InputPort<T>::CheckIfDisConnected(OutputPort<T>* output)
308 {
309     return outputPorts_.find(output) == outputPorts_.end();
310 }
311 
312 template <class T>
AddPreOutput(const std::shared_ptr<HpaeNode> & node,OutputPort<T> * output)313 void InputPort<T>::AddPreOutput(const std::shared_ptr<HpaeNode> &node, OutputPort<T> *output)
314 {
315     outputPorts_[output] = node;
316 }
317 
318 template <class T>
RemovePreOutput(OutputPort<T> * output)319 void InputPort<T>::RemovePreOutput(OutputPort<T> *output)
320 {
321     outputPorts_.erase(output);
322 }
323 
324 template <class T>
PullOutputData()325 T OutputPort<T>::PullOutputData()
326 {
327     if (outputData_.empty()) {
328         hpaeNode_->DoProcess();
329     }
330     if (!outputData_.empty()) {
331         T retValue = std::move(outputData_.back());
332         outputData_.pop_back();
333         return retValue;
334     } else {
335         return nullptr;
336     }
337 }
338 
339 template <class T>
WriteDataToOutput(T data,HpaeBufferType bufferType)340 void OutputPort<T>::WriteDataToOutput(T data, HpaeBufferType bufferType)
341 {
342     // for default type
343     if (bufferType == HPAE_BUFFER_TYPE_DEFAULT) {
344         outputData_.clear();
345         outputData_.emplace_back(std::move(data));
346 
347         for (size_t i = 1; i < inputPortSet_.size(); i++) {
348             outputData_.push_back(outputData_[0]);
349         }
350         return;
351     }
352     // for cobuffer type
353     if (bufferType == HPAE_BUFFER_TYPE_COBUFFER) {
354         for (auto &i : coInputPorts_) {
355             i.second->Enqueue(data);
356         }
357         return;
358     }
359     return;
360 }
361 
362 template <class T>
AddInput(InputPort<T> * input)363 void OutputPort<T>::AddInput(InputPort<T> *input)
364 {
365     inputPortSet_.insert(input);
366 }
367 template <class T>
AddInput(InputPort<T> * input,const std::shared_ptr<HpaeNode> & node)368 void OutputPort<T>::AddInput(InputPort<T> *input, const std::shared_ptr<HpaeNode> &node)
369 {
370     coInputPorts_[input] = node;
371 }
372 template <class T>
GetInputNum()373 size_t OutputPort<T>::GetInputNum() const
374 {
375     return inputPortSet_.size();
376 }
377 template <class T>
RemoveInput(InputPort<T> * input,HpaeBufferType bufferType)378 bool OutputPort<T>::RemoveInput(InputPort<T> *input, HpaeBufferType bufferType)
379 {
380     // for default type
381     if (bufferType == HPAE_BUFFER_TYPE_DEFAULT) {
382         auto it = inputPortSet_.find(input);
383         if (it == inputPortSet_.end()) {
384             return false;
385         }
386         inputPortSet_.erase(it);
387         return true;
388     }
389     // for cobuffer type
390     if (bufferType == HPAE_BUFFER_TYPE_COBUFFER) {
391         auto it = coInputPorts_.find(input);
392         if (it == coInputPorts_.end()) {
393             return false;
394         }
395         coInputPorts_.erase(it);
396         return true;
397     }
398     return true;
399 }
400 
401 }  // namespace HPAE
402 }  // namespace AudioStandard
403 }  // namespace OHOS
404 #endif