diff --git a/webrtc/Nack.cpp b/webrtc/Nack.cpp index f3e6fa77..f30339e9 100644 --- a/webrtc/Nack.cpp +++ b/webrtc/Nack.cpp @@ -19,14 +19,31 @@ namespace mediakit { // RTC配置项目 namespace Rtc { #define RTC_FIELD "rtc." +//~ 发送端 // Nack缓存包最早时间间隔 const string kMaxNackMS = RTC_FIELD "maxNackMS"; // Nack包检查间隔(包数量) const string kRtpCacheCheckInterval = RTC_FIELD "rtpCacheCheckInterval"; +//~ 接收端 +//最大保留的rtp丢包状态个数 +const string kNackMaxSize = RTC_FIELD "nackMaxSize"; +// rtp丢包状态最长保留时间 +const string kNackMaxMS = RTC_FIELD "nackMaxMS"; +// nack最多请求重传10次 +const string kNackMaxCount = RTC_FIELD "nackMaxCount"; +// nack重传频率,rtt的倍数 +const string kNackIntervalRatio = RTC_FIELD "nackIntervalRatio"; +// nack包中rtp个数,减小此值可以让nack包响应更灵敏 +const string kNackRtpSize = RTC_FIELD "nackRtpSize"; static onceToken token([]() { mINI::Instance()[kMaxNackMS] = 5 * 1000; mINI::Instance()[kRtpCacheCheckInterval] = 100; + mINI::Instance()[kNackMaxSize] = 2048; + mINI::Instance()[kNackMaxMS] = 3 * 1000; + mINI::Instance()[kNackMaxCount] = 15; + mINI::Instance()[kNackIntervalRatio] = 1.0f; + mINI::Instance()[kNackRtpSize] = 8; }); } // namespace Rtc @@ -163,10 +180,13 @@ void NackContext::makeNack(uint16_t max_seq, bool flush) { eraseFrontSeq(); // 最多生成5个nack包,防止seq大幅跳跃导致一直循环 auto max_nack = 5u; + GET_CONFIG(uint32_t, nack_rtpsize, Rtc::kNackRtpSize); + // kNackRtpSize must between 0 and 16 + nack_rtpsize = std::min(nack_rtpsize, FCI_NACK::kBitSize); while (_nack_seq != max_seq && max_nack--) { // 一次不能发送超过16+1个rtp的状态 uint16_t nack_rtp_count = std::min(FCI_NACK::kBitSize, max_seq - (uint16_t)(_nack_seq + 1)); - if (!flush && nack_rtp_count < kNackRtpSize) { + if (!flush && nack_rtp_count < nack_rtpsize) { // 非flush状态下,seq个数不足以发送一次nack break; } @@ -221,7 +241,9 @@ void NackContext::clearNackStatus(uint16_t seq) { _nack_send_status.erase(it); // 限定rtt在合理有效范围内 - _rtt = max(10, min(rtt, kNackMaxMS / kNackMaxCount)); + GET_CONFIG(uint32_t, nack_maxms, Rtc::kNackMaxMS); + GET_CONFIG(uint32_t, nack_maxcount, Rtc::kNackMaxCount); + _rtt = max(10, min(rtt, nack_maxms / nack_maxcount)); } void NackContext::recordNack(const FCI_NACK &nack) { @@ -237,7 +259,8 @@ void NackContext::recordNack(const FCI_NACK &nack) { ++i; } // 记录太多了,移除一部分早期的记录 - while (_nack_send_status.size() > kNackMaxSize) { + GET_CONFIG(uint32_t, nack_maxsize, Rtc::kNackMaxSize); + while (_nack_send_status.size() > nack_maxsize) { _nack_send_status.erase(_nack_send_status.begin()); } } @@ -245,13 +268,16 @@ void NackContext::recordNack(const FCI_NACK &nack) { uint64_t NackContext::reSendNack() { set nack_rtp; auto now = getCurrentMillisecond(); + GET_CONFIG(uint32_t, nack_maxms, Rtc::kNackMaxMS); + GET_CONFIG(uint32_t, nack_maxcount, Rtc::kNackMaxCount); + GET_CONFIG(float, nack_intervalratio, Rtc::kNackIntervalRatio); for (auto it = _nack_send_status.begin(); it != _nack_send_status.end();) { - if (now - it->second.first_stamp > kNackMaxMS) { + if (now - it->second.first_stamp > nack_maxms) { // 该rtp丢失太久了,不再要求重传 it = _nack_send_status.erase(it); continue; } - if (now - it->second.update_stamp < kNackIntervalRatio * _rtt) { + if (now - it->second.update_stamp < nack_intervalratio * _rtt) { // 距离上次nack不足2倍的rtt,不用再发送nack ++it; continue; @@ -260,7 +286,7 @@ uint64_t NackContext::reSendNack() { nack_rtp.emplace(it->first); // 更新nack发送时间戳 it->second.update_stamp = now; - if (++(it->second.nack_count) == kNackMaxCount) { + if (++(it->second.nack_count) == nack_maxcount) { // nack次数太多,移除之 it = _nack_send_status.erase(it); continue; diff --git a/webrtc/Nack.h b/webrtc/Nack.h index b0cd22b4..8ed98be9 100644 --- a/webrtc/Nack.h +++ b/webrtc/Nack.h @@ -41,18 +41,6 @@ class NackContext { public: using Ptr = std::shared_ptr; using onNack = std::function; - //最大保留的rtp丢包状态个数 - static constexpr auto kNackMaxSize = 2048; - // rtp丢包状态最长保留时间 - static constexpr auto kNackMaxMS = 3 * 1000; - // nack最多请求重传10次 - static constexpr auto kNackMaxCount = 15; - // nack重传频率,rtt的倍数 - static constexpr auto kNackIntervalRatio = 1.0f; - // nack包中rtp个数,减小此值可以让nack包响应更灵敏 - static constexpr auto kNackRtpSize = 8; - - static_assert(kNackRtpSize >=0 && kNackRtpSize <= FCI_NACK::kBitSize, "NackContext::kNackRtpSize must between 0 and 16"); NackContext();