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) {