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 }