Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: webrtc/modules/remote_bitrate_estimator/test/packet_receiver.cc

Issue 1202253003: More Simulation Framework features (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressing trybot failures Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 13 matching lines...) Expand all
24 namespace webrtc { 24 namespace webrtc {
25 namespace testing { 25 namespace testing {
26 namespace bwe { 26 namespace bwe {
27 27
28 PacketReceiver::PacketReceiver(PacketProcessorListener* listener, 28 PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
29 int flow_id, 29 int flow_id,
30 BandwidthEstimatorType bwe_type, 30 BandwidthEstimatorType bwe_type,
31 bool plot_delay, 31 bool plot_delay,
32 bool plot_bwe) 32 bool plot_bwe)
33 : PacketProcessor(listener, flow_id, kReceiver), 33 : PacketProcessor(listener, flow_id, kReceiver),
34 now_ms_(0),
34 delay_log_prefix_(), 35 delay_log_prefix_(),
35 metric_log_prefix_(), 36 metric_log_prefix_(),
36 packet_loss_log_prefix_(), 37 packet_loss_log_prefix_(),
38 available_capacity_log_prefix_(),
39 throughput_log_prefix_(),
37 last_delay_plot_ms_(0), 40 last_delay_plot_ms_(0),
41 last_throughput_plot_ms_(0),
38 last_metric_plot_ms_(0), 42 last_metric_plot_ms_(0),
39 last_packet_loss_plot_ms_(0), 43 last_packet_loss_plot_ms_(0),
44 last_total_capacity_plot_ms_(0),
45 last_per_flow_capacity_plot_ms_(0),
40 plot_delay_(plot_delay), 46 plot_delay_(plot_delay),
41 // TODO(magalhaesc) Add separated plot_objective_function and 47 // TODO(magalhaesc): Add following bool parameters to the constructor.
42 // plot_packet_loss parameters to the constructor. 48 plot_throughput_(true),
43 plot_objective_function_(plot_delay), 49 plot_objective_function_(false),
44 plot_packet_loss_(plot_delay), 50 plot_packet_loss_(true),
51 plot_total_available_capacity_(true),
52 plot_available_capacity_per_flow_(false),
45 bwe_receiver_(CreateBweReceiver(bwe_type, flow_id, plot_bwe)), 53 bwe_receiver_(CreateBweReceiver(bwe_type, flow_id, plot_bwe)),
46 total_delay_ms_(0), 54 delays_ms_(),
47 total_throughput_(0), 55 throughput_bytes_(),
48 number_packets_(0) { 56 weighted_estimate_error_(),
57 last_unweighted_estimate_error_(0),
58 optimal_throughput_bits_(0),
59 last_total_available_bitrate_kbps_(0),
60 last_available_bitrate_per_flow_kbps_(0),
61 start_computing_metrics_ms_(0),
62 started_computing_metrics_(false),
63 alg_name_(bwe_names[bwe_type]) {
49 // Setup the prefix ststd::rings used when logging. 64 // Setup the prefix ststd::rings used when logging.
50 std::stringstream ss1; 65 std::stringstream ss1;
51 ss1 << "Delay_" << flow_id << "#2"; 66 ss1 << "Delay_ms_" << flow_id << "#2";
52 delay_log_prefix_ = ss1.str(); 67 delay_log_prefix_ = ss1.str();
53 68
54 std::stringstream ss2; 69 std::stringstream ss2;
55 ss2 << "Objective_function_" << flow_id << "#2"; 70 ss2 << "Objective_function_" << flow_id << "#2";
56 metric_log_prefix_ = ss2.str(); 71 metric_log_prefix_ = ss2.str();
57 72
58 std::stringstream ss3; 73 std::stringstream ss3;
59 ss3 << "Packet_Loss_" << flow_id << "#2"; 74 ss3 << "Packet_Loss_" << flow_id << "#2";
60 packet_loss_log_prefix_ = ss3.str(); 75 packet_loss_log_prefix_ = ss3.str();
76
77 // Plot Available capacity together with throughputs.
78 std::stringstream ss4;
79 ss4 << "Throughput_kbps" << flow_id << "#1";
80 available_capacity_log_prefix_ = ss4.str();
81
82 std::stringstream ss5;
83 ss5 << "Throughput_kbps_" << flow_id << "#2";
84 throughput_log_prefix_ = ss5.str();
61 } 85 }
62 86
63 PacketReceiver::~PacketReceiver() { 87 PacketReceiver::~PacketReceiver() {
64 } 88 }
65 89
66 void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) { 90 void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) {
67 Packets feedback; 91 Packets feedback;
68 for (auto it = in_out->begin(); it != in_out->end();) { 92 for (auto it = in_out->begin(); it != in_out->end();) {
69 // PacketReceivers are only associated with a single stream, and therefore 93 // PacketReceivers are only associated with a single stream, and therefore
70 // should only process a single flow id. 94 // should only process a single flow id.
71 // TODO(holmer): Break this out into a Demuxer which implements both 95 // TODO(holmer): Break this out into a Demuxer which implements both
72 // PacketProcessorListener and PacketProcessor. 96 // PacketProcessorListener and PacketProcessor.
73 BWE_TEST_LOGGING_CONTEXT("Receiver"); 97 BWE_TEST_LOGGING_CONTEXT("Receiver");
74 if ((*it)->GetPacketType() == Packet::kMedia && 98 if ((*it)->GetPacketType() == Packet::kMedia &&
75 (*it)->flow_id() == *flow_ids().begin()) { 99 (*it)->flow_id() == *flow_ids().begin()) {
76 BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin()); 100 BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin());
77 const MediaPacket* media_packet = static_cast<const MediaPacket*>(*it); 101 const MediaPacket* media_packet = static_cast<const MediaPacket*>(*it);
78 // We're treating the send time (from previous filter) as the arrival 102 // We're treating the send time (from previous filter) as the arrival
79 // time once packet reaches the estimator. 103 // time once packet reaches the estimator.
80 int64_t arrival_time_ms = (media_packet->send_time_us() + 500) / 1000; 104 int64_t arrival_time_ms = (media_packet->send_time_us() + 500) / 1000;
81 int64_t send_time_ms = (media_packet->creation_time_us() + 500) / 1000; 105 int64_t send_time_ms = (media_packet->creation_time_us() + 500) / 1000;
82 delay_stats_.Push(arrival_time_ms - send_time_ms); 106 delay_stats_.Push(arrival_time_ms - send_time_ms);
83 PlotDelay(arrival_time_ms, send_time_ms); 107 PlotDelay(arrival_time_ms, send_time_ms);
108 PlotThroughput(arrival_time_ms);
109 PlotTotalAvailableCapacity(arrival_time_ms);
110 PlotAvailableCapacityPerFlow(arrival_time_ms);
84 PlotObjectiveFunction(arrival_time_ms); 111 PlotObjectiveFunction(arrival_time_ms);
85 PlotPacketLoss(arrival_time_ms); 112 PlotPacketLoss(arrival_time_ms);
86 113
87 total_delay_ms_ += arrival_time_ms - send_time_ms; 114 int64_t current_capacity_per_flow_kbps =
88 total_throughput_ += media_packet->payload_size(); 115 static_cast<int64_t>(media_packet->get_capacity_per_flow_kbps());
89 ++number_packets_; 116
117 if (arrival_time_ms >= start_computing_metrics_ms_) {
118 if (!started_computing_metrics_) {
119 start_computing_metrics_ms_ = arrival_time_ms;
120 now_ms_ = arrival_time_ms;
121 started_computing_metrics_ = true;
122 }
123
124 delays_ms_.push_back(arrival_time_ms - send_time_ms);
125 throughput_bytes_.push_back(media_packet->payload_size());
126
127 int64_t current_bitrate_diff_kbps =
128 static_cast<int64_t>(media_packet->get_sending_estimate_kbps()) -
129 current_capacity_per_flow_kbps;
130
131 // now_ms_ was still not updated here.
132 weighted_estimate_error_.push_back(
133 ((current_bitrate_diff_kbps + last_unweighted_estimate_error_) *
134 (arrival_time_ms - now_ms_)) /
135 2);
136
137 optimal_throughput_bits_ += ((current_capacity_per_flow_kbps +
138 last_available_bitrate_per_flow_kbps_) *
139 (arrival_time_ms - now_ms_)) /
140 2;
141
142 last_unweighted_estimate_error_ = current_bitrate_diff_kbps;
143 }
144
145 last_available_bitrate_per_flow_kbps_ = current_capacity_per_flow_kbps;
146 last_total_available_bitrate_kbps_ =
147 media_packet->get_total_capacity_kbps();
148
149 now_ms_ = std::max(now_ms_, arrival_time_ms);
stefan-webrtc 2015/06/25 14:44:05 Break this plotting stuff out to a method.
magalhaesc 2015/07/01 12:48:40 Done, moved to MetricRecorder
90 150
91 bwe_receiver_->ReceivePacket(arrival_time_ms, *media_packet); 151 bwe_receiver_->ReceivePacket(arrival_time_ms, *media_packet);
92 FeedbackPacket* fb = bwe_receiver_->GetFeedback(arrival_time_ms); 152 FeedbackPacket* fb = bwe_receiver_->GetFeedback(arrival_time_ms);
93 if (fb) 153 if (fb)
94 feedback.push_back(fb); 154 feedback.push_back(fb);
95 delete media_packet; 155 delete media_packet;
96 it = in_out->erase(it); 156 it = in_out->erase(it);
97 } else { 157 } else {
98 ++it; 158 ++it;
99 } 159 }
100 } 160 }
101 // Insert feedback packets to be sent back to the sender. 161 // Insert feedback packets to be sent back to the sender.
102 in_out->merge(feedback, DereferencingComparator<Packet>); 162 in_out->merge(feedback, DereferencingComparator<Packet>);
103 } 163 }
104 164
105 void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) { 165 void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) {
106 static const int kDelayPlotIntervalMs = 100; 166 static const int kDelayPlotIntervalMs = 100;
107 if (!plot_delay_) 167 if (!plot_delay_)
108 return; 168 return;
109 if (arrival_time_ms - last_delay_plot_ms_ > kDelayPlotIntervalMs) { 169 if (arrival_time_ms - last_delay_plot_ms_ > kDelayPlotIntervalMs) {
110 BWE_TEST_LOGGING_PLOT(0, delay_log_prefix_, arrival_time_ms, 170 BWE_TEST_LOGGING_PLOT_WITH_NAME(0, delay_log_prefix_, arrival_time_ms,
111 arrival_time_ms - send_time_ms); 171 arrival_time_ms - send_time_ms, alg_name_);
112 last_delay_plot_ms_ = arrival_time_ms; 172 last_delay_plot_ms_ = arrival_time_ms;
113 } 173 }
114 } 174 }
115 175
176 void PacketReceiver::PlotThroughput(int64_t arrival_time_ms) {
177 static const int kThroughputPlotIntervalMs = 1000;
178 if (!plot_throughput_)
179 return;
180 if (arrival_time_ms - last_throughput_plot_ms_ > kThroughputPlotIntervalMs) {
181 BWE_TEST_LOGGING_PLOT_WITH_NAME(0, throughput_log_prefix_, arrival_time_ms,
182 bwe_receiver_->RecentKbps(), alg_name_);
183 last_throughput_plot_ms_ = arrival_time_ms;
184 }
185 }
186
187 void PacketReceiver::PlotTotalAvailableCapacity(int64_t arrival_time_ms) {
188 static const int kAvailableCapacityPerFlowMs = 1000;
189 if (!plot_total_available_capacity_)
190 return;
191 if (arrival_time_ms - last_total_capacity_plot_ms_ >
192 kAvailableCapacityPerFlowMs) {
193 BWE_TEST_LOGGING_PLOT_WITH_NAME(
194 0, available_capacity_log_prefix_, arrival_time_ms,
195 last_total_available_bitrate_kbps_, "Available");
196 last_total_capacity_plot_ms_ = arrival_time_ms;
197 }
198 }
199
200 void PacketReceiver::PlotAvailableCapacityPerFlow(int64_t arrival_time_ms) {
201 static const int kAvailableCapacityPerFlowMs = 1000;
202 if (!plot_available_capacity_per_flow_)
203 return;
204 if (arrival_time_ms - last_per_flow_capacity_plot_ms_ >
205 kAvailableCapacityPerFlowMs) {
206 BWE_TEST_LOGGING_PLOT_WITH_NAME(
207 0, available_capacity_log_prefix_, arrival_time_ms,
208 last_available_bitrate_per_flow_kbps_, "Available_per_flow");
209 last_per_flow_capacity_plot_ms_ = arrival_time_ms;
210 }
211 }
212
213 template <typename T>
stefan-webrtc 2015/06/25 14:44:05 All of these methods should go in the beginning an
magalhaesc 2015/07/01 12:48:40 Done, moved to MetricReceiver
214 inline T Sum(std::vector<T>& input) {
stefan-webrtc 2015/06/25 14:44:05 No need for inline.
magalhaesc 2015/07/01 12:48:40 Done.
215 T total = 0;
216 for (auto it = input.begin(); it != input.end(); ++it) {
217 total += *it;
218 }
219 return total;
220 }
221
222 template <typename T>
223 inline double Average(std::vector<T>& array, size_t size) {
224 return static_cast<double>(Sum(array)) / size;
225 }
226
227 template <typename T>
228 inline std::vector<T> Abs(std::vector<T>& input) {
229 std::vector<T> output;
230 for (auto it = input.begin(); it != input.end(); ++it) {
231 output.push_back(std::abs(*it));
232 }
233 return output;
234 }
235
236 template <typename T>
237 inline std::vector<double> Pow(std::vector<T>& input, double p) {
238 std::vector<double> output;
239 for (auto it = input.begin(); it != input.end(); ++it) {
240 output.push_back(pow(static_cast<double>(*it), p));
241 }
242 return output;
243 }
244
245 template <typename T>
246 inline double StandardDeviation(std::vector<T>& array, size_t size) {
247 double mean = Average(array, size);
248 std::vector<double> square_values = Pow(array, 2.0);
249 double var = Average(square_values, size) - mean * mean;
250 return sqrt(var);
251 }
252
253 // Holder mean, Manhattan distance for p=1, EuclidianNorm/sqrt(n) for p=2.
254 template <typename T>
255 inline double NormLp(std::vector<T>& array, size_t size, double p) {
256 std::vector<T> abs_values = Abs(array);
257 std::vector<double> pow_values = Pow(abs_values, p);
258 return pow(Sum(pow_values) / size, 1.0 / p);
259 }
260
261 template <typename T>
262 inline std::vector<T> PositiveFilter(std::vector<T>& input) {
263 std::vector<T> output(input);
264 for (auto it = output.begin(); it != output.end(); ++it) {
265 (*it) = (*it) > 0 ? (*it) : 0;
266 }
267 return output;
268 }
269
270 template <typename T>
271 inline std::vector<T> NegativeFilter(std::vector<T>& input) {
272 std::vector<T> output(input);
273 for (auto it = output.begin(); it != output.end(); ++it) {
274 (*it) = (*it) < 0 ? -(*it) : 0;
275 }
276 return output;
277 }
278
279 // The weighted_estimate_error_ was weighted based on time windows.
280 // This function scales back the result before plotting.
281 double PacketReceiver::Renormalize(double x) {
282 size_t num_packets_received = delays_ms_.size();
283 return (x * num_packets_received) / now_ms_;
284 }
285
286 inline double U(int64_t x, double alpha) {
287 if (alpha == 1.0) {
288 return log(static_cast<double>(x));
289 }
290 return pow(static_cast<double>(x), 1.0 - alpha) / (1.0 - alpha);
291 }
292
293 inline double U(size_t x, double alpha) {
294 return U(static_cast<int64_t>(x), alpha);
295 }
296
297 // TODO(magalhaesc): Update ObjectiveFunction.
116 double PacketReceiver::ObjectiveFunction() { 298 double PacketReceiver::ObjectiveFunction() {
stefan-webrtc 2015/06/25 14:44:05 Not sure we ended up using this? Maybe better to r
magalhaesc 2015/07/01 12:48:40 They are now in the MetricRecorder file, so separa
117 const double kDelta = 1.0; // Delay penalty factor. 299 const double kDelta = 0.15; // Delay penalty factor.
118 double throughput_metric = log(static_cast<double>(total_throughput_)); 300 const double kAlpha = 1.0;
119 double delay_penalty = kDelta * log(static_cast<double>(total_delay_ms_)); 301 const double kBeta = 1.0;
302
303 double throughput_metric = U(Sum(throughput_bytes_), kAlpha);
304 double delay_penalty = kDelta * U(Sum(delays_ms_), kBeta);
305
120 return throughput_metric - delay_penalty; 306 return throughput_metric - delay_penalty;
121 } 307 }
122 308
123 void PacketReceiver::PlotObjectiveFunction(int64_t arrival_time_ms) { 309 void PacketReceiver::PlotObjectiveFunction(int64_t arrival_time_ms) {
124 static const int kMetricPlotIntervalMs = 1000; 310 static const int kMetricPlotIntervalMs = 1000;
125 if (!plot_objective_function_) { 311 if (!plot_objective_function_) {
126 return; 312 return;
127 } 313 }
128 if (arrival_time_ms - last_metric_plot_ms_ > kMetricPlotIntervalMs) { 314 if (arrival_time_ms - last_metric_plot_ms_ > kMetricPlotIntervalMs) {
129 BWE_TEST_LOGGING_PLOT(1, metric_log_prefix_, arrival_time_ms, 315 BWE_TEST_LOGGING_PLOT(1, metric_log_prefix_, arrival_time_ms,
130 ObjectiveFunction()); 316 ObjectiveFunction());
131 last_metric_plot_ms_ = arrival_time_ms; 317 last_metric_plot_ms_ = arrival_time_ms;
132 } 318 }
133 } 319 }
134 320
135 void PacketReceiver::PlotPacketLoss(int64_t arrival_time_ms) { 321 void PacketReceiver::PlotPacketLoss(int64_t arrival_time_ms) {
136 static const int kPacketLossPlotIntervalMs = 500; 322 static const int kPacketLossPlotIntervalMs = 500;
137 if (!plot_packet_loss_) { 323 if (!plot_packet_loss_) {
138 return; 324 return;
139 } 325 }
140 if (arrival_time_ms - last_packet_loss_plot_ms_ > kPacketLossPlotIntervalMs) { 326 if (arrival_time_ms - last_packet_loss_plot_ms_ > kPacketLossPlotIntervalMs) {
141 BWE_TEST_LOGGING_PLOT(2, packet_loss_log_prefix_, arrival_time_ms, 327 BWE_TEST_LOGGING_PLOT_WITH_NAME(
142 bwe_receiver_->RecentPacketLossRatio()); 328 2, "Recent_" + packet_loss_log_prefix_, arrival_time_ms,
329 bwe_receiver_->RecentPacketLossRatio(), alg_name_);
143 last_packet_loss_plot_ms_ = arrival_time_ms; 330 last_packet_loss_plot_ms_ = arrival_time_ms;
144 } 331 }
145 } 332 }
146 333
334 void PacketReceiver::PlotThroughputHistogram(const std::string& title,
335 const std::string& bwe_name,
336 int num_flows,
337 int64_t extra_offset_ms,
338 const std::string optimum_id) {
339 size_t num_packets_received = delays_ms_.size();
340
341 int64_t duration_ms = now_ms_ - start_computing_metrics_ms_ - extra_offset_ms;
342
343 double average_bitrate_kbps =
344 static_cast<double>(8 * Sum(throughput_bytes_) / duration_ms);
345
346 double optimal_bitrate_per_flow_kbps =
347 static_cast<double>(optimal_throughput_bits_ / duration_ms);
348
349 std::vector<int64_t> positive = PositiveFilter(weighted_estimate_error_);
350 std::vector<int64_t> negative = NegativeFilter(weighted_estimate_error_);
351
352 double p_error = Renormalize(NormLp(positive, num_packets_received, 1.0));
353 double n_error = Renormalize(NormLp(negative, num_packets_received, 1.0));
354
355 // Prevent the error to be too close to zero (plotting issue).
356 double extra_error = average_bitrate_kbps / 500;
357
358 std::string optimum_title =
359 optimum_id.empty() ? "optimal_bitrate" : "optimal_bitrates#" + optimum_id;
360
361 BWE_TEST_LOGGING_LABEL(4, title, "average_bitrate_(kbps)", num_flows);
362 BWE_TEST_LOGGING_LIMITERRORBAR(
363 4, bwe_name, average_bitrate_kbps,
364 average_bitrate_kbps - n_error - extra_error,
365 average_bitrate_kbps + p_error + extra_error, "estimate_error",
366 optimal_bitrate_per_flow_kbps, optimum_title, *flow_ids().begin());
367
368 // Silencing unused variable compiling error.
369 (void)p_error;
370 (void)n_error;
371 (void)extra_error;
372 (void)optimal_bitrate_per_flow_kbps;
stefan-webrtc 2015/06/25 14:44:05 RTC_UNUSED
magalhaesc 2015/07/01 12:48:40 Done.
373 }
374
375 void PacketReceiver::PlotThroughputHistogram(const std::string& title,
376 const std::string& bwe_name,
377 int num_flows,
378 int64_t extra_offset_ms) {
379 PlotThroughputHistogram(title, bwe_name, num_flows, extra_offset_ms, "");
380 }
381
382 void PacketReceiver::PlotDelayHistogram(const std::string& title,
383 const std::string& bwe_name,
384 int num_flows) {
385 size_t num_packets_received = delays_ms_.size();
386 double average_delay_ms = Average(delays_ms_, num_packets_received);
387
388 // Prevent the error to be too close to zero (plotting issue).
389 double extra_error = average_delay_ms / 500;
390
391 double tenth_sigma_ms =
392 StandardDeviation(delays_ms_, num_packets_received) / 10.0 + extra_error;
393
394 BWE_TEST_LOGGING_LABEL(5, title, "average_delay_(ms)", num_flows)
395 BWE_TEST_LOGGING_ERRORBAR(
396 5, bwe_name, average_delay_ms, average_delay_ms - tenth_sigma_ms,
397 average_delay_ms + tenth_sigma_ms, "sigma/10", *flow_ids().begin());
398
399 // Silencing unused variable compiling error.
400 (void)tenth_sigma_ms;
stefan-webrtc 2015/06/25 14:44:05 RTC_UNUSED
magalhaesc 2015/07/01 12:48:40 Done.
401 }
402
403 void PacketReceiver::PlotLossHistogram(const std::string& title,
404 const std::string& bwe_name,
405 int num_flows) {
406 BWE_TEST_LOGGING_LABEL(6, title, "packet_loss_ratio_(%)", num_flows)
407 BWE_TEST_LOGGING_BAR(6, bwe_name,
408 100.0f * bwe_receiver_->GlobalReceiverPacketLossRatio(),
409 *flow_ids().begin());
410 }
411
412 void PacketReceiver::PlotObjectiveHistogram(const std::string& title,
413 const std::string& bwe_name,
414 int num_flows) {
415 BWE_TEST_LOGGING_LABEL(7, title, "objective_function", num_flows)
416 BWE_TEST_LOGGING_BAR(7, bwe_name, ObjectiveFunction(), *flow_ids().begin());
417 }
418
147 Stats<double> PacketReceiver::GetDelayStats() const { 419 Stats<double> PacketReceiver::GetDelayStats() const {
148 return delay_stats_; 420 return delay_stats_;
149 } 421 }
150 } // namespace bwe 422 } // namespace bwe
151 } // namespace testing 423 } // namespace testing
152 } // namespace webrtc 424 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698