diff --git a/src/Rtcp/RtcpContext.cpp b/src/Rtcp/RtcpContext.cpp index 7ced4f4c..d2afbc95 100644 --- a/src/Rtcp/RtcpContext.cpp +++ b/src/Rtcp/RtcpContext.cpp @@ -14,12 +14,16 @@ using namespace toolkit; namespace mediakit { -RtcpContext::RtcpContext(bool is_receiver) { - _is_receiver = is_receiver; -} void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) { - if (_is_receiver) { + ++_packets; + _bytes += bytes; + _last_rtp_stamp = stamp; + _last_ntp_stamp_ms = ntp_stamp_ms; +} + +void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) { + { //接收者才做复杂的统计运算 auto sys_stamp = getCurrentMillisecond(); if (_last_rtp_sys_stamp) { @@ -57,11 +61,7 @@ void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uin _last_rtp_seq = seq; _last_rtp_sys_stamp = sys_stamp; } - - ++_packets; - _bytes += bytes; - _last_rtp_stamp = stamp; - _last_ntp_stamp_ms = ntp_stamp_ms; + RtcpContext::onRtp(seq, stamp, ntp_stamp_ms, sample_rate, bytes); } void RtcpContext::onRtcp(RtcpHeader *rtcp) { @@ -115,9 +115,9 @@ uint32_t RtcpContext::getRtt(uint32_t ssrc) const { } size_t RtcpContext::getExpectedPackets() const { - if (!_is_receiver) { - throw std::runtime_error("rtp发送者无法统计应收包数"); - } + throw std::runtime_error("没有实现, rtp发送者无法统计应收包数"); +} +size_t RtcpContextForRecv::getExpectedPackets() const { return (_seq_cycles << 16) + _seq_max - _seq_base + 1; } @@ -129,9 +129,10 @@ size_t RtcpContext::getExpectedPacketsInterval() { } size_t RtcpContext::getLost() { - if (!_is_receiver) { - throw std::runtime_error("rtp发送者无法统计丢包率"); - } + throw std::runtime_error("没有实现, rtp发送者无法统计丢包率"); +} + +size_t RtcpContextForRecv::getLost() { return getExpectedPackets() - _packets; } @@ -143,9 +144,10 @@ size_t RtcpContext::geLostInterval() { } Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) { - if (_is_receiver) { - throw std::runtime_error("rtp接收者尝试发送sr包"); - } + 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); @@ -165,9 +167,11 @@ Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) { } Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) { - if (!_is_receiver) { - throw std::runtime_error("rtp发送者尝试发送rr包"); - } + 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 b51c04fa..d4e30d7b 100644 --- a/src/Rtcp/RtcpContext.h +++ b/src/Rtcp/RtcpContext.h @@ -20,11 +20,7 @@ namespace mediakit { class RtcpContext { public: using Ptr = std::shared_ptr; - /** - * 创建rtcp上下文 - * @param is_receiver 是否为rtp接收者,接收者更消耗性能 - */ - RtcpContext(bool is_receiver); + virtual ~RtcpContext() = default; /** * 输出或输入rtp时调用 @@ -34,7 +30,7 @@ public: * @param rtp rtp时间戳采样率,视频一般为90000,音频一般为采样率 * @param bytes rtp数据长度 */ - void onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes); + virtual void onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes); /** * 输入sr rtcp包 @@ -45,19 +41,19 @@ public: /** * 计算总丢包数 */ - size_t getLost(); + virtual size_t getLost(); /** * 返回理应收到的rtp数 */ - size_t getExpectedPackets() const; + virtual size_t getExpectedPackets() const; /** * 创建SR rtcp包 * @param rtcp_ssrc rtcp的ssrc * @return rtcp包 */ - Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc); + virtual Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc); /** * 创建RR rtcp包 @@ -65,7 +61,7 @@ public: * @param rtp_ssrc rtp的ssrc * @return rtcp包 */ - Buffer::Ptr createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc); + virtual Buffer::Ptr createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc); /** * 获取rtt @@ -84,9 +80,7 @@ public: */ size_t geLostInterval(); -private: - //是否为接收者 - bool _is_receiver; +protected: //时间戳抖动值 double _jitter = 0; //收到或发送的rtp的字节数 @@ -120,5 +114,17 @@ private: map _sender_report_ntp; }; +class RtcpContextForSend : public RtcpContext { +public: + Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc) override; +}; + +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 getLost() override; +}; }//namespace mediakit #endif //ZLMEDIAKIT_RTCPCONTEXT_H diff --git a/src/Rtp/RtpServer.cpp b/src/Rtp/RtpServer.cpp index 7947f00f..d2356a86 100644 --- a/src/Rtp/RtpServer.cpp +++ b/src/Rtp/RtpServer.cpp @@ -23,11 +23,11 @@ RtpServer::~RtpServer() { } } -class RtcpHelper : public RtcpContext, public std::enable_shared_from_this { +class RtcpHelper : public RtcpContextForRecv, public std::enable_shared_from_this { public: using Ptr = std::shared_ptr; - RtcpHelper(Socket::Ptr rtcp_sock, uint32_t sample_rate) : RtcpContext(true){ + RtcpHelper(Socket::Ptr rtcp_sock, uint32_t sample_rate) { _rtcp_sock = std::move(rtcp_sock); _sample_rate = sample_rate; } diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index ceb74061..93c6f93b 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -206,7 +206,7 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) { } _rtcp_context.clear(); for (auto &track : _sdp_track) { - _rtcp_context.emplace_back(std::make_shared(true)); + _rtcp_context.emplace_back(std::make_shared()); } sendSetup(0); } diff --git a/src/Rtsp/RtspPusher.cpp b/src/Rtsp/RtspPusher.cpp index c7fee8e1..402efb8b 100644 --- a/src/Rtsp/RtspPusher.cpp +++ b/src/Rtsp/RtspPusher.cpp @@ -179,7 +179,7 @@ void RtspPusher::sendAnnounce() { } _rtcp_context.clear(); for (auto &track : _track_vec) { - _rtcp_context.emplace_back(std::make_shared(false)); + _rtcp_context.emplace_back(std::make_shared()); } _on_res_func = std::bind(&RtspPusher::handleResAnnounce, this, placeholders::_1); sendRtspRequest("ANNOUNCE", _url, {}, src->getSdp()); diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index a6b502f0..edb9a104 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -257,7 +257,7 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { } _rtcp_context.clear(); for (auto &track : _sdp_track) { - _rtcp_context.emplace_back(std::make_shared(true)); + _rtcp_context.emplace_back(std::make_shared()); } _push_src = std::make_shared(_media_info._vhost, _media_info._app, _media_info._streamid); _push_src->setListener(dynamic_pointer_cast(shared_from_this())); @@ -418,7 +418,7 @@ void RtspSession::onAuthSuccess() { } strongSelf->_rtcp_context.clear(); for (auto &track : strongSelf->_sdp_track) { - strongSelf->_rtcp_context.emplace_back(std::make_shared(false)); + strongSelf->_rtcp_context.emplace_back(std::make_shared()); } strongSelf->_sessionid = makeRandStr(12); strongSelf->_play_src = rtsp_src; diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 6e0f5b99..5aab8e10 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -420,7 +420,7 @@ void WebRtcTransportImp::onStartWebRTC() { track->offer_ssrc_rtx = m_offer->getRtxSSRC(); track->plan_rtp = &m_answer.plan[0];; track->plan_rtx = m_answer.getRelatedRtxPlan(track->plan_rtp->pt); - track->rtcp_context_send = std::make_shared(false); + track->rtcp_context_send = std::make_shared(); //send ssrc --> MediaTrack _ssrc_to_track[track->answer_ssrc_rtp] = track; @@ -656,7 +656,7 @@ private: private: NackContext _nack_ctx; - RtcpContext _rtcp_context{true}; + RtcpContextForRecv _rtcp_context; EventPoller::Ptr _poller; DelayTask::Ptr _delay_task; function _on_nack;