1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rtcp_context.h"
17 #include <netinet/in.h>
18 #include "common/common_macro.h"
19 #include "common/media_log.h"
20 #include "utils/utils.h"
21 
22 namespace OHOS {
23 namespace Sharing {
OnRtp(uint16_t , uint32_t stamp, uint64_t ntpStampMs, uint32_t , size_t bytes)24 void RtcpContext::OnRtp(uint16_t /*seq*/, uint32_t stamp, uint64_t ntpStampMs, uint32_t /*sampleRate*/, size_t bytes)
25 {
26     ++packets_;
27     bytes_ += bytes;
28     lastRtpStamp_ = stamp;
29     lastNtpStampMs_ = ntpStampMs;
30 }
31 
32 //------------------------------ RtcpSenderContext ------------------------------//
CreateRtcpSR(uint32_t rtcpSSRC)33 DataBuffer::Ptr RtcpSenderContext::CreateRtcpSR(uint32_t rtcpSSRC)
34 {
35     auto rtcp = RtcpSR::Create(0);
36     rtcp->SetNtpStamp(lastNtpStampMs_);
37     rtcp->rtpts_ = htonl(lastRtpStamp_);
38     rtcp->ssrc_ = htonl(rtcpSSRC);
39     rtcp->packetCount_ = htonl((uint32_t)packets_);
40     rtcp->octetCount_ = htonl((uint32_t)bytes_);
41 
42     auto lastSrLsr =
43         ((ntohl(rtcp->ntpmsw_) & 0xFFFF) << 16) | ((ntohl(rtcp->ntplsw_) >> 16) & 0xFFFF); // 16:byte offset
44     senderReportNtp_[lastSrLsr] = GetCurrentMillisecond();
45     if (senderReportNtp_.size() >= 5) { // 5:fixed capacity
46         senderReportNtp_.erase(senderReportNtp_.begin());
47     }
48 
49     DataBuffer::Ptr ret = std::make_shared<DataBuffer>();
50     ret->PushData((char *)rtcp.get(), rtcp->GetSize());
51     return ret;
52 }
53 
OnRtcp(RtcpHeader *rtcp)54 void RtcpSenderContext::OnRtcp(RtcpHeader *rtcp)
55 {
56     RETURN_IF_NULL(rtcp);
57     switch ((RtcpType)rtcp->pt_) {
58         case RtcpType::RTCP_RR: {
59             auto rtcpRR = (RtcpRR *)rtcp;
60             for (auto &item : rtcpRR->GetItemList()) {
61                 if (!item->lastSrStamp_) {
62                     continue;
63                 }
64                 auto it = senderReportNtp_.find(item->lastSrStamp_);
65                 if (it == senderReportNtp_.end()) {
66                     continue;
67                 }
68                 // time: sender (send SR) -> receiver (recv SR) -> receiver (send RR) -> sender (recv RR)
69                 auto msInc = GetCurrentMillisecond() - it->second;
70                 // time: receiver (recv SR) -> receiver (send RR)
71                 auto delayMs = (uint64_t)item->delaySinceLastSr_ * 1000 / 65536; // 1000:unit, 65536:max seq
72                 // time: [sender (send SR) -> receiver (recv SR)] + [receiver (send RR) -> sender (recv RR)]
73                 auto rtt = (int32_t)(msInc - delayMs);
74                 if (rtt >= 0) {
75                     rtt_[item->ssrc_] = rtt;
76                 }
77             }
78             break;
79         }
80         case RtcpType::RTCP_XR: {
81             auto rtcp_xr = (RtcpXRRRTR *)rtcp;
82             if (rtcp_xr->bt_ == 4) { // 4:xrXrrtr
83                 xrXrrtrRecvLastRr_[rtcp_xr->ssrc_] =
84                     ((rtcp_xr->ntpmsw_ & 0xFFFF) << 16) | ((rtcp_xr->ntplsw_ >> 16) & 0xFFFF); // 16:byte offset
85                 xrRrtrRecvSysStamp_[rtcp_xr->ssrc_] = GetCurrentMillisecond();
86             } else if (rtcp_xr->bt_ == 5) { // 5:dlrr
87                 SHARING_LOGD("for sender not recive dlrr.");
88             } else {
89                 SHARING_LOGD("not support xr bt.");
90             }
91             break;
92         }
93         default:
94             break;
95     }
96 }
97 
CreateRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc)98 DataBuffer::Ptr RtcpSenderContext::CreateRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc)
99 {
100     return nullptr;
101 }
102 
GetRtt(uint32_t ssrc) const103 uint32_t RtcpSenderContext::GetRtt(uint32_t ssrc) const
104 {
105     auto it = rtt_.find(ssrc);
106     if (it == rtt_.end()) {
107         return 0;
108     }
109 
110     return it->second;
111 }
112 
113 //------------------------------ RtcpReceiverContext ------------------------------//
OnRtp(uint16_t seq, uint32_t stamp, uint64_t ntpStampMs, uint32_t sampleRate, size_t bytes)114 void RtcpReceiverContext::OnRtp(uint16_t seq, uint32_t stamp, uint64_t ntpStampMs, uint32_t sampleRate, size_t bytes)
115 {
116     // the receiver performs complex statistical operations
117     auto sysStamp = GetCurrentMillisecond();
118     if (lastRtpSysStamp_) {
119         // calculate timestamp jitter value
120         double diff = double((int64_t(sysStamp) - int64_t(lastRtpSysStamp_)) * (sampleRate / double(1000.0)) -
121                              (int64_t(stamp) - int64_t(lastRtpStamp_)));
122         if (diff < 0) {
123             diff = -diff;
124         }
125         // jitter unit: sampling numbers
126         jitter_ += (diff - jitter_) / 16.0; // 16.0:jitter unit
127     } else {
128         jitter_ = 0;
129     }
130 
131     if (lastRtpSeq_ > 0xFF00 && seq < 0xFF && (!seqCycles_ || packets_ - lastCyclePackets_ > 0x1FFF)) {
132         // if the last seq > 0xff00 and the current seq < 0xff,
133         // and no loopback occurs or the interval from the last loopback exceeds 0x1fff packets,
134         // the loopback is considered
135         ++seqCycles_;
136         lastCyclePackets_ = packets_;
137         seqMax_ = seq;
138     } else if (seq > seqMax_) {
139         // maximum seq before loop back
140         seqMax_ = seq;
141     }
142 
143     if (!seqBase_) {
144         // record the first rtp's seq
145         seqBase_ = seq;
146     } else if (!seqCycles_ && seq < seqBase_) {
147         // if no loopback occurs, the latest seq is taken as the base seq
148         seqBase_ = seq;
149     }
150 
151     lastRtpSeq_ = seq;
152     lastRtpSysStamp_ = sysStamp;
153 
154     RtcpContext::OnRtp(seq, stamp, ntpStampMs, sampleRate, bytes);
155 }
156 
OnRtcp(RtcpHeader *rtcp)157 void RtcpReceiverContext::OnRtcp(RtcpHeader *rtcp)
158 {
159     RETURN_IF_NULL(rtcp);
160     switch ((RtcpType)rtcp->pt_) {
161         case RtcpType::RTCP_SR: {
162             auto rtcpSR = (RtcpSR *)rtcp;
163             // last SR timestamp (LSR): 32 bits
164             //  The middle 32 bits out of 64 in the NTP timestamp (as explained in
165             //  Section 4) received as part of the most recent RTCP sender report
166             //  (SR) packet from source SSRC_n.  If no SR has been received yet,
167             //  the field is set to zero.
168             lastSrLsr_ = (((ntohl(rtcpSR->ntpmsw_) & 0xffff) << 16) | // 16:byte offset
169                           ((ntohl(rtcpSR->ntplsw_) >> 16) & 0xffff)); // 16:byte offset
170             lastSrNtpSys_ = GetCurrentMillisecond();
171             break;
172         }
173         default:
174             break;
175     }
176 }
177 
CreateRtcpRR(uint32_t rtcpSSRC, uint32_t rtpSSRC)178 DataBuffer::Ptr RtcpReceiverContext::CreateRtcpRR(uint32_t rtcpSSRC, uint32_t rtpSSRC)
179 {
180     auto rtcp = RtcpRR::Create(1);
181     if (rtcp == nullptr) {
182         return nullptr;
183     }
184 
185     rtcp->ssrc_ = htonl(rtcpSSRC);
186 
187     ReportItem *item = (ReportItem *)&rtcp->items_;
188     if (item == nullptr) {
189         return nullptr;
190     }
191 
192     item->ssrc_ = htonl(rtpSSRC);
193 
194     uint8_t fraction = 0;
195     auto expectedInterval = GetExpectedPacketsInterval();
196     if (expectedInterval != 0) {
197         fraction = uint8_t((GetLostInterval() << 8) / expectedInterval); // 8:byte offset
198     }
199 
200     // fraction = packet loss rate (percentage) * 256
201     item->fractionLost_ = fraction;
202     item->cumulative_ = htonl(uint32_t(GetLost())) >> 8; // 8:byte offset
203     item->seqCycles_ = htons(seqCycles_);
204     item->seqMax_ = htons(seqMax_);
205     item->jitter_ = htonl(uint32_t(jitter_));
206     item->lastSrStamp_ = htonl(lastSrLsr_);
207 
208     // now - recv Last SR time
209     auto delay = GetCurrentMillisecond() - lastSrNtpSys_;
210     // in units of 1/65536 seconds
211     auto dlsr = (uint32_t)(delay / 1000.0f * 65536); // 1000.0:unit, 65536:max seq
212     item->delaySinceLastSr_ = htonl(lastSrLsr_ ? dlsr : 0);
213 
214     DataBuffer::Ptr ret = std::make_shared<DataBuffer>();
215     ret->PushData((char *)rtcp.get(), rtcp->GetSize());
216     return ret;
217 }
218 
GetExpectedPackets() const219 size_t RtcpReceiverContext::GetExpectedPackets() const
220 {
221     return (seqCycles_ << 16) + seqMax_ - seqBase_ + 1; // 16:byte offset
222 }
223 
GetExpectedPacketsInterval()224 size_t RtcpReceiverContext::GetExpectedPacketsInterval()
225 {
226     auto expected = GetExpectedPackets();
227     auto ret = expected - lastExpected_;
228     lastExpected_ = expected;
229     return ret;
230 }
231 
GetLost()232 size_t RtcpReceiverContext::GetLost()
233 {
234     return GetExpectedPackets() - packets_;
235 }
236 
GetLostInterval()237 size_t RtcpReceiverContext::GetLostInterval()
238 {
239     auto lost = GetLost();
240     auto ret = lost - lastLost_;
241     lastLost_ = lost;
242     return ret;
243 }
244 
245 } // namespace Sharing
246 } // namespace OHOS