• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <AudioStreamGraphRtcp.h>
18 #include <RtcpEncoderNode.h>
19 #include <RtcpDecoderNode.h>
20 #include <SocketReaderNode.h>
21 #include <SocketWriterNode.h>
22 #include <ImsMediaNetworkUtil.h>
23 #include <ImsMediaTrace.h>
24 
AudioStreamGraphRtcp(BaseSessionCallback * callback,int localFd)25 AudioStreamGraphRtcp::AudioStreamGraphRtcp(BaseSessionCallback* callback, int localFd) :
26         AudioStreamGraph(callback, localFd)
27 {
28     mConfig = nullptr;
29 }
30 
~AudioStreamGraphRtcp()31 AudioStreamGraphRtcp::~AudioStreamGraphRtcp() {}
32 
create(RtpConfig * config)33 ImsMediaResult AudioStreamGraphRtcp::create(RtpConfig* config)
34 {
35     IMLOGD1("[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* pNodeRtcpEncoder = new RtcpEncoderNode(mCallback);
44     pNodeRtcpEncoder->SetMediaType(IMS_MEDIA_AUDIO);
45     char localIp[MAX_IP_LEN];
46     uint32_t localPort = 0;
47     ImsMediaNetworkUtil::getLocalIpPortFromSocket(mLocalFd, localIp, MAX_IP_LEN, localPort);
48     RtpAddress localAddress(localIp, localPort - 1);
49     (static_cast<RtcpEncoderNode*>(pNodeRtcpEncoder))->SetLocalAddress(localAddress);
50     pNodeRtcpEncoder->SetConfig(config);
51     AddNode(pNodeRtcpEncoder);
52 
53     BaseNode* pNodeSocketWriter = new SocketWriterNode(mCallback);
54     pNodeSocketWriter->SetMediaType(IMS_MEDIA_AUDIO);
55     (static_cast<SocketWriterNode*>(pNodeSocketWriter))->SetLocalFd(mLocalFd);
56     (static_cast<SocketWriterNode*>(pNodeSocketWriter))
57             ->SetLocalAddress(RtpAddress(localIp, localPort));
58     (static_cast<SocketWriterNode*>(pNodeSocketWriter))->SetProtocolType(kProtocolRtcp);
59     pNodeSocketWriter->SetConfig(config);
60     AddNode(pNodeSocketWriter);
61     pNodeRtcpEncoder->ConnectRearNode(pNodeSocketWriter);
62     setState(StreamState::kStreamStateCreated);
63 
64     BaseNode* pNodeSocketReader = new SocketReaderNode(mCallback);
65     pNodeSocketReader->SetMediaType(IMS_MEDIA_AUDIO);
66     (static_cast<SocketReaderNode*>(pNodeSocketReader))->SetLocalFd(mLocalFd);
67     (static_cast<SocketReaderNode*>(pNodeSocketReader))
68             ->SetLocalAddress(RtpAddress(localIp, localPort));
69     (static_cast<SocketReaderNode*>(pNodeSocketReader))->SetProtocolType(kProtocolRtcp);
70     pNodeSocketReader->SetConfig(config);
71     AddNode(pNodeSocketReader);
72 
73     BaseNode* pNodeRtcpDecoder = new RtcpDecoderNode(mCallback);
74     pNodeRtcpDecoder->SetMediaType(IMS_MEDIA_AUDIO);
75     (static_cast<RtcpDecoderNode*>(pNodeRtcpDecoder))->SetLocalAddress(localAddress);
76     pNodeRtcpDecoder->SetConfig(config);
77     AddNode(pNodeRtcpDecoder);
78     pNodeSocketReader->ConnectRearNode(pNodeRtcpDecoder);
79     return ImsMediaResult::RESULT_SUCCESS;
80 }
81 
update(RtpConfig * config)82 ImsMediaResult AudioStreamGraphRtcp::update(RtpConfig* config)
83 {
84     IMLOGD1("[update] state[%d]", mGraphState);
85 
86     if (config == nullptr)
87     {
88         return RESULT_INVALID_PARAM;
89     }
90 
91     AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
92 
93     if (*reinterpret_cast<AudioConfig*>(mConfig) == *pConfig)
94     {
95         IMLOGI0("[update] no update");
96         return RESULT_SUCCESS;
97     }
98 
99     if (mConfig != nullptr)
100     {
101         delete mConfig;
102         mConfig = new AudioConfig(pConfig);
103     }
104 
105     if (mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_NO_FLOW)
106     {
107         IMLOGI0("[update] pause RTCP");
108         return stop();
109     }
110 
111     ImsMediaResult ret = ImsMediaResult::RESULT_NOT_READY;
112 
113     // update in running state
114     if (mGraphState == kStreamStateRunning)
115     {
116         mScheduler->Stop();
117 
118         for (auto& node : mListNodeStarted)
119         {
120             IMLOGD1("[update] update node[%s]", node->GetNodeName());
121             ret = node->UpdateConfig(pConfig);
122             if (ret != RESULT_SUCCESS)
123             {
124                 IMLOGE2("[update] error in update node[%s], ret[%d]", node->GetNodeName(), ret);
125             }
126         }
127 
128         mScheduler->Start();
129     }
130 
131     if (mGraphState == kStreamStateCreated &&
132             mConfig->getMediaDirection() != RtpConfig::MEDIA_DIRECTION_NO_FLOW)
133     {
134         IMLOGI0("[update] resume RTCP");
135         return start();
136     }
137 
138     return ret;
139 }
140 
start()141 ImsMediaResult AudioStreamGraphRtcp::start()
142 {
143     if (mConfig == nullptr)
144     {
145         return RESULT_NOT_READY;
146     }
147 
148     if (mConfig->getMediaDirection() != RtpConfig::MEDIA_DIRECTION_NO_FLOW)
149     {
150         return BaseStreamGraph::start();
151     }
152 
153     // not started
154     return RESULT_SUCCESS;
155 }
156 
OnEvent(int32_t type,uint64_t param1,uint64_t param2)157 bool AudioStreamGraphRtcp::OnEvent(int32_t type, uint64_t param1, uint64_t param2)
158 {
159     IMLOGI3("[onEvent] type[%d], param1[%d], param2[%d]", type, param1, param2);
160 
161     switch (type)
162     {
163         case kRequestSendRtcpXrReport:
164         {
165             BaseNode* node = findNode(kNodeIdRtcpEncoder);
166 
167             if (node != nullptr)
168             {
169                 RtcpEncoderNode* encoder = reinterpret_cast<RtcpEncoderNode*>(node);
170                 encoder->SendRtcpXr(
171                         reinterpret_cast<uint8_t*>(param1), static_cast<uint32_t>(param2));
172                 return true;
173             }
174         }
175         break;
176         default:
177             break;
178     }
179 
180     return false;
181 }