Home | History | Annotate | Download | only in video
      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 #include <assert.h>
     11 
     12 #include <algorithm>
     13 #include <sstream>
     14 #include <string>
     15 
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 #include "webrtc/call.h"
     19 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
     20 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
     21 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
     22 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     23 #include "webrtc/system_wrappers/interface/rtp_to_ntp.h"
     24 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     25 #include "webrtc/system_wrappers/interface/thread_annotations.h"
     26 #include "webrtc/test/direct_transport.h"
     27 #include "webrtc/test/encoder_settings.h"
     28 #include "webrtc/test/fake_audio_device.h"
     29 #include "webrtc/test/fake_decoder.h"
     30 #include "webrtc/test/fake_encoder.h"
     31 #include "webrtc/test/frame_generator.h"
     32 #include "webrtc/test/frame_generator_capturer.h"
     33 #include "webrtc/test/rtp_rtcp_observer.h"
     34 #include "webrtc/test/testsupport/fileutils.h"
     35 #include "webrtc/test/testsupport/perf_test.h"
     36 #include "webrtc/video/transport_adapter.h"
     37 #include "webrtc/voice_engine/include/voe_base.h"
     38 #include "webrtc/voice_engine/include/voe_codec.h"
     39 #include "webrtc/voice_engine/include/voe_network.h"
     40 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
     41 #include "webrtc/voice_engine/include/voe_video_sync.h"
     42 
     43 namespace webrtc {
     44 
     45 static unsigned int kLongTimeoutMs = 120 * 1000;
     46 static const uint32_t kSendSsrc = 0x654321;
     47 static const uint32_t kReceiverLocalSsrc = 0x123456;
     48 static const uint8_t kSendPayloadType = 125;
     49 
     50 class CallPerfTest : public ::testing::Test {
     51  public:
     52   CallPerfTest()
     53       : send_stream_(NULL), fake_encoder_(Clock::GetRealTimeClock()) {}
     54 
     55  protected:
     56   void CreateTestConfig(Call* call) {
     57     send_config_ = call->GetDefaultSendConfig();
     58     send_config_.rtp.ssrcs.push_back(kSendSsrc);
     59     send_config_.encoder_settings.encoder = &fake_encoder_;
     60     send_config_.encoder_settings.payload_type = kSendPayloadType;
     61     send_config_.encoder_settings.payload_name = "FAKE";
     62     video_streams_ = test::CreateVideoStreams(1);
     63   }
     64 
     65   void RunVideoSendTest(Call* call,
     66                         const VideoSendStream::Config& config,
     67                         test::RtpRtcpObserver* observer) {
     68     send_stream_ = call->CreateVideoSendStream(config, video_streams_, NULL);
     69     scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
     70         test::FrameGeneratorCapturer::Create(
     71             send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
     72     send_stream_->Start();
     73     frame_generator_capturer->Start();
     74 
     75     EXPECT_EQ(kEventSignaled, observer->Wait());
     76 
     77     observer->StopSending();
     78     frame_generator_capturer->Stop();
     79     send_stream_->Stop();
     80     call->DestroyVideoSendStream(send_stream_);
     81   }
     82 
     83   void TestMinTransmitBitrate(bool pad_to_min_bitrate);
     84 
     85   void TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
     86                           int threshold_ms,
     87                           int start_time_ms,
     88                           int run_time_ms);
     89 
     90   VideoSendStream::Config send_config_;
     91   std::vector<VideoStream> video_streams_;
     92   VideoSendStream* send_stream_;
     93   test::FakeEncoder fake_encoder_;
     94 };
     95 
     96 class SyncRtcpObserver : public test::RtpRtcpObserver {
     97  public:
     98   explicit SyncRtcpObserver(const FakeNetworkPipe::Config& config)
     99       : test::RtpRtcpObserver(kLongTimeoutMs, config),
    100         crit_(CriticalSectionWrapper::CreateCriticalSection()) {}
    101 
    102   virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
    103     RTCPUtility::RTCPParserV2 parser(packet, length, true);
    104     EXPECT_TRUE(parser.IsValid());
    105 
    106     for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
    107          packet_type != RTCPUtility::kRtcpNotValidCode;
    108          packet_type = parser.Iterate()) {
    109       if (packet_type == RTCPUtility::kRtcpSrCode) {
    110         const RTCPUtility::RTCPPacket& packet = parser.Packet();
    111         RtcpMeasurement ntp_rtp_pair(
    112             packet.SR.NTPMostSignificant,
    113             packet.SR.NTPLeastSignificant,
    114             packet.SR.RTPTimestamp);
    115         StoreNtpRtpPair(ntp_rtp_pair);
    116       }
    117     }
    118     return SEND_PACKET;
    119   }
    120 
    121   int64_t RtpTimestampToNtp(uint32_t timestamp) const {
    122     CriticalSectionScoped lock(crit_.get());
    123     int64_t timestamp_in_ms = -1;
    124     if (ntp_rtp_pairs_.size() == 2) {
    125       // TODO(stefan): We can't EXPECT_TRUE on this call due to a bug in the
    126       // RTCP sender where it sends RTCP SR before any RTP packets, which leads
    127       // to a bogus NTP/RTP mapping.
    128       RtpToNtpMs(timestamp, ntp_rtp_pairs_, &timestamp_in_ms);
    129       return timestamp_in_ms;
    130     }
    131     return -1;
    132   }
    133 
    134  private:
    135   void StoreNtpRtpPair(RtcpMeasurement ntp_rtp_pair) {
    136     CriticalSectionScoped lock(crit_.get());
    137     for (RtcpList::iterator it = ntp_rtp_pairs_.begin();
    138          it != ntp_rtp_pairs_.end();
    139          ++it) {
    140       if (ntp_rtp_pair.ntp_secs == it->ntp_secs &&
    141           ntp_rtp_pair.ntp_frac == it->ntp_frac) {
    142         // This RTCP has already been added to the list.
    143         return;
    144       }
    145     }
    146     // We need two RTCP SR reports to map between RTP and NTP. More than two
    147     // will not improve the mapping.
    148     if (ntp_rtp_pairs_.size() == 2) {
    149       ntp_rtp_pairs_.pop_back();
    150     }
    151     ntp_rtp_pairs_.push_front(ntp_rtp_pair);
    152   }
    153 
    154   const scoped_ptr<CriticalSectionWrapper> crit_;
    155   RtcpList ntp_rtp_pairs_ GUARDED_BY(crit_);
    156 };
    157 
    158 class VideoRtcpAndSyncObserver : public SyncRtcpObserver, public VideoRenderer {
    159   static const int kInSyncThresholdMs = 50;
    160   static const int kStartupTimeMs = 2000;
    161   static const int kMinRunTimeMs = 30000;
    162 
    163  public:
    164   VideoRtcpAndSyncObserver(Clock* clock,
    165                            int voe_channel,
    166                            VoEVideoSync* voe_sync,
    167                            SyncRtcpObserver* audio_observer)
    168       : SyncRtcpObserver(FakeNetworkPipe::Config()),
    169         clock_(clock),
    170         voe_channel_(voe_channel),
    171         voe_sync_(voe_sync),
    172         audio_observer_(audio_observer),
    173         creation_time_ms_(clock_->TimeInMilliseconds()),
    174         first_time_in_sync_(-1) {}
    175 
    176   virtual void RenderFrame(const I420VideoFrame& video_frame,
    177                            int time_to_render_ms) OVERRIDE {
    178     int64_t now_ms = clock_->TimeInMilliseconds();
    179     uint32_t playout_timestamp = 0;
    180     if (voe_sync_->GetPlayoutTimestamp(voe_channel_, playout_timestamp) != 0)
    181       return;
    182     int64_t latest_audio_ntp =
    183         audio_observer_->RtpTimestampToNtp(playout_timestamp);
    184     int64_t latest_video_ntp = RtpTimestampToNtp(video_frame.timestamp());
    185     if (latest_audio_ntp < 0 || latest_video_ntp < 0)
    186       return;
    187     int time_until_render_ms =
    188         std::max(0, static_cast<int>(video_frame.render_time_ms() - now_ms));
    189     latest_video_ntp += time_until_render_ms;
    190     int64_t stream_offset = latest_audio_ntp - latest_video_ntp;
    191     std::stringstream ss;
    192     ss << stream_offset;
    193     webrtc::test::PrintResult("stream_offset",
    194                               "",
    195                               "synchronization",
    196                               ss.str(),
    197                               "ms",
    198                               false);
    199     int64_t time_since_creation = now_ms - creation_time_ms_;
    200     // During the first couple of seconds audio and video can falsely be
    201     // estimated as being synchronized. We don't want to trigger on those.
    202     if (time_since_creation < kStartupTimeMs)
    203       return;
    204     if (std::abs(latest_audio_ntp - latest_video_ntp) < kInSyncThresholdMs) {
    205       if (first_time_in_sync_ == -1) {
    206         first_time_in_sync_ = now_ms;
    207         webrtc::test::PrintResult("sync_convergence_time",
    208                                   "",
    209                                   "synchronization",
    210                                   time_since_creation,
    211                                   "ms",
    212                                   false);
    213       }
    214       if (time_since_creation > kMinRunTimeMs)
    215         observation_complete_->Set();
    216     }
    217   }
    218 
    219  private:
    220   Clock* const clock_;
    221   int voe_channel_;
    222   VoEVideoSync* voe_sync_;
    223   SyncRtcpObserver* audio_observer_;
    224   int64_t creation_time_ms_;
    225   int64_t first_time_in_sync_;
    226 };
    227 
    228 TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSync) {
    229   VoiceEngine* voice_engine = VoiceEngine::Create();
    230   VoEBase* voe_base = VoEBase::GetInterface(voice_engine);
    231   VoECodec* voe_codec = VoECodec::GetInterface(voice_engine);
    232   VoENetwork* voe_network = VoENetwork::GetInterface(voice_engine);
    233   VoEVideoSync* voe_sync = VoEVideoSync::GetInterface(voice_engine);
    234   const std::string audio_filename =
    235       test::ResourcePath("voice_engine/audio_long16", "pcm");
    236   ASSERT_STRNE("", audio_filename.c_str());
    237   test::FakeAudioDevice fake_audio_device(Clock::GetRealTimeClock(),
    238                                           audio_filename);
    239   EXPECT_EQ(0, voe_base->Init(&fake_audio_device, NULL));
    240   int channel = voe_base->CreateChannel();
    241 
    242   FakeNetworkPipe::Config net_config;
    243   net_config.queue_delay_ms = 500;
    244   SyncRtcpObserver audio_observer(net_config);
    245   VideoRtcpAndSyncObserver observer(Clock::GetRealTimeClock(),
    246                                     channel,
    247                                     voe_sync,
    248                                     &audio_observer);
    249 
    250   Call::Config receiver_config(observer.ReceiveTransport());
    251   receiver_config.voice_engine = voice_engine;
    252   scoped_ptr<Call> sender_call(
    253       Call::Create(Call::Config(observer.SendTransport())));
    254   scoped_ptr<Call> receiver_call(Call::Create(receiver_config));
    255   CodecInst isac = {103, "ISAC", 16000, 480, 1, 32000};
    256   EXPECT_EQ(0, voe_codec->SetSendCodec(channel, isac));
    257 
    258   class VoicePacketReceiver : public PacketReceiver {
    259    public:
    260     VoicePacketReceiver(int channel, VoENetwork* voe_network)
    261         : channel_(channel),
    262           voe_network_(voe_network),
    263           parser_(RtpHeaderParser::Create()) {}
    264     virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
    265                                          size_t length) OVERRIDE {
    266       int ret;
    267       if (parser_->IsRtcp(packet, static_cast<int>(length))) {
    268         ret = voe_network_->ReceivedRTCPPacket(
    269             channel_, packet, static_cast<unsigned int>(length));
    270       } else {
    271         ret = voe_network_->ReceivedRTPPacket(
    272             channel_, packet, static_cast<unsigned int>(length), PacketTime());
    273       }
    274       return ret == 0 ? DELIVERY_OK : DELIVERY_PACKET_ERROR;
    275     }
    276 
    277    private:
    278     int channel_;
    279     VoENetwork* voe_network_;
    280     scoped_ptr<RtpHeaderParser> parser_;
    281   } voe_packet_receiver(channel, voe_network);
    282 
    283   audio_observer.SetReceivers(&voe_packet_receiver, &voe_packet_receiver);
    284 
    285   internal::TransportAdapter transport_adapter(audio_observer.SendTransport());
    286   transport_adapter.Enable();
    287   EXPECT_EQ(0,
    288             voe_network->RegisterExternalTransport(channel, transport_adapter));
    289 
    290   observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver());
    291 
    292   test::FakeDecoder fake_decoder;
    293 
    294   CreateTestConfig(sender_call.get());
    295 
    296   VideoReceiveStream::Config receive_config =
    297       receiver_call->GetDefaultReceiveConfig();
    298   assert(receive_config.codecs.empty());
    299   VideoCodec codec =
    300       test::CreateDecoderVideoCodec(send_config_.encoder_settings);
    301   receive_config.codecs.push_back(codec);
    302   assert(receive_config.external_decoders.empty());
    303   ExternalVideoDecoder decoder;
    304   decoder.decoder = &fake_decoder;
    305   decoder.payload_type = send_config_.encoder_settings.payload_type;
    306   receive_config.external_decoders.push_back(decoder);
    307   receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
    308   receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
    309   receive_config.renderer = &observer;
    310   receive_config.audio_channel_id = channel;
    311 
    312   VideoSendStream* send_stream =
    313       sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
    314   VideoReceiveStream* receive_stream =
    315       receiver_call->CreateVideoReceiveStream(receive_config);
    316   scoped_ptr<test::FrameGeneratorCapturer> capturer(
    317       test::FrameGeneratorCapturer::Create(send_stream->Input(),
    318                                            video_streams_[0].width,
    319                                            video_streams_[0].height,
    320                                            30,
    321                                            Clock::GetRealTimeClock()));
    322   receive_stream->Start();
    323   send_stream->Start();
    324   capturer->Start();
    325 
    326   fake_audio_device.Start();
    327   EXPECT_EQ(0, voe_base->StartPlayout(channel));
    328   EXPECT_EQ(0, voe_base->StartReceive(channel));
    329   EXPECT_EQ(0, voe_base->StartSend(channel));
    330 
    331   EXPECT_EQ(kEventSignaled, observer.Wait())
    332       << "Timed out while waiting for audio and video to be synchronized.";
    333 
    334   EXPECT_EQ(0, voe_base->StopSend(channel));
    335   EXPECT_EQ(0, voe_base->StopReceive(channel));
    336   EXPECT_EQ(0, voe_base->StopPlayout(channel));
    337   fake_audio_device.Stop();
    338 
    339   capturer->Stop();
    340   send_stream->Stop();
    341   receive_stream->Stop();
    342   observer.StopSending();
    343   audio_observer.StopSending();
    344 
    345   voe_base->DeleteChannel(channel);
    346   voe_base->Release();
    347   voe_codec->Release();
    348   voe_network->Release();
    349   voe_sync->Release();
    350   sender_call->DestroyVideoSendStream(send_stream);
    351   receiver_call->DestroyVideoReceiveStream(receive_stream);
    352   VoiceEngine::Delete(voice_engine);
    353 }
    354 
    355 class CaptureNtpTimeObserver : public test::RtpRtcpObserver,
    356                                public VideoRenderer {
    357  public:
    358   CaptureNtpTimeObserver(Clock* clock,
    359                          const FakeNetworkPipe::Config& config,
    360                          int threshold_ms,
    361                          int start_time_ms,
    362                          int run_time_ms)
    363       : RtpRtcpObserver(kLongTimeoutMs, config),
    364         clock_(clock),
    365         threshold_ms_(threshold_ms),
    366         start_time_ms_(start_time_ms),
    367         run_time_ms_(run_time_ms),
    368         creation_time_ms_(clock_->TimeInMilliseconds()),
    369         capturer_(NULL),
    370         rtp_start_timestamp_set_(false),
    371         rtp_start_timestamp_(0) {}
    372 
    373   virtual void RenderFrame(const I420VideoFrame& video_frame,
    374                            int time_to_render_ms) OVERRIDE {
    375     if (video_frame.ntp_time_ms() <= 0) {
    376       // Haven't got enough RTCP SR in order to calculate the capture ntp time.
    377       return;
    378     }
    379 
    380     int64_t now_ms = clock_->TimeInMilliseconds();
    381     int64_t time_since_creation = now_ms - creation_time_ms_;
    382     if (time_since_creation < start_time_ms_) {
    383       // Wait for |start_time_ms_| before start measuring.
    384       return;
    385     }
    386 
    387     if (time_since_creation > run_time_ms_) {
    388       observation_complete_->Set();
    389     }
    390 
    391     FrameCaptureTimeList::iterator iter =
    392         capture_time_list_.find(video_frame.timestamp());
    393     EXPECT_TRUE(iter != capture_time_list_.end());
    394 
    395     // The real capture time has been wrapped to uint32_t before converted
    396     // to rtp timestamp in the sender side. So here we convert the estimated
    397     // capture time to a uint32_t 90k timestamp also for comparing.
    398     uint32_t estimated_capture_timestamp =
    399         90 * static_cast<uint32_t>(video_frame.ntp_time_ms());
    400     uint32_t real_capture_timestamp = iter->second;
    401     int time_offset_ms = real_capture_timestamp - estimated_capture_timestamp;
    402     time_offset_ms = time_offset_ms / 90;
    403     std::stringstream ss;
    404     ss << time_offset_ms;
    405 
    406     webrtc::test::PrintResult("capture_ntp_time",
    407                               "",
    408                               "real - estimated",
    409                               ss.str(),
    410                               "ms",
    411                               true);
    412     EXPECT_TRUE(std::abs(time_offset_ms) < threshold_ms_);
    413   }
    414 
    415   virtual Action OnSendRtp(const uint8_t* packet, size_t length) {
    416     RTPHeader header;
    417     EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
    418 
    419     if (!rtp_start_timestamp_set_) {
    420       // Calculate the rtp timestamp offset in order to calculate the real
    421       // capture time.
    422       uint32_t first_capture_timestamp =
    423           90 * static_cast<uint32_t>(capturer_->first_frame_capture_time());
    424       rtp_start_timestamp_ = header.timestamp - first_capture_timestamp;
    425       rtp_start_timestamp_set_ = true;
    426     }
    427 
    428     uint32_t capture_timestamp = header.timestamp - rtp_start_timestamp_;
    429     capture_time_list_.insert(capture_time_list_.end(),
    430                               std::make_pair(header.timestamp,
    431                                              capture_timestamp));
    432     return SEND_PACKET;
    433   }
    434 
    435   void SetCapturer(test::FrameGeneratorCapturer* capturer) {
    436     capturer_ = capturer;
    437   }
    438 
    439  private:
    440   Clock* clock_;
    441   int threshold_ms_;
    442   int start_time_ms_;
    443   int run_time_ms_;
    444   int64_t creation_time_ms_;
    445   test::FrameGeneratorCapturer* capturer_;
    446   bool rtp_start_timestamp_set_;
    447   uint32_t rtp_start_timestamp_;
    448   typedef std::map<uint32_t, uint32_t> FrameCaptureTimeList;
    449   FrameCaptureTimeList capture_time_list_;
    450 };
    451 
    452 void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
    453                                       int threshold_ms,
    454                                       int start_time_ms,
    455                                       int run_time_ms) {
    456   CaptureNtpTimeObserver observer(Clock::GetRealTimeClock(),
    457                                   net_config,
    458                                   threshold_ms,
    459                                   start_time_ms,
    460                                   run_time_ms);
    461 
    462   // Sender/receiver call.
    463   Call::Config receiver_config(observer.ReceiveTransport());
    464   scoped_ptr<Call> receiver_call(Call::Create(receiver_config));
    465   scoped_ptr<Call> sender_call(
    466       Call::Create(Call::Config(observer.SendTransport())));
    467   observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver());
    468 
    469   // Configure send stream.
    470   CreateTestConfig(sender_call.get());
    471   VideoSendStream* send_stream =
    472       sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
    473   scoped_ptr<test::FrameGeneratorCapturer> capturer(
    474       test::FrameGeneratorCapturer::Create(send_stream->Input(),
    475                                            video_streams_[0].width,
    476                                            video_streams_[0].height,
    477                                            30,
    478                                            Clock::GetRealTimeClock()));
    479   observer.SetCapturer(capturer.get());
    480 
    481   // Configure receive stream.
    482   VideoReceiveStream::Config receive_config =
    483       receiver_call->GetDefaultReceiveConfig();
    484   assert(receive_config.codecs.empty());
    485   VideoCodec codec =
    486       test::CreateDecoderVideoCodec(send_config_.encoder_settings);
    487   receive_config.codecs.push_back(codec);
    488   assert(receive_config.external_decoders.empty());
    489   ExternalVideoDecoder decoder;
    490   test::FakeDecoder fake_decoder;
    491   decoder.decoder = &fake_decoder;
    492   decoder.payload_type = send_config_.encoder_settings.payload_type;
    493   receive_config.external_decoders.push_back(decoder);
    494   receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
    495   receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
    496   receive_config.renderer = &observer;
    497   // Enable the receiver side rtt calculation.
    498   receive_config.rtp.rtcp_xr.receiver_reference_time_report = true;
    499   VideoReceiveStream* receive_stream =
    500       receiver_call->CreateVideoReceiveStream(receive_config);
    501 
    502   // Start the test
    503   receive_stream->Start();
    504   send_stream->Start();
    505   capturer->Start();
    506 
    507   EXPECT_EQ(kEventSignaled, observer.Wait())
    508       << "Timed out while waiting for estimated capture ntp time to be "
    509       << "within bounds.";
    510 
    511   capturer->Stop();
    512   send_stream->Stop();
    513   receive_stream->Stop();
    514   observer.StopSending();
    515 
    516   sender_call->DestroyVideoSendStream(send_stream);
    517   receiver_call->DestroyVideoReceiveStream(receive_stream);
    518 }
    519 
    520 TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkDelay) {
    521   FakeNetworkPipe::Config net_config;
    522   net_config.queue_delay_ms = 100;
    523   // TODO(wu): lower the threshold as the calculation/estimatation becomes more
    524   // accurate.
    525   const int kThresholdMs = 100;
    526   const int kStartTimeMs = 10000;
    527   const int kRunTimeMs = 20000;
    528   TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs);
    529 }
    530 
    531 TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkJitter) {
    532   FakeNetworkPipe::Config net_config;
    533   net_config.queue_delay_ms = 100;
    534   net_config.delay_standard_deviation_ms = 10;
    535   // TODO(wu): lower the threshold as the calculation/estimatation becomes more
    536   // accurate.
    537   const int kThresholdMs = 100;
    538   const int kStartTimeMs = 10000;
    539   const int kRunTimeMs = 20000;
    540   TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs);
    541 }
    542 
    543 TEST_F(CallPerfTest, RegisterCpuOveruseObserver) {
    544   // Verifies that either a normal or overuse callback is triggered.
    545   class OveruseCallbackObserver : public test::RtpRtcpObserver,
    546                                   public webrtc::OveruseCallback {
    547    public:
    548     OveruseCallbackObserver() : RtpRtcpObserver(kLongTimeoutMs) {}
    549 
    550     virtual void OnOveruse() OVERRIDE {
    551       observation_complete_->Set();
    552     }
    553     virtual void OnNormalUse() OVERRIDE {
    554       observation_complete_->Set();
    555     }
    556   };
    557 
    558   OveruseCallbackObserver observer;
    559   Call::Config call_config(observer.SendTransport());
    560   call_config.overuse_callback = &observer;
    561   scoped_ptr<Call> call(Call::Create(call_config));
    562 
    563   CreateTestConfig(call.get());
    564   RunVideoSendTest(call.get(), send_config_, &observer);
    565 }
    566 
    567 void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
    568   static const int kMaxEncodeBitrateKbps = 30;
    569   static const int kMinTransmitBitrateBps = 150000;
    570   static const int kMinAcceptableTransmitBitrate = 130;
    571   static const int kMaxAcceptableTransmitBitrate = 170;
    572   static const int kNumBitrateObservationsInRange = 100;
    573   class BitrateObserver : public test::RtpRtcpObserver, public PacketReceiver {
    574    public:
    575     explicit BitrateObserver(bool using_min_transmit_bitrate)
    576         : test::RtpRtcpObserver(kLongTimeoutMs),
    577           send_stream_(NULL),
    578           send_transport_receiver_(NULL),
    579           using_min_transmit_bitrate_(using_min_transmit_bitrate),
    580           num_bitrate_observations_in_range_(0) {}
    581 
    582     virtual void SetReceivers(PacketReceiver* send_transport_receiver,
    583                               PacketReceiver* receive_transport_receiver)
    584         OVERRIDE {
    585       send_transport_receiver_ = send_transport_receiver;
    586       test::RtpRtcpObserver::SetReceivers(this, receive_transport_receiver);
    587     }
    588 
    589     void SetSendStream(VideoSendStream* send_stream) {
    590       send_stream_ = send_stream;
    591     }
    592 
    593    private:
    594     virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
    595                                          size_t length) OVERRIDE {
    596       VideoSendStream::Stats stats = send_stream_->GetStats();
    597       if (stats.substreams.size() > 0) {
    598         assert(stats.substreams.size() == 1);
    599         int bitrate_kbps = stats.substreams.begin()->second.bitrate_bps / 1000;
    600         if (bitrate_kbps > 0) {
    601           test::PrintResult(
    602               "bitrate_stats_",
    603               (using_min_transmit_bitrate_ ? "min_transmit_bitrate"
    604                                            : "without_min_transmit_bitrate"),
    605               "bitrate_kbps",
    606               static_cast<size_t>(bitrate_kbps),
    607               "kbps",
    608               false);
    609           if (using_min_transmit_bitrate_) {
    610             if (bitrate_kbps > kMinAcceptableTransmitBitrate &&
    611                 bitrate_kbps < kMaxAcceptableTransmitBitrate) {
    612               ++num_bitrate_observations_in_range_;
    613             }
    614           } else {
    615             // Expect bitrate stats to roughly match the max encode bitrate.
    616             if (bitrate_kbps > kMaxEncodeBitrateKbps - 5 &&
    617                 bitrate_kbps < kMaxEncodeBitrateKbps + 5) {
    618               ++num_bitrate_observations_in_range_;
    619             }
    620           }
    621           if (num_bitrate_observations_in_range_ ==
    622               kNumBitrateObservationsInRange)
    623             observation_complete_->Set();
    624         }
    625       }
    626       return send_transport_receiver_->DeliverPacket(packet, length);
    627     }
    628 
    629     VideoSendStream* send_stream_;
    630     PacketReceiver* send_transport_receiver_;
    631     const bool using_min_transmit_bitrate_;
    632     int num_bitrate_observations_in_range_;
    633   } observer(pad_to_min_bitrate);
    634 
    635   scoped_ptr<Call> sender_call(
    636       Call::Create(Call::Config(observer.SendTransport())));
    637   scoped_ptr<Call> receiver_call(
    638       Call::Create(Call::Config(observer.ReceiveTransport())));
    639 
    640   CreateTestConfig(sender_call.get());
    641   fake_encoder_.SetMaxBitrate(kMaxEncodeBitrateKbps);
    642 
    643   observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver());
    644 
    645   if (pad_to_min_bitrate) {
    646     send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
    647   } else {
    648     assert(send_config_.rtp.min_transmit_bitrate_bps == 0);
    649   }
    650 
    651   VideoReceiveStream::Config receive_config =
    652       receiver_call->GetDefaultReceiveConfig();
    653   receive_config.codecs.clear();
    654   VideoCodec codec =
    655       test::CreateDecoderVideoCodec(send_config_.encoder_settings);
    656   receive_config.codecs.push_back(codec);
    657   test::FakeDecoder fake_decoder;
    658   ExternalVideoDecoder decoder;
    659   decoder.decoder = &fake_decoder;
    660   decoder.payload_type = send_config_.encoder_settings.payload_type;
    661   receive_config.external_decoders.push_back(decoder);
    662   receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
    663   receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
    664 
    665   VideoSendStream* send_stream =
    666       sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
    667   VideoReceiveStream* receive_stream =
    668       receiver_call->CreateVideoReceiveStream(receive_config);
    669   scoped_ptr<test::FrameGeneratorCapturer> capturer(
    670       test::FrameGeneratorCapturer::Create(send_stream->Input(),
    671                                            video_streams_[0].width,
    672                                            video_streams_[0].height,
    673                                            30,
    674                                            Clock::GetRealTimeClock()));
    675   observer.SetSendStream(send_stream);
    676   receive_stream->Start();
    677   send_stream->Start();
    678   capturer->Start();
    679 
    680   EXPECT_EQ(kEventSignaled, observer.Wait())
    681       << "Timeout while waiting for send-bitrate stats.";
    682 
    683   send_stream->Stop();
    684   receive_stream->Stop();
    685   observer.StopSending();
    686   capturer->Stop();
    687   sender_call->DestroyVideoSendStream(send_stream);
    688   receiver_call->DestroyVideoReceiveStream(receive_stream);
    689 }
    690 
    691 TEST_F(CallPerfTest, PadsToMinTransmitBitrate) { TestMinTransmitBitrate(true); }
    692 
    693 TEST_F(CallPerfTest, NoPadWithoutMinTransmitBitrate) {
    694   TestMinTransmitBitrate(false);
    695 }
    696 
    697 }  // namespace webrtc
    698