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