aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/remote_bitrate_estimator/test/metric_recorder.h
blob: 2be13e0b0b7249ef90f65e739580247922d43931 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_

#include <map>
#include <set>
#include <string>
#include <vector>

#include "webrtc/base/common.h"
#include "webrtc/test/testsupport/gtest_prod_util.h"

namespace webrtc {
namespace testing {
namespace bwe {

class ChokeFilter;
class PacketSender;

class LinkShare {
 public:
  explicit LinkShare(ChokeFilter* choke_filter);

  void PauseFlow(int flow_id);   // Increases available capacity per flow.
  void ResumeFlow(int flow_id);  // Decreases available capacity per flow.

  uint32_t TotalAvailableKbps();
  // If the given flow is paused, its output is zero.
  uint32_t AvailablePerFlowKbps(int flow_id);

 private:
  ChokeFilter* choke_filter_;
  std::set<int> running_flows_;
};

struct PlotInformation {
  PlotInformation()
      : prefix(),
        last_plot_ms(0),
        time_ms(0),
        value(0.0),
        plot_interval_ms(0) {}
  template <typename T>
  void Update(int64_t now_ms, T new_value) {
    time_ms = now_ms;
    value = static_cast<double>(new_value);
  }
  std::string prefix;
  bool plot;
  int64_t last_plot_ms;
  int64_t time_ms;
  double value;
  int64_t plot_interval_ms;
};

class MetricRecorder {
 public:
  MetricRecorder(const std::string algorithm_name,
                 int flow_id,
                 PacketSender* packet_sender,
                 LinkShare* link_share);

  void SetPlotInformation(const std::vector<std::string>& prefixes,
                          bool plot_delay,
                          bool plot_loss);

  template <typename T>
  void PlotLine(int windows_id,
                const std::string& prefix,
                int64_t time_ms,
                T y);

  void PlotDynamics(int metric);
  void PlotAllDynamics();

  void UpdateTimeMs(int64_t time_ms);
  void UpdateThroughput(int64_t bitrate_kbps, size_t payload_size);
  void UpdateSendingEstimateKbps(int64_t bitrate_kbps);
  void UpdateDelayMs(int64_t delay_ms);
  void UpdateLoss(float loss_ratio);
  void UpdateObjective();

  void PlotThroughputHistogram(const std::string& title,
                               const std::string& bwe_name,
                               size_t num_flows,
                               int64_t extra_offset_ms,
                               const std::string optimum_id) const;

  void PlotThroughputHistogram(const std::string& title,
                               const std::string& bwe_name,
                               size_t num_flows,
                               int64_t extra_offset_ms) const;

  void PlotDelayHistogram(const std::string& title,
                          const std::string& bwe_name,
                          size_t num_flows,
                          int64_t one_way_path_delay_ms) const;

  void PlotLossHistogram(const std::string& title,
                         const std::string& bwe_name,
                         size_t num_flows,
                         float global_loss_ratio) const;

  void PlotObjectiveHistogram(const std::string& title,
                              const std::string& bwe_name,
                              size_t num_flows) const;

  void set_start_computing_metrics_ms(int64_t start_computing_metrics_ms) {
    start_computing_metrics_ms_ = start_computing_metrics_ms;
  }

  void set_plot_available_capacity(bool plot) {
    plot_information_[kTotalAvailable].plot = plot;
  }

  void PauseFlow();                         // Plot zero.
  void ResumeFlow(int64_t paused_time_ms);  // Plot zero.
  void PlotZero();

 private:
  FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, NoPackets);
  FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, RegularPackets);
  FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, VariableDelayPackets);

  uint32_t GetTotalAvailableKbps();
  uint32_t GetAvailablePerFlowKbps();
  uint32_t GetSendingEstimateKbps();
  double ObjectiveFunction() const;

  double Renormalize(double x) const;
  bool ShouldRecord(int64_t arrival_time_ms);

  void PushDelayMs(int64_t delay_ms, int64_t arrival_time_ms);
  void PushThroughputBytes(size_t throughput_bytes, int64_t arrival_time_ms);

  void UpdateEstimateError(int64_t new_value);
  double DelayStdDev() const;
  int64_t NthDelayPercentile(int n) const;
  double AverageBitrateKbps(int64_t extra_offset_ms) const;
  int64_t RunDurationMs(int64_t extra_offset_ms) const;

  enum Metrics {
    kThroughput = 0,
    kSendingEstimate,
    kDelay,
    kLoss,
    kObjective,
    kTotalAvailable,
    kAvailablePerFlow,
    kNumMetrics
  };

  std::string algorithm_name_;
  int flow_id_;
  LinkShare* link_share_;

  int64_t now_ms_;

  PlotInformation plot_information_[kNumMetrics];

  int64_t sum_delays_ms_;
  // delay_histogram_ms_[i] counts how many packets have delay = i ms.
  std::map<int64_t, size_t> delay_histogram_ms_;
  int64_t sum_delays_square_ms2_;  // Used to compute standard deviation.
  size_t sum_throughput_bytes_;
  // ((Receiving rate - available bitrate per flow) * time window)^p.
  // 0 for negative values, 1 for positive values.
  int64_t sum_lp_weighted_estimate_error_[2];
  int64_t last_unweighted_estimate_error_;
  int64_t optimal_throughput_bits_;
  int64_t last_available_bitrate_per_flow_kbps_;
  int64_t start_computing_metrics_ms_;
  bool started_computing_metrics_;
  size_t num_packets_received_;
};

}  // namespace bwe
}  // namespace testing
}  // namespace webrtc
#endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_