From ba5ca8f5c7c6e0779bfbfb8cf60f581cc4cad05a Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sun, 27 Feb 2022 02:07:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Drtp=20seq=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E5=AF=BC=E8=87=B4rtp=20nack=E9=87=8D=E4=BC=A0=E5=88=97?= =?UTF-8?q?=E9=98=9F=E5=BC=82=E5=B8=B8=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webrtc/Nack.cpp | 44 ++++++++++++++++++++++++++------------ webrtc/Nack.h | 11 +++++----- webrtc/WebRtcTransport.cpp | 4 ++-- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/webrtc/Nack.cpp b/webrtc/Nack.cpp index 60d314b3..5ac35b2f 100644 --- a/webrtc/Nack.cpp +++ b/webrtc/Nack.cpp @@ -16,22 +16,22 @@ using namespace mediakit; static constexpr uint32_t kMaxNackMS = 10 * 1000; -void NackList::push_back(RtpPacket::Ptr rtp) { +void NackList::pushBack(RtpPacket::Ptr rtp) { auto seq = rtp->getSeq(); _nack_cache_seq.emplace_back(seq); _nack_cache_pkt.emplace(seq, std::move(rtp)); - while (get_cache_ms() > kMaxNackMS) { + while (getCacheMS() > kMaxNackMS) { //需要清除部分nack缓存 - pop_front(); + popFront(); } } -void NackList::for_each_nack(const FCI_NACK &nack, const function &func) { +void NackList::forEach(const FCI_NACK &nack, const function &func) { auto seq = nack.getPid(); for (auto bit : nack.getBitArray()) { if (bit) { //丢包 - RtpPacket::Ptr *ptr = get_rtp(seq); + RtpPacket::Ptr *ptr = getRtp(seq); if (ptr) { func(*ptr); } @@ -40,7 +40,7 @@ void NackList::for_each_nack(const FCI_NACK &nack, const functionsecond; } -uint32_t NackList::get_cache_ms() { - if (_nack_cache_seq.size() < 2) { +uint32_t NackList::getCacheMS() { + auto back_stamp = getRtpStamp(_nack_cache_seq.back()); + if (back_stamp == -1) { + _nack_cache_seq.pop_back(); return 0; } - uint32_t back = _nack_cache_pkt[_nack_cache_seq.back()]->getStampMS(false); - uint32_t front = _nack_cache_pkt[_nack_cache_seq.front()]->getStampMS(false); - if (back >= front) { - return back - front; + + auto front_stamp = getRtpStamp(_nack_cache_seq.front()); + if (front_stamp == -1) { + _nack_cache_seq.pop_front(); + return 0; + } + + if (back_stamp >= front_stamp) { + return back_stamp - front_stamp; } //很有可能回环了 - return back + (UINT32_MAX - front); + return back_stamp + (UINT32_MAX - front_stamp); } +int64_t NackList::getRtpStamp(uint16_t seq) { + auto it = _nack_cache_pkt.find(seq); + if (it == _nack_cache_pkt.end()) { + return -1; + } + return it->second->getStampMS(false); +} + + //////////////////////////////////////////////////////////////////////////////////////////////// void NackContext::received(uint16_t seq, bool is_rtx) { diff --git a/webrtc/Nack.h b/webrtc/Nack.h index bc82eb88..7f51bdba 100644 --- a/webrtc/Nack.h +++ b/webrtc/Nack.h @@ -20,13 +20,14 @@ public: NackList() = default; ~NackList() = default; - void push_back(mediakit::RtpPacket::Ptr rtp); - void for_each_nack(const mediakit::FCI_NACK &nack, const std::function &cb); + void pushBack(mediakit::RtpPacket::Ptr rtp); + void forEach(const mediakit::FCI_NACK &nack, const std::function &cb); private: - void pop_front(); - uint32_t get_cache_ms(); - mediakit::RtpPacket::Ptr *get_rtp(uint16_t seq); + void popFront(); + uint32_t getCacheMS(); + int64_t getRtpStamp(uint16_t seq); + mediakit::RtpPacket::Ptr *getRtp(uint16_t seq); private: std::deque _nack_cache_seq; diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index ac81bcf7..c5e03ffd 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -652,7 +652,7 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { } auto &track = it->second; auto &fci = fb->getFci(); - track->nack_list.for_each_nack(fci, [&](const RtpPacket::Ptr &rtp) { + track->nack_list.forEach(fci, [&](const RtpPacket::Ptr &rtp) { //rtp重传 onSendRtp(rtp, true, true); }); @@ -807,7 +807,7 @@ void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool r if (!rtx) { //统计rtp发送情况,好做sr汇报 track->rtcp_context_send->onRtp(rtp->getSeq(), rtp->getStamp(), rtp->ntp_stamp, rtp->sample_rate, rtp->size() - RtpPacket::kRtpTcpHeaderSize); - track->nack_list.push_back(rtp); + track->nack_list.pushBack(rtp); #if 0 //此处模拟发送丢包 if (rtp->type == TrackVideo && rtp->getSeq() % 100 == 0) {