• 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 <RtcpDecoderNode.h>
18 #include <ImsMediaTrace.h>
19 #include <ImsMediaVideoUtil.h>
20 
21 #ifdef DEBUG_BITRATE_CHANGE_SIMULATION
22 static int32_t gTestBitrate = 384000;
23 #endif
24 
RtcpDecoderNode(BaseSessionCallback * callback)25 RtcpDecoderNode::RtcpDecoderNode(BaseSessionCallback* callback) :
26         BaseNode(callback)
27 {
28     mRtpSession = nullptr;
29     mInactivityTime = 0;
30     mNoRtcpTime = 0;
31 }
32 
~RtcpDecoderNode()33 RtcpDecoderNode::~RtcpDecoderNode()
34 {
35     if (mRtpSession != nullptr)
36     {
37         mRtpSession->SetRtcpEncoderListener(nullptr);
38         IRtpSession::ReleaseInstance(mRtpSession);
39         mRtpSession = nullptr;
40     }
41 }
42 
GetNodeId()43 kBaseNodeId RtcpDecoderNode::GetNodeId()
44 {
45     return kNodeIdRtcpDecoder;
46 }
47 
Start()48 ImsMediaResult RtcpDecoderNode::Start()
49 {
50     IMLOGD0("[Start]");
51 
52     if (mRtpSession == nullptr)
53     {
54         mRtpSession = IRtpSession::GetInstance(mMediaType, mLocalAddress, mPeerAddress);
55 
56         if (mRtpSession == nullptr)
57         {
58             IMLOGE0("[Start] Can't create rtp session");
59             return RESULT_NOT_READY;
60         }
61     }
62 
63     mRtpSession->SetRtcpDecoderListener(this);
64     mNoRtcpTime = 0;
65     mNodeState = kNodeStateRunning;
66     return RESULT_SUCCESS;
67 }
68 
Stop()69 void RtcpDecoderNode::Stop()
70 {
71     IMLOGD0("[Stop]");
72 
73     if (mRtpSession)
74     {
75         mRtpSession->StopRtcp();
76     }
77 
78     mNodeState = kNodeStateStopped;
79 }
80 
OnDataFromFrontNode(ImsMediaSubType subtype,uint8_t * pData,uint32_t nDataSize,uint32_t nTimeStamp,bool bMark,uint32_t nSeqNum,ImsMediaSubType nDataType,uint32_t arrivalTime)81 void RtcpDecoderNode::OnDataFromFrontNode(ImsMediaSubType subtype, uint8_t* pData,
82         uint32_t nDataSize, uint32_t nTimeStamp, bool bMark, uint32_t nSeqNum,
83         ImsMediaSubType nDataType, uint32_t arrivalTime)
84 {
85     (void)nDataType;
86     (void)arrivalTime;
87 
88     IMLOGD_PACKET6(IM_PACKET_LOG_RTCP,
89             "[OnMediaDataInd] media[%d] subtype[%d], Size[%d], TS[%u], Mark[%d], Seq[%d]",
90             mMediaType, subtype, nDataSize, nTimeStamp, bMark, nSeqNum);
91     if (mRtpSession != nullptr)
92     {
93         mRtpSession->ProcRtcpPacket(pData, nDataSize);
94     }
95 }
96 
IsRunTime()97 bool RtcpDecoderNode::IsRunTime()
98 {
99     return true;
100 }
101 
IsSourceNode()102 bool RtcpDecoderNode::IsSourceNode()
103 {
104     return false;
105 }
106 
SetConfig(void * config)107 void RtcpDecoderNode::SetConfig(void* config)
108 {
109     if (config == nullptr)
110     {
111         return;
112     }
113 
114     RtpConfig* pConfig = reinterpret_cast<RtpConfig*>(config);
115     mPeerAddress = RtpAddress(pConfig->getRemoteAddress().c_str(), pConfig->getRemotePort());
116     IMLOGD2("[SetConfig] peer Ip[%s], port[%d]", mPeerAddress.ipAddress, mPeerAddress.port);
117 }
118 
IsSameConfig(void * config)119 bool RtcpDecoderNode::IsSameConfig(void* config)
120 {
121     if (config == nullptr)
122     {
123         return true;
124     }
125 
126     RtpConfig* pConfig = reinterpret_cast<RtpConfig*>(config);
127     RtpAddress peerAddress =
128             RtpAddress(pConfig->getRemoteAddress().c_str(), pConfig->getRemotePort());
129 
130     return (mPeerAddress == peerAddress);
131 }
132 
OnRtcpInd(tRtpSvc_IndicationFromStack type,void * data)133 void RtcpDecoderNode::OnRtcpInd(tRtpSvc_IndicationFromStack type, void* data)
134 {
135     if (data == nullptr)
136     {
137         return;
138     }
139 
140     switch (type)
141     {
142         case RTPSVC_RECEIVE_RTCP_SR_IND:
143         {
144             tNotifyReceiveRtcpSrInd* payload = reinterpret_cast<tNotifyReceiveRtcpSrInd*>(data);
145             IMLOGD_PACKET2(IM_PACKET_LOG_RTCP, "[OnRtcpInd] RtcpSr - fractionLost[%d], jitter[%d]",
146                     payload->stRecvRpt.fractionLost, payload->stRecvRpt.jitter);
147 
148             if (mMediaType == IMS_MEDIA_AUDIO)
149             {
150                 mCallback->SendEvent(kCollectPacketInfo, kStreamRtcp);
151             }
152 #ifdef DEBUG_BITRATE_CHANGE_SIMULATION
153             else if (mMediaType == IMS_MEDIA_VIDEO)
154             {
155                 gTestBitrate *= 0.8;
156                 mCallback->SendEvent(kRequestVideoBitrateChange, gTestBitrate);
157             }
158 #endif
159         }
160         break;
161         case RTPSVC_RECEIVE_RTCP_RR_IND:
162         {
163             tNotifyReceiveRtcpRrInd* payload = reinterpret_cast<tNotifyReceiveRtcpRrInd*>(data);
164             IMLOGD_PACKET2(IM_PACKET_LOG_RTCP, "[OnRtcpInd] RtcpRr - fractionLost[%d], jitter[%d]",
165                     payload->stRecvRpt.fractionLost, payload->stRecvRpt.jitter);
166 
167             if (mMediaType == IMS_MEDIA_AUDIO)
168             {
169                 mCallback->SendEvent(kCollectPacketInfo, kStreamRtcp);
170             }
171 #ifdef DEBUG_BITRATE_CHANGE_SIMULATION
172             else if (mMediaType == IMS_MEDIA_VIDEO)
173             {
174                 gTestBitrate *= 0.8;
175                 mCallback->SendEvent(kRequestVideoBitrateChange, gTestBitrate);
176             }
177 #endif
178         }
179         break;
180         case RTPSVC_RECEIVE_RTCP_FB_IND:
181         case RTPSVC_RECEIVE_RTCP_PAYLOAD_FB_IND:
182         {
183             tRtpSvcIndSt_ReceiveRtcpFeedbackInd* payload =
184                     reinterpret_cast<tRtpSvcIndSt_ReceiveRtcpFeedbackInd*>(data);
185             uint32_t feedbackType = 0;
186 
187             if (type == RTPSVC_RECEIVE_RTCP_FB_IND)
188             {
189                 feedbackType = payload->wFmt;
190             }
191             else if (type == RTPSVC_RECEIVE_RTCP_PAYLOAD_FB_IND)
192             {
193                 feedbackType = payload->wFmt + kPsfbBoundary;
194             }
195 
196             switch (feedbackType)
197             {
198                 case kRtpFbNack:
199                     /** do nothing */
200                     break;
201                 case kRtpFbTmmbr:
202                     ReceiveTmmbr(payload);
203                     break;
204                 case kRtpFbTmmbn:
205                     break;
206                 case kPsfbPli:  // FALL_THROUGH
207                 case kPsfbFir:
208                     RequestIdrFrame();
209                     break;
210                 default:
211                     IMLOGI2("[OnRtcpInd] unhandled payload[%d], fmt[%d]", payload->wPayloadType,
212                             payload->wFmt);
213                     break;
214             }
215         }
216         break;
217         default:
218             IMLOGI1("[OnRtcpInd] unhandled type[%d]", type);
219             break;
220     }
221 }
222 
OnNumReceivedPacket(uint32_t nNumRtcpSRPacket,uint32_t nNumRtcpRRPacket)223 void RtcpDecoderNode::OnNumReceivedPacket(uint32_t nNumRtcpSRPacket, uint32_t nNumRtcpRRPacket)
224 {
225     IMLOGD_PACKET3(IM_PACKET_LOG_RTCP,
226             "[OnNumReceivedPacket] InactivityTime[%d], numRtcpSR[%d], numRtcpRR[%d]",
227             mInactivityTime, nNumRtcpSRPacket, nNumRtcpRRPacket);
228 
229     if (nNumRtcpSRPacket == 0 && nNumRtcpRRPacket == 0)
230     {
231         mNoRtcpTime++;
232     }
233     else
234     {
235         mNoRtcpTime = 0;
236     }
237 
238     if (mInactivityTime != 0 && mNoRtcpTime == mInactivityTime)
239     {
240         if (mCallback != nullptr)
241         {
242             mCallback->SendEvent(kImsMediaEventMediaInactivity, kProtocolRtcp, mInactivityTime);
243         }
244     }
245 }
246 
OnEvent(uint32_t event,uint32_t param)247 void RtcpDecoderNode::OnEvent(uint32_t event, uint32_t param)
248 {
249     mCallback->SendEvent(event, param);
250 }
251 
SetLocalAddress(const RtpAddress & address)252 void RtcpDecoderNode::SetLocalAddress(const RtpAddress& address)
253 {
254     mLocalAddress = address;
255 }
256 
SetPeerAddress(const RtpAddress & address)257 void RtcpDecoderNode::SetPeerAddress(const RtpAddress& address)
258 {
259     mPeerAddress = address;
260 }
261 
SetInactivityTimerSec(const uint32_t time)262 void RtcpDecoderNode::SetInactivityTimerSec(const uint32_t time)
263 {
264     IMLOGD2("[SetInactivityTimerSec] media[%d], time[%d] reset", mMediaType, time);
265     mInactivityTime = time;
266     mNoRtcpTime = 0;
267 }
268 
ReceiveTmmbr(const tRtpSvcIndSt_ReceiveRtcpFeedbackInd * payload)269 void RtcpDecoderNode::ReceiveTmmbr(const tRtpSvcIndSt_ReceiveRtcpFeedbackInd* payload)
270 {
271     if (payload == nullptr || payload->pMsg == nullptr || mCallback == nullptr)
272     {
273         return;
274     }
275 
276     // Read bitrate from TMMBR
277     mBitReader.SetBuffer(payload->pMsg, 64);
278     /** read 16 bit and combine it */
279     uint32_t receivedSsrc = mBitReader.Read(16);
280     receivedSsrc = (receivedSsrc << 16) | mBitReader.Read(16);
281     uint32_t receivedExp = mBitReader.Read(6);
282     uint32_t receivedMantissa = mBitReader.Read(17);
283     uint32_t receivedOverhead = mBitReader.Read(9);
284     uint32_t bitrate = receivedMantissa << receivedExp;
285 
286     IMLOGD3("[ReceiveTmmbr] received TMMBR, exp[%d], mantissa[%d], bitrate[%d]", receivedExp,
287             receivedMantissa, bitrate);
288 
289     // Set the bitrate to encoder
290     mCallback->SendEvent(kRequestVideoBitrateChange, bitrate);
291 
292     // Send TMMBN to peer
293     uint32_t exp = 0;
294     uint32_t mantissa = 0;
295     ImsMediaVideoUtil::ConvertBitrateToPower(bitrate, exp, mantissa);
296 
297     InternalRequestEventParam* pParam = new InternalRequestEventParam(
298             kRtpFbTmmbn, TmmbrParams(receivedSsrc, exp, mantissa, receivedOverhead));
299     mCallback->SendEvent(kRequestVideoSendTmmbn, reinterpret_cast<uint64_t>(pParam));
300 }
301 
RequestIdrFrame()302 void RtcpDecoderNode::RequestIdrFrame()
303 {
304     IMLOGD0("[RequestIdrFrame]");
305 
306     if (mCallback != nullptr)
307     {
308         mCallback->SendEvent(kRequestVideoIdrFrame, 0);
309     }
310 }