Skip to content

Commit fd40ae4

Browse files
Add nack request resend
1 parent 07acbfd commit fd40ae4

File tree

2 files changed

+56
-34
lines changed

2 files changed

+56
-34
lines changed

include/rtc/rtcpnackrequester.hpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,26 @@ namespace rtc {
2121

2222
class RTC_CPP_EXPORT RtcpNackRequester final : public MediaHandler {
2323
public:
24+
RtcpNackRequester(SSRC ssrc, size_t jitterSize = 5, size_t nackResendIntervalMs = 10,
25+
size_t nackResendTimesMax = 10);
2426
SSRC ssrc;
25-
size_t jitterSize;
26-
size_t nackWaitMs;
27-
28-
RtcpNackRequester(SSRC ssrc, size_t jitterSize = 5, size_t nackWaitMs = 50);
2927
void incoming(message_vector &messages, const message_callback &send) override;
3028

3129
private:
32-
uint16_t expectSequence = 0;
33-
std::chrono::steady_clock::time_point nackWaitUntil;
30+
size_t jitterSize;
31+
size_t nackResendIntervalMs;
32+
size_t nackResendTimesMax;
33+
34+
bool initialized = false;
35+
uint16_t expectedSeq;
36+
size_t nackResendTimes = 0;
37+
std::chrono::steady_clock::time_point nextNackTime = std::chrono::steady_clock::now();
3438

35-
std::unordered_map<uint16_t, message_ptr> receivePackets;
36-
std::set<uint16_t> lostSequenceNumbers;
39+
std::map<uint16_t, message_ptr> jitterBuffer;
3740

38-
message_ptr nackMesssage(uint16_t sequence);
41+
auto isSeqNewerOrEqual(uint16_t seq1, uint16_t seq2) -> bool;
42+
void clearBuffer();
43+
auto nackMessage(uint16_t sequence) -> message_ptr;
3944
};
4045

4146
} // namespace rtc

src/rtcpnackrequester.cpp

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
#include "impl/internals.hpp"
1515

1616
namespace rtc {
17-
18-
RtcpNackRequester::RtcpNackRequester(SSRC ssrc, size_t jitterSize, size_t nackWaitMs)
19-
: ssrc(ssrc), jitterSize(jitterSize), nackWaitMs(nackWaitMs) {}
17+
RtcpNackRequester::RtcpNackRequester(SSRC ssrc, size_t jitterSize, size_t nackResendIntervalMs,
18+
size_t nackResendTimesMax)
19+
: ssrc(ssrc), jitterSize(jitterSize), nackResendIntervalMs(nackResendIntervalMs),
20+
nackResendTimesMax(nackResendTimesMax) {}
2021

2122
void RtcpNackRequester::incoming(message_vector &messages, const message_callback &send) {
2223
message_vector result;
@@ -33,45 +34,61 @@ void RtcpNackRequester::incoming(message_vector &messages, const message_callbac
3334

3435
auto rtp = reinterpret_cast<RtpHeader *>(message->data());
3536
uint16_t seqNo = rtp->seqNumber();
36-
lostSequenceNumbers.erase(seqNo);
3737

38-
if (expectSequence == 0) {
39-
expectSequence = seqNo;
38+
if (!initialized) {
39+
expectedSeq = seqNo;
40+
initialized = true;
4041
}
41-
if ((int16_t)(seqNo - expectSequence) >= 0) {
42-
receivePackets[seqNo] = message;
42+
if (isSeqNewerOrEqual(seqNo, expectedSeq)) {
43+
jitterBuffer[seqNo] = message;
4344
}
4445
}
4546

46-
while (receivePackets.size() > jitterSize) {
47-
bool alreadyReceived = receivePackets.count(expectSequence) > 0;
47+
while (jitterBuffer.size() > 0) {
48+
bool alreadyReceived = jitterBuffer.count(expectedSeq) > 0;
4849
if (alreadyReceived) {
49-
auto packet = receivePackets[expectSequence];
50+
auto packet = jitterBuffer[expectedSeq];
5051
result.push_back(packet);
51-
receivePackets.erase(expectSequence);
52-
expectSequence++;
52+
jitterBuffer.erase(expectedSeq);
53+
expectedSeq++;
54+
nackResendTimes = 0;
5355
continue;
5456
} else {
55-
bool alreadySentNack = lostSequenceNumbers.count(expectSequence) > 0;
57+
if (jitterBuffer.size() < jitterSize) {
58+
break;
59+
}
60+
if (nackResendTimes >= nackResendTimesMax) {
61+
PLOG_VERBOSE << "Skip NACK for lost packet: " << expectedSeq;
62+
clearBuffer();
63+
break;
64+
}
65+
5666
auto now = std::chrono::steady_clock::now();
57-
if (alreadySentNack) {
58-
if (now >= nackWaitUntil) {
59-
PLOG_VERBOSE << "Skip NACK for lost packet: " << expectSequence;
60-
expectSequence++;
61-
}
62-
} else {
63-
PLOG_VERBOSE << "Sending NACK for lost packet: " << expectSequence;
64-
lostSequenceNumbers.insert(expectSequence);
65-
nackWaitUntil = now + std::chrono::milliseconds(nackWaitMs);
66-
send(nackMesssage(expectSequence));
67+
if (now > nextNackTime) {
68+
PLOG_VERBOSE << "Sending NACK for lost packet: " << expectedSeq;
69+
nextNackTime = now + std::chrono::milliseconds(nackResendIntervalMs);
70+
send(nackMessage(expectedSeq));
71+
nackResendTimes++;
6772
}
73+
6874
break;
6975
}
7076
}
7177
messages.swap(result);
7278
}
7379

74-
message_ptr RtcpNackRequester::nackMesssage(uint16_t sequence) {
80+
auto RtcpNackRequester::isSeqNewerOrEqual(uint16_t seq1, uint16_t seq2) -> bool {
81+
return (int16_t)(seq1 - seq2) >= 0;
82+
}
83+
84+
void RtcpNackRequester::clearBuffer() {
85+
initialized = false;
86+
jitterBuffer.clear();
87+
nackResendTimes = 0;
88+
nextNackTime = std::chrono::steady_clock::now();
89+
}
90+
91+
auto RtcpNackRequester::nackMessage(uint16_t sequence) -> message_ptr {
7592
unsigned int fciCount = 0;
7693
uint16_t fciPID = 0;
7794

0 commit comments

Comments
 (0)