1 /*
2 * Copyright (c) 2019 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 #include "modules/congestion_controller/goog_cc/robust_throughput_estimator.h"
12
13 #include "api/transport/field_trial_based_config.h"
14 #include "test/field_trial.h"
15 #include "test/gtest.h"
16
17 namespace webrtc {
18 namespace {
CreateFeedbackVector(size_t number_of_packets,DataSize packet_size,TimeDelta send_increment,TimeDelta recv_increment,Timestamp * send_clock,Timestamp * recv_clock,uint16_t * sequence_number)19 std::vector<PacketResult> CreateFeedbackVector(size_t number_of_packets,
20 DataSize packet_size,
21 TimeDelta send_increment,
22 TimeDelta recv_increment,
23 Timestamp* send_clock,
24 Timestamp* recv_clock,
25 uint16_t* sequence_number) {
26 std::vector<PacketResult> packet_feedback_vector(number_of_packets);
27 for (size_t i = 0; i < number_of_packets; i++) {
28 packet_feedback_vector[i].receive_time = *recv_clock;
29 packet_feedback_vector[i].sent_packet.send_time = *send_clock;
30 packet_feedback_vector[i].sent_packet.sequence_number = *sequence_number;
31 packet_feedback_vector[i].sent_packet.size = packet_size;
32 *send_clock += send_increment;
33 *recv_clock += recv_increment;
34 *sequence_number += 1;
35 }
36 return packet_feedback_vector;
37 }
38 } // anonymous namespace
39
TEST(RobustThroughputEstimatorTest,SteadyRate)40 TEST(RobustThroughputEstimatorTest, SteadyRate) {
41 webrtc::test::ScopedFieldTrials field_trials(
42 "WebRTC-Bwe-RobustThroughputEstimatorSettings/"
43 "enabled:true,assume_shared_link:false,reduce_bias:true,min_packets:10,"
44 "window_duration:100ms/");
45 FieldTrialBasedConfig field_trial_config;
46 RobustThroughputEstimatorSettings settings(&field_trial_config);
47 RobustThroughputEstimator throughput_estimator(settings);
48 DataSize packet_size(DataSize::Bytes(1000));
49 Timestamp send_clock(Timestamp::Millis(100000));
50 Timestamp recv_clock(Timestamp::Millis(10000));
51 TimeDelta send_increment(TimeDelta::Millis(10));
52 TimeDelta recv_increment(TimeDelta::Millis(10));
53 uint16_t sequence_number = 100;
54 std::vector<PacketResult> packet_feedback =
55 CreateFeedbackVector(9, packet_size, send_increment, recv_increment,
56 &send_clock, &recv_clock, &sequence_number);
57 throughput_estimator.IncomingPacketFeedbackVector(packet_feedback);
58 EXPECT_FALSE(throughput_estimator.bitrate().has_value());
59
60 packet_feedback =
61 CreateFeedbackVector(11, packet_size, send_increment, recv_increment,
62 &send_clock, &recv_clock, &sequence_number);
63 throughput_estimator.IncomingPacketFeedbackVector(packet_feedback);
64 auto throughput = throughput_estimator.bitrate();
65 EXPECT_TRUE(throughput.has_value());
66 EXPECT_NEAR(throughput.value().bytes_per_sec<double>(), 100 * 1000.0,
67 0.05 * 100 * 1000.0); // Allow 5% error
68 }
69
TEST(RobustThroughputEstimatorTest,DelaySpike)70 TEST(RobustThroughputEstimatorTest, DelaySpike) {
71 webrtc::test::ScopedFieldTrials field_trials(
72 "WebRTC-Bwe-RobustThroughputEstimatorSettings/"
73 "enabled:true,assume_shared_link:false,reduce_bias:true,min_packets:10,"
74 "window_duration:100ms/");
75 FieldTrialBasedConfig field_trial_config;
76 RobustThroughputEstimatorSettings settings(&field_trial_config);
77 RobustThroughputEstimator throughput_estimator(settings);
78 DataSize packet_size(DataSize::Bytes(1000));
79 Timestamp send_clock(Timestamp::Millis(100000));
80 Timestamp recv_clock(Timestamp::Millis(10000));
81 TimeDelta send_increment(TimeDelta::Millis(10));
82 TimeDelta recv_increment(TimeDelta::Millis(10));
83 uint16_t sequence_number = 100;
84 std::vector<PacketResult> packet_feedback =
85 CreateFeedbackVector(20, packet_size, send_increment, recv_increment,
86 &send_clock, &recv_clock, &sequence_number);
87 throughput_estimator.IncomingPacketFeedbackVector(packet_feedback);
88 auto throughput = throughput_estimator.bitrate();
89 EXPECT_TRUE(throughput.has_value());
90 EXPECT_NEAR(throughput.value().bytes_per_sec<double>(), 100 * 1000.0,
91 0.05 * 100 * 1000.0); // Allow 5% error
92
93 // Delay spike
94 recv_clock += TimeDelta::Millis(40);
95
96 // Faster delivery after the gap
97 recv_increment = TimeDelta::Millis(2);
98 packet_feedback =
99 CreateFeedbackVector(5, packet_size, send_increment, recv_increment,
100 &send_clock, &recv_clock, &sequence_number);
101 throughput_estimator.IncomingPacketFeedbackVector(packet_feedback);
102 throughput = throughput_estimator.bitrate();
103 EXPECT_TRUE(throughput.has_value());
104 EXPECT_NEAR(throughput.value().bytes_per_sec<double>(), 100 * 1000.0,
105 0.05 * 100 * 1000.0); // Allow 5% error
106
107 // Delivery at normal rate. This will be capped by the send rate.
108 recv_increment = TimeDelta::Millis(10);
109 packet_feedback =
110 CreateFeedbackVector(5, packet_size, send_increment, recv_increment,
111 &send_clock, &recv_clock, &sequence_number);
112 throughput_estimator.IncomingPacketFeedbackVector(packet_feedback);
113 throughput = throughput_estimator.bitrate();
114 EXPECT_TRUE(throughput.has_value());
115 EXPECT_NEAR(throughput.value().bytes_per_sec<double>(), 100 * 1000.0,
116 0.05 * 100 * 1000.0); // Allow 5% error
117 }
118
TEST(RobustThroughputEstimatorTest,CappedByReceiveRate)119 TEST(RobustThroughputEstimatorTest, CappedByReceiveRate) {
120 webrtc::test::ScopedFieldTrials field_trials(
121 "WebRTC-Bwe-RobustThroughputEstimatorSettings/"
122 "enabled:true,assume_shared_link:false,reduce_bias:true,min_packets:10,"
123 "window_duration:100ms/");
124 FieldTrialBasedConfig field_trial_config;
125 RobustThroughputEstimatorSettings settings(&field_trial_config);
126 RobustThroughputEstimator throughput_estimator(settings);
127 DataSize packet_size(DataSize::Bytes(1000));
128 Timestamp send_clock(Timestamp::Millis(100000));
129 Timestamp recv_clock(Timestamp::Millis(10000));
130 TimeDelta send_increment(TimeDelta::Millis(10));
131 TimeDelta recv_increment(TimeDelta::Millis(40));
132 uint16_t sequence_number = 100;
133 std::vector<PacketResult> packet_feedback =
134 CreateFeedbackVector(20, packet_size, send_increment, recv_increment,
135 &send_clock, &recv_clock, &sequence_number);
136 throughput_estimator.IncomingPacketFeedbackVector(packet_feedback);
137 auto throughput = throughput_estimator.bitrate();
138 EXPECT_TRUE(throughput.has_value());
139 EXPECT_NEAR(throughput.value().bytes_per_sec<double>(), 25 * 1000.0,
140 0.05 * 25 * 1000.0); // Allow 5% error
141 }
142
TEST(RobustThroughputEstimatorTest,CappedBySendRate)143 TEST(RobustThroughputEstimatorTest, CappedBySendRate) {
144 webrtc::test::ScopedFieldTrials field_trials(
145 "WebRTC-Bwe-RobustThroughputEstimatorSettings/"
146 "enabled:true,assume_shared_link:false,reduce_bias:true,min_packets:10,"
147 "window_duration:100ms/");
148 FieldTrialBasedConfig field_trial_config;
149 RobustThroughputEstimatorSettings settings(&field_trial_config);
150 RobustThroughputEstimator throughput_estimator(settings);
151 DataSize packet_size(DataSize::Bytes(1000));
152 Timestamp send_clock(Timestamp::Millis(100000));
153 Timestamp recv_clock(Timestamp::Millis(10000));
154 TimeDelta send_increment(TimeDelta::Millis(20));
155 TimeDelta recv_increment(TimeDelta::Millis(10));
156 uint16_t sequence_number = 100;
157 std::vector<PacketResult> packet_feedback =
158 CreateFeedbackVector(20, packet_size, send_increment, recv_increment,
159 &send_clock, &recv_clock, &sequence_number);
160 throughput_estimator.IncomingPacketFeedbackVector(packet_feedback);
161 auto throughput = throughput_estimator.bitrate();
162 EXPECT_TRUE(throughput.has_value());
163 EXPECT_NEAR(throughput.value().bytes_per_sec<double>(), 50 * 1000.0,
164 0.05 * 50 * 1000.0); // Allow 5% error
165 }
166
167 } // namespace webrtc*/
168