receive_side_congestion_controller_unittest.cc (9178B)
1 /* 2 * Copyright (c) 2016 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/include/receive_side_congestion_controller.h" 12 13 #include <cstdint> 14 #include <memory> 15 #include <vector> 16 17 #include "api/environment/environment_factory.h" 18 #include "api/field_trials.h" 19 #include "api/media_types.h" 20 #include "api/test/network_emulation/create_cross_traffic.h" 21 #include "api/test/network_emulation/cross_traffic.h" 22 #include "api/units/data_rate.h" 23 #include "api/units/data_size.h" 24 #include "api/units/time_delta.h" 25 #include "api/units/timestamp.h" 26 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" 27 #include "modules/rtp_rtcp/source/rtcp_packet.h" 28 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h" 29 #include "modules/rtp_rtcp/source/rtcp_packet/congestion_control_feedback.h" 30 #include "modules/rtp_rtcp/source/rtp_header_extensions.h" 31 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 32 #include "rtc_base/buffer.h" 33 #include "system_wrappers/include/clock.h" 34 #include "test/create_test_field_trials.h" 35 #include "test/gmock.h" 36 #include "test/gtest.h" 37 #include "test/scenario/scenario.h" 38 #include "test/scenario/scenario_config.h" 39 40 namespace webrtc { 41 namespace test { 42 namespace { 43 44 using ::testing::_; 45 using ::testing::AtLeast; 46 using ::testing::ElementsAre; 47 using ::testing::MockFunction; 48 using ::testing::SizeIs; 49 50 constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(60'000); 51 52 TEST(ReceiveSideCongestionControllerTest, SendsRembWithAbsSendTime) { 53 static constexpr DataSize kPayloadSize = DataSize::Bytes(1000); 54 MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)> 55 feedback_sender; 56 MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; 57 SimulatedClock clock(123456); 58 59 ReceiveSideCongestionController controller(CreateEnvironment(&clock), 60 feedback_sender.AsStdFunction(), 61 remb_sender.AsStdFunction()); 62 63 RtpHeaderExtensionMap extensions; 64 extensions.Register<AbsoluteSendTime>(1); 65 RtpPacketReceived packet(&extensions); 66 packet.SetSsrc(0x11eb21c); 67 packet.ReserveExtension<AbsoluteSendTime>(); 68 packet.SetPayloadSize(kPayloadSize.bytes()); 69 70 EXPECT_CALL(remb_sender, Call(_, ElementsAre(packet.Ssrc()))) 71 .Times(AtLeast(1)); 72 73 for (int i = 0; i < 10; ++i) { 74 clock.AdvanceTime(kPayloadSize / kInitialBitrate); 75 Timestamp now = clock.CurrentTime(); 76 packet.SetExtension<AbsoluteSendTime>(AbsoluteSendTime::To24Bits(now)); 77 packet.set_arrival_time(now); 78 controller.OnReceivedPacket(packet, MediaType::VIDEO); 79 } 80 } 81 82 TEST(ReceiveSideCongestionControllerTest, 83 SendsRembAfterSetMaxDesiredReceiveBitrate) { 84 MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)> 85 feedback_sender; 86 MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; 87 SimulatedClock clock(123456); 88 89 ReceiveSideCongestionController controller(CreateEnvironment(&clock), 90 feedback_sender.AsStdFunction(), 91 remb_sender.AsStdFunction()); 92 EXPECT_CALL(remb_sender, Call(123, _)); 93 controller.SetMaxDesiredReceiveBitrate(DataRate::BitsPerSec(123)); 94 } 95 96 void CheckRfc8888Feedback( 97 const std::vector<std::unique_ptr<rtcp::RtcpPacket>>& rtcp_packets) { 98 ASSERT_THAT(rtcp_packets, SizeIs(1)); 99 Buffer buffer = rtcp_packets[0]->Build(); 100 rtcp::CommonHeader header; 101 EXPECT_TRUE(header.Parse(buffer.data(), buffer.size())); 102 // Check for RFC 8888 format message type 11(CCFB) 103 EXPECT_EQ(header.fmt(), 104 rtcp::CongestionControlFeedback::kFeedbackMessageType); 105 } 106 107 TEST(ReceiveSideCongestionControllerTest, SendsRfc8888FeedbackIfForced) { 108 FieldTrials field_trials = CreateTestFieldTrials( 109 "WebRTC-RFC8888CongestionControlFeedback/force_send:true/"); 110 MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)> 111 rtcp_sender; 112 MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; 113 SimulatedClock clock(123456); 114 ReceiveSideCongestionController controller( 115 CreateEnvironment(&clock, &field_trials), rtcp_sender.AsStdFunction(), 116 remb_sender.AsStdFunction()); 117 118 // Expect that RTCP feedback is sent. 119 EXPECT_CALL(rtcp_sender, Call) 120 .WillOnce( 121 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) { 122 CheckRfc8888Feedback(rtcp_packets); 123 }); 124 // Expect that REMB is not sent. 125 EXPECT_CALL(remb_sender, Call).Times(0); 126 127 RtpPacketReceived packet; 128 packet.set_arrival_time(clock.CurrentTime()); 129 controller.OnReceivedPacket(packet, MediaType::VIDEO); 130 TimeDelta next_process = controller.MaybeProcess(); 131 clock.AdvanceTime(next_process); 132 next_process = controller.MaybeProcess(); 133 } 134 135 TEST(ReceiveSideCongestionControllerTest, SendsRfc8888FeedbackIfEnabled) { 136 MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)> 137 rtcp_sender; 138 MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; 139 SimulatedClock clock(123456); 140 ReceiveSideCongestionController controller(CreateEnvironment(&clock), 141 rtcp_sender.AsStdFunction(), 142 remb_sender.AsStdFunction()); 143 controller.EnableSendCongestionControlFeedbackAccordingToRfc8888(); 144 145 // Expect that RTCP feedback is sent. 146 EXPECT_CALL(rtcp_sender, Call) 147 .WillOnce( 148 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) { 149 CheckRfc8888Feedback(rtcp_packets); 150 }); 151 // Expect that REMB is not sent. 152 EXPECT_CALL(remb_sender, Call).Times(0); 153 154 RtpPacketReceived packet; 155 packet.set_arrival_time(clock.CurrentTime()); 156 controller.OnReceivedPacket(packet, MediaType::VIDEO); 157 TimeDelta next_process = controller.MaybeProcess(); 158 clock.AdvanceTime(next_process); 159 next_process = controller.MaybeProcess(); 160 } 161 162 TEST(ReceiveSideCongestionControllerTest, 163 SendsNoFeedbackIfNotRfcRfc8888EnabledAndNoTransportFeedback) { 164 MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)> 165 rtcp_sender; 166 MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; 167 SimulatedClock clock(123456); 168 ReceiveSideCongestionController controller(CreateEnvironment(&clock), 169 rtcp_sender.AsStdFunction(), 170 remb_sender.AsStdFunction()); 171 172 // No Transport feedback is sent because received packet does not have 173 // transport sequence number rtp header extension. 174 EXPECT_CALL(rtcp_sender, Call).Times(0); 175 RtpPacketReceived packet; 176 packet.set_arrival_time(clock.CurrentTime()); 177 controller.OnReceivedPacket(packet, MediaType::VIDEO); 178 TimeDelta next_process = controller.MaybeProcess(); 179 clock.AdvanceTime(next_process); 180 next_process = controller.MaybeProcess(); 181 } 182 183 TEST(ReceiveSideCongestionControllerTest, ConvergesToCapacity) { 184 Scenario s("receive_cc_unit/converge"); 185 NetworkSimulationConfig net_conf; 186 net_conf.bandwidth = DataRate::KilobitsPerSec(1000); 187 net_conf.delay = TimeDelta::Millis(50); 188 auto* client = s.CreateClient("send", [&](CallClientConfig* c) { 189 c->transport.rates.start_rate = DataRate::KilobitsPerSec(300); 190 }); 191 192 auto* route = s.CreateRoutes(client, {s.CreateSimulationNode(net_conf)}, 193 s.CreateClient("return", CallClientConfig()), 194 {s.CreateSimulationNode(net_conf)}); 195 VideoStreamConfig video; 196 video.stream.packet_feedback = false; 197 s.CreateVideoStream(route->forward(), video); 198 s.RunFor(TimeDelta::Seconds(30)); 199 EXPECT_NEAR(client->send_bandwidth().kbps(), 900, 150); 200 } 201 202 TEST(ReceiveSideCongestionControllerTest, IsFairToTCP) { 203 Scenario s("receive_cc_unit/tcp_fairness"); 204 NetworkSimulationConfig net_conf; 205 net_conf.bandwidth = DataRate::KilobitsPerSec(1000); 206 net_conf.delay = TimeDelta::Millis(50); 207 auto* client = s.CreateClient("send", [&](CallClientConfig* c) { 208 c->transport.rates.start_rate = DataRate::KilobitsPerSec(1000); 209 }); 210 auto send_net = {s.CreateSimulationNode(net_conf)}; 211 auto ret_net = {s.CreateSimulationNode(net_conf)}; 212 auto* route = s.CreateRoutes( 213 client, send_net, s.CreateClient("return", CallClientConfig()), ret_net); 214 VideoStreamConfig video; 215 video.stream.packet_feedback = false; 216 s.CreateVideoStream(route->forward(), video); 217 s.net()->StartCrossTraffic(CreateFakeTcpCrossTraffic( 218 s.net()->CreateRoute(send_net), s.net()->CreateRoute(ret_net), 219 FakeTcpConfig())); 220 s.RunFor(TimeDelta::Seconds(30)); 221 // For some reason we get outcompeted by TCP here, this should probably be 222 // fixed and a lower bound should be added to the test. 223 EXPECT_LT(client->send_bandwidth().kbps(), 750); 224 } 225 } // namespace 226 } // namespace test 227 } // namespace webrtc