mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 12:37:09 +08:00
修复rtp seq重复导致rtp nack重传列队异常的bug
This commit is contained in:
parent
7a5cf925b0
commit
ba5ca8f5c7
@ -16,22 +16,22 @@ using namespace mediakit;
|
|||||||
|
|
||||||
static constexpr uint32_t kMaxNackMS = 10 * 1000;
|
static constexpr uint32_t kMaxNackMS = 10 * 1000;
|
||||||
|
|
||||||
void NackList::push_back(RtpPacket::Ptr rtp) {
|
void NackList::pushBack(RtpPacket::Ptr rtp) {
|
||||||
auto seq = rtp->getSeq();
|
auto seq = rtp->getSeq();
|
||||||
_nack_cache_seq.emplace_back(seq);
|
_nack_cache_seq.emplace_back(seq);
|
||||||
_nack_cache_pkt.emplace(seq, std::move(rtp));
|
_nack_cache_pkt.emplace(seq, std::move(rtp));
|
||||||
while (get_cache_ms() > kMaxNackMS) {
|
while (getCacheMS() > kMaxNackMS) {
|
||||||
//需要清除部分nack缓存
|
//需要清除部分nack缓存
|
||||||
pop_front();
|
popFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NackList::for_each_nack(const FCI_NACK &nack, const function<void(const RtpPacket::Ptr &rtp)> &func) {
|
void NackList::forEach(const FCI_NACK &nack, const function<void(const RtpPacket::Ptr &rtp)> &func) {
|
||||||
auto seq = nack.getPid();
|
auto seq = nack.getPid();
|
||||||
for (auto bit : nack.getBitArray()) {
|
for (auto bit : nack.getBitArray()) {
|
||||||
if (bit) {
|
if (bit) {
|
||||||
//丢包
|
//丢包
|
||||||
RtpPacket::Ptr *ptr = get_rtp(seq);
|
RtpPacket::Ptr *ptr = getRtp(seq);
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
func(*ptr);
|
func(*ptr);
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ void NackList::for_each_nack(const FCI_NACK &nack, const function<void(const Rtp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NackList::pop_front() {
|
void NackList::popFront() {
|
||||||
if (_nack_cache_seq.empty()) {
|
if (_nack_cache_seq.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ void NackList::pop_front() {
|
|||||||
_nack_cache_seq.pop_front();
|
_nack_cache_seq.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpPacket::Ptr *NackList::get_rtp(uint16_t seq) {
|
RtpPacket::Ptr *NackList::getRtp(uint16_t seq) {
|
||||||
auto it = _nack_cache_pkt.find(seq);
|
auto it = _nack_cache_pkt.find(seq);
|
||||||
if (it == _nack_cache_pkt.end()) {
|
if (it == _nack_cache_pkt.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -56,19 +56,35 @@ RtpPacket::Ptr *NackList::get_rtp(uint16_t seq) {
|
|||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t NackList::get_cache_ms() {
|
uint32_t NackList::getCacheMS() {
|
||||||
if (_nack_cache_seq.size() < 2) {
|
auto back_stamp = getRtpStamp(_nack_cache_seq.back());
|
||||||
|
if (back_stamp == -1) {
|
||||||
|
_nack_cache_seq.pop_back();
|
||||||
return 0;
|
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);
|
auto front_stamp = getRtpStamp(_nack_cache_seq.front());
|
||||||
if (back >= front) {
|
if (front_stamp == -1) {
|
||||||
return back - front;
|
_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) {
|
void NackContext::received(uint16_t seq, bool is_rtx) {
|
||||||
|
@ -20,13 +20,14 @@ public:
|
|||||||
NackList() = default;
|
NackList() = default;
|
||||||
~NackList() = default;
|
~NackList() = default;
|
||||||
|
|
||||||
void push_back(mediakit::RtpPacket::Ptr rtp);
|
void pushBack(mediakit::RtpPacket::Ptr rtp);
|
||||||
void for_each_nack(const mediakit::FCI_NACK &nack, const std::function<void(const mediakit::RtpPacket::Ptr &rtp)> &cb);
|
void forEach(const mediakit::FCI_NACK &nack, const std::function<void(const mediakit::RtpPacket::Ptr &rtp)> &cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void pop_front();
|
void popFront();
|
||||||
uint32_t get_cache_ms();
|
uint32_t getCacheMS();
|
||||||
mediakit::RtpPacket::Ptr *get_rtp(uint16_t seq);
|
int64_t getRtpStamp(uint16_t seq);
|
||||||
|
mediakit::RtpPacket::Ptr *getRtp(uint16_t seq);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<uint16_t> _nack_cache_seq;
|
std::deque<uint16_t> _nack_cache_seq;
|
||||||
|
@ -652,7 +652,7 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
auto &track = it->second;
|
auto &track = it->second;
|
||||||
auto &fci = fb->getFci<FCI_NACK>();
|
auto &fci = fb->getFci<FCI_NACK>();
|
||||||
track->nack_list.for_each_nack(fci, [&](const RtpPacket::Ptr &rtp) {
|
track->nack_list.forEach(fci, [&](const RtpPacket::Ptr &rtp) {
|
||||||
//rtp重传
|
//rtp重传
|
||||||
onSendRtp(rtp, true, true);
|
onSendRtp(rtp, true, true);
|
||||||
});
|
});
|
||||||
@ -807,7 +807,7 @@ void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool r
|
|||||||
if (!rtx) {
|
if (!rtx) {
|
||||||
//统计rtp发送情况,好做sr汇报
|
//统计rtp发送情况,好做sr汇报
|
||||||
track->rtcp_context_send->onRtp(rtp->getSeq(), rtp->getStamp(), rtp->ntp_stamp, rtp->sample_rate, rtp->size() - RtpPacket::kRtpTcpHeaderSize);
|
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 0
|
||||||
//此处模拟发送丢包
|
//此处模拟发送丢包
|
||||||
if (rtp->type == TrackVideo && rtp->getSeq() % 100 == 0) {
|
if (rtp->type == TrackVideo && rtp->getSeq() % 100 == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user