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