mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
合并pr:#1158
This commit is contained in:
parent
638ef8c731
commit
702c505a17
@ -14,14 +14,97 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
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;
|
++_packets;
|
||||||
_bytes += bytes;
|
_bytes += bytes;
|
||||||
_last_rtp_stamp = stamp;
|
_last_rtp_stamp = stamp;
|
||||||
_last_ntp_stamp_ms = ntp_stamp_ms;
|
_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) {
|
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);
|
RtcpContext::onRtp(seq, stamp, ntp_stamp_ms, sample_rate, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtcpContext::onRtcp(RtcpHeader *rtcp) {
|
void RtcpContextForRecv::onRtcp(RtcpHeader *rtcp) {
|
||||||
switch ((RtcpType) rtcp->pt) {
|
switch ((RtcpType) rtcp->pt) {
|
||||||
case RtcpType::RTCP_SR: {
|
case RtcpType::RTCP_SR: {
|
||||||
auto rtcp_sr = (RtcpSR *) rtcp;
|
auto rtcp_sr = (RtcpSR *) rtcp;
|
||||||
@ -79,50 +162,14 @@ void RtcpContext::onRtcp(RtcpHeader *rtcp) {
|
|||||||
_last_sr_ntp_sys = getCurrentMillisecond();
|
_last_sr_ntp_sys = getCurrentMillisecond();
|
||||||
break;
|
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;
|
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 {
|
size_t RtcpContextForRecv::getExpectedPackets() const {
|
||||||
return (_seq_cycles << 16) + _seq_max - _seq_base + 1;
|
return (_seq_cycles << 16) + _seq_max - _seq_base + 1;
|
||||||
}
|
}
|
||||||
size_t RtcpContext::getExpectedPacketsInterval() {
|
|
||||||
throw std::runtime_error("没有实现, rtp发送者无法统计应收包数");
|
|
||||||
}
|
|
||||||
size_t RtcpContextForRecv::getExpectedPacketsInterval() {
|
size_t RtcpContextForRecv::getExpectedPacketsInterval() {
|
||||||
auto expected = getExpectedPackets();
|
auto expected = getExpectedPackets();
|
||||||
auto ret = expected - _last_expected;
|
auto ret = expected - _last_expected;
|
||||||
@ -130,17 +177,10 @@ size_t RtcpContextForRecv::getExpectedPacketsInterval() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RtcpContext::getLost() {
|
|
||||||
throw std::runtime_error("没有实现, rtp发送者无法统计丢包率");
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t RtcpContextForRecv::getLost() {
|
size_t RtcpContextForRecv::getLost() {
|
||||||
return getExpectedPackets() - _packets;
|
return getExpectedPackets() - _packets;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RtcpContext::geLostInterval() {
|
|
||||||
throw std::runtime_error("没有实现, rtp发送者无法统计丢包率");
|
|
||||||
}
|
|
||||||
size_t RtcpContextForRecv::geLostInterval() {
|
size_t RtcpContextForRecv::geLostInterval() {
|
||||||
auto lost = getLost();
|
auto lost = getLost();
|
||||||
auto ret = lost - _last_lost;
|
auto ret = lost - _last_lost;
|
||||||
@ -148,34 +188,6 @@ size_t RtcpContextForRecv::geLostInterval() {
|
|||||||
return ret;
|
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) {
|
Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) {
|
||||||
auto rtcp = RtcpRR::create(1);
|
auto rtcp = RtcpRR::create(1);
|
||||||
rtcp->ssrc = htonl(rtcp_ssrc);
|
rtcp->ssrc = htonl(rtcp_ssrc);
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
* 输入sr rtcp包
|
* 输入sr rtcp包
|
||||||
* @param rtcp 输入一个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);
|
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时间戳,毫秒
|
//上次的rtp时间戳,毫秒
|
||||||
uint32_t _last_rtp_stamp = 0;
|
uint32_t _last_rtp_stamp = 0;
|
||||||
uint64_t _last_ntp_stamp_ms = 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<uint32_t/*ssrc*/, uint32_t/*rtt*/> _rtt;
|
|
||||||
map<uint32_t/*last_sr_lsr*/, uint64_t/*ntp stamp*/> _sender_report_ntp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtcpContextForSend : public RtcpContext {
|
class RtcpContextForSend : public RtcpContext {
|
||||||
public:
|
public:
|
||||||
Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc) override;
|
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<uint32_t/*ssrc*/, uint32_t/*rtt*/> _rtt;
|
||||||
|
map<uint32_t/*last_sr_lsr*/, uint64_t/*ntp stamp*/> _sender_report_ntp;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtcpContextForRecv : public RtcpContext {
|
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;
|
double _jitter = 0;
|
||||||
//第一个seq的值
|
//第一个seq的值
|
||||||
@ -120,13 +125,15 @@ class RtcpContextForRecv : public RtcpContext {
|
|||||||
uint16_t _last_rtp_seq = 0;
|
uint16_t _last_rtp_seq = 0;
|
||||||
//上次的rtp的系统时间戳(毫秒)用于统计抖动
|
//上次的rtp的系统时间戳(毫秒)用于统计抖动
|
||||||
uint64_t _last_rtp_sys_stamp = 0;
|
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;
|
size_t _last_lost = 0;
|
||||||
Buffer::Ptr createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) override;
|
//上次统计应收rtp包总数
|
||||||
size_t getExpectedPackets() const override;
|
size_t _last_expected = 0;
|
||||||
size_t getExpectedPacketsInterval() override;
|
//上次收到sr包时计算出的Last SR timestamp
|
||||||
size_t getLost() override;
|
uint32_t _last_sr_lsr = 0;
|
||||||
size_t geLostInterval() override;
|
//上次收到sr时的系统时间戳,单位毫秒
|
||||||
|
uint64_t _last_sr_ntp_sys = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
#endif //ZLMEDIAKIT_RTCPCONTEXT_H
|
#endif //ZLMEDIAKIT_RTCPCONTEXT_H
|
||||||
|
Loading…
Reference in New Issue
Block a user