blob: ab5e5687b997babebb420c37f6f5166f04b397c3 [file] [log] [blame]
Sebastian Janssonc5017132018-02-02 15:24:161/*
2 * Copyright 2018 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
Artem Titov46c4e602018-08-17 12:26:5411#include "api/test/simulated_network.h"
Artem Titov4e199e92018-08-20 11:30:3912#include "call/fake_network_pipe.h"
13#include "call/simulated_network.h"
Sebastian Janssonc5017132018-02-02 15:24:1614#include "modules/rtp_rtcp/include/rtp_rtcp.h"
15#include "rtc_base/rate_limiter.h"
16#include "system_wrappers/include/sleep.h"
17#include "test/call_test.h"
Niels Möller4db138e2018-04-19 07:04:1318#include "test/fake_encoder.h"
Sebastian Janssonc5017132018-02-02 15:24:1619#include "test/field_trial.h"
20#include "test/gtest.h"
21#include "test/rtcp_packet_parser.h"
22#include "test/rtp_rtcp_observer.h"
Niels Möllercbcbc222018-09-28 07:07:2423#include "test/video_encoder_proxy_factory.h"
Sebastian Janssonc5017132018-02-02 15:24:1624
25namespace webrtc {
26
Ilya Nikolaevskiycb960622018-09-04 09:07:3127class BandwidthEndToEndTest : public test::CallTest {
Sebastian Janssonc5017132018-02-02 15:24:1628 public:
Ilya Nikolaevskiycb960622018-09-04 09:07:3129 BandwidthEndToEndTest() = default;
Sebastian Janssonc5017132018-02-02 15:24:1630};
31
Ilya Nikolaevskiycb960622018-09-04 09:07:3132TEST_F(BandwidthEndToEndTest, ReceiveStreamSendsRemb) {
Sebastian Janssonc5017132018-02-02 15:24:1633 class RembObserver : public test::EndToEndTest {
34 public:
35 RembObserver() : EndToEndTest(kDefaultTimeoutMs) {}
36
37 void ModifyVideoConfigs(
38 VideoSendStream::Config* send_config,
39 std::vector<VideoReceiveStream::Config>* receive_configs,
40 VideoEncoderConfig* encoder_config) override {
41 send_config->rtp.extensions.clear();
42 send_config->rtp.extensions.push_back(RtpExtension(
43 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
44 (*receive_configs)[0].rtp.remb = true;
45 (*receive_configs)[0].rtp.transport_cc = false;
46 }
47
48 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
49 test::RtcpPacketParser parser;
50 EXPECT_TRUE(parser.Parse(packet, length));
51
52 if (parser.remb()->num_packets() > 0) {
53 EXPECT_EQ(kReceiverLocalVideoSsrc, parser.remb()->sender_ssrc());
54 EXPECT_LT(0U, parser.remb()->bitrate_bps());
55 EXPECT_EQ(1U, parser.remb()->ssrcs().size());
56 EXPECT_EQ(kVideoSendSsrcs[0], parser.remb()->ssrcs()[0]);
57 observation_complete_.Set();
58 }
59
60 return SEND_PACKET;
61 }
62 void PerformTest() override {
63 EXPECT_TRUE(Wait()) << "Timed out while waiting for a "
64 "receiver RTCP REMB packet to be "
65 "sent.";
66 }
67 } test;
68
69 RunBaseTest(&test);
70}
71
72class BandwidthStatsTest : public test::EndToEndTest {
73 public:
74 explicit BandwidthStatsTest(bool send_side_bwe)
75 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
76 sender_call_(nullptr),
77 receiver_call_(nullptr),
78 has_seen_pacer_delay_(false),
79 send_side_bwe_(send_side_bwe) {}
80
81 void ModifyVideoConfigs(
82 VideoSendStream::Config* send_config,
83 std::vector<VideoReceiveStream::Config>* receive_configs,
84 VideoEncoderConfig* encoder_config) override {
85 if (!send_side_bwe_) {
86 send_config->rtp.extensions.clear();
87 send_config->rtp.extensions.push_back(RtpExtension(
88 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
89 (*receive_configs)[0].rtp.remb = true;
90 (*receive_configs)[0].rtp.transport_cc = false;
91 }
92 }
93
94 Action OnSendRtp(const uint8_t* packet, size_t length) override {
95 Call::Stats sender_stats = sender_call_->GetStats();
96 Call::Stats receiver_stats = receiver_call_->GetStats();
97 if (!has_seen_pacer_delay_)
98 has_seen_pacer_delay_ = sender_stats.pacer_delay_ms > 0;
99 if (sender_stats.send_bandwidth_bps > 0 && has_seen_pacer_delay_) {
100 if (send_side_bwe_ || receiver_stats.recv_bandwidth_bps > 0)
101 observation_complete_.Set();
102 }
103 return SEND_PACKET;
104 }
105
106 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
107 sender_call_ = sender_call;
108 receiver_call_ = receiver_call;
109 }
110
111 void PerformTest() override {
112 EXPECT_TRUE(Wait()) << "Timed out while waiting for "
113 "non-zero bandwidth stats.";
114 }
115
116 private:
117 Call* sender_call_;
118 Call* receiver_call_;
119 bool has_seen_pacer_delay_;
120 const bool send_side_bwe_;
121};
122
Ilya Nikolaevskiycb960622018-09-04 09:07:31123TEST_F(BandwidthEndToEndTest, VerifySendSideBweStats) {
Sebastian Janssonc5017132018-02-02 15:24:16124 BandwidthStatsTest test(true);
125 RunBaseTest(&test);
126}
127
Ilya Nikolaevskiycb960622018-09-04 09:07:31128TEST_F(BandwidthEndToEndTest, VerifyRecvSideBweStats) {
Sebastian Janssonc5017132018-02-02 15:24:16129 BandwidthStatsTest test(false);
130 RunBaseTest(&test);
131}
132
133// Verifies that it's possible to limit the send BWE by sending a REMB.
134// This is verified by allowing the send BWE to ramp-up to >1000 kbps,
135// then have the test generate a REMB of 500 kbps and verify that the send BWE
136// is reduced to exactly 500 kbps. Then a REMB of 1000 kbps is generated and the
137// test verifies that the send BWE ramps back up to exactly 1000 kbps.
Ilya Nikolaevskiycb960622018-09-04 09:07:31138TEST_F(BandwidthEndToEndTest, RembWithSendSideBwe) {
Sebastian Janssonc5017132018-02-02 15:24:16139 class BweObserver : public test::EndToEndTest {
140 public:
141 BweObserver()
142 : EndToEndTest(kDefaultTimeoutMs),
143 sender_call_(nullptr),
144 clock_(Clock::GetRealTimeClock()),
145 sender_ssrc_(0),
146 remb_bitrate_bps_(1000000),
147 receive_transport_(nullptr),
148 stop_event_(false, false),
149 poller_thread_(&BitrateStatsPollingThread,
150 this,
151 "BitrateStatsPollingThread"),
152 state_(kWaitForFirstRampUp),
153 retransmission_rate_limiter_(clock_, 1000) {}
154
155 ~BweObserver() {}
156
157 test::PacketTransport* CreateReceiveTransport(
158 test::SingleThreadedTaskQueueForTesting* task_queue) override {
159 receive_transport_ = new test::PacketTransport(
160 task_queue, nullptr, this, test::PacketTransport::kReceiver,
Artem Titov4e199e92018-08-20 11:30:39161 payload_type_map_,
162 absl::make_unique<FakeNetworkPipe>(
163 Clock::GetRealTimeClock(),
164 absl::make_unique<SimulatedNetwork>(
165 DefaultNetworkSimulationConfig())));
Sebastian Janssonc5017132018-02-02 15:24:16166 return receive_transport_;
167 }
168
Sebastian Jansson72582242018-07-13 11:19:42169 void ModifySenderCallConfig(Call::Config* config) override {
Sebastian Janssonc5017132018-02-02 15:24:16170 // Set a high start bitrate to reduce the test completion time.
Sebastian Jansson72582242018-07-13 11:19:42171 config->bitrate_config.start_bitrate_bps = remb_bitrate_bps_;
Sebastian Janssonc5017132018-02-02 15:24:16172 }
173
174 void ModifyVideoConfigs(
175 VideoSendStream::Config* send_config,
176 std::vector<VideoReceiveStream::Config>* receive_configs,
177 VideoEncoderConfig* encoder_config) override {
178 ASSERT_EQ(1u, send_config->rtp.ssrcs.size());
179 sender_ssrc_ = send_config->rtp.ssrcs[0];
180
181 encoder_config->max_bitrate_bps = 2000000;
182
183 ASSERT_EQ(1u, receive_configs->size());
184 RtpRtcp::Configuration config;
185 config.receiver_only = true;
186 config.clock = clock_;
187 config.outgoing_transport = receive_transport_;
188 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
189 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
190 rtp_rtcp_->SetRemoteSSRC((*receive_configs)[0].rtp.remote_ssrc);
191 rtp_rtcp_->SetSSRC((*receive_configs)[0].rtp.local_ssrc);
192 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
193 }
194
195 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
196 sender_call_ = sender_call;
197 }
198
199 static void BitrateStatsPollingThread(void* obj) {
200 static_cast<BweObserver*>(obj)->PollStats();
201 }
202
203 void PollStats() {
204 do {
205 if (sender_call_) {
206 Call::Stats stats = sender_call_->GetStats();
207 switch (state_) {
208 case kWaitForFirstRampUp:
209 if (stats.send_bandwidth_bps >= remb_bitrate_bps_) {
210 state_ = kWaitForRemb;
211 remb_bitrate_bps_ /= 2;
212 rtp_rtcp_->SetRemb(
213 remb_bitrate_bps_,
214 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
215 rtp_rtcp_->SendRTCP(kRtcpRr);
216 }
217 break;
218
219 case kWaitForRemb:
220 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
221 state_ = kWaitForSecondRampUp;
222 remb_bitrate_bps_ *= 2;
223 rtp_rtcp_->SetRemb(
224 remb_bitrate_bps_,
225 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
226 rtp_rtcp_->SendRTCP(kRtcpRr);
227 }
228 break;
229
230 case kWaitForSecondRampUp:
231 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
232 observation_complete_.Set();
233 }
234 break;
235 }
236 }
237 } while (!stop_event_.Wait(1000));
238 }
239
240 void PerformTest() override {
241 poller_thread_.Start();
242 EXPECT_TRUE(Wait())
243 << "Timed out while waiting for bitrate to change according to REMB.";
244 stop_event_.Set();
245 poller_thread_.Stop();
246 }
247
248 private:
249 enum TestState { kWaitForFirstRampUp, kWaitForRemb, kWaitForSecondRampUp };
250
251 Call* sender_call_;
252 Clock* const clock_;
253 uint32_t sender_ssrc_;
254 int remb_bitrate_bps_;
255 std::unique_ptr<RtpRtcp> rtp_rtcp_;
256 test::PacketTransport* receive_transport_;
257 rtc::Event stop_event_;
258 rtc::PlatformThread poller_thread_;
259 TestState state_;
260 RateLimiter retransmission_rate_limiter_;
261 } test;
262
263 RunBaseTest(&test);
264}
265
Ilya Nikolaevskiycb960622018-09-04 09:07:31266TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) {
Sebastian Janssonc5017132018-02-02 15:24:16267 class EncoderRateStatsTest : public test::EndToEndTest,
268 public test::FakeEncoder {
269 public:
270 explicit EncoderRateStatsTest(
271 test::SingleThreadedTaskQueueForTesting* task_queue)
272 : EndToEndTest(kDefaultTimeoutMs),
273 FakeEncoder(Clock::GetRealTimeClock()),
274 task_queue_(task_queue),
275 send_stream_(nullptr),
Niels Möller4db138e2018-04-19 07:04:13276 encoder_factory_(this),
Sebastian Janssonc5017132018-02-02 15:24:16277 bitrate_kbps_(0) {}
278
279 void OnVideoStreamsCreated(
280 VideoSendStream* send_stream,
281 const std::vector<VideoReceiveStream*>& receive_streams) override {
282 send_stream_ = send_stream;
283 }
284
285 void ModifyVideoConfigs(
286 VideoSendStream::Config* send_config,
287 std::vector<VideoReceiveStream::Config>* receive_configs,
288 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 07:04:13289 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Sebastian Janssonc5017132018-02-02 15:24:16290 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
291 }
292
Erik Språng566124a2018-04-23 10:32:22293 int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
Sebastian Janssonc5017132018-02-02 15:24:16294 uint32_t framerate) override {
295 // Make sure not to trigger on any default zero bitrates.
296 if (rate_allocation.get_sum_bps() == 0)
297 return 0;
298 rtc::CritScope lock(&crit_);
299 bitrate_kbps_ = rate_allocation.get_sum_kbps();
300 observation_complete_.Set();
301 return 0;
302 }
303
304 void PerformTest() override {
305 ASSERT_TRUE(Wait())
306 << "Timed out while waiting for encoder SetRates() call.";
307
308 task_queue_->SendTask([this]() {
309 WaitForEncoderTargetBitrateMatchStats();
310 send_stream_->Stop();
311 WaitForStatsReportZeroTargetBitrate();
312 send_stream_->Start();
313 WaitForEncoderTargetBitrateMatchStats();
314 });
315 }
316
317 void WaitForEncoderTargetBitrateMatchStats() {
318 for (int i = 0; i < kDefaultTimeoutMs; ++i) {
319 VideoSendStream::Stats stats = send_stream_->GetStats();
320 {
321 rtc::CritScope lock(&crit_);
322 if ((stats.target_media_bitrate_bps + 500) / 1000 ==
323 static_cast<int>(bitrate_kbps_)) {
324 return;
325 }
326 }
327 SleepMs(1);
328 }
329 FAIL()
330 << "Timed out waiting for stats reporting the currently set bitrate.";
331 }
332
333 void WaitForStatsReportZeroTargetBitrate() {
334 for (int i = 0; i < kDefaultTimeoutMs; ++i) {
335 if (send_stream_->GetStats().target_media_bitrate_bps == 0) {
336 return;
337 }
338 SleepMs(1);
339 }
340 FAIL() << "Timed out waiting for stats reporting zero bitrate.";
341 }
342
343 private:
344 test::SingleThreadedTaskQueueForTesting* const task_queue_;
345 rtc::CriticalSection crit_;
346 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 07:07:24347 test::VideoEncoderProxyFactory encoder_factory_;
Sebastian Janssonc5017132018-02-02 15:24:16348 uint32_t bitrate_kbps_ RTC_GUARDED_BY(crit_);
349 } test(&task_queue_);
350
351 RunBaseTest(&test);
352}
353} // namespace webrtc