Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / remote_bitrate_estimator / test / bwe_test_framework.cc
index 9b64eaf..546ae2c 100644 (file)
 
 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
 
+#include <cstdio>
+#include <sstream>
+
 namespace webrtc {
 namespace testing {
 namespace bwe {
 
+class RateCounter {
+ public:
+  RateCounter()
+      : kWindowSizeUs(1000000),
+        packets_per_second_(0),
+        bytes_per_second_(0),
+        last_accumulated_us_(0),
+        window_() {}
+
+  void UpdateRates(int64_t send_time_us, uint32_t payload_size) {
+    packets_per_second_++;
+    bytes_per_second_ += payload_size;
+    last_accumulated_us_ = send_time_us;
+    window_.push_back(std::make_pair(send_time_us, payload_size));
+    while (!window_.empty()) {
+      const TimeSizePair& packet = window_.front();
+      if (packet.first > (last_accumulated_us_ - kWindowSizeUs)) {
+        break;
+      }
+      assert(packets_per_second_ >= 1);
+      assert(bytes_per_second_ >= packet.second);
+      packets_per_second_--;
+      bytes_per_second_ -= packet.second;
+      window_.pop_front();
+    }
+  }
+
+  uint32_t bits_per_second() const {
+    return bytes_per_second_ * 8;
+  }
+  uint32_t packets_per_second() const { return packets_per_second_; }
+
+ private:
+  typedef std::pair<int64_t, uint32_t> TimeSizePair;
+
+  const int64_t kWindowSizeUs;
+  uint32_t packets_per_second_;
+  uint32_t bytes_per_second_;
+  int64_t last_accumulated_us_;
+  std::list<TimeSizePair> window_;
+};
+
 Random::Random(uint32_t seed)
     : a_(0x531FDB97 ^ seed),
       b_(0x6420ECA8 + seed) {
@@ -42,20 +87,23 @@ int Random::Gaussian(int mean, int standard_deviation) {
 }
 
 Packet::Packet()
-    : send_time_us_(0),
+    : creation_time_us_(-1),
+      send_time_us_(-1),
       payload_size_(0) {
    memset(&header_, 0, sizeof(header_));
 }
 
 Packet::Packet(int64_t send_time_us, uint32_t payload_size,
-          const RTPHeader& header)
-  : send_time_us_(send_time_us),
+               const RTPHeader& header)
+  : creation_time_us_(send_time_us),
+    send_time_us_(send_time_us),
     payload_size_(payload_size),
     header_(header) {
 }
 
 Packet::Packet(int64_t send_time_us, uint32_t sequence_number)
-    : send_time_us_(send_time_us),
+    : creation_time_us_(send_time_us),
+      send_time_us_(send_time_us),
       payload_size_(0) {
    memset(&header_, 0, sizeof(header_));
    header_.sequenceNumber = sequence_number;
@@ -96,46 +144,50 @@ PacketProcessor::~PacketProcessor() {
 
 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener)
     : PacketProcessor(listener),
-      kWindowSizeUs(1000000),
-      packets_per_second_(0),
-      bytes_per_second_(0),
-      last_accumulated_us_(0),
-      window_(),
+      rate_counter_(new RateCounter()),
       pps_stats_(),
-      kbps_stats_() {
-}
+      kbps_stats_(),
+      name_("") {}
+
+RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
+                                     const std::string& name)
+    : PacketProcessor(listener),
+      rate_counter_(new RateCounter()),
+      pps_stats_(),
+      kbps_stats_(),
+      name_(name) {}
 
 RateCounterFilter::~RateCounterFilter() {
   LogStats();
 }
 
+uint32_t RateCounterFilter::packets_per_second() const {
+  return rate_counter_->packets_per_second();
+}
+
+uint32_t RateCounterFilter::bits_per_second() const {
+  return rate_counter_->bits_per_second();
+}
+
 void RateCounterFilter::LogStats() {
   BWE_TEST_LOGGING_CONTEXT("RateCounterFilter");
   pps_stats_.Log("pps");
   kbps_stats_.Log("kbps");
 }
 
+void RateCounterFilter::Plot(int64_t timestamp_ms) {
+  BWE_TEST_LOGGING_CONTEXT(name_.c_str());
+  BWE_TEST_LOGGING_PLOT("Throughput_#1", timestamp_ms,
+                        rate_counter_->bits_per_second() / 1000.0);
+}
+
 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
   assert(in_out);
   for (PacketsConstIt it = in_out->begin(); it != in_out->end(); ++it) {
-    packets_per_second_++;
-    bytes_per_second_ += it->payload_size();
-    last_accumulated_us_ = it->send_time_us();
-  }
-  window_.insert(window_.end(), in_out->begin(), in_out->end());
-  while (!window_.empty()) {
-    const Packet& packet = window_.front();
-    if (packet.send_time_us() > (last_accumulated_us_ - kWindowSizeUs)) {
-      break;
-    }
-    assert(packets_per_second_ >= 1);
-    assert(bytes_per_second_ >= packet.payload_size());
-    packets_per_second_--;
-    bytes_per_second_ -= packet.payload_size();
-    window_.pop_front();
+    rate_counter_->UpdateRates(it->send_time_us(), it->payload_size());
   }
-  pps_stats_.Push(packets_per_second_);
-  kbps_stats_.Push((bytes_per_second_ * 8) / 1000.0);
+  pps_stats_.Push(rate_counter_->packets_per_second());
+  kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
 }
 
 LossFilter::LossFilter(PacketProcessorListener* listener)
@@ -280,6 +332,91 @@ void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
   }
 }
 
+TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
+    PacketProcessorListener* listener)
+    : PacketProcessor(listener),
+      delivery_times_us_(),
+      next_delivery_it_(),
+      local_time_us_(-1),
+      rate_counter_(new RateCounter),
+      name_("") {}
+
+TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
+    PacketProcessorListener* listener,
+    const std::string& name)
+    : PacketProcessor(listener),
+      delivery_times_us_(),
+      next_delivery_it_(),
+      local_time_us_(-1),
+      rate_counter_(new RateCounter),
+      name_(name) {}
+
+TraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() {
+}
+
+bool TraceBasedDeliveryFilter::Init(const std::string& filename) {
+  FILE* trace_file = fopen(filename.c_str(), "r");
+  if (!trace_file) {
+    return false;
+  }
+  int64_t first_timestamp = -1;
+  while(!feof(trace_file)) {
+    const size_t kMaxLineLength = 100;
+    char line[kMaxLineLength];
+    if (fgets(line, kMaxLineLength, trace_file)) {
+      std::string line_string(line);
+      std::istringstream buffer(line_string);
+      int64_t timestamp;
+      buffer >> timestamp;
+      timestamp /= 1000;  // Convert to microseconds.
+      if (first_timestamp == -1)
+        first_timestamp = timestamp;
+      assert(delivery_times_us_.empty() ||
+             timestamp - first_timestamp - delivery_times_us_.back() >= 0);
+      delivery_times_us_.push_back(timestamp - first_timestamp);
+    }
+  }
+  assert(!delivery_times_us_.empty());
+  next_delivery_it_ = delivery_times_us_.begin();
+  fclose(trace_file);
+  return true;
+}
+
+void TraceBasedDeliveryFilter::Plot(int64_t timestamp_ms) {
+  BWE_TEST_LOGGING_CONTEXT(name_.c_str());
+  // This plots the max possible throughput of the trace-based delivery filter,
+  // which will be reached if a packet sent on every packet slot of the trace.
+  BWE_TEST_LOGGING_PLOT("MaxThroughput_#1", timestamp_ms,
+                        rate_counter_->bits_per_second() / 1000.0);
+}
+
+void TraceBasedDeliveryFilter::RunFor(int64_t time_ms, Packets* in_out) {
+  assert(in_out);
+  for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
+    do {
+      ProceedToNextSlot();
+      const int kPayloadSize = 1240;
+      rate_counter_->UpdateRates(local_time_us_, kPayloadSize);
+    } while (local_time_us_ < it->send_time_us());
+    it->set_send_time_us(local_time_us_);
+  }
+}
+
+void TraceBasedDeliveryFilter::ProceedToNextSlot() {
+  if (*next_delivery_it_ <= local_time_us_) {
+    ++next_delivery_it_;
+    if (next_delivery_it_ == delivery_times_us_.end()) {
+      // When the trace wraps we allow two packets to be sent back-to-back.
+      for (TimeList::iterator it = delivery_times_us_.begin();
+           it != delivery_times_us_.end(); ++it) {
+        *it += local_time_us_;
+      }
+      next_delivery_it_ = delivery_times_us_.begin();
+    }
+  }
+  local_time_us_ = *next_delivery_it_;
+}
+
 PacketSender::PacketSender(PacketProcessorListener* listener)
     : PacketProcessor(listener) {
 }
@@ -290,10 +427,10 @@ VideoSender::VideoSender(PacketProcessorListener* listener, float fps,
       kMaxPayloadSizeBytes(1000),
       kTimestampBase(0xff80ff00ul),
       frame_period_ms_(1000.0 / fps),
-      next_frame_ms_(frame_period_ms_ * first_frame_offset),
-      now_ms_(0.0),
       bytes_per_second_((1000 * kbps) / 8),
       frame_size_bytes_(bytes_per_second_ / fps),
+      next_frame_ms_(frame_period_ms_ * first_frame_offset),
+      now_ms_(0.0),
       prototype_header_() {
   assert(first_frame_offset >= 0.0f);
   assert(first_frame_offset < 1.0f);
@@ -335,6 +472,18 @@ void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
   }
   in_out->merge(newPackets);
 }
+
+AdaptiveVideoSender::AdaptiveVideoSender(PacketProcessorListener* listener,
+                                         float fps,
+                                         uint32_t kbps,
+                                         uint32_t ssrc,
+                                         float first_frame_offset)
+    : VideoSender(listener, fps, kbps, ssrc, first_frame_offset) {}
+
+void AdaptiveVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
+  bytes_per_second_ = feedback.estimated_bps / 8;
+  frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
+}
 }  // namespace bwe
 }  // namespace testing
 }  // namespace webrtc