From 0d61de758e5620a1e4a5cc89e20ec1814f9176a0 Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Tue, 11 May 2021 12:12:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84nack=E4=B8=8E=E4=B8=A2?= =?UTF-8?q?=E5=8C=85=E9=87=8D=E4=BC=A02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webrtc/WebRtcTransport.cpp | 31 +++++++++++++++++++++++++------ webrtc/WebRtcTransport.h | 16 +++++++++++++--- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 1cd574c8..0b1f4372 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -429,6 +429,9 @@ void WebRtcTransportImp::onStartWebRTC() { }, [&ref, this](const RtpPacket::Ptr &rtp) mutable { onBeforeSortedRtp(ref, rtp); }); + ref.nack_ctx.setOnNack([&ref, this](const FCI_NACK &nack) mutable{ + onNack(ref, nack); + }); } if (m.type != TrackApplication) { //记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id @@ -676,14 +679,21 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) { auto &info = it->second; #if 1 - //此处模拟接受丢包 auto header = (RtpHeader *) buf; auto seq = ntohs(header->seq); - if (seq % 10 == 0) { - //丢包 - return; + if (info.is_common_rtp) { + //此处模拟接受丢包 + if (info.media->type == TrackVideo && seq % 10 == 0) { + //丢包 + DebugL << "模拟接受丢包:" << seq; + return; + } else { + info.nack_ctx.received(seq); + } } else { - info.nack_ctx.received(seq); + //收到重传包 + header->ssrc = info.media->rtp_rtx_ssrc[0].ssrc; + InfoL << "收到重传包:" << seq; } #endif @@ -691,6 +701,14 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) { info.receiver->inputRtp(info.media->type, info.plan->sample_rate, (uint8_t *) buf, len); } +void WebRtcTransportImp::onNack(RtpPayloadInfo &info, const FCI_NACK &nack) { + auto rtcp = RtcpFB::create(RTPFBType::RTCP_RTPFB_NACK, &nack, FCI_NACK::kSize); + rtcp->ssrc = htons(0); + rtcp->ssrc_media = htonl(info.media->rtp_rtx_ssrc[0].ssrc); + InfoL << rtcp->RtcpHeader::dumpString(); + sendRtcpPacket((char *) rtcp.get(), rtcp->getSize(), true); +} + /////////////////////////////////////////////////////////////////// void WebRtcTransportImp::onSortedRtp(RtpPayloadInfo &info, RtpPacket::Ptr rtp) { @@ -756,11 +774,12 @@ void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool r #if 0 //此处模拟发送丢包 if(rtp->getSeq() % 10 == 0){ + DebugL << "模拟发送丢包:" << rtp->getSeq(); return; } #endif } else { - WarnL << "重传rtp:" << rtp->getSeq(); + WarnL << "rtp发送重传:" << rtp->getSeq(); } sendRtpPacket(rtp->data() + RtpPacket::kRtpTcpHeaderSize, rtp->size() - RtpPacket::kRtpTcpHeaderSize, flush, info); _bytes_usage += rtp->size() - RtpPacket::kRtpTcpHeaderSize; diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index caeb80a6..beebd16c 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -192,6 +192,8 @@ private: class NackContext { public: + using onNack = function; + void received(uint16_t seq) { if (!_last_max_seq && _seq.empty()) { _last_max_seq = seq - 1; @@ -229,7 +231,7 @@ public: for (auto i = 0; i < FCI_NACK::kBitSize; ++i) { vec[i] = _seq.find(_last_max_seq + i + 2) == _seq.end(); } - onNack(FCI_NACK(_last_max_seq + 1, vec)); + doNack(FCI_NACK(_last_max_seq + 1, vec)); _last_max_seq += FCI_NACK::kBitSize + 1; if (_last_max_seq >= max_seq) { _seq.clear(); @@ -241,11 +243,17 @@ public: } } - void onNack(const FCI_NACK &nack) { - InfoL << nack.dumpString() << " " << _seq.size(); + void setOnNack(onNack cb) { + _cb = std::move(cb); } private: + void doNack(const FCI_NACK &nack) { + if (_cb) { + _cb(nack); + } + } + void eraseFrontSeq(){ //前面部分seq是连续的,未丢包,移除之 for (auto it = _seq.begin(); it != _seq.end();) { @@ -259,6 +267,7 @@ private: } private: + onNack _cb; set _seq; uint16_t _last_max_seq = 0; }; @@ -343,6 +352,7 @@ private: void onSortedRtp(RtpPayloadInfo &info, RtpPacket::Ptr rtp); void onBeforeSortedRtp(RtpPayloadInfo &info, const RtpPacket::Ptr &rtp); + void onNack(RtpPayloadInfo &info, const FCI_NACK &nack); private: //用掉的总流量