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 <AudioStreamGraphRtpRx.h>
18 #include <IAudioPlayerNode.h>
19 #include <AudioRtpPayloadDecoderNode.h>
20 #include <RtpDecoderNode.h>
21 #include <SocketReaderNode.h>
22 #include <ImsMediaTrace.h>
23 #include <ImsMediaNetworkUtil.h>
24 #include <AudioConfig.h>
25
AudioStreamGraphRtpRx(BaseSessionCallback * callback,int localFd)26 AudioStreamGraphRtpRx::AudioStreamGraphRtpRx(BaseSessionCallback* callback, int localFd) :
27 AudioStreamGraph(callback, localFd)
28 {
29 }
30
~AudioStreamGraphRtpRx()31 AudioStreamGraphRtpRx::~AudioStreamGraphRtpRx() {}
32
create(RtpConfig * config)33 ImsMediaResult AudioStreamGraphRtpRx::create(RtpConfig* config)
34 {
35 IMLOGI1("[create] state[%d]", mGraphState);
36
37 if (config == nullptr)
38 {
39 return RESULT_INVALID_PARAM;
40 }
41
42 mConfig = new AudioConfig(reinterpret_cast<AudioConfig*>(config));
43 BaseNode* pNodeSocketReader = new SocketReaderNode(mCallback);
44 pNodeSocketReader->SetMediaType(IMS_MEDIA_AUDIO);
45
46 char localIp[MAX_IP_LEN];
47 uint32_t localPort = 0;
48 ImsMediaNetworkUtil::getLocalIpPortFromSocket(mLocalFd, localIp, MAX_IP_LEN, localPort);
49 RtpAddress localAddress(localIp, localPort);
50 (static_cast<SocketReaderNode*>(pNodeSocketReader))->SetLocalFd(mLocalFd);
51 (static_cast<SocketReaderNode*>(pNodeSocketReader))->SetLocalAddress(localAddress);
52 (static_cast<SocketReaderNode*>(pNodeSocketReader))->SetProtocolType(kProtocolRtp);
53 pNodeSocketReader->SetConfig(config);
54 pNodeSocketReader->Prepare();
55 AddNode(pNodeSocketReader);
56
57 BaseNode* pNodeRtpDecoder = new RtpDecoderNode(mCallback);
58 pNodeRtpDecoder->SetMediaType(IMS_MEDIA_AUDIO);
59 pNodeRtpDecoder->SetConfig(mConfig);
60 (static_cast<RtpDecoderNode*>(pNodeRtpDecoder))->SetLocalAddress(localAddress);
61 AddNode(pNodeRtpDecoder);
62 pNodeSocketReader->ConnectRearNode(pNodeRtpDecoder);
63
64 BaseNode* pNodeRtpPayloadDecoder = new AudioRtpPayloadDecoderNode(mCallback);
65 pNodeRtpPayloadDecoder->SetMediaType(IMS_MEDIA_AUDIO);
66 pNodeRtpPayloadDecoder->SetConfig(mConfig);
67 AddNode(pNodeRtpPayloadDecoder);
68 pNodeRtpDecoder->ConnectRearNode(pNodeRtpPayloadDecoder);
69
70 BaseNode* pNodeRenderer = new IAudioPlayerNode(mCallback);
71 pNodeRenderer->SetMediaType(IMS_MEDIA_AUDIO);
72 pNodeRenderer->SetConfig(mConfig);
73 AddNode(pNodeRenderer);
74 pNodeRtpPayloadDecoder->ConnectRearNode(pNodeRenderer);
75 setState(StreamState::kStreamStateCreated);
76 return RESULT_SUCCESS;
77 }
78
update(RtpConfig * config)79 ImsMediaResult AudioStreamGraphRtpRx::update(RtpConfig* config)
80 {
81 IMLOGI1("[update] state[%d]", mGraphState);
82
83 if (config == nullptr)
84 {
85 return RESULT_INVALID_PARAM;
86 }
87
88 AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
89
90 if (*mConfig == *pConfig)
91 {
92 IMLOGI0("[update] no update");
93 return RESULT_SUCCESS;
94 }
95
96 if (mConfig != nullptr)
97 {
98 delete mConfig;
99 }
100
101 mConfig = new AudioConfig(pConfig);
102
103 if (mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_NO_FLOW ||
104 mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_ONLY ||
105 mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_INACTIVE)
106 {
107 IMLOGI0("[update] pause RX");
108 return stop();
109 }
110
111 ImsMediaResult ret = RESULT_NOT_READY;
112 bool needsToStart = false;
113
114 if (mGraphState == kStreamStateRunning)
115 {
116 stop();
117 needsToStart = true;
118 }
119
120 if (mGraphState == kStreamStateCreated)
121 {
122 for (auto& node : mListNodeToStart)
123 {
124 IMLOGD1("[update] update node[%s]", node->GetNodeName());
125 ret = node->UpdateConfig(mConfig);
126
127 if (ret != RESULT_SUCCESS)
128 {
129 IMLOGE2("[update] error in update node[%s], ret[%d]", node->GetNodeName(), ret);
130 }
131 }
132 }
133
134 if (mGraphState == kStreamStateCreated &&
135 (pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY ||
136 pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE))
137 {
138 IMLOGI0("[update] resume RX");
139 return start();
140 }
141
142 if (needsToStart)
143 {
144 return start();
145 }
146
147 return ret;
148 }
149
start()150 ImsMediaResult AudioStreamGraphRtpRx::start()
151 {
152 if (mConfig == nullptr)
153 {
154 return RESULT_NOT_READY;
155 }
156
157 if (mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY ||
158 mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE)
159 {
160 return BaseStreamGraph::start();
161 }
162
163 // not started
164 return RESULT_SUCCESS;
165 }
166
processCmr(const uint32_t cmrType,const uint32_t cmrDefine)167 void AudioStreamGraphRtpRx::processCmr(const uint32_t cmrType, const uint32_t cmrDefine)
168 {
169 BaseNode* node = findNode(kNodeIdAudioPlayer);
170
171 if (node != nullptr)
172 {
173 (reinterpret_cast<IAudioPlayerNode*>(node))->ProcessCmr(cmrType, cmrDefine);
174 }
175 }
176
adjustDelay(const int32_t delayMs)177 void AudioStreamGraphRtpRx::adjustDelay(const int32_t delayMs)
178 {
179 BaseNode* node = findNode(kNodeIdAudioPlayer);
180
181 if (node != nullptr)
182 {
183 (reinterpret_cast<IAudioPlayerNode*>(node))->AdjustDelay(delayMs);
184 }
185 }