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