1 /* 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_ 12 #define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_ 13 14 #include <map> 15 #include <set> 16 #include <string> 17 #include <vector> 18 19 #include "webrtc/base/common.h" 20 #include "webrtc/test/testsupport/gtest_prod_util.h" 21 22 namespace webrtc { 23 namespace testing { 24 namespace bwe { 25 26 class ChokeFilter; 27 class PacketSender; 28 29 class LinkShare { 30 public: 31 explicit LinkShare(ChokeFilter* choke_filter); 32 33 void PauseFlow(int flow_id); // Increases available capacity per flow. 34 void ResumeFlow(int flow_id); // Decreases available capacity per flow. 35 36 uint32_t TotalAvailableKbps(); 37 // If the given flow is paused, its output is zero. 38 uint32_t AvailablePerFlowKbps(int flow_id); 39 40 private: 41 ChokeFilter* choke_filter_; 42 std::set<int> running_flows_; 43 }; 44 45 struct PlotInformation { PlotInformationPlotInformation46 PlotInformation() 47 : prefix(), 48 last_plot_ms(0), 49 time_ms(0), 50 value(0.0), 51 plot_interval_ms(0) {} 52 template <typename T> UpdatePlotInformation53 void Update(int64_t now_ms, T new_value) { 54 time_ms = now_ms; 55 value = static_cast<double>(new_value); 56 } 57 std::string prefix; 58 bool plot; 59 int64_t last_plot_ms; 60 int64_t time_ms; 61 double value; 62 int64_t plot_interval_ms; 63 }; 64 65 class MetricRecorder { 66 public: 67 MetricRecorder(const std::string algorithm_name, 68 int flow_id, 69 PacketSender* packet_sender, 70 LinkShare* link_share); 71 72 void SetPlotInformation(const std::vector<std::string>& prefixes, 73 bool plot_delay, 74 bool plot_loss); 75 76 template <typename T> 77 void PlotLine(int windows_id, 78 const std::string& prefix, 79 int64_t time_ms, 80 T y); 81 82 void PlotDynamics(int metric); 83 void PlotAllDynamics(); 84 85 void UpdateTimeMs(int64_t time_ms); 86 void UpdateThroughput(int64_t bitrate_kbps, size_t payload_size); 87 void UpdateSendingEstimateKbps(int64_t bitrate_kbps); 88 void UpdateDelayMs(int64_t delay_ms); 89 void UpdateLoss(float loss_ratio); 90 void UpdateObjective(); 91 92 void PlotThroughputHistogram(const std::string& title, 93 const std::string& bwe_name, 94 size_t num_flows, 95 int64_t extra_offset_ms, 96 const std::string optimum_id) const; 97 98 void PlotThroughputHistogram(const std::string& title, 99 const std::string& bwe_name, 100 size_t num_flows, 101 int64_t extra_offset_ms) const; 102 103 void PlotDelayHistogram(const std::string& title, 104 const std::string& bwe_name, 105 size_t num_flows, 106 int64_t one_way_path_delay_ms) const; 107 108 void PlotLossHistogram(const std::string& title, 109 const std::string& bwe_name, 110 size_t num_flows, 111 float global_loss_ratio) const; 112 113 void PlotObjectiveHistogram(const std::string& title, 114 const std::string& bwe_name, 115 size_t num_flows) const; 116 set_start_computing_metrics_ms(int64_t start_computing_metrics_ms)117 void set_start_computing_metrics_ms(int64_t start_computing_metrics_ms) { 118 start_computing_metrics_ms_ = start_computing_metrics_ms; 119 } 120 set_plot_available_capacity(bool plot)121 void set_plot_available_capacity(bool plot) { 122 plot_information_[kTotalAvailable].plot = plot; 123 } 124 125 void PauseFlow(); // Plot zero. 126 void ResumeFlow(int64_t paused_time_ms); // Plot zero. 127 void PlotZero(); 128 129 private: 130 FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, NoPackets); 131 FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, RegularPackets); 132 FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, VariableDelayPackets); 133 134 uint32_t GetTotalAvailableKbps(); 135 uint32_t GetAvailablePerFlowKbps(); 136 uint32_t GetSendingEstimateKbps(); 137 double ObjectiveFunction() const; 138 139 double Renormalize(double x) const; 140 bool ShouldRecord(int64_t arrival_time_ms); 141 142 void PushDelayMs(int64_t delay_ms, int64_t arrival_time_ms); 143 void PushThroughputBytes(size_t throughput_bytes, int64_t arrival_time_ms); 144 145 void UpdateEstimateError(int64_t new_value); 146 double DelayStdDev() const; 147 int64_t NthDelayPercentile(int n) const; 148 double AverageBitrateKbps(int64_t extra_offset_ms) const; 149 int64_t RunDurationMs(int64_t extra_offset_ms) const; 150 151 enum Metrics { 152 kThroughput = 0, 153 kSendingEstimate, 154 kDelay, 155 kLoss, 156 kObjective, 157 kTotalAvailable, 158 kAvailablePerFlow, 159 kNumMetrics 160 }; 161 162 std::string algorithm_name_; 163 int flow_id_; 164 LinkShare* link_share_; 165 166 int64_t now_ms_; 167 168 PlotInformation plot_information_[kNumMetrics]; 169 170 int64_t sum_delays_ms_; 171 // delay_histogram_ms_[i] counts how many packets have delay = i ms. 172 std::map<int64_t, size_t> delay_histogram_ms_; 173 int64_t sum_delays_square_ms2_; // Used to compute standard deviation. 174 size_t sum_throughput_bytes_; 175 // ((Receiving rate - available bitrate per flow) * time window)^p. 176 // 0 for negative values, 1 for positive values. 177 int64_t sum_lp_weighted_estimate_error_[2]; 178 int64_t last_unweighted_estimate_error_; 179 int64_t optimal_throughput_bits_; 180 int64_t last_available_bitrate_per_flow_kbps_; 181 int64_t start_computing_metrics_ms_; 182 bool started_computing_metrics_; 183 size_t num_packets_received_; 184 }; 185 186 } // namespace bwe 187 } // namespace testing 188 } // namespace webrtc 189 #endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_ 190