优化rtp统计性能

This commit is contained in:
xiongziliang 2021-01-31 19:55:47 +08:00
parent 070bf19cb5
commit 51435d955c
5 changed files with 79 additions and 53 deletions

View File

@ -9,65 +9,75 @@
*/ */
#include "RtcpContext.h" #include "RtcpContext.h"
#include "Util/logger.h"
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
void RtcpContext::clear(){ void RtcpContext::clear() {
memset(this, 0, sizeof(RtcpContext)); memset(this, 0, sizeof(RtcpContext));
} }
RtcpContext::RtcpContext(uint32_t sample_rate){ RtcpContext::RtcpContext(uint32_t sample_rate, bool is_receiver) {
_sample_rate = sample_rate; _sample_rate = sample_rate;
_is_receiver = is_receiver;
} }
void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, size_t bytes) { void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, size_t bytes) {
_bytes += bytes; if (_is_receiver) {
++_packets; //接收者才做复杂的统计运算
auto sys_stamp = getCurrentMillisecond();
auto sys_stamp = getCurrentMillisecond(); if (_last_rtp_sys_stamp) {
if (_last_rtp_sys_stamp) { //计算时间戳抖动值
//计算时间戳抖动值 double diff = double(
double diff = double(int64_t(sys_stamp) - int64_t(_last_rtp_sys_stamp) - int64_t(stamp) + int64_t(_last_rtp_stamp)); int64_t(sys_stamp) - int64_t(_last_rtp_sys_stamp) - int64_t(stamp) + int64_t(_last_rtp_stamp));
if (diff < 0) { if (diff < 0) {
diff = -diff; diff = -diff;
}
//抖动单位为采样次数
diff *= (_sample_rate / 1000.0);
_jitter += (diff - _jitter) / 16.0;
} else {
_jitter = 0;
} }
//抖动单位为采样次数
diff *= (_sample_rate / 1000.0); if (_last_rtp_seq > 0xFF00 && seq < 0xFF && (!_seq_cycles || _packets - _last_cycle_packets > 0x1FFF)) {
_jitter += (diff - _jitter) / 16.0; //上次seq大于0xFF00且本次seq小于0xFF
} else { //且未发生回环或者距离上次回环间隔超过0x1FFF个包则认为回环
_jitter = 0; ++_seq_cycles;
} _last_cycle_packets = _packets;
_seq_max = seq;
if (_last_rtp_seq > 0xFF00 && seq < 0xFF && (!_seq_cycles || _packets - _last_cycle_packets > 0x1FFF)) { } else if (seq > _seq_max) {
//上次seq大于0xFF00且本次seq小于0xFF //本次回环前最大seq
//且未发生回环或者距离上次回环间隔超过0x1FFF个包则认为回环 _seq_max = seq;
++_seq_cycles; }
_last_cycle_packets = _packets;
_seq_max = seq; if (!_seq_base) {
} else if (seq > _seq_max) { //记录第一个rtp的seq
//本次回环前最大seq _seq_base = seq;
_seq_max = seq; } else if (!_seq_cycles && seq < _seq_base) {
} //未发生回环那么取最新的seq为基准seq
_seq_base = seq;
if (!_seq_base) { }
//记录第一个rtp的seq
_seq_base = seq; _last_rtp_seq = seq;
} else if (!_seq_cycles && seq < _seq_base) { _last_rtp_sys_stamp = sys_stamp;
//未发生回环那么取最新的seq为基准seq
_seq_base = seq;
} }
++_packets;
_bytes += bytes;
_last_rtp_stamp = stamp; _last_rtp_stamp = stamp;
_last_rtp_sys_stamp = sys_stamp;
_last_rtp_seq = seq;
} }
void RtcpContext::onRtcp(RtcpHeader *rtcp){ void RtcpContext::onRtcp(RtcpHeader *rtcp) {
if ((RtcpType) rtcp->pt != RtcpType::RTCP_SR) { if ((RtcpType) rtcp->pt != RtcpType::RTCP_SR) {
return; return;
} }
auto rtcp_sr = (RtcpSR *)(rtcp); if (!_is_receiver) {
WarnL << "rtp发送者收到sr包";
return;
}
auto rtcp_sr = (RtcpSR *) (rtcp);
/** /**
last SR timestamp (LSR): 32 bits last SR timestamp (LSR): 32 bits
The middle 32 bits out of 64 in the NTP timestamp (as explained in The middle 32 bits out of 64 in the NTP timestamp (as explained in
@ -79,29 +89,38 @@ void RtcpContext::onRtcp(RtcpHeader *rtcp){
_last_sr_ntp_sys = getCurrentMillisecond(); _last_sr_ntp_sys = getCurrentMillisecond();
} }
size_t RtcpContext::getExpectedPackets() const{ size_t RtcpContext::getExpectedPackets() const {
if (!_is_receiver) {
throw std::runtime_error("rtp发送者无法统计应收包数");
}
return (_seq_cycles << 16) + _seq_max - _seq_base + 1; return (_seq_cycles << 16) + _seq_max - _seq_base + 1;
} }
size_t RtcpContext::getExpectedPacketsInterval(){ size_t RtcpContext::getExpectedPacketsInterval() {
auto expected = getExpectedPackets(); auto expected = getExpectedPackets();
auto ret = expected - _last_expected; auto ret = expected - _last_expected;
_last_expected = expected; _last_expected = expected;
return ret; return ret;
} }
size_t RtcpContext::getLost(){ size_t RtcpContext::getLost() {
if (!_is_receiver) {
throw std::runtime_error("rtp发送者无法统计丢包率");
}
return getExpectedPackets() - _packets; return getExpectedPackets() - _packets;
} }
size_t RtcpContext::geLostInterval(){ size_t RtcpContext::geLostInterval() {
auto lost = getLost(); auto lost = getLost();
auto ret = lost - _last_lost; auto ret = lost - _last_lost;
_last_lost = lost; _last_lost = lost;
return ret; return ret;
} }
Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc){ Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) {
if (_is_receiver) {
throw std::runtime_error("rtp接收者尝试发送sr包");
}
auto rtcp = RtcpSR::create(0); auto rtcp = RtcpSR::create(0);
rtcp->ssrc = htonl(rtcp_ssrc); rtcp->ssrc = htonl(rtcp_ssrc);
@ -111,12 +130,15 @@ Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc){
//转换成rtp时间戳 //转换成rtp时间戳
rtcp->rtpts = htonl(uint32_t(_last_rtp_stamp * (_sample_rate / 1000.0))); rtcp->rtpts = htonl(uint32_t(_last_rtp_stamp * (_sample_rate / 1000.0)));
rtcp->packet_count = htonl((uint32_t)_packets); rtcp->packet_count = htonl((uint32_t) _packets);
rtcp->octet_count = htonl((uint32_t)_bytes); rtcp->octet_count = htonl((uint32_t) _bytes);
return RtcpHeader::toBuffer(std::move(rtcp)); return RtcpHeader::toBuffer(std::move(rtcp));
} }
Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc){ Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) {
if (!_is_receiver) {
throw std::runtime_error("rtp发送者尝试发送rr包");
}
auto rtcp = RtcpRR::create(1); auto rtcp = RtcpRR::create(1);
rtcp->ssrc = htonl(rtcp_ssrc); rtcp->ssrc = htonl(rtcp_ssrc);
@ -139,7 +161,7 @@ Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc){
// now - Last SR time,单位毫秒 // now - Last SR time,单位毫秒
auto delay = getCurrentMillisecond() - _last_sr_ntp_sys; auto delay = getCurrentMillisecond() - _last_sr_ntp_sys;
// in units of 1/65536 seconds // in units of 1/65536 seconds
auto dlsr = (uint32_t)(delay / 1000.0f * 65536); auto dlsr = (uint32_t) (delay / 1000.0f * 65536);
item->delay_since_last_sr = htonl(_last_sr_lsr ? dlsr : 0); item->delay_since_last_sr = htonl(_last_sr_lsr ? dlsr : 0);
return RtcpHeader::toBuffer(rtcp); return RtcpHeader::toBuffer(rtcp);
} }

View File

@ -23,8 +23,9 @@ public:
/** /**
* rtcp上下文 * rtcp上下文
* @param sample_rate 90000 * @param sample_rate 90000
* @param is_receiver rtp接收者
*/ */
RtcpContext(uint32_t sample_rate); RtcpContext(uint32_t sample_rate, bool is_receiver);
/** /**
* rtp时调用 * rtp时调用
@ -82,6 +83,8 @@ private:
size_t geLostInterval(); size_t geLostInterval();
private: private:
//是否为接收者
bool _is_receiver;
//时间戳抖动值 //时间戳抖动值
double _jitter = 0; double _jitter = 0;
//视频默认90000,音频为采样率 //视频默认90000,音频为采样率

View File

@ -204,7 +204,7 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
throw std::runtime_error("onCheckSDP faied"); throw std::runtime_error("onCheckSDP faied");
} }
for (auto &track : _sdp_track) { for (auto &track : _sdp_track) {
_rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate)); _rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate, true));
} }
sendSetup(0); sendSetup(0);
} }

View File

@ -177,7 +177,7 @@ void RtspPusher::sendAnnounce() {
throw std::runtime_error("无有效的Sdp Track"); throw std::runtime_error("无有效的Sdp Track");
} }
for (auto &track : _track_vec) { for (auto &track : _track_vec) {
_rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate)); _rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate, false));
} }
_on_res_func = std::bind(&RtspPusher::handleResAnnounce, this, placeholders::_1); _on_res_func = std::bind(&RtspPusher::handleResAnnounce, this, placeholders::_1);
sendRtspRequest("ANNOUNCE", _url, {}, src->getSdp()); sendRtspRequest("ANNOUNCE", _url, {}, src->getSdp());

View File

@ -235,8 +235,9 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err); sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err);
throw SockException(Err_shutdown,StrPrinter << err << ":" << full_url); throw SockException(Err_shutdown,StrPrinter << err << ":" << full_url);
} }
_rtcp_context.clear();
for (auto &track : _sdp_track) { for (auto &track : _sdp_track) {
_rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate)); _rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate, true));
} }
_push_src = std::make_shared<RtspMediaSourceImp>(_media_info._vhost, _media_info._app, _media_info._streamid); _push_src = std::make_shared<RtspMediaSourceImp>(_media_info._vhost, _media_info._app, _media_info._streamid);
_push_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this())); _push_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
@ -406,7 +407,7 @@ void RtspSession::onAuthSuccess() {
return; return;
} }
for (auto &track : strongSelf->_sdp_track) { for (auto &track : strongSelf->_sdp_track) {
strongSelf->_rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate)); strongSelf->_rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate, false));
} }
strongSelf->_sessionid = makeRandStr(12); strongSelf->_sessionid = makeRandStr(12);
strongSelf->_play_src = rtsp_src; strongSelf->_play_src = rtsp_src;