From 77c917a6eec3462acebbccacde03601f7841e8b9 Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Thu, 6 Feb 2014 16:34:47 +0000 Subject: [PATCH] Plot the capacity of a trace-based delivery filter. Breaks out the instantaneous rate counters to its own class. R=solenberg@webrtc.org Review URL: https://webrtc-codereview.appspot.com/7999005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5494 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../bwe_simulations.cc | 4 +- .../remote_bitrate_estimator/test/bwe_plot.sh | 2 +- .../test/bwe_test_framework.cc | 117 +++++++++++++----- .../test/bwe_test_framework.h | 22 ++-- 4 files changed, 100 insertions(+), 45 deletions(-) diff --git a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc index 797d669f8..976f2a87d 100644 --- a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc +++ b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc @@ -67,7 +67,7 @@ INSTANTIATE_TEST_CASE_P(VideoSendersTest, BweSimulation, TEST_P(BweSimulation, SprintUplinkTest) { VerboseLogging(true); RateCounterFilter counter1(this, "sender_output"); - TraceBasedDeliveryFilter filter(this); + TraceBasedDeliveryFilter filter(this, "link_capacity"); RateCounterFilter counter2(this, "receiver_input"); ASSERT_TRUE(filter.Init(test::ResourcePath("sprint-uplink", "rx"))); RunFor(60 * 1000); @@ -76,7 +76,7 @@ TEST_P(BweSimulation, SprintUplinkTest) { TEST_P(BweSimulation, Verizon4gDownlinkTest) { VerboseLogging(true); RateCounterFilter counter1(this, "sender_output"); - TraceBasedDeliveryFilter filter(this); + TraceBasedDeliveryFilter filter(this, "link_capacity"); RateCounterFilter counter2(this, "receiver_input"); ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx"))); RunFor(22 * 60 * 1000); diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_plot.sh b/webrtc/modules/remote_bitrate_estimator/test/bwe_plot.sh index 627b930b0..4695af45c 100755 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_plot.sh +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_plot.sh @@ -29,7 +29,7 @@ function gen_gnuplot_input { linetypes=($(echo "$data_sets" | cut -d '#' -f 2 | cut -d ' ' -f 1)) echo -n "reset; " echo -n "set terminal wxt size 1440,900 font \"Arial,9\"; " - echo -n "set xtics 60; set xlabel \"Seconds\"; " + echo -n "set xlabel \"Seconds\"; " if [ -n $linetypes ]; then echo -n "set ylabel 'bitrate (kbps)';" echo -n "set ytics nomirror;" diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc index b4a6a09e7..546ae2c40 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc @@ -17,6 +17,48 @@ 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 TimeSizePair; + + const int64_t kWindowSizeUs; + uint32_t packets_per_second_; + uint32_t bytes_per_second_; + int64_t last_accumulated_us_; + std::list window_; +}; + Random::Random(uint32_t seed) : a_(0x531FDB97 ^ seed), b_(0x6420ECA8 + seed) { @@ -102,33 +144,31 @@ 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_(), - name_("") { -} + name_("") {} RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, const std::string& name) : 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_(), - name_(name) { -} + 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"); @@ -138,30 +178,16 @@ void RateCounterFilter::LogStats() { void RateCounterFilter::Plot(int64_t timestamp_ms) { BWE_TEST_LOGGING_CONTEXT(name_.c_str()); BWE_TEST_LOGGING_PLOT("Throughput_#1", timestamp_ms, - (bytes_per_second_ * 8) / 1000.0); + 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(); + rate_counter_->UpdateRates(it->send_time_us(), it->payload_size()); } - 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(); - } - 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) @@ -311,7 +337,22 @@ TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( : PacketProcessor(listener), delivery_times_us_(), next_delivery_it_(), - local_time_us_(-1) {} + 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"); @@ -341,11 +382,21 @@ bool TraceBasedDeliveryFilter::Init(const std::string& filename) { 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_); } diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h index d7057da7d..ddddd7499 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h @@ -21,11 +21,14 @@ #include "webrtc/modules/interface/module_common_types.h" #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" +#include "webrtc/system_wrappers/interface/scoped_ptr.h" namespace webrtc { namespace testing { namespace bwe { +class RateCounter; + template class Stats { public: Stats() @@ -193,22 +196,18 @@ class RateCounterFilter : public PacketProcessor { public: explicit RateCounterFilter(PacketProcessorListener* listener); RateCounterFilter(PacketProcessorListener* listener, - const std::string& context); + const std::string& name); virtual ~RateCounterFilter(); - uint32_t packets_per_second() const { return packets_per_second_; } - uint32_t bits_per_second() const { return bytes_per_second_ * 8; } + uint32_t packets_per_second() const; + uint32_t bits_per_second() const; void LogStats(); virtual void Plot(int64_t timestamp_ms); virtual void RunFor(int64_t time_ms, Packets* in_out); private: - const int64_t kWindowSizeUs; - uint32_t packets_per_second_; - uint32_t bytes_per_second_; - int64_t last_accumulated_us_; - Packets window_; + scoped_ptr rate_counter_; Stats pps_stats_; Stats kbps_stats_; std::string name_; @@ -298,12 +297,15 @@ class ChokeFilter : public PacketProcessor { class TraceBasedDeliveryFilter : public PacketProcessor { public: explicit TraceBasedDeliveryFilter(PacketProcessorListener* listener); - virtual ~TraceBasedDeliveryFilter() {} + TraceBasedDeliveryFilter(PacketProcessorListener* listener, + const std::string& name); + virtual ~TraceBasedDeliveryFilter(); // The file should contain nanosecond timestamps corresponding to the time // when the network can accept another packet. The timestamps should be // separated by new lines, e.g., "100000000\n125000000\n321000000\n..." bool Init(const std::string& filename); + virtual void Plot(int64_t timestamp_ms); virtual void RunFor(int64_t time_ms, Packets* in_out); private: @@ -313,6 +315,8 @@ class TraceBasedDeliveryFilter : public PacketProcessor { TimeList delivery_times_us_; TimeList::const_iterator next_delivery_it_; int64_t local_time_us_; + scoped_ptr rate_counter_; + std::string name_; DISALLOW_COPY_AND_ASSIGN(TraceBasedDeliveryFilter); };