Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Unified Diff: webrtc/voice_engine/transport_feedback_packet_loss_tracker.cc

Issue 2629883003: First-order-FEC recoverability calculation (Closed)
Patch Set: . Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/voice_engine/transport_feedback_packet_loss_tracker.cc
diff --git a/webrtc/voice_engine/transport_feedback_packet_loss_tracker.cc b/webrtc/voice_engine/transport_feedback_packet_loss_tracker.cc
index becf9646098a2f76b7739683bf945e586a54e1e5..c05b044814d9f5a2916d985d40a1a7f8da7fe9ff 100644
--- a/webrtc/voice_engine/transport_feedback_packet_loss_tracker.cc
+++ b/webrtc/voice_engine/transport_feedback_packet_loss_tracker.cc
@@ -21,26 +21,40 @@ namespace {
constexpr uint16_t kSeqNumHalf = 0x8000u;
constexpr uint16_t kSeqNumQuarter = kSeqNumHalf / 2;
constexpr size_t kMaxConsecutiveOldReports = 4;
+
+void UpdateCounter(size_t* counter, bool increment) {
+ if (increment) {
+ RTC_DCHECK_LT(*counter, std::numeric_limits<std::size_t>::max());
+ ++(*counter);
+ } else {
+ RTC_DCHECK_GT(*counter, 0);
+ --(*counter);
+ }
+}
+
} // namespace
namespace webrtc {
TransportFeedbackPacketLossTracker::TransportFeedbackPacketLossTracker(
- size_t min_window_size,
- size_t max_window_size)
- : min_window_size_(min_window_size),
- max_window_size_(max_window_size),
- ref_packet_status_(packet_status_window_.begin()) {
- RTC_DCHECK_GT(min_window_size, 0);
- RTC_DCHECK_GE(max_window_size_, min_window_size_);
- RTC_DCHECK_LE(max_window_size_, kSeqNumHalf);
+ size_t max_window_size,
+ size_t plr_min_num_packets,
+ size_t rplr_min_num_pairs)
+ : max_window_size_(max_window_size),
+ ref_packet_status_(packet_status_window_.begin()),
+ plr_state_(plr_min_num_packets),
+ rplr_state_(rplr_min_num_pairs) {
+ RTC_DCHECK_GT(plr_min_num_packets, 0);
+ RTC_DCHECK_GE(max_window_size, plr_min_num_packets);
+ RTC_DCHECK_LE(max_window_size, kSeqNumHalf);
+ RTC_DCHECK_GT(rplr_min_num_pairs, 0);
+ RTC_DCHECK_GT(max_window_size, rplr_min_num_pairs);
Reset();
}
void TransportFeedbackPacketLossTracker::Reset() {
- num_received_packets_ = 0;
- num_lost_packets_ = 0;
- num_consecutive_losses_ = 0;
+ plr_state_.Reset();
+ rplr_state_.Reset();
num_consecutive_old_reports_ = 0;
packet_status_window_.clear();
ref_packet_status_ = packet_status_window_.begin();
@@ -104,16 +118,14 @@ void TransportFeedbackPacketLossTracker::OnReceivedTransportFeedback(
}
}
-bool TransportFeedbackPacketLossTracker::GetPacketLossRates(
- float* packet_loss_rate,
- float* consecutive_packet_loss_rate) const {
- const size_t total = num_lost_packets_ + num_received_packets_;
- if (total < min_window_size_)
- return false;
- *packet_loss_rate = static_cast<float>(num_lost_packets_) / total;
- *consecutive_packet_loss_rate =
- static_cast<float>(num_consecutive_losses_) / total;
- return true;
+rtc::Optional<float>
+TransportFeedbackPacketLossTracker::GetPacketLossRate() const {
+ return plr_state_.GetMetric();
+}
+
+rtc::Optional<float>
+TransportFeedbackPacketLossTracker::GetRecoverablePacketLossRate() const {
+ return rplr_state_.GetMetric();
}
void TransportFeedbackPacketLossTracker::InsertPacketStatus(uint16_t seq_num,
@@ -124,7 +136,7 @@ void TransportFeedbackPacketLossTracker::InsertPacketStatus(uint16_t seq_num,
if (!ret.first->second && received) {
// If older status said that the packet was lost but newer one says it
// is received, we take the newer one.
- UndoPacketStatus(ret.first);
+ UpdateMetrics(ret.first, false);
ret.first->second = received;
} else {
// If the value is unchanged or if older status said that the packet was
@@ -132,66 +144,63 @@ void TransportFeedbackPacketLossTracker::InsertPacketStatus(uint16_t seq_num,
return;
}
}
- ApplyPacketStatus(ret.first);
+ UpdateMetrics(ret.first, true);
if (packet_status_window_.size() == 1)
ref_packet_status_ = ret.first;
}
void TransportFeedbackPacketLossTracker::RemoveOldestPacketStatus() {
- UndoPacketStatus(ref_packet_status_);
+ UpdateMetrics(ref_packet_status_, false);
const auto it = ref_packet_status_;
ref_packet_status_ = NextPacketStatus(it);
packet_status_window_.erase(it);
}
-void TransportFeedbackPacketLossTracker::ApplyPacketStatus(
- PacketStatusIterator it) {
+void TransportFeedbackPacketLossTracker::UpdateMetrics(
+ PacketStatusIterator it,
+ bool apply /* false = undo */) {
RTC_DCHECK(it != packet_status_window_.end());
+ UpdatePlr(it, apply);
+ UpdateRplr(it, apply);
+}
+
+void TransportFeedbackPacketLossTracker::UpdatePlr(
+ PacketStatusIterator it,
+ bool apply /* false = undo */) {
+ // Record or undo reception status of currently handled packet.
if (it->second) {
- ++num_received_packets_;
+ UpdateCounter(&plr_state_.num_received_packets_, apply);
} else {
- ++num_lost_packets_;
- const auto& next = NextPacketStatus(it);
- if (next != packet_status_window_.end() &&
- next->first == static_cast<uint16_t>(it->first + 1) && !next->second) {
- // Feedback shows that the next packet has been lost. Since this
- // packet is lost, we increase the consecutive loss counter.
- ++num_consecutive_losses_;
- }
- if (it != ref_packet_status_) {
- const auto& pre = PreviousPacketStatus(it);
- if (pre->first == static_cast<uint16_t>(it->first - 1) && !pre->second) {
- // Feedback shows that the previous packet has been lost. Since this
- // packet is lost, we increase the consecutive loss counter.
- ++num_consecutive_losses_;
- }
- }
+ UpdateCounter(&plr_state_.num_lost_packets_, apply);
}
}
-void TransportFeedbackPacketLossTracker::UndoPacketStatus(
- PacketStatusIterator it) {
- RTC_DCHECK(it != packet_status_window_.end());
- if (it->second) {
- RTC_DCHECK_GT(num_received_packets_, 0);
- --num_received_packets_;
- } else {
- RTC_DCHECK_GT(num_lost_packets_, 0);
- --num_lost_packets_;
- const auto& next = NextPacketStatus(it);
- if (next != packet_status_window_.end() &&
- next->first == static_cast<uint16_t>(it->first + 1) && !next->second) {
- RTC_DCHECK_GT(num_consecutive_losses_, 0);
- --num_consecutive_losses_;
- }
- if (it != ref_packet_status_) {
- const auto& pre = PreviousPacketStatus(it);
- if (pre->first == static_cast<uint16_t>(it->first - 1) && !pre->second) {
- RTC_DCHECK_GT(num_consecutive_losses_, 0);
- --num_consecutive_losses_;
+void TransportFeedbackPacketLossTracker::UpdateRplr(
+ PacketStatusIterator it,
+ bool apply /* false = undo */) {
+ // Previous packet and current packet might compose a known pair.
+ // If so, the RPLR state needs to be updated accordingly.
+ if (it != ref_packet_status_) {
+ const auto& prev = PreviousPacketStatus(it);
+ if (prev->first == static_cast<uint16_t>(it->first - 1)) {
+ UpdateCounter(&rplr_state_.num_known_pairs_, apply);
+ if (!prev->second && it->second) {
+ UpdateCounter(
+ &rplr_state_.num_recoverable_losses_, apply);
}
}
}
+
+ // Current packet and next packet might compose a pair.
+ // If so, the RPLR state needs to be updated accordingly.
+ const auto& next = NextPacketStatus(it);
+ if (next != packet_status_window_.end() &&
+ next->first == static_cast<uint16_t>(it->first + 1)) {
+ UpdateCounter(&rplr_state_.num_known_pairs_, apply);
+ if (!it->second && next->second) {
+ UpdateCounter(&rplr_state_.num_recoverable_losses_, apply);
+ }
+ }
}
TransportFeedbackPacketLossTracker::PacketStatusIterator
@@ -236,42 +245,70 @@ TransportFeedbackPacketLossTracker::NextPacketStatus(PacketStatusIterator it) {
// to unit test.
void TransportFeedbackPacketLossTracker::Validate() const { // Testing only!
RTC_CHECK_LE(packet_status_window_.size(), max_window_size_);
- RTC_CHECK_GE(num_lost_packets_, num_consecutive_losses_);
RTC_CHECK_EQ(packet_status_window_.size(),
- num_lost_packets_ + num_received_packets_);
+ plr_state_.num_lost_packets_ + plr_state_.num_received_packets_);
+ RTC_CHECK_LE(rplr_state_.num_recoverable_losses_,
+ rplr_state_.num_known_pairs_);
+ RTC_CHECK_LE(rplr_state_.num_known_pairs_,
+ packet_status_window_.size() - 1);
size_t received_packets = 0;
size_t lost_packets = 0;
- size_t consecutive_losses = 0;
+ size_t known_status_pairs = 0;
+ size_t recoverable_losses = 0;
if (!packet_status_window_.empty()) {
PacketStatusIterator it = ref_packet_status_;
- bool pre_lost = false;
- uint16_t pre_seq_num = it->first - 1;
do {
if (it->second) {
++received_packets;
} else {
++lost_packets;
- if (pre_lost && pre_seq_num == static_cast<uint16_t>(it->first - 1))
- ++consecutive_losses;
+ }
+
+ auto next = std::next(it);
+ if (next == packet_status_window_.end())
+ next = packet_status_window_.begin();
+
+ if (next != ref_packet_status_ &&
+ next->first == static_cast<uint16_t>(it->first + 1)) {
+ ++known_status_pairs;
+ if (!it->second && next->second)
+ ++recoverable_losses;
}
RTC_CHECK_LT(ForwardDiff(ReferenceSequenceNumber(), it->first),
kSeqNumHalf);
- pre_lost = !it->second;
- pre_seq_num = it->first;
-
- ++it;
- if (it == packet_status_window_.end())
- it = packet_status_window_.begin();
+ it = next;
} while (it != ref_packet_status_);
}
- RTC_CHECK_EQ(num_received_packets_, received_packets);
- RTC_CHECK_EQ(num_lost_packets_, lost_packets);
- RTC_CHECK_EQ(num_consecutive_losses_, consecutive_losses);
+ RTC_CHECK_EQ(plr_state_.num_received_packets_, received_packets);
+ RTC_CHECK_EQ(plr_state_.num_lost_packets_, lost_packets);
+ RTC_CHECK_EQ(rplr_state_.num_known_pairs_, known_status_pairs);
+ RTC_CHECK_EQ(rplr_state_.num_recoverable_losses_, recoverable_losses);
+}
+
+rtc::Optional<float>
+TransportFeedbackPacketLossTracker::PlrState::GetMetric() const {
+ const size_t total = num_lost_packets_ + num_received_packets_;
+ if (total < min_num_packets_) {
+ return rtc::Optional<float>();
+ } else {
+ return rtc::Optional<float>(
+ static_cast<float>(num_lost_packets_) / total);
+ }
+}
+
+rtc::Optional<float>
+TransportFeedbackPacketLossTracker::RplrState::GetMetric() const {
+ if (num_known_pairs_ < min_num_pairs_) {
+ return rtc::Optional<float>();
+ } else {
+ return rtc::Optional<float>(
+ static_cast<float>(num_recoverable_losses_) / num_known_pairs_);
+ }
}
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698