1 /**
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <BaseNode.h>
18 #include <ImsMediaTrace.h>
19 #include <stdlib.h>
20 
21 using NODE_ID_PAIR = std::pair<kBaseNodeId, const char*>;
22 static std::vector<NODE_ID_PAIR> vectorNodeId{
23         std::make_pair(kNodeIdUnknown, "NodeUnknown"),
24         std::make_pair(kNodeIdSocketWriter, "SocketWriter"),
25         std::make_pair(kNodeIdSocketReader, "SocketReader"),
26         std::make_pair(kNodeIdRtpEncoder, "RtpEncoder"),
27         std::make_pair(kNodeIdRtpDecoder, "RtpDecoder"),
28         std::make_pair(kNodeIdRtcpEncoder, "RtcpEncoder"),
29         std::make_pair(kNodeIdRtcpDecoder, "RtcpDecoder"),
30         std::make_pair(kNodeIdAudioSource, "AudioSource"),
31         std::make_pair(kNodeIdAudioPlayer, "AudioPlayer"),
32         std::make_pair(kNodeIdDtmfEncoder, "DtmfEncoder"),
33         std::make_pair(kNodeIdAudioPayloadEncoder, "AudioPayloadEncoder"),
34         std::make_pair(kNodeIdAudioPayloadDecoder, "AudioPayloadDecoder"),
35         std::make_pair(kNodeIdVideoSource, "VideoSource"),
36         std::make_pair(kNodeIdVideoRenderer, "VideoRenderer"),
37         std::make_pair(kNodeIdVideoPayloadEncoder, "VideoPayloadEncoder"),
38         std::make_pair(kNodeIdVideoPayloadDecoder, "VideoPayloadDecoder"),
39         std::make_pair(kNodeIdTextSource, "TextSource"),
40         std::make_pair(kNodeIdTextRenderer, "TextRenderer"),
41         std::make_pair(kNodeIdTextPayloadEncoder, "TextPayloadEncoder"),
42         std::make_pair(kNodeIdTextPayloadDecoder, "TextPayloadDecoder"),
43 };
44 
BaseNode(BaseSessionCallback * callback)45 BaseNode::BaseNode(BaseSessionCallback* callback)
46 {
47     mScheduler = nullptr;
48     mCallback = callback;
49     mNodeState = kNodeStateStopped;
50     mMediaType = IMS_MEDIA_AUDIO;
51     mListFrontNodes.clear();
52     mListRearNodes.clear();
53 }
54 
~BaseNode()55 BaseNode::~BaseNode()
56 {
57     ClearDataQueue();
58     mNodeState = kNodeStateStopped;
59 }
60 
SetSessionCallback(BaseSessionCallback * callback)61 void BaseNode::SetSessionCallback(BaseSessionCallback* callback)
62 {
63     mCallback = callback;
64 }
65 
SetSchedulerCallback(std::shared_ptr<StreamSchedulerCallback> & callback)66 void BaseNode::SetSchedulerCallback(std::shared_ptr<StreamSchedulerCallback>& callback)
67 {
68     mScheduler = callback;
69 }
70 
ConnectRearNode(BaseNode * pRearNode)71 void BaseNode::ConnectRearNode(BaseNode* pRearNode)
72 {
73     if (pRearNode == nullptr)
74     {
75         return;
76     }
77 
78     IMLOGD3("[ConnectRearNode] type[%d] connect [%s] to [%s]", mMediaType, GetNodeName(),
79             pRearNode->GetNodeName());
80     mListRearNodes.push_back(pRearNode);
81     pRearNode->mListFrontNodes.push_back(this);
82 }
83 
DisconnectNodes()84 void BaseNode::DisconnectNodes()
85 {
86     while (!mListFrontNodes.empty())
87     {
88         DisconnectFrontNode(mListFrontNodes.back());
89     }
90 
91     while (!mListRearNodes.empty())
92     {
93         DisconnectRearNode(mListRearNodes.back());
94     }
95 }
96 
ClearDataQueue()97 void BaseNode::ClearDataQueue()
98 {
99     IMLOGD1("[ClearDataQueue] queue size[%d]", mDataQueue.GetCount());
100     mDataQueue.Clear();
101 }
102 
GetNodeId()103 kBaseNodeId BaseNode::GetNodeId()
104 {
105     return kNodeIdUnknown;
106 }
107 
Prepare()108 bool BaseNode::Prepare()
109 {
110     return RESULT_SUCCESS;
111 }
112 
Start()113 ImsMediaResult BaseNode::Start()
114 {
115     if (!IsRunTimeStart())
116     {
117         return RESULT_SUCCESS;
118     }
119     else
120     {
121         IMLOGW0("[Start] Error - base method");
122         return RESULT_NOT_SUPPORTED;
123     }
124 }
125 
ProcessStart()126 ImsMediaResult BaseNode::ProcessStart()
127 {
128     IMLOGW0("[ProcessStart] Error - base method");
129     return RESULT_NOT_SUPPORTED;
130 }
131 
IsRunTimeStart()132 bool BaseNode::IsRunTimeStart()
133 {
134     return true;
135 }
136 
SetConfig(void * config)137 void BaseNode::SetConfig(void* config)
138 {
139     (void)config;
140     IMLOGW0("[SetConfig] Error - base method");
141 }
142 
IsSameConfig(void * config)143 bool BaseNode::IsSameConfig(void* config)
144 {
145     (void)config;
146     IMLOGW0("[IsSameConfig] Error - base method");
147     return true;
148 }
149 
UpdateConfig(void * config)150 ImsMediaResult BaseNode::UpdateConfig(void* config)
151 {
152     // check config items updates
153     bool isUpdateNode = false;
154 
155     if (IsSameConfig(config))
156     {
157         IMLOGD0("[UpdateConfig] no update");
158         return RESULT_SUCCESS;
159     }
160     else
161     {
162         isUpdateNode = true;
163     }
164 
165     kBaseNodeState prevState = mNodeState;
166 
167     if (isUpdateNode && mNodeState == kNodeStateRunning)
168     {
169         Stop();
170     }
171 
172     // reset the parameters
173     SetConfig(config);
174 
175     if (isUpdateNode && prevState == kNodeStateRunning)
176     {
177         return Start();
178     }
179 
180     return RESULT_SUCCESS;
181 }
182 
ProcessData()183 void BaseNode::ProcessData()
184 {
185     IMLOGE0("ProcessData] Error - base method");
186 }
187 
GetNodeName()188 const char* BaseNode::GetNodeName()
189 {
190     typedef typename std::vector<std::pair<kBaseNodeId, const char*>>::iterator iterator;
191 
192     for (iterator it = vectorNodeId.begin(); it != vectorNodeId.end(); ++it)
193     {
194         if (it->first == GetNodeId())
195         {
196             return it->second;
197         }
198     }
199 
200     return nullptr;
201 }
202 
SetMediaType(ImsMediaType eType)203 void BaseNode::SetMediaType(ImsMediaType eType)
204 {
205     mMediaType = eType;
206 }
207 
GetMediaType()208 ImsMediaType BaseNode::GetMediaType()
209 {
210     return mMediaType;
211 }
212 
213 // Graph Interface
GetState()214 kBaseNodeState BaseNode::GetState()
215 {
216     return mNodeState;
217 }
218 
SetState(kBaseNodeState state)219 void BaseNode::SetState(kBaseNodeState state)
220 {
221     mNodeState = state;
222 }
223 
GetDataCount()224 uint32_t BaseNode::GetDataCount()
225 {
226     return mDataQueue.GetCount();
227 }
228 
GetData(ImsMediaSubType * psubtype,uint8_t ** ppData,uint32_t * pnDataSize,uint32_t * pnTimestamp,bool * pbMark,uint32_t * pnSeqNum,ImsMediaSubType * peDataType,uint32_t * arrivalTime)229 bool BaseNode::GetData(ImsMediaSubType* psubtype, uint8_t** ppData, uint32_t* pnDataSize,
230         uint32_t* pnTimestamp, bool* pbMark, uint32_t* pnSeqNum, ImsMediaSubType* peDataType,
231         uint32_t* arrivalTime)
232 {
233     DataEntry* pEntry;
234 
235     if (mDataQueue.Get(&pEntry))
236     {
237         if (psubtype)
238             *psubtype = pEntry->subtype;
239         if (ppData)
240             *ppData = pEntry->pbBuffer;
241         if (pnDataSize)
242             *pnDataSize = pEntry->nBufferSize;
243         if (pnTimestamp)
244             *pnTimestamp = pEntry->nTimestamp;
245         if (pbMark)
246             *pbMark = pEntry->bMark;
247         if (pnSeqNum)
248             *pnSeqNum = pEntry->nSeqNum;
249         if (peDataType)
250             *peDataType = pEntry->eDataType;
251         if (arrivalTime)
252             *arrivalTime = pEntry->arrivalTime;
253         return true;
254     }
255     else
256     {
257         if (psubtype)
258             *psubtype = MEDIASUBTYPE_UNDEFINED;
259         if (ppData)
260             *ppData = nullptr;
261         if (pnDataSize)
262             *pnDataSize = 0;
263         if (pnTimestamp)
264             *pnTimestamp = 0;
265         if (pbMark)
266             *pbMark = false;
267         if (pnSeqNum)
268             *pnSeqNum = 0;
269         if (peDataType)
270             *peDataType = MEDIASUBTYPE_UNDEFINED;
271         if (arrivalTime)
272             *arrivalTime = 0;
273         return false;
274     }
275 }
276 
AddData(uint8_t * data,uint32_t size,uint32_t timestamp,bool mark,uint32_t seq,ImsMediaSubType subtype,ImsMediaSubType dataType,uint32_t arrivalTime,int32_t index)277 void BaseNode::AddData(uint8_t* data, uint32_t size, uint32_t timestamp, bool mark, uint32_t seq,
278         ImsMediaSubType subtype, ImsMediaSubType dataType, uint32_t arrivalTime, int32_t index)
279 {
280     DataEntry entry = DataEntry();
281     entry.pbBuffer = data;
282     entry.nBufferSize = size;
283     entry.nTimestamp = timestamp;
284     entry.bMark = mark;
285     entry.nSeqNum = seq;
286     entry.eDataType = dataType;
287     entry.subtype = subtype;
288     entry.arrivalTime = arrivalTime;
289     index == -1 ? mDataQueue.Add(&entry) : mDataQueue.InsertAt(index, &entry);
290 }
291 
DeleteData()292 void BaseNode::DeleteData()
293 {
294     mDataQueue.Delete();
295 }
296 
SendDataToRearNode(ImsMediaSubType subtype,uint8_t * pData,uint32_t nDataSize,uint32_t nTimestamp,bool bMark,uint32_t nSeqNum,ImsMediaSubType nDataType,uint32_t arrivalTime)297 void BaseNode::SendDataToRearNode(ImsMediaSubType subtype, uint8_t* pData, uint32_t nDataSize,
298         uint32_t nTimestamp, bool bMark, uint32_t nSeqNum, ImsMediaSubType nDataType,
299         uint32_t arrivalTime)
300 {
301     bool nNeedRunCount = false;
302 
303     for (auto& node : mListRearNodes)
304     {
305         if (node != nullptr && node->GetState() == kNodeStateRunning)
306         {
307             node->OnDataFromFrontNode(
308                     subtype, pData, nDataSize, nTimestamp, bMark, nSeqNum, nDataType, arrivalTime);
309 
310             if (node->IsRunTime() == false)
311             {
312                 nNeedRunCount = true;
313             }
314         }
315     }
316 
317     if (nNeedRunCount == true && mScheduler != nullptr)
318     {
319         mScheduler->onAwakeScheduler();
320     }
321 }
322 
OnDataFromFrontNode(ImsMediaSubType subtype,uint8_t * pData,uint32_t nDataSize,uint32_t nTimestamp,bool bMark,uint32_t nSeqNum,ImsMediaSubType nDataType,uint32_t arrivalTime)323 void BaseNode::OnDataFromFrontNode(ImsMediaSubType subtype, uint8_t* pData, uint32_t nDataSize,
324         uint32_t nTimestamp, bool bMark, uint32_t nSeqNum, ImsMediaSubType nDataType,
325         uint32_t arrivalTime)
326 {
327     DataEntry entry = DataEntry();
328     entry.pbBuffer = pData;
329     entry.nBufferSize = nDataSize;
330     entry.nTimestamp = nTimestamp;
331     entry.bMark = bMark;
332     entry.nSeqNum = nSeqNum;
333     entry.eDataType = nDataType;
334     entry.subtype = subtype;
335     entry.arrivalTime = arrivalTime;
336     mDataQueue.Add(&entry);
337 }
338 
DisconnectRearNode(BaseNode * pRearNode)339 void BaseNode::DisconnectRearNode(BaseNode* pRearNode)
340 {
341     if (pRearNode == nullptr)
342     {
343         mListRearNodes.pop_back();
344         return;
345     }
346 
347     IMLOGD3("[DisconnectRearNode] type[%d] disconnect [%s] from [%s]", mMediaType, GetNodeName(),
348             pRearNode->GetNodeName());
349 
350     mListRearNodes.remove(pRearNode);
351     pRearNode->mListFrontNodes.remove(this);
352 }
353 
DisconnectFrontNode(BaseNode * pFrontNode)354 void BaseNode::DisconnectFrontNode(BaseNode* pFrontNode)
355 {
356     if (pFrontNode == nullptr)
357     {
358         mListFrontNodes.pop_back();
359         return;
360     }
361 
362     IMLOGD3("[DisconnectFrontNode] type[%d] disconnect [%s] from [%s]", mMediaType,
363             pFrontNode->GetNodeName(), GetNodeName());
364 
365     mListFrontNodes.remove(pFrontNode);
366     pFrontNode->mListRearNodes.remove(this);
367 }