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 <ImsMediaTrace.h>
18 #include <BaseStreamGraph.h>
19 
BaseStreamGraph(BaseSessionCallback * callback,int localFd)20 BaseStreamGraph::BaseStreamGraph(BaseSessionCallback* callback, int localFd) :
21         mCallback(callback),
22         mLocalFd(localFd),
23         mGraphState(kStreamStateIdle)
24 {
25     mScheduler = std::make_shared<StreamScheduler>();
26 
27     if (mCallback != nullptr)
28     {
29         mCallback->SendEvent(kImsMediaEventStateChanged);
30     }
31 }
32 
~BaseStreamGraph()33 BaseStreamGraph::~BaseStreamGraph()
34 {
35     deleteNodes();
36     setState(kStreamStateIdle);
37 }
38 
setLocalFd(int localFd)39 void BaseStreamGraph::setLocalFd(int localFd)
40 {
41     mLocalFd = localFd;
42 }
getLocalFd()43 int BaseStreamGraph::getLocalFd()
44 {
45     return mLocalFd;
46 }
47 
start()48 ImsMediaResult BaseStreamGraph::start()
49 {
50     IMLOGD0("[start]");
51     ImsMediaResult ret = startNodes();
52 
53     if (ret != RESULT_SUCCESS)
54     {
55         stopNodes();
56         return ret;
57     }
58 
59     setState(kStreamStateRunning);
60     return RESULT_SUCCESS;
61 }
62 
stop()63 ImsMediaResult BaseStreamGraph::stop()
64 {
65     IMLOGD0("[stop]");
66     ImsMediaResult ret = stopNodes();
67 
68     if (ret != RESULT_SUCCESS)
69     {
70         return ret;
71     }
72 
73     setState(kStreamStateCreated);
74     return RESULT_SUCCESS;
75 }
76 
setState(StreamState state)77 void BaseStreamGraph::setState(StreamState state)
78 {
79     if (mGraphState != state)
80     {
81         mGraphState = state;
82 
83         if (mCallback != nullptr)
84         {
85             mCallback->SendEvent(kImsMediaEventStateChanged);
86         }
87     }
88 }
89 
getState()90 StreamState BaseStreamGraph::getState()
91 {
92     return mGraphState;
93 }
94 
AddNode(BaseNode * pNode,bool bReverse)95 void BaseStreamGraph::AddNode(BaseNode* pNode, bool bReverse)
96 {
97     if (pNode == nullptr)
98     {
99         return;
100     }
101 
102     IMLOGD1("[AddNode] node[%s]", pNode->GetNodeName());
103 
104     if (bReverse == true)
105     {
106         mListNodeToStart.push_front(pNode);  // reverse direction
107     }
108     else
109     {
110         mListNodeToStart.push_back(pNode);
111     }
112 
113     if (!pNode->IsRunTime() || !pNode->IsRunTimeStart())
114     {
115         mScheduler->RegisterNode(pNode);
116     }
117 }
118 
RemoveNode(BaseNode * pNode)119 void BaseStreamGraph::RemoveNode(BaseNode* pNode)
120 {
121     if (pNode == nullptr)
122     {
123         return;
124     }
125 
126     IMLOGD1("[RemoveNode] node[%s]", pNode->GetNodeName());
127 
128     if (!pNode->IsRunTime() || !pNode->IsRunTimeStart())
129     {
130         mScheduler->DeRegisterNode(pNode);
131     }
132 
133     pNode->DisconnectNodes();
134     delete pNode;
135 }
136 
startNodes()137 ImsMediaResult BaseStreamGraph::startNodes()
138 {
139     ImsMediaResult ret = ImsMediaResult::RESULT_NOT_READY;
140 
141     while (!mListNodeToStart.empty())
142     {
143         BaseNode* pNode = mListNodeToStart.front();
144 
145         if (pNode != nullptr)
146         {
147             IMLOGD2("[startNodes] media[%d], start node[%s]", pNode->GetMediaType(),
148                     pNode->GetNodeName());
149 
150             ret = pNode->Start();
151 
152             if (ret != RESULT_SUCCESS)
153             {
154                 IMLOGE2("[startNodes] error start node[%s], ret[%d]", pNode->GetNodeName(), ret);
155                 return ret;
156             }
157 
158             mListNodeToStart.pop_front();
159             mListNodeStarted.push_front(pNode);
160         }
161     }
162 
163     mScheduler->Start();
164     return RESULT_SUCCESS;
165 }
166 
stopNodes()167 ImsMediaResult BaseStreamGraph::stopNodes()
168 {
169     mScheduler->Stop();
170 
171     while (!mListNodeStarted.empty())
172     {
173         BaseNode* pNode = mListNodeStarted.front();
174 
175         if (pNode != nullptr)
176         {
177             IMLOGD2("[stopNodes] media[%d], stop node[%s]", pNode->GetMediaType(),
178                     pNode->GetNodeName());
179             pNode->Stop();
180             mListNodeStarted.pop_front();
181             mListNodeToStart.push_front(pNode);
182         }
183     }
184 
185     return RESULT_SUCCESS;
186 }
187 
deleteNodes()188 void BaseStreamGraph::deleteNodes()
189 {
190     if (!mListNodeStarted.empty())
191     {
192         IMLOGE1("[deleteNodes] error node remained[%d]", mListNodeStarted.size());
193     }
194 
195     while (!mListNodeToStart.empty())
196     {
197         BaseNode* pNode = mListNodeToStart.front();
198 
199         if (pNode != nullptr)
200         {
201             IMLOGD2("[deleteNodes] media[%d], delete node[%s]", pNode->GetMediaType(),
202                     pNode->GetNodeName());
203             RemoveNode(pNode);
204         }
205 
206         mListNodeToStart.pop_front();
207     }
208 
209     setState(kStreamStateIdle);
210 }
211 
findNode(kBaseNodeId id)212 BaseNode* BaseStreamGraph::findNode(kBaseNodeId id)
213 {
214     for (auto& node : mListNodeToStart)
215     {
216         if (node != nullptr && node->GetNodeId() == id)
217         {
218             return node;
219         }
220     }
221 
222     for (auto& node : mListNodeStarted)
223     {
224         if (node != nullptr && node->GetNodeId() == id)
225         {
226             return node;
227         }
228     }
229 
230     return nullptr;
231 }
232 
setMediaQualityThreshold(MediaQualityThreshold * threshold)233 bool BaseStreamGraph::setMediaQualityThreshold(MediaQualityThreshold* threshold)
234 {
235     (void)threshold;
236     IMLOGW0("[setMediaQualityThreshold] base");
237     return false;
238 }
239 
OnEvent(int32_t type,uint64_t param1,uint64_t param2)240 bool BaseStreamGraph::OnEvent(int32_t type, uint64_t param1, uint64_t param2)
241 {
242     (void)type;
243     (void)param1;
244     (void)param2;
245     IMLOGW0("[OnEvent] base");
246     return false;
247 }