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 
146             if (mMediaType == IMS_MEDIA_AUDIO)
147             {
148                 RtcpSr* rtcpSr = new RtcpSr(payload->ntpTimestampMsw, payload->ntpTimestampLsw,
149                         payload->rtpTimestamp, payload->sendPktCount, payload->sendOctCount,
150                         RtcpRecvReport(payload->stRecvRpt.ssrc, payload->stRecvRpt.fractionLost,
151                                 payload->stRecvRpt.cumPktsLost, payload->stRecvRpt.extHighSeqNum,
152                                 payload->stRecvRpt.jitter, payload->stRecvRpt.lsr,
153                                 payload->stRecvRpt.delayLsr));
154                 mCallback->SendEvent(
155                         kCollectPacketInfo, kStreamRtcp, reinterpret_cast<uint64_t>(rtcpSr));
156             }
157 #ifdef DEBUG_BITRATE_CHANGE_SIMULATION
158             else if (mMediaType == IMS_MEDIA_VIDEO)
159             {
160                 gTestBitrate *= 0.8;
161                 mCallback->SendEvent(kRequestVideoBitrateChange, gTestBitrate);
162             }
163 #endif
164         }
165         break;
166         case RTPSVC_RECEIVE_RTCP_RR_IND:
167         {
168             tNotifyReceiveRtcpRrInd* payload = reinterpret_cast<tNotifyReceiveRtcpRrInd*>(data);
169             IMLOGD_PACKET2(IM_PACKET_LOG_RTCP, "[OnRtcpInd] RtcpRr - fractionLost[%d], jitter[%d]",
170                     payload->stRecvRpt.fractionLost, payload->stRecvRpt.jitter);
171 
172             if (mMediaType == IMS_MEDIA_AUDIO)
173             {
174                 mCallback->SendEvent(kCollectPacketInfo, kStreamRtcp);
175             }
176 #ifdef DEBUG_BITRATE_CHANGE_SIMULATION
177             else if (mMediaType == IMS_MEDIA_VIDEO)
178             {
179                 gTestBitrate *= 0.8;
180                 mCallback->SendEvent(kRequestVideoBitrateChange, gTestBitrate);
181             }
182 #endif
183         }
184         break;
185         case RTPSVC_RECEIVE_RTCP_FB_IND:
186         case RTPSVC_RECEIVE_RTCP_PAYLOAD_FB_IND:
187         {
188             tRtpSvcIndSt_ReceiveRtcpFeedbackInd* payload =
189                     reinterpret_cast<tRtpSvcIndSt_ReceiveRtcpFeedbackInd*>(data);
190             uint32_t feedbackType = 0;
191 
192             if (type == RTPSVC_RECEIVE_RTCP_FB_IND)
193             {
194                 feedbackType = payload->wFmt;
195             }
196             else if (type == RTPSVC_RECEIVE_RTCP_PAYLOAD_FB_IND)
197             {
198                 feedbackType = payload->wFmt + kPsfbBoundary;
199             }
200 
201             switch (feedbackType)
202             {
203                 case kRtpFbNack:
204                     /** do nothing */
205                     break;
206                 case kRtpFbTmmbr:
207                     ReceiveTmmbr(payload);
208                     break;
209                 case kRtpFbTmmbn:
210                     break;
211                 case kPsfbPli:  // FALL_THROUGH
212                 case kPsfbFir:
213                     RequestIdrFrame();
214                     break;
215                 default:
216                     IMLOGI2("[OnRtcpInd] unhandled payload[%d], fmt[%d]", payload->wPayloadType,
217                             payload->wFmt);
218                     break;
219             }
220         }
221         break;
222         default:
223             IMLOGI1("[OnRtcpInd] unhandled type[%d]", type);
224             break;
225     }
226 }
227 
OnNumReceivedPacket(uint32_t nNumRtcpSRPacket,uint32_t nNumRtcpRRPacket)228 void RtcpDecoderNode::OnNumReceivedPacket(uint32_t nNumRtcpSRPacket, uint32_t nNumRtcpRRPacket)
229 {
230     IMLOGD_PACKET3(IM_PACKET_LOG_RTCP,
231             "[OnNumReceivedPacket] InactivityTime[%d], numRtcpSR[%d], numRtcpRR[%d]",
232             mInactivityTime, nNumRtcpSRPacket, nNumRtcpRRPacket);
233 
234     if (nNumRtcpSRPacket == 0 && nNumRtcpRRPacket == 0)
235     {
236         mNoRtcpTime++;
237     }
238     else
239     {
240         mNoRtcpTime = 0;
241     }
242 
243     if (mInactivityTime != 0 && mNoRtcpTime == mInactivityTime)
244     {
245         if (mCallback != nullptr)
246         {
247             mCallback->SendEvent(kImsMediaEventMediaInactivity, kProtocolRtcp, mInactivityTime);
248         }
249     }
250 }
251 
OnEvent(uint32_t event,uint32_t param)252 void RtcpDecoderNode::OnEvent(uint32_t event, uint32_t param)
253 {
254     mCallback->SendEvent(event, param);
255 }
256 
SetLocalAddress(const RtpAddress & address)257 void RtcpDecoderNode::SetLocalAddress(const RtpAddress& address)
258 {
259     mLocalAddress = address;
260 }
261 
SetPeerAddress(const RtpAddress & address)262 void RtcpDecoderNode::SetPeerAddress(const RtpAddress& address)
263 {
264     mPeerAddress = address;
265 }
266 
SetInactivityTimerSec(const uint32_t time)267 void RtcpDecoderNode::SetInactivityTimerSec(const uint32_t time)
268 {
269     IMLOGD2("[SetInactivityTimerSec] media[%d], time[%d] reset", mMediaType, time);
270     mInactivityTime = time;
271     mNoRtcpTime = 0;
272 }
273 
ReceiveTmmbr(const tRtpSvcIndSt_ReceiveRtcpFeedbackInd * payload)274 void RtcpDecoderNode::ReceiveTmmbr(const tRtpSvcIndSt_ReceiveRtcpFeedbackInd* payload)
275 {
276     if (payload == nullptr || payload->pMsg == nullptr || mCallback == nullptr)
277     {
278         return;
279     }
280 
281     // Read bitrate from TMMBR
282     mBitReader.SetBuffer(payload->pMsg, 64);
283     /** read 16 bit and combine it */
284     uint32_t receivedSsrc = mBitReader.Read(16);
285     receivedSsrc = (receivedSsrc << 16) | mBitReader.Read(16);
286     uint32_t receivedExp = mBitReader.Read(6);
287     uint32_t receivedMantissa = mBitReader.Read(17);
288     uint32_t receivedOverhead = mBitReader.Read(9);
289     uint32_t bitrate = receivedMantissa << receivedExp;
290 
291     IMLOGD3("[ReceiveTmmbr] received TMMBR, exp[%d], mantissa[%d], bitrate[%d]", receivedExp,
292             receivedMantissa, bitrate);
293 
294     // Set the bitrate to encoder
295     mCallback->SendEvent(kRequestVideoBitrateChange, bitrate);
296 
297     // Send TMMBN to peer
298     uint32_t exp = 0;
299     uint32_t mantissa = 0;
300     ImsMediaVideoUtil::ConvertBitrateToPower(bitrate, exp, mantissa);
301 
302     InternalRequestEventParam* pParam = new InternalRequestEventParam(
303             kRtpFbTmmbn, TmmbrParams(receivedSsrc, exp, mantissa, receivedOverhead));
304     mCallback->SendEvent(kRequestVideoSendTmmbn, reinterpret_cast<uint64_t>(pParam));
305 }
306 
RequestIdrFrame()307 void RtcpDecoderNode::RequestIdrFrame()
308 {
309     IMLOGD0("[RequestIdrFrame]");
310 
311     if (mCallback != nullptr)
312     {
313         mCallback->SendEvent(kRequestVideoIdrFrame, 0);
314     }
315 }