diff --git a/src/Rtcp/RtcpContext.cpp b/src/Rtcp/RtcpContext.cpp
index 681c9d17..f7795405 100644
--- a/src/Rtcp/RtcpContext.cpp
+++ b/src/Rtcp/RtcpContext.cpp
@@ -14,14 +14,97 @@ using namespace toolkit;
namespace mediakit {
-
-void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) {
+void RtcpContext::onRtp(uint16_t /*seq*/, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t /*sample_rate*/, size_t bytes) {
++_packets;
_bytes += bytes;
_last_rtp_stamp = stamp;
_last_ntp_stamp_ms = ntp_stamp_ms;
}
+size_t RtcpContext::getExpectedPackets() const {
+ throw std::runtime_error("没有实现, rtp发送者无法统计应收包数");
+}
+
+size_t RtcpContext::getExpectedPacketsInterval() {
+ throw std::runtime_error("没有实现, rtp发送者无法统计应收包数");
+}
+
+size_t RtcpContext::getLost() {
+ throw std::runtime_error("没有实现, rtp发送者无法统计丢包率");
+}
+
+size_t RtcpContext::geLostInterval() {
+ throw std::runtime_error("没有实现, rtp发送者无法统计丢包率");
+}
+
+Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) {
+ throw std::runtime_error("没有实现, rtp接收者尝试发送sr包");
+}
+
+Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) {
+ throw std::runtime_error("没有实现, rtp发送者尝试发送rr包");
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+void RtcpContextForSend::onRtcp(RtcpHeader *rtcp) {
+ switch ((RtcpType) rtcp->pt) {
+ case RtcpType::RTCP_RR: {
+ auto rtcp_rr = (RtcpRR *) rtcp;
+ for (auto item : rtcp_rr->getItemList()) {
+ if (!item->last_sr_stamp) {
+ continue;
+ }
+ auto it = _sender_report_ntp.find(item->last_sr_stamp);
+ if (it == _sender_report_ntp.end()) {
+ continue;
+ }
+ //发送sr到收到rr之间的时间戳增量
+ auto ms_inc = getCurrentMillisecond() - it->second;
+ //rtp接收端收到sr包后,回复rr包的延时,已转换为毫秒
+ auto delay_ms = (uint64_t) item->delay_since_last_sr * 1000 / 65536;
+ auto rtt = (int) (ms_inc - delay_ms);
+ if (rtt >= 0) {
+ //rtt不可能小于0
+ _rtt[item->ssrc] = rtt;
+ //InfoL << "ssrc:" << item->ssrc << ",rtt:" << rtt;
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+}
+
+uint32_t RtcpContextForSend::getRtt(uint32_t ssrc) const {
+ auto it = _rtt.find(ssrc);
+ if (it == _rtt.end()) {
+ return 0;
+ }
+ return it->second;
+}
+
+Buffer::Ptr RtcpContextForSend::createRtcpSR(uint32_t rtcp_ssrc) {
+ auto rtcp = RtcpSR::create(0);
+ rtcp->setNtpStamp(_last_ntp_stamp_ms);
+ rtcp->rtpts = htonl(_last_rtp_stamp);
+ rtcp->ssrc = htonl(rtcp_ssrc);
+ rtcp->packet_count = htonl((uint32_t) _packets);
+ rtcp->octet_count = htonl((uint32_t) _bytes);
+
+ //记录上次发送的sender report信息,用于后续统计rtt
+ auto last_sr_lsr = ((ntohl(rtcp->ntpmsw) & 0xFFFF) << 16) | ((ntohl(rtcp->ntplsw) >> 16) & 0xFFFF);
+ _sender_report_ntp[last_sr_lsr] = getCurrentMillisecond();
+ if (_sender_report_ntp.size() >= 5) {
+ //删除最早的sr rtcp
+ _sender_report_ntp.erase(_sender_report_ntp.begin());
+ }
+
+ return RtcpHeader::toBuffer(std::move(rtcp));
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) {
{
//接收者才做复杂的统计运算
@@ -64,7 +147,7 @@ void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_
RtcpContext::onRtp(seq, stamp, ntp_stamp_ms, sample_rate, bytes);
}
-void RtcpContext::onRtcp(RtcpHeader *rtcp) {
+void RtcpContextForRecv::onRtcp(RtcpHeader *rtcp) {
switch ((RtcpType) rtcp->pt) {
case RtcpType::RTCP_SR: {
auto rtcp_sr = (RtcpSR *) rtcp;
@@ -79,50 +162,14 @@ void RtcpContext::onRtcp(RtcpHeader *rtcp) {
_last_sr_ntp_sys = getCurrentMillisecond();
break;
}
- case RtcpType::RTCP_RR: {
- auto rtcp_rr = (RtcpRR *) rtcp;
- for (auto item : rtcp_rr->getItemList()) {
- if (!item->last_sr_stamp) {
- continue;
- }
- auto it = _sender_report_ntp.find(item->last_sr_stamp);
- if (it == _sender_report_ntp.end()) {
- continue;
- }
- //发送sr到收到rr之间的时间戳增量
- auto ms_inc = getCurrentMillisecond() - it->second;
- //rtp接收端收到sr包后,回复rr包的延时,已转换为毫秒
- auto delay_ms = (uint64_t) item->delay_since_last_sr * 1000 / 65536;
- auto rtt = (int) (ms_inc - delay_ms);
- if (rtt >= 0) {
- //rtt不可能小于0
- _rtt[item->ssrc] = rtt;
- //InfoL << "ssrc:" << item->ssrc << ",rtt:" << rtt;
- }
- }
- break;
- }
default: break;
}
}
-uint32_t RtcpContext::getRtt(uint32_t ssrc) const {
- auto it = _rtt.find(ssrc);
- if (it == _rtt.end()) {
- return 0;
- }
- return it->second;
-}
-
-size_t RtcpContext::getExpectedPackets() const {
- throw std::runtime_error("没有实现, rtp发送者无法统计应收包数");
-}
size_t RtcpContextForRecv::getExpectedPackets() const {
return (_seq_cycles << 16) + _seq_max - _seq_base + 1;
}
-size_t RtcpContext::getExpectedPacketsInterval() {
- throw std::runtime_error("没有实现, rtp发送者无法统计应收包数");
-}
+
size_t RtcpContextForRecv::getExpectedPacketsInterval() {
auto expected = getExpectedPackets();
auto ret = expected - _last_expected;
@@ -130,17 +177,10 @@ size_t RtcpContextForRecv::getExpectedPacketsInterval() {
return ret;
}
-size_t RtcpContext::getLost() {
- throw std::runtime_error("没有实现, rtp发送者无法统计丢包率");
-}
-
size_t RtcpContextForRecv::getLost() {
return getExpectedPackets() - _packets;
}
-size_t RtcpContext::geLostInterval() {
- throw std::runtime_error("没有实现, rtp发送者无法统计丢包率");
-}
size_t RtcpContextForRecv::geLostInterval() {
auto lost = getLost();
auto ret = lost - _last_lost;
@@ -148,34 +188,6 @@ size_t RtcpContextForRecv::geLostInterval() {
return ret;
}
-Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) {
- throw std::runtime_error("没有实现, rtp接收者尝试发送sr包");
-}
-
-Buffer::Ptr RtcpContextForSend::createRtcpSR(uint32_t rtcp_ssrc) {
- auto rtcp = RtcpSR::create(0);
- rtcp->setNtpStamp(_last_ntp_stamp_ms);
- rtcp->rtpts = htonl(_last_rtp_stamp);
- rtcp->ssrc = htonl(rtcp_ssrc);
- rtcp->packet_count = htonl((uint32_t) _packets);
- rtcp->octet_count = htonl((uint32_t) _bytes);
-
- //记录上次发送的sender report信息,用于后续统计rtt
- auto last_sr_lsr = ((ntohl(rtcp->ntpmsw) & 0xFFFF) << 16) | ((ntohl(rtcp->ntplsw) >> 16) & 0xFFFF);
- _sender_report_ntp[last_sr_lsr] = getCurrentMillisecond();
- if (_sender_report_ntp.size() >= 5) {
- //删除最早的sr rtcp
- _sender_report_ntp.erase(_sender_report_ntp.begin());
- }
-
- return RtcpHeader::toBuffer(std::move(rtcp));
-}
-
-Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) {
- throw std::runtime_error("没有实现, rtp发送者尝试发送rr包");
-}
-
-
Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) {
auto rtcp = RtcpRR::create(1);
rtcp->ssrc = htonl(rtcp_ssrc);
diff --git a/src/Rtcp/RtcpContext.h b/src/Rtcp/RtcpContext.h
index c476219f..6604d5ff 100644
--- a/src/Rtcp/RtcpContext.h
+++ b/src/Rtcp/RtcpContext.h
@@ -36,7 +36,7 @@ public:
* 输入sr rtcp包
* @param rtcp 输入一个rtcp
*/
- void onRtcp(RtcpHeader *rtcp);
+ virtual void onRtcp(RtcpHeader *rtcp) = 0;
/**
* 计算总丢包数
@@ -63,13 +63,6 @@ public:
*/
virtual Buffer::Ptr createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc);
- /**
- * 获取rtt
- * @param ssrc rtp ssrc
- * @return rtt,单位毫秒
- */
- uint32_t getRtt(uint32_t ssrc) const;
-
/**
* 上次结果与本次结果间应收包数
*/
@@ -88,24 +81,36 @@ protected:
//上次的rtp时间戳,毫秒
uint32_t _last_rtp_stamp = 0;
uint64_t _last_ntp_stamp_ms = 0;
- //上次统计的丢包总数
- size_t _last_lost = 0;
- //上次统计应收rtp包总数
- size_t _last_expected = 0;
- //上次收到sr包时计算出的Last SR timestamp
- uint32_t _last_sr_lsr = 0;
- //上次收到sr时的系统时间戳,单位毫秒
- uint64_t _last_sr_ntp_sys = 0;
- map _rtt;
- map _sender_report_ntp;
};
class RtcpContextForSend : public RtcpContext {
public:
Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc) override;
+ void onRtcp(RtcpHeader *rtcp) override;
+
+ /**
+ * 获取rtt
+ * @param ssrc rtp ssrc
+ * @return rtt,单位毫秒
+ */
+ uint32_t getRtt(uint32_t ssrc) const;
+
+private:
+ map _rtt;
+ map _sender_report_ntp;
};
class RtcpContextForRecv : public RtcpContext {
+public:
+ void onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) override;
+ Buffer::Ptr createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) override;
+ size_t getExpectedPackets() const override;
+ size_t getExpectedPacketsInterval() override;
+ size_t getLost() override;
+ size_t geLostInterval() override;
+ void onRtcp(RtcpHeader *rtcp) override;
+
+private:
//时间戳抖动值
double _jitter = 0;
//第一个seq的值
@@ -120,13 +125,15 @@ class RtcpContextForRecv : public RtcpContext {
uint16_t _last_rtp_seq = 0;
//上次的rtp的系统时间戳(毫秒)用于统计抖动
uint64_t _last_rtp_sys_stamp = 0;
-public:
- void onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) override;
- Buffer::Ptr createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) override;
- size_t getExpectedPackets() const override;
- size_t getExpectedPacketsInterval() override;
- size_t getLost() override;
- size_t geLostInterval() override;
+ //上次统计的丢包总数
+ size_t _last_lost = 0;
+ //上次统计应收rtp包总数
+ size_t _last_expected = 0;
+ //上次收到sr包时计算出的Last SR timestamp
+ uint32_t _last_sr_lsr = 0;
+ //上次收到sr时的系统时间戳,单位毫秒
+ uint64_t _last_sr_ntp_sys = 0;
};
+
}//namespace mediakit
#endif //ZLMEDIAKIT_RTCPCONTEXT_H