| Index: webrtc/modules/remote_bitrate_estimator/test/bwe.cc
 | 
| diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe.cc
 | 
| index 6e8dbc7c068430905d2681508b10fb2af19fad31..9a11e2471d0d806ba19f3933d6a3c11533b8a289 100644
 | 
| --- a/webrtc/modules/remote_bitrate_estimator/test/bwe.cc
 | 
| +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe.cc
 | 
| @@ -29,7 +29,17 @@ namespace bwe {
 | 
|  const int kSetCapacity = 1000;
 | 
|  
 | 
|  BweReceiver::BweReceiver(int flow_id)
 | 
| -    : flow_id_(flow_id), received_packets_(kSetCapacity) {
 | 
| +    : flow_id_(flow_id),
 | 
| +      received_packets_(kSetCapacity),
 | 
| +      rate_counter_(),
 | 
| +      loss_account() {
 | 
| +}
 | 
| +
 | 
| +BweReceiver::BweReceiver(int flow_id, int64_t window_size_ms)
 | 
| +    : flow_id_(flow_id),
 | 
| +      received_packets_(kSetCapacity),
 | 
| +      rate_counter_(window_size_ms),
 | 
| +      loss_account() {
 | 
|  }
 | 
|  
 | 
|  class NullBweSender : public BweSender {
 | 
| @@ -97,24 +107,58 @@ BweReceiver* CreateBweReceiver(BandwidthEstimatorType type,
 | 
|    return NULL;
 | 
|  }
 | 
|  
 | 
| -float BweReceiver::GlobalPacketLossRatio() {
 | 
| -  if (received_packets_.empty()) {
 | 
| -    return 0.0f;
 | 
| +// Take into account all LinkedSet content.
 | 
| +void BweReceiver::UpdateLoss() {
 | 
| +  loss_account.Add(LinkedSetPacketLossRatio());
 | 
| +}
 | 
| +
 | 
| +void BweReceiver::ClearSet() {
 | 
| +  received_packets_.Clear();
 | 
| +}
 | 
| +
 | 
| +// Preserve 10% latest packets and update packet loss based on the oldest
 | 
| +// 90%, that will be removed.
 | 
| +void BweReceiver::RelieveSetAndUpdateLoss() {
 | 
| +  // Compute Loss for the whole LinkedSet and updates loss_account_.
 | 
| +  UpdateLoss();
 | 
| +
 | 
| +  size_t num_preserved_elements = received_packets_.size() / 10;
 | 
| +  PacketNodeIt it = received_packets_.begin();
 | 
| +  std::advance(it, num_preserved_elements);
 | 
| +
 | 
| +  while (it != received_packets_.end()) {
 | 
| +    received_packets_.Erase(it++);
 | 
|    }
 | 
| -  // Possibly there are packets missing.
 | 
| -  const uint16_t kMaxGap = 1.5 * kSetCapacity;
 | 
| -  uint16_t min = received_packets_.find_min();
 | 
| -  uint16_t max = received_packets_.find_max();
 | 
| -
 | 
| -  int gap;
 | 
| -  if (max - min < kMaxGap) {
 | 
| -    gap = max - min + 1;
 | 
| -  } else {  // There was an overflow.
 | 
| -    max = received_packets_.upper_bound(kMaxGap);
 | 
| -    min = received_packets_.lower_bound(0xFFFF - kMaxGap);
 | 
| -    gap = max + (0xFFFF - min) + 2;
 | 
| +
 | 
| +  // Compute Loss for the preserved elements
 | 
| +  loss_account.Subtract(LinkedSetPacketLossRatio());
 | 
| +}
 | 
| +
 | 
| +float BweReceiver::GlobalReceiverPacketLossRatio() {
 | 
| +  UpdateLoss();
 | 
| +  return loss_account.LossRatio();
 | 
| +}
 | 
| +
 | 
| +// This function considers at most kSetCapacity = 1000 packets.
 | 
| +LossAccount BweReceiver::LinkedSetPacketLossRatio() {
 | 
| +  if (received_packets_.empty()) {
 | 
| +    return LossAccount();
 | 
|    }
 | 
| -  return static_cast<float>(received_packets_.size()) / gap;
 | 
| +
 | 
| +  uint16_t oldest_seq_num = received_packets_.OldestSeqNumber();
 | 
| +  uint16_t newest_seq_num = received_packets_.NewestSeqNumber();
 | 
| +
 | 
| +  size_t set_total_packets =
 | 
| +      static_cast<uint16_t>(newest_seq_num - oldest_seq_num + 1);
 | 
| +
 | 
| +  size_t set_received_packets = received_packets_.size();
 | 
| +  size_t set_lost_packets = set_total_packets - set_received_packets;
 | 
| +
 | 
| +  return LossAccount(set_total_packets, set_lost_packets);
 | 
| +}
 | 
| +
 | 
| +uint32_t BweReceiver::RecentKbps() const {
 | 
| +  return (rate_counter_.bits_per_second() + 500) / 1000;
 | 
|  }
 | 
|  
 | 
|  // Go through a fixed time window of most recent packets received and
 | 
| @@ -133,26 +177,26 @@ float BweReceiver::RecentPacketLossRatio() {
 | 
|    // Lowest timestamp limit, oldest one that should be checked.
 | 
|    int64_t time_limit_ms = (*node_it)->arrival_time_ms - kPacketLossTimeWindowMs;
 | 
|    // Oldest and newest values found within the given time window.
 | 
| -  uint16_t oldest_seq_nb = (*node_it)->sequence_number;
 | 
| -  uint16_t newest_seq_nb = oldest_seq_nb;
 | 
| +  uint16_t oldest_seq_num = (*node_it)->sequence_number;
 | 
| +  uint16_t newest_seq_num = oldest_seq_num;
 | 
|  
 | 
|    while (node_it != received_packets_.end()) {
 | 
|      if ((*node_it)->arrival_time_ms < time_limit_ms) {
 | 
|        break;
 | 
|      }
 | 
|      uint16_t seq_nb = (*node_it)->sequence_number;
 | 
| -    if (IsNewerSequenceNumber(seq_nb, newest_seq_nb)) {
 | 
| -      newest_seq_nb = seq_nb;
 | 
| +    if (IsNewerSequenceNumber(seq_nb, newest_seq_num)) {
 | 
| +      newest_seq_num = seq_nb;
 | 
|      }
 | 
| -    if (IsNewerSequenceNumber(oldest_seq_nb, seq_nb)) {
 | 
| -      oldest_seq_nb = seq_nb;
 | 
| +    if (IsNewerSequenceNumber(oldest_seq_num, seq_nb)) {
 | 
| +      oldest_seq_num = seq_nb;
 | 
|      }
 | 
|      ++node_it;
 | 
|      ++number_packets_received;
 | 
|    }
 | 
|    // Interval width between oldest and newest sequence number.
 | 
| -  // There was an overflow if newest_seq_nb < oldest_seq_nb.
 | 
| -  int gap = static_cast<uint16_t>(newest_seq_nb - oldest_seq_nb + 1);
 | 
| +  // There was an overflow if newest_seq_num < oldest_seq_num.
 | 
| +  int gap = static_cast<uint16_t>(newest_seq_num - oldest_seq_num + 1);
 | 
|  
 | 
|    return static_cast<float>(gap - number_packets_received) / gap;
 | 
|  }
 | 
| @@ -161,7 +205,7 @@ void LinkedSet::Insert(uint16_t sequence_number,
 | 
|                         int64_t send_time_ms,
 | 
|                         int64_t arrival_time_ms,
 | 
|                         size_t payload_size) {
 | 
| -  std::map<uint16_t, PacketNodeIt>::iterator it = map_.find(sequence_number);
 | 
| +  auto it = map_.find(sequence_number);
 | 
|    if (it != map_.end()) {
 | 
|      PacketNodeIt node_it = it->second;
 | 
|      PacketIdentifierNode* node = *node_it;
 | 
| @@ -179,6 +223,12 @@ void LinkedSet::Insert(uint16_t sequence_number,
 | 
|                                          arrival_time_ms, payload_size));
 | 
|    }
 | 
|  }
 | 
| +
 | 
| +void LinkedSet::Insert(PacketIdentifierNode packet_identifier) {
 | 
| +  Insert(packet_identifier.sequence_number, packet_identifier.send_time_ms,
 | 
| +         packet_identifier.arrival_time_ms, packet_identifier.payload_size);
 | 
| +}
 | 
| +
 | 
|  void LinkedSet::RemoveTail() {
 | 
|    map_.erase(list_.back()->sequence_number);
 | 
|    list_.pop_back();
 | 
| @@ -188,6 +238,24 @@ void LinkedSet::UpdateHead(PacketIdentifierNode* new_head) {
 | 
|    map_[new_head->sequence_number] = list_.begin();
 | 
|  }
 | 
|  
 | 
| +void LinkedSet::Erase(PacketNodeIt node_it) {
 | 
| +  map_.erase((*node_it)->sequence_number);
 | 
| +  list_.erase(node_it);
 | 
| +}
 | 
| +
 | 
| +void LossAccount::Add(LossAccount rhs) {
 | 
| +  num_total += rhs.num_total;
 | 
| +  num_lost += rhs.num_lost;
 | 
| +}
 | 
| +void LossAccount::Subtract(LossAccount rhs) {
 | 
| +  num_total -= rhs.num_total;
 | 
| +  num_lost -= rhs.num_lost;
 | 
| +}
 | 
| +
 | 
| +float LossAccount::LossRatio() {
 | 
| +  return static_cast<float>(num_lost) / num_total;
 | 
| +}
 | 
| +
 | 
|  }  // namespace bwe
 | 
|  }  // namespace testing
 | 
|  }  // namespace webrtc
 | 
| 
 |