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
43namespace webrtc {
44
45static unsigned int kLongTimeoutMs = 120 * 1000;
46static const uint32_t kSendSsrc = 0x654321;
47static const uint32_t kReceiverLocalSsrc = 0x123456;
48static const uint8_t kSendPayloadType = 125;
49
50class 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
96class 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
158class 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
228TEST_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
355class 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
452void 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
520TEST_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
531TEST_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
543TEST_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
567void 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
691TEST_F(CallPerfTest, PadsToMinTransmitBitrate) { TestMinTransmitBitrate(true); }
692
693TEST_F(CallPerfTest, NoPadWithoutMinTransmitBitrate) {
694  TestMinTransmitBitrate(false);
695}
696
697}  // namespace webrtc
698