From 964cf391454ff188142d66fb49d0b75f8e01a68c Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Fri, 25 Jun 2021 14:59:27 +0800 Subject: [PATCH] =?UTF-8?q?RtcpContext=E4=BF=AE=E6=94=B9=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=88=B3=E5=8D=95=E4=BD=8D=E3=80=81=E6=95=B4=E7=90=86WebRTC?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtcp/RtcpContext.cpp | 6 ++-- src/Rtcp/RtcpContext.h | 7 ++--- src/Rtp/RtpServer.cpp | 4 +-- src/Rtsp/RtspPlayer.cpp | 4 +-- src/Rtsp/RtspPusher.cpp | 4 +-- src/Rtsp/RtspSession.cpp | 6 ++-- webrtc/WebRtcTransport.cpp | 64 ++++++++++++++++++++------------------ webrtc/WebRtcTransport.h | 6 ++-- 8 files changed, 49 insertions(+), 52 deletions(-) diff --git a/src/Rtcp/RtcpContext.cpp b/src/Rtcp/RtcpContext.cpp index 9b4e31cc..384b15b2 100644 --- a/src/Rtcp/RtcpContext.cpp +++ b/src/Rtcp/RtcpContext.cpp @@ -18,8 +18,7 @@ void RtcpContext::clear() { memset(this, 0, sizeof(RtcpContext)); } -RtcpContext::RtcpContext(uint32_t sample_rate, bool is_receiver) { - _sample_rate = sample_rate; +RtcpContext::RtcpContext(bool is_receiver) { _is_receiver = is_receiver; } @@ -35,7 +34,6 @@ void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, size_t bytes) { diff = -diff; } //抖动单位为采样次数 - diff *= (_sample_rate / 1000.0); _jitter += (diff - _jitter) / 16.0; } else { _jitter = 0; @@ -129,7 +127,7 @@ Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) { rtcp->setNtpStamp(tv); //转换成rtp时间戳 - rtcp->rtpts = htonl(uint32_t(_last_rtp_stamp * (_sample_rate / 1000.0))); + rtcp->rtpts = htonl(_last_rtp_stamp); rtcp->packet_count = htonl((uint32_t) _packets); rtcp->octet_count = htonl((uint32_t) _bytes); return RtcpHeader::toBuffer(std::move(rtcp)); diff --git a/src/Rtcp/RtcpContext.h b/src/Rtcp/RtcpContext.h index 85be0c29..d9f705ef 100644 --- a/src/Rtcp/RtcpContext.h +++ b/src/Rtcp/RtcpContext.h @@ -22,15 +22,14 @@ public: using Ptr = std::shared_ptr; /** * 创建rtcp上下文 - * @param sample_rate 音频采用率,视频一般为90000 * @param is_receiver 是否为rtp接收者,接收者更消耗性能 */ - RtcpContext(uint32_t sample_rate, bool is_receiver); + RtcpContext(bool is_receiver); /** * 输出或输入rtp时调用 * @param seq rtp的seq - * @param stamp rtp的时间戳,单位毫秒 + * @param stamp rtp的时间戳,单位采样数(非毫秒) * @param bytes rtp数据长度 */ void onRtp(uint16_t seq, uint32_t stamp, size_t bytes); @@ -87,8 +86,6 @@ private: bool _is_receiver; //时间戳抖动值 double _jitter = 0; - //视频默认90000,音频为采样率 - uint32_t _sample_rate; //收到或发送的rtp的字节数 size_t _bytes = 0; //收到或发送的rtp的个数 diff --git a/src/Rtp/RtpServer.cpp b/src/Rtp/RtpServer.cpp index 6462abac..6827138f 100644 --- a/src/Rtp/RtpServer.cpp +++ b/src/Rtp/RtpServer.cpp @@ -27,7 +27,7 @@ class RtcpHelper : public RtcpContext, public std::enable_shared_from_this; - RtcpHelper(Socket::Ptr rtcp_sock, uint32_t sample_rate) : RtcpContext(sample_rate, true){ + RtcpHelper(Socket::Ptr rtcp_sock, uint32_t sample_rate) : RtcpContext(true){ _rtcp_sock = std::move(rtcp_sock); _sample_rate = sample_rate; } @@ -35,7 +35,7 @@ public: void onRecvRtp(const Buffer::Ptr &buf, struct sockaddr *addr, int addr_len){ //统计rtp接受情况,用于发送rr包 auto header = (RtpHeader *) buf->data(); - onRtp(ntohs(header->seq), ntohl(header->stamp) * uint64_t(1000) / _sample_rate, buf->size()); + onRtp(ntohs(header->seq), ntohl(header->stamp), buf->size()); sendRtcp(ntohl(header->ssrc), addr, addr_len); } diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index f3b7004f..45d0f445 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -205,7 +205,7 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) { } _rtcp_context.clear(); for (auto &track : _sdp_track) { - _rtcp_context.emplace_back(std::make_shared(track->_samplerate, true)); + _rtcp_context.emplace_back(std::make_shared(true)); } sendSetup(0); } @@ -591,7 +591,7 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC void RtspPlayer::onBeforeRtpSorted(const RtpPacket::Ptr &rtp, int track_idx){ auto &rtcp_ctx = _rtcp_context[track_idx]; - rtcp_ctx->onRtp(rtp->getSeq(), rtp->getStampMS(), rtp->size() - RtpPacket::kRtpTcpHeaderSize); + rtcp_ctx->onRtp(rtp->getSeq(), ntohl(rtp->getHeader()->stamp), rtp->size() - RtpPacket::kRtpTcpHeaderSize); auto &ticker = _rtcp_send_ticker[track_idx]; if (ticker.elapsedTime() < 3 * 1000) { diff --git a/src/Rtsp/RtspPusher.cpp b/src/Rtsp/RtspPusher.cpp index c19b0ce7..2d0a8abe 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(track->_samplerate, false)); + _rtcp_context.emplace_back(std::make_shared(false)); } _on_res_func = std::bind(&RtspPusher::handleResAnnounce, this, placeholders::_1); sendRtspRequest("ANNOUNCE", _url, {}, src->getSdp()); @@ -360,7 +360,7 @@ void RtspPusher::updateRtcpContext(const RtpPacket::Ptr &rtp){ int track_index = getTrackIndexByTrackType(rtp->type); auto &ticker = _rtcp_send_ticker[track_index]; auto &rtcp_ctx = _rtcp_context[track_index]; - rtcp_ctx->onRtp(rtp->getSeq(), rtp->getStampMS(), rtp->size() - RtpPacket::kRtpTcpHeaderSize); + rtcp_ctx->onRtp(rtp->getSeq(), ntohl(rtp->getHeader()->stamp), rtp->size() - RtpPacket::kRtpTcpHeaderSize); //send rtcp every 5 second if (ticker.elapsedTime() > 5 * 1000) { diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 1e12adee..e86eb399 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -252,7 +252,7 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { } _rtcp_context.clear(); for (auto &track : _sdp_track) { - _rtcp_context.emplace_back(std::make_shared(track->_samplerate, true)); + _rtcp_context.emplace_back(std::make_shared(true)); } _push_src = std::make_shared(_media_info._vhost, _media_info._app, _media_info._streamid); _push_src->setListener(dynamic_pointer_cast(shared_from_this())); @@ -413,7 +413,7 @@ void RtspSession::onAuthSuccess() { } strongSelf->_rtcp_context.clear(); for (auto &track : strongSelf->_sdp_track) { - strongSelf->_rtcp_context.emplace_back(std::make_shared(track->_samplerate, false)); + strongSelf->_rtcp_context.emplace_back(std::make_shared(false)); } strongSelf->_sessionid = makeRandStr(12); strongSelf->_play_src = rtsp_src; @@ -1126,7 +1126,7 @@ void RtspSession::onBeforeRtpSorted(const RtpPacket::Ptr &rtp, int track_index){ void RtspSession::updateRtcpContext(const RtpPacket::Ptr &rtp){ int track_index = getTrackIndexByTrackType(rtp->type); auto &rtcp_ctx = _rtcp_context[track_index]; - rtcp_ctx->onRtp(rtp->getSeq(), rtp->getStampMS(), rtp->size() - RtpPacket::kRtpTcpHeaderSize); + rtcp_ctx->onRtp(rtp->getSeq(), ntohl(rtp->getHeader()->stamp), rtp->size() - RtpPacket::kRtpTcpHeaderSize); auto &ticker = _rtcp_send_tickers[track_index]; //send rtcp every 5 second diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index b5891ab2..2a1b14f3 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -408,19 +408,19 @@ void WebRtcTransportImp::onStartWebRTC() { info->offer_ssrc_rtx = m_offer->getRtxSSRC(); info->plan_rtp = &m_answer.plan[0];; info->plan_rtx = m_answer.getRelatedRtxPlan(info->plan_rtp->pt); - info->rtcp_context_send = std::make_shared(info->plan_rtp->sample_rate, false); + info->rtcp_context_send = std::make_shared(false); //send ssrc --> MediaTrack - _rtp_info_ssrc[info->answer_ssrc_rtp] = info; + _ssrc_to_track[info->answer_ssrc_rtp] = info; //recv ssrc --> MediaTrack - _rtp_info_ssrc[info->offer_ssrc_rtp] = info; + _ssrc_to_track[info->offer_ssrc_rtp] = info; //rtp pt --> MediaTrack - _rtp_info_pt.emplace(info->plan_rtp->pt, std::make_pair(false, info)); + _pt_to_track.emplace(info->plan_rtp->pt, std::make_pair(false, info)); if (info->plan_rtx) { //rtx pt --> MediaTrack - _rtp_info_pt.emplace(info->plan_rtx->pt, std::make_pair(true, info)); + _pt_to_track.emplace(info->plan_rtx->pt, std::make_pair(true, info)); } if (m_offer->type != TrackApplication) { //记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id @@ -464,10 +464,10 @@ void WebRtcTransportImp::onStartWebRTC() { } auto rtsp_media = rtsp_send_sdp.getMedia(m.type); if (rtsp_media && getCodecId(rtsp_media->plan[0].codec) == getCodecId(m.plan[0].codec)) { - auto it = _rtp_info_pt.find(m.plan[0].pt); - CHECK(it != _rtp_info_pt.end()); + auto it = _pt_to_track.find(m.plan[0].pt); + CHECK(it != _pt_to_track.end()); //记录发送rtp时约定的信息,届时发送rtp时需要修改pt和ssrc - _send_rtp_info[m.type] = it->second.second; + _type_to_track[m.type] = it->second.second; } } } @@ -558,8 +558,7 @@ SdpAttrCandidate::Ptr WebRtcTransportImp::getIceCandidate() const{ class RtpChannel : public RtpReceiver { public: - uint32_t ssrc; - RtcpContext::Ptr rtcp_context; + uint32_t rtp_ssrc; public: RtpChannel(function on_rtp, function on_nack) { @@ -576,11 +575,16 @@ public: //统计rtp接受情况,便于生成nack rtcp包 nack_ctx.received(seq); //统计rtp收到的情况,好做rr汇报 - rtcp_context->onRtp(seq, ntohl(rtp->stamp) * uint64_t(1000) / sample_rate, len); + rtcp_context.onRtp(seq, ntohl(rtp->stamp), len); } return handleOneRtp((int) type, type, sample_rate, ptr, len); } + Buffer::Ptr createRtcpRR(RtcpHeader *sr, uint32_t ssrc) { + rtcp_context.onRtcp(sr); + return rtcp_context.createRtcpRR(ssrc, rtp_ssrc); + } + protected: void onRtpSorted(RtpPacket::Ptr rtp, int track_index) override { _on_sort(std::move(rtp)); @@ -588,6 +592,7 @@ protected: private: NackContext nack_ctx; + RtcpContext rtcp_context{true}; function _on_sort; }; @@ -611,15 +616,14 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { case RtcpType::RTCP_SR : { //对方汇报rtp发送情况 RtcpSR *sr = (RtcpSR *) rtcp; - auto it = _rtp_info_ssrc.find(sr->ssrc); - if (it != _rtp_info_ssrc.end()) { + auto it = _ssrc_to_track.find(sr->ssrc); + if (it != _ssrc_to_track.end()) { auto &info = it->second; auto rtp_chn = info->getRtpChannel(sr->ssrc); if(!rtp_chn){ WarnL << "未识别的sr rtcp包:" << rtcp->dumpString(); } else { - rtp_chn->rtcp_context->onRtcp(sr); - auto rr = rtp_chn->rtcp_context->createRtcpRR(info->answer_ssrc_rtp, sr->ssrc); + auto rr = rtp_chn->createRtcpRR(sr, info->answer_ssrc_rtp); sendRtcpPacket(rr->data(), rr->size(), true); } } else { @@ -632,8 +636,8 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { //对方汇报rtp接收情况 RtcpRR *rr = (RtcpRR *) rtcp; for (auto item : rr->getItemList()) { - auto it = _rtp_info_ssrc.find(item->ssrc); - if (it != _rtp_info_ssrc.end()) { + auto it = _ssrc_to_track.find(item->ssrc); + if (it != _ssrc_to_track.end()) { auto &info = it->second; auto sr = info->rtcp_context_send->createRtcpSR(info->answer_ssrc_rtp); sendRtcpPacket(sr->data(), sr->size(), true); @@ -647,12 +651,12 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { //对方汇报停止发送rtp RtcpBye *bye = (RtcpBye *) rtcp; for (auto ssrc : bye->getSSRC()) { - auto it = _rtp_info_ssrc.find(*ssrc); - if (it == _rtp_info_ssrc.end()) { + auto it = _ssrc_to_track.find(*ssrc); + if (it == _ssrc_to_track.end()) { WarnL << "未识别的bye rtcp包:" << rtcp->dumpString(); continue; } - _rtp_info_ssrc.erase(it); + _ssrc_to_track.erase(it); } onShutdown(SockException(Err_eof, "rtcp bye message received")); break; @@ -666,8 +670,8 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { switch ((RTPFBType) rtcp->report_count) { case RTPFBType::RTCP_RTPFB_NACK : { RtcpFB *fb = (RtcpFB *) rtcp; - auto it = _rtp_info_ssrc.find(fb->ssrc_media); - if (it == _rtp_info_ssrc.end()) { + auto it = _ssrc_to_track.find(fb->ssrc_media); + if (it == _ssrc_to_track.end()) { WarnL << "未识别的 rtcp包:" << rtcp->dumpString(); return; } @@ -752,11 +756,9 @@ void WebRtcTransportImp::createRtpChannel(const string &rid, uint32_t ssrc, cons onSendNack(*info, nack, ssrc); }); //rid --> rtp ssrc - ref->ssrc = ssrc; - //rtp ssrc --> RtcpContext - ref->rtcp_context = std::make_shared(info->plan_rtp->sample_rate, true); + ref->rtp_ssrc = ssrc; //rtp ssrc --> MediaTrack - _rtp_info_ssrc[ssrc] = info; + _ssrc_to_track[ssrc] = info; InfoL << "create rtp receiver of ssrc:" << ssrc << ", rid:" << rid << ", codec:" << info->plan_rtp->codec; } @@ -766,8 +768,8 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) { RtpHeader *rtp = (RtpHeader *) buf; //根据接收到的rtp的pt信息,找到该流的信息 - auto it = _rtp_info_pt.find(rtp->pt); - if (it == _rtp_info_pt.end()) { + auto it = _pt_to_track.find(rtp->pt); + if (it == _pt_to_track.end()) { WarnL << "unknown rtp pt:" << (int)rtp->pt; return; } @@ -822,7 +824,7 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) { //rtx 转换为 rtp rtp->pt = info->plan_rtp->pt; rtp->seq = htons(origin_seq); - rtp->ssrc = htonl(ref->ssrc); + rtp->ssrc = htonl(ref->rtp_ssrc); memmove((uint8_t *) buf + 2, buf, payload - (uint8_t *) buf); buf += 2; @@ -878,14 +880,14 @@ void WebRtcTransportImp::onSortedRtp(MediaTrack &info, const string &rid, RtpPac /////////////////////////////////////////////////////////////////// void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx){ - auto &info = _send_rtp_info[rtp->type]; + auto &info = _type_to_track[rtp->type]; if (!info) { //忽略,对方不支持该编码类型 return; } if (!rtx) { //统计rtp发送情况,好做sr汇报 - info->rtcp_context_send->onRtp(rtp->getSeq(), rtp->getStampMS(), rtp->size() - RtpPacket::kRtpTcpHeaderSize); + info->rtcp_context_send->onRtp(rtp->getSeq(), ntohl(rtp->getHeader()->stamp), rtp->size() - RtpPacket::kRtpTcpHeaderSize); info->nack_list.push_back(rtp); #if 0 //此处模拟发送丢包 diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index 4b24f488..87450ff3 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -384,11 +384,11 @@ private: //播放rtsp源的reader对象 RtspMediaSource::RingType::RingReader::Ptr _reader; //根据发送rtp的track类型获取相关信息 - MediaTrack::Ptr _send_rtp_info[2]; + MediaTrack::Ptr _type_to_track[2]; //根据接收rtp的pt获取相关信息 - unordered_map > _rtp_info_pt; + unordered_map > _pt_to_track; //根据rtcp的ssrc获取相关信息,只记录rtp的ssrc,rtx的ssrc不记录 - unordered_map _rtp_info_ssrc; + unordered_map _ssrc_to_track; //发送rtp时需要修改rtp ext id map _rtp_ext_type_to_id; //接收rtp时需要修改rtp ext id