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