aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/src/protocols/rtc/rtc_ldr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtransport/src/protocols/rtc/rtc_ldr.cc')
-rw-r--r--libtransport/src/protocols/rtc/rtc_ldr.cc71
1 files changed, 51 insertions, 20 deletions
diff --git a/libtransport/src/protocols/rtc/rtc_ldr.cc b/libtransport/src/protocols/rtc/rtc_ldr.cc
index 1ca1cf48d..abf6cda2c 100644
--- a/libtransport/src/protocols/rtc/rtc_ldr.cc
+++ b/libtransport/src/protocols/rtc/rtc_ldr.cc
@@ -36,17 +36,17 @@ RTCLossDetectionAndRecovery::RTCLossDetectionAndRecovery(
Indexer *indexer, asio::io_service &io_service,
interface::RtcTransportRecoveryStrategies type,
RecoveryStrategy::SendRtxCallback &&callback,
- interface::StrategyCallback *external_callback) {
+ interface::StrategyCallback &&external_callback) {
rs_type_ = type;
if (type == interface::RtcTransportRecoveryStrategies::RECOVERY_OFF) {
rs_ = std::make_shared<RecoveryStrategyRecoveryOff>(
- indexer, std::move(callback), io_service, external_callback);
+ indexer, std::move(callback), io_service, std::move(external_callback));
} else if (type == interface::RtcTransportRecoveryStrategies::DELAY_BASED) {
rs_ = std::make_shared<RecoveryStrategyDelayBased>(
- indexer, std::move(callback), io_service, external_callback);
+ indexer, std::move(callback), io_service, std::move(external_callback));
} else if (type == interface::RtcTransportRecoveryStrategies::FEC_ONLY) {
rs_ = std::make_shared<RecoveryStrategyFecOnly>(
- indexer, std::move(callback), io_service, external_callback);
+ indexer, std::move(callback), io_service, std::move(external_callback));
} else if (type == interface::RtcTransportRecoveryStrategies::LOW_RATE ||
type == interface::RtcTransportRecoveryStrategies::
LOW_RATE_AND_BESTPATH ||
@@ -55,12 +55,12 @@ RTCLossDetectionAndRecovery::RTCLossDetectionAndRecovery(
type == interface::RtcTransportRecoveryStrategies::
LOW_RATE_AND_ALL_FWD_STRATEGIES) {
rs_ = std::make_shared<RecoveryStrategyLowRate>(
- indexer, std::move(callback), io_service, external_callback);
+ indexer, std::move(callback), io_service, std::move(external_callback));
} else {
// default
rs_type_ = interface::RtcTransportRecoveryStrategies::RTX_ONLY;
rs_ = std::make_shared<RecoveryStrategyRtxOnly>(
- indexer, std::move(callback), io_service, external_callback);
+ indexer, std::move(callback), io_service, std::move(external_callback));
}
}
@@ -97,19 +97,21 @@ void RTCLossDetectionAndRecovery::onNewRound(bool in_sync) {
rs_->onNewRound(in_sync);
}
-void RTCLossDetectionAndRecovery::onTimeout(uint32_t seq, bool lost) {
+bool RTCLossDetectionAndRecovery::onTimeout(uint32_t seq, bool lost) {
if (!lost) {
- detectLoss(seq, seq + 1);
+ return detectLoss(seq, seq + 1, false);
} else {
rs_->onLostTimeout(seq);
}
+ return false;
}
-void RTCLossDetectionAndRecovery::onPacketRecoveredFec(uint32_t seq) {
+bool RTCLossDetectionAndRecovery::onPacketRecoveredFec(uint32_t seq) {
rs_->receivedPacket(seq);
+ return false;
}
-void RTCLossDetectionAndRecovery::onDataPacketReceived(
+bool RTCLossDetectionAndRecovery::onDataPacketReceived(
const core::ContentObject &content_object) {
uint32_t seq = content_object.getName().getSuffix();
bool is_rtx = rs_->isRtx(seq);
@@ -118,10 +120,13 @@ void RTCLossDetectionAndRecovery::onDataPacketReceived(
<< "received data. add from "
<< rs_->getState()->getHighestSeqReceivedInOrder() + 1 << " to " << seq;
if (!is_rtx)
- detectLoss(rs_->getState()->getHighestSeqReceivedInOrder() + 1, seq);
+ return detectLoss(rs_->getState()->getHighestSeqReceivedInOrder() + 1, seq,
+ false);
+
+ return false;
}
-void RTCLossDetectionAndRecovery::onNackPacketReceived(
+bool RTCLossDetectionAndRecovery::onNackPacketReceived(
const core::ContentObject &nack) {
struct nack_packet_t *nack_pkt =
(struct nack_packet_t *)nack.getPayload()->data();
@@ -140,11 +145,18 @@ void RTCLossDetectionAndRecovery::onNackPacketReceived(
<< "received nack. add from "
<< rs_->getState()->getHighestSeqReceivedInOrder() + 1 << " to "
<< production_seq;
- detectLoss(rs_->getState()->getHighestSeqReceivedInOrder() + 1,
- production_seq);
+
+ // if it is a future nack store it in the list set of nacked seq
+ if (production_seq <= seq) rs_->receivedFutureNack(seq);
+
+ // call the detectLoss function using the probe flag = true. in fact the
+ // losses detected using nacks are the same as the one detected using probes,
+ // we should not increase the loss counter
+ return detectLoss(rs_->getState()->getHighestSeqReceivedInOrder() + 1,
+ production_seq, true);
}
-void RTCLossDetectionAndRecovery::onProbePacketReceived(
+bool RTCLossDetectionAndRecovery::onProbePacketReceived(
const core::ContentObject &probe) {
// we don't log the reception of a probe packet for the sentinel timer because
// probes are not taken into account into the sync window. we use them as
@@ -157,12 +169,13 @@ void RTCLossDetectionAndRecovery::onProbePacketReceived(
<< rs_->getState()->getHighestSeqReceivedInOrder() + 1 << " to "
<< production_seq;
- detectLoss(rs_->getState()->getHighestSeqReceivedInOrder() + 1,
- production_seq);
+ return detectLoss(rs_->getState()->getHighestSeqReceivedInOrder() + 1,
+ production_seq, true);
}
-void RTCLossDetectionAndRecovery::detectLoss(uint32_t start, uint32_t stop) {
- if (start >= stop) return;
+bool RTCLossDetectionAndRecovery::detectLoss(uint32_t start, uint32_t stop,
+ bool recv_probe) {
+ if (start >= stop) return false;
// skip nacked packets
if (start <= rs_->getState()->getLastSeqNacked()) {
@@ -174,13 +187,31 @@ void RTCLossDetectionAndRecovery::detectLoss(uint32_t start, uint32_t stop) {
start = rs_->getState()->getHighestSeqReceivedInOrder() + 1;
}
+ bool loss_detected = false;
for (uint32_t seq = start; seq < stop; seq++) {
if (rs_->getState()->getPacketState(seq) == PacketState::UNKNOWN) {
if (rs_->lossDetected(seq)) {
- rs_->getState()->onLossDetected(seq);
+ loss_detected = true;
+ if ((recv_probe || rs_->wasNacked(seq)) && !rs_->isFecOn()) {
+ // these losses were detected using a probe and fec is off.
+ // in this case most likelly the procotol is about to go out of sync
+ // and the packets are not really lost (e.g. increase in prod rate).
+ // for this reason we do not
+ // count the losses in the stats. Instead we do the following
+ // 1. send RTX for the packets in case they were really lost
+ // 2. return to the RTC protocol that a loss was detected using a
+ // probe. the protocol will switch to catch_up mode to increase the
+ // size of the window
+ rs_->requestPossibleLostPacket(seq);
+ } else {
+ // if fec is on we don't need to mask pontetial losses, so increase
+ // the loss rate
+ rs_->notifyNewLossDetedcted(seq);
+ }
}
}
}
+ return loss_detected;
}
} // namespace rtc