• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 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 <algorithm>
12 #include <limits>
13 #include <memory>
14 #include <string>
15 
16 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
17 #include "api/rtc_event_log/rtc_event_log.h"
18 #include "api/task_queue/task_queue_base.h"
19 #include "api/test/simulated_network.h"
20 #include "api/video/builtin_video_bitrate_allocator_factory.h"
21 #include "api/video/video_bitrate_allocation.h"
22 #include "api/video_codecs/video_encoder.h"
23 #include "api/video_codecs/video_encoder_config.h"
24 #include "call/call.h"
25 #include "call/fake_network_pipe.h"
26 #include "call/simulated_network.h"
27 #include "modules/audio_coding/include/audio_coding_module.h"
28 #include "modules/audio_device/include/test_audio_device.h"
29 #include "modules/audio_mixer/audio_mixer_impl.h"
30 #include "modules/rtp_rtcp/source/rtp_packet.h"
31 #include "rtc_base/checks.h"
32 #include "rtc_base/synchronization/mutex.h"
33 #include "rtc_base/task_queue_for_test.h"
34 #include "rtc_base/thread.h"
35 #include "rtc_base/thread_annotations.h"
36 #include "system_wrappers/include/metrics.h"
37 #include "test/call_test.h"
38 #include "test/direct_transport.h"
39 #include "test/drifting_clock.h"
40 #include "test/encoder_settings.h"
41 #include "test/fake_encoder.h"
42 #include "test/field_trial.h"
43 #include "test/frame_generator_capturer.h"
44 #include "test/gtest.h"
45 #include "test/null_transport.h"
46 #include "test/rtp_header_parser.h"
47 #include "test/rtp_rtcp_observer.h"
48 #include "test/testsupport/file_utils.h"
49 #include "test/testsupport/perf_test.h"
50 #include "test/video_encoder_proxy_factory.h"
51 #include "video/transport_adapter.h"
52 
53 using webrtc::test::DriftingClock;
54 
55 namespace webrtc {
56 namespace {
57 enum : int {  // The first valid value is 1.
58   kTransportSequenceNumberExtensionId = 1,
59 };
60 }  // namespace
61 
62 class CallPerfTest : public test::CallTest {
63  public:
CallPerfTest()64   CallPerfTest() {
65     RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
66                                       kTransportSequenceNumberExtensionId));
67   }
68 
69  protected:
70   enum class FecMode { kOn, kOff };
71   enum class CreateOrder { kAudioFirst, kVideoFirst };
72   void TestAudioVideoSync(FecMode fec,
73                           CreateOrder create_first,
74                           float video_ntp_speed,
75                           float video_rtp_speed,
76                           float audio_rtp_speed,
77                           const std::string& test_label);
78 
79   void TestMinTransmitBitrate(bool pad_to_min_bitrate);
80 
81   void TestCaptureNtpTime(const BuiltInNetworkBehaviorConfig& net_config,
82                           int threshold_ms,
83                           int start_time_ms,
84                           int run_time_ms);
85   void TestMinAudioVideoBitrate(int test_bitrate_from,
86                                 int test_bitrate_to,
87                                 int test_bitrate_step,
88                                 int min_bwe,
89                                 int start_bwe,
90                                 int max_bwe);
91 };
92 
93 class VideoRtcpAndSyncObserver : public test::RtpRtcpObserver,
94                                  public rtc::VideoSinkInterface<VideoFrame> {
95   static const int kInSyncThresholdMs = 50;
96   static const int kStartupTimeMs = 2000;
97   static const int kMinRunTimeMs = 30000;
98 
99  public:
VideoRtcpAndSyncObserver(TaskQueueBase * task_queue,Clock * clock,const std::string & test_label)100   explicit VideoRtcpAndSyncObserver(TaskQueueBase* task_queue,
101                                     Clock* clock,
102                                     const std::string& test_label)
103       : test::RtpRtcpObserver(CallPerfTest::kLongTimeoutMs),
104         clock_(clock),
105         test_label_(test_label),
106         creation_time_ms_(clock_->TimeInMilliseconds()),
107         task_queue_(task_queue) {}
108 
OnFrame(const VideoFrame & video_frame)109   void OnFrame(const VideoFrame& video_frame) override {
110     task_queue_->PostTask(ToQueuedTask([this]() { CheckStats(); }));
111   }
112 
CheckStats()113   void CheckStats() {
114     if (!receive_stream_)
115       return;
116 
117     VideoReceiveStream::Stats stats = receive_stream_->GetStats();
118     if (stats.sync_offset_ms == std::numeric_limits<int>::max())
119       return;
120 
121     int64_t now_ms = clock_->TimeInMilliseconds();
122     int64_t time_since_creation = now_ms - creation_time_ms_;
123     // During the first couple of seconds audio and video can falsely be
124     // estimated as being synchronized. We don't want to trigger on those.
125     if (time_since_creation < kStartupTimeMs)
126       return;
127     if (std::abs(stats.sync_offset_ms) < kInSyncThresholdMs) {
128       if (first_time_in_sync_ == -1) {
129         first_time_in_sync_ = now_ms;
130         webrtc::test::PrintResult("sync_convergence_time", test_label_,
131                                   "synchronization", time_since_creation, "ms",
132                                   false);
133       }
134       if (time_since_creation > kMinRunTimeMs)
135         observation_complete_.Set();
136     }
137     if (first_time_in_sync_ != -1)
138       sync_offset_ms_list_.push_back(stats.sync_offset_ms);
139   }
140 
set_receive_stream(VideoReceiveStream * receive_stream)141   void set_receive_stream(VideoReceiveStream* receive_stream) {
142     RTC_DCHECK_EQ(task_queue_, TaskQueueBase::Current());
143     // Note that receive_stream may be nullptr.
144     receive_stream_ = receive_stream;
145   }
146 
PrintResults()147   void PrintResults() {
148     test::PrintResultList("stream_offset", test_label_, "synchronization",
149                           sync_offset_ms_list_, "ms", false);
150   }
151 
152  private:
153   Clock* const clock_;
154   std::string test_label_;
155   const int64_t creation_time_ms_;
156   int64_t first_time_in_sync_ = -1;
157   VideoReceiveStream* receive_stream_ = nullptr;
158   std::vector<double> sync_offset_ms_list_;
159   TaskQueueBase* const task_queue_;
160 };
161 
TestAudioVideoSync(FecMode fec,CreateOrder create_first,float video_ntp_speed,float video_rtp_speed,float audio_rtp_speed,const std::string & test_label)162 void CallPerfTest::TestAudioVideoSync(FecMode fec,
163                                       CreateOrder create_first,
164                                       float video_ntp_speed,
165                                       float video_rtp_speed,
166                                       float audio_rtp_speed,
167                                       const std::string& test_label) {
168   const char* kSyncGroup = "av_sync";
169   const uint32_t kAudioSendSsrc = 1234;
170   const uint32_t kAudioRecvSsrc = 5678;
171 
172   BuiltInNetworkBehaviorConfig audio_net_config;
173   audio_net_config.queue_delay_ms = 500;
174   audio_net_config.loss_percent = 5;
175 
176   auto observer = std::make_unique<VideoRtcpAndSyncObserver>(
177       task_queue(), Clock::GetRealTimeClock(), test_label);
178 
179   std::map<uint8_t, MediaType> audio_pt_map;
180   std::map<uint8_t, MediaType> video_pt_map;
181 
182   std::unique_ptr<test::PacketTransport> audio_send_transport;
183   std::unique_ptr<test::PacketTransport> video_send_transport;
184   std::unique_ptr<test::PacketTransport> receive_transport;
185   test::NullTransport rtcp_send_transport;
186 
187   AudioSendStream* audio_send_stream;
188   AudioReceiveStream* audio_receive_stream;
189   std::unique_ptr<DriftingClock> drifting_clock;
190 
191   SendTask(RTC_FROM_HERE, task_queue(), [&]() {
192     metrics::Reset();
193     rtc::scoped_refptr<TestAudioDeviceModule> fake_audio_device =
194         TestAudioDeviceModule::Create(
195             task_queue_factory_.get(),
196             TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000),
197             TestAudioDeviceModule::CreateDiscardRenderer(48000),
198             audio_rtp_speed);
199     EXPECT_EQ(0, fake_audio_device->Init());
200 
201     AudioState::Config send_audio_state_config;
202     send_audio_state_config.audio_mixer = AudioMixerImpl::Create();
203     send_audio_state_config.audio_processing =
204         AudioProcessingBuilder().Create();
205     send_audio_state_config.audio_device_module = fake_audio_device;
206     Call::Config sender_config(send_event_log_.get());
207 
208     auto audio_state = AudioState::Create(send_audio_state_config);
209     fake_audio_device->RegisterAudioCallback(audio_state->audio_transport());
210     sender_config.audio_state = audio_state;
211     Call::Config receiver_config(recv_event_log_.get());
212     receiver_config.audio_state = audio_state;
213     CreateCalls(sender_config, receiver_config);
214 
215     std::copy_if(std::begin(payload_type_map_), std::end(payload_type_map_),
216                  std::inserter(audio_pt_map, audio_pt_map.end()),
217                  [](const std::pair<const uint8_t, MediaType>& pair) {
218                    return pair.second == MediaType::AUDIO;
219                  });
220     std::copy_if(std::begin(payload_type_map_), std::end(payload_type_map_),
221                  std::inserter(video_pt_map, video_pt_map.end()),
222                  [](const std::pair<const uint8_t, MediaType>& pair) {
223                    return pair.second == MediaType::VIDEO;
224                  });
225 
226     audio_send_transport = std::make_unique<test::PacketTransport>(
227         task_queue(), sender_call_.get(), observer.get(),
228         test::PacketTransport::kSender, audio_pt_map,
229         std::make_unique<FakeNetworkPipe>(
230             Clock::GetRealTimeClock(),
231             std::make_unique<SimulatedNetwork>(audio_net_config)));
232     audio_send_transport->SetReceiver(receiver_call_->Receiver());
233 
234     video_send_transport = std::make_unique<test::PacketTransport>(
235         task_queue(), sender_call_.get(), observer.get(),
236         test::PacketTransport::kSender, video_pt_map,
237         std::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
238                                           std::make_unique<SimulatedNetwork>(
239                                               BuiltInNetworkBehaviorConfig())));
240     video_send_transport->SetReceiver(receiver_call_->Receiver());
241 
242     receive_transport = std::make_unique<test::PacketTransport>(
243         task_queue(), receiver_call_.get(), observer.get(),
244         test::PacketTransport::kReceiver, payload_type_map_,
245         std::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
246                                           std::make_unique<SimulatedNetwork>(
247                                               BuiltInNetworkBehaviorConfig())));
248     receive_transport->SetReceiver(sender_call_->Receiver());
249 
250     CreateSendConfig(1, 0, 0, video_send_transport.get());
251     CreateMatchingReceiveConfigs(receive_transport.get());
252 
253     AudioSendStream::Config audio_send_config(audio_send_transport.get());
254     audio_send_config.rtp.ssrc = kAudioSendSsrc;
255     audio_send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
256         kAudioSendPayloadType, {"ISAC", 16000, 1});
257     audio_send_config.encoder_factory = CreateBuiltinAudioEncoderFactory();
258     audio_send_stream = sender_call_->CreateAudioSendStream(audio_send_config);
259 
260     GetVideoSendConfig()->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
261     if (fec == FecMode::kOn) {
262       GetVideoSendConfig()->rtp.ulpfec.red_payload_type = kRedPayloadType;
263       GetVideoSendConfig()->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
264       video_receive_configs_[0].rtp.red_payload_type = kRedPayloadType;
265       video_receive_configs_[0].rtp.ulpfec_payload_type = kUlpfecPayloadType;
266     }
267     video_receive_configs_[0].rtp.nack.rtp_history_ms = 1000;
268     video_receive_configs_[0].renderer = observer.get();
269     video_receive_configs_[0].sync_group = kSyncGroup;
270 
271     AudioReceiveStream::Config audio_recv_config;
272     audio_recv_config.rtp.remote_ssrc = kAudioSendSsrc;
273     audio_recv_config.rtp.local_ssrc = kAudioRecvSsrc;
274     audio_recv_config.rtcp_send_transport = &rtcp_send_transport;
275     audio_recv_config.sync_group = kSyncGroup;
276     audio_recv_config.decoder_factory = audio_decoder_factory_;
277     audio_recv_config.decoder_map = {
278         {kAudioSendPayloadType, {"ISAC", 16000, 1}}};
279 
280     if (create_first == CreateOrder::kAudioFirst) {
281       audio_receive_stream =
282           receiver_call_->CreateAudioReceiveStream(audio_recv_config);
283       CreateVideoStreams();
284     } else {
285       CreateVideoStreams();
286       audio_receive_stream =
287           receiver_call_->CreateAudioReceiveStream(audio_recv_config);
288     }
289     EXPECT_EQ(1u, video_receive_streams_.size());
290     observer->set_receive_stream(video_receive_streams_[0]);
291     drifting_clock = std::make_unique<DriftingClock>(clock_, video_ntp_speed);
292     CreateFrameGeneratorCapturerWithDrift(drifting_clock.get(), video_rtp_speed,
293                                           kDefaultFramerate, kDefaultWidth,
294                                           kDefaultHeight);
295 
296     Start();
297 
298     audio_send_stream->Start();
299     audio_receive_stream->Start();
300   });
301 
302   EXPECT_TRUE(observer->Wait())
303       << "Timed out while waiting for audio and video to be synchronized.";
304 
305   SendTask(RTC_FROM_HERE, task_queue(), [&]() {
306     // Clear the pointer to the receive stream since it will now be deleted.
307     observer->set_receive_stream(nullptr);
308 
309     audio_send_stream->Stop();
310     audio_receive_stream->Stop();
311 
312     Stop();
313 
314     DestroyStreams();
315 
316     video_send_transport.reset();
317     audio_send_transport.reset();
318     receive_transport.reset();
319 
320     sender_call_->DestroyAudioSendStream(audio_send_stream);
321     receiver_call_->DestroyAudioReceiveStream(audio_receive_stream);
322 
323     DestroyCalls();
324   });
325 
326   observer->PrintResults();
327 
328   // In quick test synchronization may not be achieved in time.
329   if (!field_trial::IsEnabled("WebRTC-QuickPerfTest")) {
330 // TODO(bugs.webrtc.org/10417): Reenable this for iOS
331 #if !defined(WEBRTC_IOS)
332     EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
333 #endif
334   }
335 
336   task_queue()->PostTask(
337       ToQueuedTask([to_delete = observer.release()]() { delete to_delete; }));
338 }
339 
TEST_F(CallPerfTest,PlaysOutAudioAndVideoInSyncWithoutClockDrift)340 TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithoutClockDrift) {
341   TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst,
342                      DriftingClock::kNoDrift, DriftingClock::kNoDrift,
343                      DriftingClock::kNoDrift, "_video_no_drift");
344 }
345 
TEST_F(CallPerfTest,PlaysOutAudioAndVideoInSyncWithVideoNtpDrift)346 TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithVideoNtpDrift) {
347   TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst,
348                      DriftingClock::PercentsFaster(10.0f),
349                      DriftingClock::kNoDrift, DriftingClock::kNoDrift,
350                      "_video_ntp_drift");
351 }
352 
TEST_F(CallPerfTest,PlaysOutAudioAndVideoInSyncWithAudioFasterThanVideoDrift)353 TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithAudioFasterThanVideoDrift) {
354   TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst,
355                      DriftingClock::kNoDrift,
356                      DriftingClock::PercentsSlower(30.0f),
357                      DriftingClock::PercentsFaster(30.0f), "_audio_faster");
358 }
359 
TEST_F(CallPerfTest,PlaysOutAudioAndVideoInSyncWithVideoFasterThanAudioDrift)360 TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithVideoFasterThanAudioDrift) {
361   TestAudioVideoSync(FecMode::kOn, CreateOrder::kVideoFirst,
362                      DriftingClock::kNoDrift,
363                      DriftingClock::PercentsFaster(30.0f),
364                      DriftingClock::PercentsSlower(30.0f), "_video_faster");
365 }
366 
TestCaptureNtpTime(const BuiltInNetworkBehaviorConfig & net_config,int threshold_ms,int start_time_ms,int run_time_ms)367 void CallPerfTest::TestCaptureNtpTime(
368     const BuiltInNetworkBehaviorConfig& net_config,
369     int threshold_ms,
370     int start_time_ms,
371     int run_time_ms) {
372   class CaptureNtpTimeObserver : public test::EndToEndTest,
373                                  public rtc::VideoSinkInterface<VideoFrame> {
374    public:
375     CaptureNtpTimeObserver(const BuiltInNetworkBehaviorConfig& net_config,
376                            int threshold_ms,
377                            int start_time_ms,
378                            int run_time_ms)
379         : EndToEndTest(kLongTimeoutMs),
380           net_config_(net_config),
381           clock_(Clock::GetRealTimeClock()),
382           threshold_ms_(threshold_ms),
383           start_time_ms_(start_time_ms),
384           run_time_ms_(run_time_ms),
385           creation_time_ms_(clock_->TimeInMilliseconds()),
386           capturer_(nullptr),
387           rtp_start_timestamp_set_(false),
388           rtp_start_timestamp_(0) {}
389 
390    private:
391     std::unique_ptr<test::PacketTransport> CreateSendTransport(
392         TaskQueueBase* task_queue,
393         Call* sender_call) override {
394       return std::make_unique<test::PacketTransport>(
395           task_queue, sender_call, this, test::PacketTransport::kSender,
396           payload_type_map_,
397           std::make_unique<FakeNetworkPipe>(
398               Clock::GetRealTimeClock(),
399               std::make_unique<SimulatedNetwork>(net_config_)));
400     }
401 
402     std::unique_ptr<test::PacketTransport> CreateReceiveTransport(
403         TaskQueueBase* task_queue) override {
404       return std::make_unique<test::PacketTransport>(
405           task_queue, nullptr, this, test::PacketTransport::kReceiver,
406           payload_type_map_,
407           std::make_unique<FakeNetworkPipe>(
408               Clock::GetRealTimeClock(),
409               std::make_unique<SimulatedNetwork>(net_config_)));
410     }
411 
412     void OnFrame(const VideoFrame& video_frame) override {
413       MutexLock lock(&mutex_);
414       if (video_frame.ntp_time_ms() <= 0) {
415         // Haven't got enough RTCP SR in order to calculate the capture ntp
416         // time.
417         return;
418       }
419 
420       int64_t now_ms = clock_->TimeInMilliseconds();
421       int64_t time_since_creation = now_ms - creation_time_ms_;
422       if (time_since_creation < start_time_ms_) {
423         // Wait for |start_time_ms_| before start measuring.
424         return;
425       }
426 
427       if (time_since_creation > run_time_ms_) {
428         observation_complete_.Set();
429       }
430 
431       FrameCaptureTimeList::iterator iter =
432           capture_time_list_.find(video_frame.timestamp());
433       EXPECT_TRUE(iter != capture_time_list_.end());
434 
435       // The real capture time has been wrapped to uint32_t before converted
436       // to rtp timestamp in the sender side. So here we convert the estimated
437       // capture time to a uint32_t 90k timestamp also for comparing.
438       uint32_t estimated_capture_timestamp =
439           90 * static_cast<uint32_t>(video_frame.ntp_time_ms());
440       uint32_t real_capture_timestamp = iter->second;
441       int time_offset_ms = real_capture_timestamp - estimated_capture_timestamp;
442       time_offset_ms = time_offset_ms / 90;
443       time_offset_ms_list_.push_back(time_offset_ms);
444 
445       EXPECT_TRUE(std::abs(time_offset_ms) < threshold_ms_);
446     }
447 
448     Action OnSendRtp(const uint8_t* packet, size_t length) override {
449       MutexLock lock(&mutex_);
450       RtpPacket rtp_packet;
451       EXPECT_TRUE(rtp_packet.Parse(packet, length));
452 
453       if (!rtp_start_timestamp_set_) {
454         // Calculate the rtp timestamp offset in order to calculate the real
455         // capture time.
456         uint32_t first_capture_timestamp =
457             90 * static_cast<uint32_t>(capturer_->first_frame_capture_time());
458         rtp_start_timestamp_ = rtp_packet.Timestamp() - first_capture_timestamp;
459         rtp_start_timestamp_set_ = true;
460       }
461 
462       uint32_t capture_timestamp =
463           rtp_packet.Timestamp() - rtp_start_timestamp_;
464       capture_time_list_.insert(
465           capture_time_list_.end(),
466           std::make_pair(rtp_packet.Timestamp(), capture_timestamp));
467       return SEND_PACKET;
468     }
469 
470     void OnFrameGeneratorCapturerCreated(
471         test::FrameGeneratorCapturer* frame_generator_capturer) override {
472       capturer_ = frame_generator_capturer;
473     }
474 
475     void ModifyVideoConfigs(
476         VideoSendStream::Config* send_config,
477         std::vector<VideoReceiveStream::Config>* receive_configs,
478         VideoEncoderConfig* encoder_config) override {
479       (*receive_configs)[0].renderer = this;
480       // Enable the receiver side rtt calculation.
481       (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report = true;
482     }
483 
484     void PerformTest() override {
485       EXPECT_TRUE(Wait()) << "Timed out while waiting for "
486                              "estimated capture NTP time to be "
487                              "within bounds.";
488       test::PrintResultList("capture_ntp_time", "", "real - estimated",
489                             time_offset_ms_list_, "ms", true);
490     }
491 
492     Mutex mutex_;
493     const BuiltInNetworkBehaviorConfig net_config_;
494     Clock* const clock_;
495     int threshold_ms_;
496     int start_time_ms_;
497     int run_time_ms_;
498     int64_t creation_time_ms_;
499     test::FrameGeneratorCapturer* capturer_;
500     bool rtp_start_timestamp_set_;
501     uint32_t rtp_start_timestamp_;
502     typedef std::map<uint32_t, uint32_t> FrameCaptureTimeList;
503     FrameCaptureTimeList capture_time_list_ RTC_GUARDED_BY(&mutex_);
504     std::vector<double> time_offset_ms_list_;
505   } test(net_config, threshold_ms, start_time_ms, run_time_ms);
506 
507   RunBaseTest(&test);
508 }
509 
510 // Flaky tests, disabled on Mac and Windows due to webrtc:8291.
511 #if !(defined(WEBRTC_MAC) || defined(WEBRTC_WIN))
TEST_F(CallPerfTest,CaptureNtpTimeWithNetworkDelay)512 TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkDelay) {
513   BuiltInNetworkBehaviorConfig net_config;
514   net_config.queue_delay_ms = 100;
515   // TODO(wu): lower the threshold as the calculation/estimatation becomes more
516   // accurate.
517   const int kThresholdMs = 100;
518   const int kStartTimeMs = 10000;
519   const int kRunTimeMs = 20000;
520   TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs);
521 }
522 
TEST_F(CallPerfTest,CaptureNtpTimeWithNetworkJitter)523 TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkJitter) {
524   BuiltInNetworkBehaviorConfig net_config;
525   net_config.queue_delay_ms = 100;
526   net_config.delay_standard_deviation_ms = 10;
527   // TODO(wu): lower the threshold as the calculation/estimatation becomes more
528   // accurate.
529   const int kThresholdMs = 100;
530   const int kStartTimeMs = 10000;
531   const int kRunTimeMs = 20000;
532   TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs);
533 }
534 #endif
535 
TEST_F(CallPerfTest,ReceivesCpuOveruseAndUnderuse)536 TEST_F(CallPerfTest, ReceivesCpuOveruseAndUnderuse) {
537   // Minimal normal usage at the start, then 30s overuse to allow filter to
538   // settle, and then 80s underuse to allow plenty of time for rampup again.
539   test::ScopedFieldTrials fake_overuse_settings(
540       "WebRTC-ForceSimulatedOveruseIntervalMs/1-30000-80000/");
541 
542   class LoadObserver : public test::SendTest,
543                        public test::FrameGeneratorCapturer::SinkWantsObserver {
544    public:
545     LoadObserver() : SendTest(kLongTimeoutMs), test_phase_(TestPhase::kInit) {}
546 
547     void OnFrameGeneratorCapturerCreated(
548         test::FrameGeneratorCapturer* frame_generator_capturer) override {
549       frame_generator_capturer->SetSinkWantsObserver(this);
550       // Set a high initial resolution to be sure that we can scale down.
551       frame_generator_capturer->ChangeResolution(1920, 1080);
552     }
553 
554     // OnSinkWantsChanged is called when FrameGeneratorCapturer::AddOrUpdateSink
555     // is called.
556     // TODO(sprang): Add integration test for maintain-framerate mode?
557     void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
558                             const rtc::VideoSinkWants& wants) override {
559       // At kStart expect CPU overuse. Then expect CPU underuse when the encoder
560       // delay has been decreased.
561       switch (test_phase_) {
562         case TestPhase::kInit:
563           // Max framerate should be set initially.
564           if (wants.max_framerate_fps != std::numeric_limits<int>::max() &&
565               wants.max_pixel_count == std::numeric_limits<int>::max()) {
566             test_phase_ = TestPhase::kStart;
567           } else {
568             ADD_FAILURE() << "Got unexpected adaptation request, max res = "
569                           << wants.max_pixel_count << ", target res = "
570                           << wants.target_pixel_count.value_or(-1)
571                           << ", max fps = " << wants.max_framerate_fps;
572           }
573           break;
574         case TestPhase::kStart:
575           if (wants.max_pixel_count < std::numeric_limits<int>::max()) {
576             // On adapting down, VideoStreamEncoder::VideoSourceProxy will set
577             // only the max pixel count, leaving the target unset.
578             test_phase_ = TestPhase::kAdaptedDown;
579           } else {
580             ADD_FAILURE() << "Got unexpected adaptation request, max res = "
581                           << wants.max_pixel_count << ", target res = "
582                           << wants.target_pixel_count.value_or(-1)
583                           << ", max fps = " << wants.max_framerate_fps;
584           }
585           break;
586         case TestPhase::kAdaptedDown:
587           // On adapting up, the adaptation counter will again be at zero, and
588           // so all constraints will be reset.
589           if (wants.max_pixel_count == std::numeric_limits<int>::max() &&
590               !wants.target_pixel_count) {
591             test_phase_ = TestPhase::kAdaptedUp;
592             observation_complete_.Set();
593           } else {
594             ADD_FAILURE() << "Got unexpected adaptation request, max res = "
595                           << wants.max_pixel_count << ", target res = "
596                           << wants.target_pixel_count.value_or(-1)
597                           << ", max fps = " << wants.max_framerate_fps;
598           }
599           break;
600         case TestPhase::kAdaptedUp:
601           ADD_FAILURE() << "Got unexpected adaptation request, max res = "
602                         << wants.max_pixel_count << ", target res = "
603                         << wants.target_pixel_count.value_or(-1)
604                         << ", max fps = " << wants.max_framerate_fps;
605       }
606     }
607 
608     void ModifyVideoConfigs(
609         VideoSendStream::Config* send_config,
610         std::vector<VideoReceiveStream::Config>* receive_configs,
611         VideoEncoderConfig* encoder_config) override {}
612 
613     void PerformTest() override {
614       EXPECT_TRUE(Wait()) << "Timed out before receiving an overuse callback.";
615     }
616 
617     enum class TestPhase {
618       kInit,
619       kStart,
620       kAdaptedDown,
621       kAdaptedUp
622     } test_phase_;
623   } test;
624 
625   RunBaseTest(&test);
626 }
627 
TestMinTransmitBitrate(bool pad_to_min_bitrate)628 void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
629   static const int kMaxEncodeBitrateKbps = 30;
630   static const int kMinTransmitBitrateBps = 150000;
631   static const int kMinAcceptableTransmitBitrate = 130;
632   static const int kMaxAcceptableTransmitBitrate = 170;
633   static const int kNumBitrateObservationsInRange = 100;
634   static const int kAcceptableBitrateErrorMargin = 15;  // +- 7
635   class BitrateObserver : public test::EndToEndTest {
636    public:
637     explicit BitrateObserver(bool using_min_transmit_bitrate)
638         : EndToEndTest(kLongTimeoutMs),
639           send_stream_(nullptr),
640           converged_(false),
641           pad_to_min_bitrate_(using_min_transmit_bitrate),
642           min_acceptable_bitrate_(using_min_transmit_bitrate
643                                       ? kMinAcceptableTransmitBitrate
644                                       : (kMaxEncodeBitrateKbps -
645                                          kAcceptableBitrateErrorMargin / 2)),
646           max_acceptable_bitrate_(using_min_transmit_bitrate
647                                       ? kMaxAcceptableTransmitBitrate
648                                       : (kMaxEncodeBitrateKbps +
649                                          kAcceptableBitrateErrorMargin / 2)),
650           num_bitrate_observations_in_range_(0) {}
651 
652    private:
653     // TODO(holmer): Run this with a timer instead of once per packet.
654     Action OnSendRtp(const uint8_t* packet, size_t length) override {
655       VideoSendStream::Stats stats = send_stream_->GetStats();
656       if (!stats.substreams.empty()) {
657         RTC_DCHECK_EQ(1, stats.substreams.size());
658         int bitrate_kbps =
659             stats.substreams.begin()->second.total_bitrate_bps / 1000;
660         if (bitrate_kbps > min_acceptable_bitrate_ &&
661             bitrate_kbps < max_acceptable_bitrate_) {
662           converged_ = true;
663           ++num_bitrate_observations_in_range_;
664           if (num_bitrate_observations_in_range_ ==
665               kNumBitrateObservationsInRange)
666             observation_complete_.Set();
667         }
668         if (converged_)
669           bitrate_kbps_list_.push_back(bitrate_kbps);
670       }
671       return SEND_PACKET;
672     }
673 
674     void OnVideoStreamsCreated(
675         VideoSendStream* send_stream,
676         const std::vector<VideoReceiveStream*>& receive_streams) override {
677       send_stream_ = send_stream;
678     }
679 
680     void ModifyVideoConfigs(
681         VideoSendStream::Config* send_config,
682         std::vector<VideoReceiveStream::Config>* receive_configs,
683         VideoEncoderConfig* encoder_config) override {
684       if (pad_to_min_bitrate_) {
685         encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
686       } else {
687         RTC_DCHECK_EQ(0, encoder_config->min_transmit_bitrate_bps);
688       }
689     }
690 
691     void PerformTest() override {
692       EXPECT_TRUE(Wait()) << "Timeout while waiting for send-bitrate stats.";
693       test::PrintResultList(
694           "bitrate_stats_",
695           (pad_to_min_bitrate_ ? "min_transmit_bitrate"
696                                : "without_min_transmit_bitrate"),
697           "bitrate_kbps", bitrate_kbps_list_, "kbps", false);
698     }
699 
700     VideoSendStream* send_stream_;
701     bool converged_;
702     const bool pad_to_min_bitrate_;
703     const int min_acceptable_bitrate_;
704     const int max_acceptable_bitrate_;
705     int num_bitrate_observations_in_range_;
706     std::vector<double> bitrate_kbps_list_;
707   } test(pad_to_min_bitrate);
708 
709   fake_encoder_max_bitrate_ = kMaxEncodeBitrateKbps;
710   RunBaseTest(&test);
711 }
712 
TEST_F(CallPerfTest,PadsToMinTransmitBitrate)713 TEST_F(CallPerfTest, PadsToMinTransmitBitrate) {
714   TestMinTransmitBitrate(true);
715 }
716 
TEST_F(CallPerfTest,NoPadWithoutMinTransmitBitrate)717 TEST_F(CallPerfTest, NoPadWithoutMinTransmitBitrate) {
718   TestMinTransmitBitrate(false);
719 }
720 
721 // TODO(bugs.webrtc.org/8878)
722 #if defined(WEBRTC_MAC)
723 #define MAYBE_KeepsHighBitrateWhenReconfiguringSender \
724   DISABLED_KeepsHighBitrateWhenReconfiguringSender
725 #else
726 #define MAYBE_KeepsHighBitrateWhenReconfiguringSender \
727   KeepsHighBitrateWhenReconfiguringSender
728 #endif
TEST_F(CallPerfTest,MAYBE_KeepsHighBitrateWhenReconfiguringSender)729 TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
730   static const uint32_t kInitialBitrateKbps = 400;
731   static const uint32_t kReconfigureThresholdKbps = 600;
732 
733   class VideoStreamFactory
734       : public VideoEncoderConfig::VideoStreamFactoryInterface {
735    public:
736     VideoStreamFactory() {}
737 
738    private:
739     std::vector<VideoStream> CreateEncoderStreams(
740         int width,
741         int height,
742         const VideoEncoderConfig& encoder_config) override {
743       std::vector<VideoStream> streams =
744           test::CreateVideoStreams(width, height, encoder_config);
745       streams[0].min_bitrate_bps = 50000;
746       streams[0].target_bitrate_bps = streams[0].max_bitrate_bps = 2000000;
747       return streams;
748     }
749   };
750 
751   class BitrateObserver : public test::EndToEndTest, public test::FakeEncoder {
752    public:
753     BitrateObserver()
754         : EndToEndTest(kDefaultTimeoutMs),
755           FakeEncoder(Clock::GetRealTimeClock()),
756           encoder_inits_(0),
757           last_set_bitrate_kbps_(0),
758           send_stream_(nullptr),
759           frame_generator_(nullptr),
760           encoder_factory_(this),
761           bitrate_allocator_factory_(
762               CreateBuiltinVideoBitrateAllocatorFactory()) {}
763 
764     int32_t InitEncode(const VideoCodec* config,
765                        const VideoEncoder::Settings& settings) override {
766       ++encoder_inits_;
767       if (encoder_inits_ == 1) {
768         // First time initialization. Frame size is known.
769         // |expected_bitrate| is affected by bandwidth estimation before the
770         // first frame arrives to the encoder.
771         uint32_t expected_bitrate = last_set_bitrate_kbps_ > 0
772                                         ? last_set_bitrate_kbps_
773                                         : kInitialBitrateKbps;
774         EXPECT_EQ(expected_bitrate, config->startBitrate)
775             << "Encoder not initialized at expected bitrate.";
776         EXPECT_EQ(kDefaultWidth, config->width);
777         EXPECT_EQ(kDefaultHeight, config->height);
778       } else if (encoder_inits_ == 2) {
779         EXPECT_EQ(2 * kDefaultWidth, config->width);
780         EXPECT_EQ(2 * kDefaultHeight, config->height);
781         EXPECT_GE(last_set_bitrate_kbps_, kReconfigureThresholdKbps);
782         EXPECT_GT(config->startBitrate, kReconfigureThresholdKbps)
783             << "Encoder reconfigured with bitrate too far away from last set.";
784         observation_complete_.Set();
785       }
786       return FakeEncoder::InitEncode(config, settings);
787     }
788 
789     void SetRates(const RateControlParameters& parameters) override {
790       last_set_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
791       if (encoder_inits_ == 1 &&
792           parameters.bitrate.get_sum_kbps() > kReconfigureThresholdKbps) {
793         time_to_reconfigure_.Set();
794       }
795       FakeEncoder::SetRates(parameters);
796     }
797 
798     void ModifySenderBitrateConfig(
799         BitrateConstraints* bitrate_config) override {
800       bitrate_config->start_bitrate_bps = kInitialBitrateKbps * 1000;
801     }
802 
803     void ModifyVideoConfigs(
804         VideoSendStream::Config* send_config,
805         std::vector<VideoReceiveStream::Config>* receive_configs,
806         VideoEncoderConfig* encoder_config) override {
807       send_config->encoder_settings.encoder_factory = &encoder_factory_;
808       send_config->encoder_settings.bitrate_allocator_factory =
809           bitrate_allocator_factory_.get();
810       encoder_config->max_bitrate_bps = 2 * kReconfigureThresholdKbps * 1000;
811       encoder_config->video_stream_factory =
812           new rtc::RefCountedObject<VideoStreamFactory>();
813 
814       encoder_config_ = encoder_config->Copy();
815     }
816 
817     void OnVideoStreamsCreated(
818         VideoSendStream* send_stream,
819         const std::vector<VideoReceiveStream*>& receive_streams) override {
820       send_stream_ = send_stream;
821     }
822 
823     void OnFrameGeneratorCapturerCreated(
824         test::FrameGeneratorCapturer* frame_generator_capturer) override {
825       frame_generator_ = frame_generator_capturer;
826     }
827 
828     void PerformTest() override {
829       ASSERT_TRUE(time_to_reconfigure_.Wait(kDefaultTimeoutMs))
830           << "Timed out before receiving an initial high bitrate.";
831       frame_generator_->ChangeResolution(kDefaultWidth * 2, kDefaultHeight * 2);
832       send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
833       EXPECT_TRUE(Wait())
834           << "Timed out while waiting for a couple of high bitrate estimates "
835              "after reconfiguring the send stream.";
836     }
837 
838    private:
839     rtc::Event time_to_reconfigure_;
840     int encoder_inits_;
841     uint32_t last_set_bitrate_kbps_;
842     VideoSendStream* send_stream_;
843     test::FrameGeneratorCapturer* frame_generator_;
844     test::VideoEncoderProxyFactory encoder_factory_;
845     std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
846     VideoEncoderConfig encoder_config_;
847   } test;
848 
849   RunBaseTest(&test);
850 }
851 
852 // Discovers the minimal supported audio+video bitrate. The test bitrate is
853 // considered supported if Rtt does not go above 400ms with the network
854 // contrained to the test bitrate.
855 //
856 // |test_bitrate_from test_bitrate_to| bitrate constraint range
857 // |test_bitrate_step| bitrate constraint update step during the test
858 // |min_bwe max_bwe| BWE range
859 // |start_bwe| initial BWE
TestMinAudioVideoBitrate(int test_bitrate_from,int test_bitrate_to,int test_bitrate_step,int min_bwe,int start_bwe,int max_bwe)860 void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from,
861                                             int test_bitrate_to,
862                                             int test_bitrate_step,
863                                             int min_bwe,
864                                             int start_bwe,
865                                             int max_bwe) {
866   static const std::string kAudioTrackId = "audio_track_0";
867   static constexpr int kOpusBitrateFbBps = 32000;
868   static constexpr int kBitrateStabilizationMs = 10000;
869   static constexpr int kBitrateMeasurements = 10;
870   static constexpr int kBitrateMeasurementMs = 1000;
871   static constexpr int kShortDelayMs = 10;
872   static constexpr int kMinGoodRttMs = 400;
873 
874   class MinVideoAndAudioBitrateTester : public test::EndToEndTest {
875    public:
876     MinVideoAndAudioBitrateTester(int test_bitrate_from,
877                                   int test_bitrate_to,
878                                   int test_bitrate_step,
879                                   int min_bwe,
880                                   int start_bwe,
881                                   int max_bwe,
882                                   TaskQueueBase* task_queue)
883         : EndToEndTest(),
884           test_bitrate_from_(test_bitrate_from),
885           test_bitrate_to_(test_bitrate_to),
886           test_bitrate_step_(test_bitrate_step),
887           min_bwe_(min_bwe),
888           start_bwe_(start_bwe),
889           max_bwe_(max_bwe),
890           task_queue_(task_queue) {}
891 
892    protected:
893     BuiltInNetworkBehaviorConfig GetFakeNetworkPipeConfig() {
894       BuiltInNetworkBehaviorConfig pipe_config;
895       pipe_config.link_capacity_kbps = test_bitrate_from_;
896       return pipe_config;
897     }
898 
899     std::unique_ptr<test::PacketTransport> CreateSendTransport(
900         TaskQueueBase* task_queue,
901         Call* sender_call) override {
902       auto network =
903           std::make_unique<SimulatedNetwork>(GetFakeNetworkPipeConfig());
904       send_simulated_network_ = network.get();
905       return std::make_unique<test::PacketTransport>(
906           task_queue, sender_call, this, test::PacketTransport::kSender,
907           test::CallTest::payload_type_map_,
908           std::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
909                                             std::move(network)));
910     }
911 
912     std::unique_ptr<test::PacketTransport> CreateReceiveTransport(
913         TaskQueueBase* task_queue) override {
914       auto network =
915           std::make_unique<SimulatedNetwork>(GetFakeNetworkPipeConfig());
916       receive_simulated_network_ = network.get();
917       return std::make_unique<test::PacketTransport>(
918           task_queue, nullptr, this, test::PacketTransport::kReceiver,
919           test::CallTest::payload_type_map_,
920           std::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
921                                             std::move(network)));
922     }
923 
924     void PerformTest() override {
925       // Quick test mode, just to exercise all the code paths without actually
926       // caring about performance measurements.
927       const bool quick_perf_test =
928           field_trial::IsEnabled("WebRTC-QuickPerfTest");
929       int last_passed_test_bitrate = -1;
930       for (int test_bitrate = test_bitrate_from_;
931            test_bitrate_from_ < test_bitrate_to_
932                ? test_bitrate <= test_bitrate_to_
933                : test_bitrate >= test_bitrate_to_;
934            test_bitrate += test_bitrate_step_) {
935         BuiltInNetworkBehaviorConfig pipe_config;
936         pipe_config.link_capacity_kbps = test_bitrate;
937         send_simulated_network_->SetConfig(pipe_config);
938         receive_simulated_network_->SetConfig(pipe_config);
939 
940         rtc::Thread::SleepMs(quick_perf_test ? kShortDelayMs
941                                              : kBitrateStabilizationMs);
942 
943         int64_t avg_rtt = 0;
944         for (int i = 0; i < kBitrateMeasurements; i++) {
945           Call::Stats call_stats;
946           SendTask(RTC_FROM_HERE, task_queue_, [this, &call_stats]() {
947             call_stats = sender_call_->GetStats();
948           });
949           avg_rtt += call_stats.rtt_ms;
950           rtc::Thread::SleepMs(quick_perf_test ? kShortDelayMs
951                                                : kBitrateMeasurementMs);
952         }
953         avg_rtt = avg_rtt / kBitrateMeasurements;
954         if (avg_rtt > kMinGoodRttMs) {
955           break;
956         } else {
957           last_passed_test_bitrate = test_bitrate;
958         }
959       }
960       EXPECT_GT(last_passed_test_bitrate, -1)
961           << "Minimum supported bitrate out of the test scope";
962       webrtc::test::PrintResult("min_test_bitrate_", "", "min_bitrate",
963                                 last_passed_test_bitrate, "kbps", false);
964     }
965 
966     void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
967       sender_call_ = sender_call;
968       BitrateConstraints bitrate_config;
969       bitrate_config.min_bitrate_bps = min_bwe_;
970       bitrate_config.start_bitrate_bps = start_bwe_;
971       bitrate_config.max_bitrate_bps = max_bwe_;
972       sender_call->GetTransportControllerSend()->SetSdpBitrateParameters(
973           bitrate_config);
974     }
975 
976     size_t GetNumVideoStreams() const override { return 1; }
977 
978     size_t GetNumAudioStreams() const override { return 1; }
979 
980     void ModifyAudioConfigs(
981         AudioSendStream::Config* send_config,
982         std::vector<AudioReceiveStream::Config>* receive_configs) override {
983       send_config->send_codec_spec->target_bitrate_bps =
984           absl::optional<int>(kOpusBitrateFbBps);
985     }
986 
987    private:
988     const int test_bitrate_from_;
989     const int test_bitrate_to_;
990     const int test_bitrate_step_;
991     const int min_bwe_;
992     const int start_bwe_;
993     const int max_bwe_;
994     SimulatedNetwork* send_simulated_network_;
995     SimulatedNetwork* receive_simulated_network_;
996     Call* sender_call_;
997     TaskQueueBase* const task_queue_;
998   } test(test_bitrate_from, test_bitrate_to, test_bitrate_step, min_bwe,
999          start_bwe, max_bwe, task_queue());
1000 
1001   RunBaseTest(&test);
1002 }
1003 
1004 // TODO(bugs.webrtc.org/8878)
1005 #if defined(WEBRTC_MAC)
1006 #define MAYBE_MinVideoAndAudioBitrate DISABLED_MinVideoAndAudioBitrate
1007 #else
1008 #define MAYBE_MinVideoAndAudioBitrate MinVideoAndAudioBitrate
1009 #endif
TEST_F(CallPerfTest,MAYBE_MinVideoAndAudioBitrate)1010 TEST_F(CallPerfTest, MAYBE_MinVideoAndAudioBitrate) {
1011   TestMinAudioVideoBitrate(110, 40, -10, 10000, 70000, 200000);
1012 }
1013 
1014 }  // namespace webrtc
1015