• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
11 #include <memory>
12 
13 #include "api/task_queue/task_queue_base.h"
14 #include "api/test/simulated_network.h"
15 #include "api/units/time_delta.h"
16 #include "api/video/builtin_video_bitrate_allocator_factory.h"
17 #include "api/video/video_bitrate_allocation.h"
18 #include "call/fake_network_pipe.h"
19 #include "call/simulated_network.h"
20 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
21 #include "rtc_base/rate_limiter.h"
22 #include "rtc_base/synchronization/mutex.h"
23 #include "rtc_base/task_queue_for_test.h"
24 #include "system_wrappers/include/sleep.h"
25 #include "test/call_test.h"
26 #include "test/fake_encoder.h"
27 #include "test/field_trial.h"
28 #include "test/gtest.h"
29 #include "test/rtcp_packet_parser.h"
30 #include "test/rtp_rtcp_observer.h"
31 #include "test/video_encoder_proxy_factory.h"
32 
33 namespace webrtc {
34 namespace {
35 enum : int {  // The first valid value is 1.
36   kAbsSendTimeExtensionId = 1,
37   kTransportSequenceNumberId,
38 };
39 }  // namespace
40 
41 class BandwidthEndToEndTest : public test::CallTest {
42  public:
43   BandwidthEndToEndTest() = default;
44 };
45 
TEST_F(BandwidthEndToEndTest,ReceiveStreamSendsRemb)46 TEST_F(BandwidthEndToEndTest, ReceiveStreamSendsRemb) {
47   class RembObserver : public test::EndToEndTest {
48    public:
49     RembObserver() : EndToEndTest(kDefaultTimeout) {}
50 
51     void ModifyVideoConfigs(
52         VideoSendStream::Config* send_config,
53         std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
54         VideoEncoderConfig* encoder_config) override {
55       send_config->rtp.extensions.clear();
56       send_config->rtp.extensions.push_back(
57           RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
58       (*receive_configs)[0].rtp.transport_cc = false;
59     }
60 
61     Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
62       test::RtcpPacketParser parser;
63       EXPECT_TRUE(parser.Parse(packet, length));
64 
65       if (parser.remb()->num_packets() > 0) {
66         EXPECT_EQ(kReceiverLocalVideoSsrc, parser.remb()->sender_ssrc());
67         EXPECT_LT(0U, parser.remb()->bitrate_bps());
68         EXPECT_EQ(1U, parser.remb()->ssrcs().size());
69         EXPECT_EQ(kVideoSendSsrcs[0], parser.remb()->ssrcs()[0]);
70         observation_complete_.Set();
71       }
72 
73       return SEND_PACKET;
74     }
75     void PerformTest() override {
76       EXPECT_TRUE(Wait()) << "Timed out while waiting for a "
77                              "receiver RTCP REMB packet to be "
78                              "sent.";
79     }
80   } test;
81 
82   RunBaseTest(&test);
83 }
84 
85 class BandwidthStatsTest : public test::EndToEndTest {
86  public:
BandwidthStatsTest(bool send_side_bwe,TaskQueueBase * task_queue)87   BandwidthStatsTest(bool send_side_bwe, TaskQueueBase* task_queue)
88       : EndToEndTest(test::CallTest::kDefaultTimeout),
89         sender_call_(nullptr),
90         receiver_call_(nullptr),
91         has_seen_pacer_delay_(false),
92         send_side_bwe_(send_side_bwe),
93         task_queue_(task_queue) {}
94 
~BandwidthStatsTest()95   ~BandwidthStatsTest() override {
96     // Block until all already posted tasks run to avoid races when such task
97     // accesses `this`.
98     SendTask(task_queue_, [] {});
99   }
100 
ModifyVideoConfigs(VideoSendStream::Config * send_config,std::vector<VideoReceiveStreamInterface::Config> * receive_configs,VideoEncoderConfig * encoder_config)101   void ModifyVideoConfigs(
102       VideoSendStream::Config* send_config,
103       std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
104       VideoEncoderConfig* encoder_config) override {
105     send_config->rtp.extensions.clear();
106     if (!send_side_bwe_) {
107       send_config->rtp.extensions.push_back(
108           RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
109       (*receive_configs)[0].rtp.transport_cc = false;
110     } else {
111       send_config->rtp.extensions.push_back(
112           RtpExtension(RtpExtension::kTransportSequenceNumberUri,
113                        kTransportSequenceNumberId));
114       (*receive_configs)[0].rtp.transport_cc = true;
115     }
116 
117     // Force a too high encoder bitrate to make sure we get pacer delay.
118     encoder_config->number_of_streams = 1;
119     encoder_config->max_bitrate_bps = kMaxBitrateBps * 2;
120     encoder_config->simulcast_layers[0].min_bitrate_bps = kMaxBitrateBps * 2;
121     encoder_config->simulcast_layers[0].target_bitrate_bps = kMaxBitrateBps * 2;
122     encoder_config->simulcast_layers[0].max_bitrate_bps = kMaxBitrateBps * 2;
123   }
124 
ModifySenderBitrateConfig(BitrateConstraints * bitrate_config)125   void ModifySenderBitrateConfig(BitrateConstraints* bitrate_config) override {
126     bitrate_config->max_bitrate_bps = kMaxBitrateBps;
127   }
128 
129   // Called on the pacer thread.
OnSendRtp(const uint8_t * packet,size_t length)130   Action OnSendRtp(const uint8_t* packet, size_t length) override {
131     // Stats need to be fetched on the thread where the caller objects were
132     // constructed.
133     task_queue_->PostTask([this]() {
134       if (!sender_call_ || !receiver_call_) {
135         return;
136       }
137 
138       Call::Stats sender_stats = sender_call_->GetStats();
139       if (!has_seen_pacer_delay_) {
140         has_seen_pacer_delay_ = sender_stats.pacer_delay_ms > 0;
141       }
142 
143       if (sender_stats.send_bandwidth_bps > 0 && has_seen_pacer_delay_) {
144         Call::Stats receiver_stats = receiver_call_->GetStats();
145         if (send_side_bwe_ || receiver_stats.recv_bandwidth_bps > 0) {
146           observation_complete_.Set();
147         }
148       }
149     });
150 
151     return SEND_PACKET;
152   }
153 
OnCallsCreated(Call * sender_call,Call * receiver_call)154   void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
155     sender_call_ = sender_call;
156     receiver_call_ = receiver_call;
157   }
158 
OnStreamsStopped()159   void OnStreamsStopped() override {
160     sender_call_ = nullptr;
161     receiver_call_ = nullptr;
162   }
163 
PerformTest()164   void PerformTest() override {
165     EXPECT_TRUE(Wait()) << "Timed out while waiting for "
166                            "non-zero bandwidth stats.";
167   }
168 
169  private:
170   static const int kMaxBitrateBps = 3000000;
171   Call* sender_call_;
172   Call* receiver_call_;
173   bool has_seen_pacer_delay_;
174   const bool send_side_bwe_;
175   TaskQueueBase* const task_queue_;
176 };
177 
TEST_F(BandwidthEndToEndTest,VerifySendSideBweStats)178 TEST_F(BandwidthEndToEndTest, VerifySendSideBweStats) {
179   BandwidthStatsTest test(true, task_queue());
180   RunBaseTest(&test);
181 }
182 
TEST_F(BandwidthEndToEndTest,VerifyRecvSideBweStats)183 TEST_F(BandwidthEndToEndTest, VerifyRecvSideBweStats) {
184   BandwidthStatsTest test(false, task_queue());
185   RunBaseTest(&test);
186 }
187 
188 // Verifies that it's possible to limit the send BWE by sending a REMB.
189 // This is verified by allowing the send BWE to ramp-up to >1000 kbps,
190 // then have the test generate a REMB of 500 kbps and verify that the send BWE
191 // is reduced to exactly 500 kbps. Then a REMB of 1000 kbps is generated and the
192 // test verifies that the send BWE ramps back up to exactly 1000 kbps.
TEST_F(BandwidthEndToEndTest,RembWithSendSideBwe)193 TEST_F(BandwidthEndToEndTest, RembWithSendSideBwe) {
194   class BweObserver : public test::EndToEndTest {
195    public:
196     explicit BweObserver(TaskQueueBase* task_queue)
197         : EndToEndTest(kDefaultTimeout),
198           sender_call_(nullptr),
199           clock_(Clock::GetRealTimeClock()),
200           sender_ssrc_(0),
201           remb_bitrate_bps_(1000000),
202           receive_transport_(nullptr),
203           state_(kWaitForFirstRampUp),
204           retransmission_rate_limiter_(clock_, 1000),
205           task_queue_(task_queue) {}
206 
207     void OnStreamsStopped() override { rtp_rtcp_ = nullptr; }
208 
209     std::unique_ptr<test::PacketTransport> CreateReceiveTransport(
210         TaskQueueBase* task_queue) override {
211       auto receive_transport = std::make_unique<test::PacketTransport>(
212           task_queue, nullptr, this, test::PacketTransport::kReceiver,
213           payload_type_map_,
214           std::make_unique<FakeNetworkPipe>(
215               Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
216                                              BuiltInNetworkBehaviorConfig())));
217       receive_transport_ = receive_transport.get();
218       return receive_transport;
219     }
220 
221     void ModifySenderBitrateConfig(
222         BitrateConstraints* bitrate_config) override {
223       // Set a high start bitrate to reduce the test completion time.
224       bitrate_config->start_bitrate_bps = remb_bitrate_bps_;
225     }
226 
227     void ModifyVideoConfigs(
228         VideoSendStream::Config* send_config,
229         std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
230         VideoEncoderConfig* encoder_config) override {
231       ASSERT_EQ(1u, send_config->rtp.ssrcs.size());
232       sender_ssrc_ = send_config->rtp.ssrcs[0];
233 
234       encoder_config->max_bitrate_bps = 2000000;
235 
236       ASSERT_EQ(1u, receive_configs->size());
237       RtpRtcpInterface::Configuration config;
238       config.receiver_only = true;
239       config.clock = clock_;
240       config.outgoing_transport = receive_transport_;
241       config.retransmission_rate_limiter = &retransmission_rate_limiter_;
242       config.local_media_ssrc = (*receive_configs)[0].rtp.local_ssrc;
243       rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(config);
244       rtp_rtcp_->SetRemoteSSRC((*receive_configs)[0].rtp.remote_ssrc);
245       rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
246     }
247 
248     void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
249       RTC_DCHECK(sender_call);
250       sender_call_ = sender_call;
251       task_queue_->PostTask([this]() { PollStats(); });
252     }
253 
254     void PollStats() {
255       Call::Stats stats = sender_call_->GetStats();
256       switch (state_) {
257         case kWaitForFirstRampUp:
258           if (stats.send_bandwidth_bps >= remb_bitrate_bps_) {
259             state_ = kWaitForRemb;
260             remb_bitrate_bps_ /= 2;
261             rtp_rtcp_->SetRemb(
262                 remb_bitrate_bps_,
263                 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
264             rtp_rtcp_->SendRTCP(kRtcpRr);
265           }
266           break;
267 
268         case kWaitForRemb:
269           if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
270             state_ = kWaitForSecondRampUp;
271             remb_bitrate_bps_ *= 2;
272             rtp_rtcp_->SetRemb(
273                 remb_bitrate_bps_,
274                 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
275             rtp_rtcp_->SendRTCP(kRtcpRr);
276           }
277           break;
278 
279         case kWaitForSecondRampUp:
280           if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
281             observation_complete_.Set();
282             return;
283           }
284           break;
285       }
286 
287       task_queue_->PostDelayedTask([this] { PollStats(); },
288                                    TimeDelta::Seconds(1));
289     }
290 
291     void PerformTest() override {
292       EXPECT_TRUE(Wait())
293           << "Timed out while waiting for bitrate to change according to REMB.";
294     }
295 
296    private:
297     enum TestState { kWaitForFirstRampUp, kWaitForRemb, kWaitForSecondRampUp };
298 
299     Call* sender_call_;
300     Clock* const clock_;
301     uint32_t sender_ssrc_;
302     int remb_bitrate_bps_;
303     std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_;
304     test::PacketTransport* receive_transport_;
305     TestState state_;
306     RateLimiter retransmission_rate_limiter_;
307     TaskQueueBase* const task_queue_;
308   } test(task_queue());
309 
310   RunBaseTest(&test);
311 }
312 
TEST_F(BandwidthEndToEndTest,ReportsSetEncoderRates)313 TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) {
314   // If these fields trial are on, we get lower bitrates than expected by this
315   // test, due to the packetization overhead and encoder pushback.
316   webrtc::test::ScopedFieldTrials field_trials(
317       std::string(field_trial::GetFieldTrialString()) +
318       "WebRTC-VideoRateControl/bitrate_adjuster:false/");
319   class EncoderRateStatsTest : public test::EndToEndTest,
320                                public test::FakeEncoder {
321    public:
322     explicit EncoderRateStatsTest(TaskQueueBase* task_queue)
323         : EndToEndTest(kDefaultTimeout),
324           FakeEncoder(Clock::GetRealTimeClock()),
325           task_queue_(task_queue),
326           send_stream_(nullptr),
327           encoder_factory_(this),
328           bitrate_allocator_factory_(
329               CreateBuiltinVideoBitrateAllocatorFactory()),
330           bitrate_kbps_(0) {}
331 
332     void OnVideoStreamsCreated(VideoSendStream* send_stream,
333                                const std::vector<VideoReceiveStreamInterface*>&
334                                    receive_streams) override {
335       send_stream_ = send_stream;
336     }
337 
338     void ModifyVideoConfigs(
339         VideoSendStream::Config* send_config,
340         std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
341         VideoEncoderConfig* encoder_config) override {
342       send_config->encoder_settings.encoder_factory = &encoder_factory_;
343       send_config->encoder_settings.bitrate_allocator_factory =
344           bitrate_allocator_factory_.get();
345       RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
346     }
347 
348     void SetRates(const RateControlParameters& parameters) override {
349       // Make sure not to trigger on any default zero bitrates.
350       if (parameters.bitrate.get_sum_bps() == 0)
351         return;
352       MutexLock lock(&mutex_);
353       bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
354       observation_complete_.Set();
355     }
356 
357     void PerformTest() override {
358       ASSERT_TRUE(Wait())
359           << "Timed out while waiting for encoder SetRates() call.";
360 
361       SendTask(task_queue_, [this]() {
362         WaitForEncoderTargetBitrateMatchStats();
363         send_stream_->Stop();
364         WaitForStatsReportZeroTargetBitrate();
365         send_stream_->Start();
366         WaitForEncoderTargetBitrateMatchStats();
367       });
368     }
369 
370     void WaitForEncoderTargetBitrateMatchStats() {
371       for (int i = 0; i < kDefaultTimeout.ms(); ++i) {
372         VideoSendStream::Stats stats = send_stream_->GetStats();
373         {
374           MutexLock lock(&mutex_);
375           if ((stats.target_media_bitrate_bps + 500) / 1000 ==
376               static_cast<int>(bitrate_kbps_)) {
377             return;
378           }
379         }
380         SleepMs(1);
381       }
382       FAIL()
383           << "Timed out waiting for stats reporting the currently set bitrate.";
384     }
385 
386     void WaitForStatsReportZeroTargetBitrate() {
387       for (int i = 0; i < kDefaultTimeout.ms(); ++i) {
388         if (send_stream_->GetStats().target_media_bitrate_bps == 0) {
389           return;
390         }
391         SleepMs(1);
392       }
393       FAIL() << "Timed out waiting for stats reporting zero bitrate.";
394     }
395 
396    private:
397     TaskQueueBase* const task_queue_;
398     Mutex mutex_;
399     VideoSendStream* send_stream_;
400     test::VideoEncoderProxyFactory encoder_factory_;
401     std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
402     uint32_t bitrate_kbps_ RTC_GUARDED_BY(mutex_);
403   } test(task_queue());
404 
405   RunBaseTest(&test);
406 }
407 }  // namespace webrtc
408