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
113 if (mGraphState == kStreamStateRunning)
114 {
115 mScheduler->Stop();
116
117 for (auto& node : mListNodeStarted)
118 {
119 IMLOGD1("[update] update node[%s]", node->GetNodeName());
120 ret = node->UpdateConfig(mConfig);
121
122 if (ret != RESULT_SUCCESS)
123 {
124 IMLOGE2("[update] error in update node[%s], ret[%d]", node->GetNodeName(), ret);
125 }
126 }
127 mScheduler->Start();
128 }
129 else if (mGraphState == kStreamStateCreated)
130 {
131 for (auto& node : mListNodeToStart)
132 {
133 IMLOGD1("[update] update node[%s]", node->GetNodeName());
134 ret = node->UpdateConfig(mConfig);
135
136 if (ret != RESULT_SUCCESS)
137 {
138 IMLOGE2("[update] error in update node[%s], ret[%d]", node->GetNodeName(), ret);
139 }
140 }
141 }
142
143 if (mGraphState == kStreamStateCreated &&
144 (pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY ||
145 pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE))
146 {
147 IMLOGI0("[update] resume RX");
148 return start();
149 }
150
151 return ret;
152 }
153
processCmr(const uint32_t cmrType,const uint32_t cmrDefine)154 void AudioStreamGraphRtpRx::processCmr(const uint32_t cmrType, const uint32_t cmrDefine)
155 {
156 BaseNode* node = findNode(kNodeIdAudioPlayer);
157
158 if (node != nullptr)
159 {
160 (reinterpret_cast<IAudioPlayerNode*>(node))->ProcessCmr(cmrType, cmrDefine);
161 }
162 }
163
start()164 ImsMediaResult AudioStreamGraphRtpRx::start()
165 {
166 if (mConfig == nullptr)
167 {
168 return RESULT_NOT_READY;
169 }
170
171 if (mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY ||
172 mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE)
173 {
174 return BaseStreamGraph::start();
175 }
176
177 // not started
178 return RESULT_SUCCESS;
179 }