146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org/*
246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org *
446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org *  Use of this source code is governed by a BSD-style license
546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org *  that can be found in the LICENSE file in the root of the source
646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org *  tree. An additional intellectual property rights grant can be found
746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org *  in the file PATENTS.  All contributing project authors may
846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org */
1046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include <functional>
1146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include <list>
1246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include <string>
1346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
1446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
1546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
1646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/call.h"
1746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
1846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
1946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
20c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org#include "webrtc/system_wrappers/interface/thread_annotations.h"
21ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org#include "webrtc/system_wrappers/interface/trace.h"
2246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/test/direct_transport.h"
23e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org#include "webrtc/test/encoder_settings.h"
2446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/test/fake_decoder.h"
2546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/test/fake_encoder.h"
2646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org#include "webrtc/test/frame_generator_capturer.h"
2746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
2846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgnamespace webrtc {
2946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
3046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgstatic const int kTOFExtensionId = 4;
3146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgstatic const int kASTExtensionId = 5;
3246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
3346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgstatic unsigned int kDefaultTimeoutMs = 30 * 1000;
3446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgstatic const uint32_t kSendSsrc = 0x654321;
3546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgstatic const uint32_t kReceiverLocalSsrc = 0x123456;
3646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgstatic const uint8_t kSendPayloadType = 125;
3746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
3846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.orgclass BitrateEstimatorTest : public ::testing::Test {
3946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org public:
4046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  BitrateEstimatorTest()
4146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      : receiver_trace_(),
4246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        send_transport_(),
4346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        receive_transport_(),
4446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        sender_call_(),
4546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        receiver_call_(),
4646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        send_config_(),
4746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        receive_config_(),
4846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        streams_() {
4946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  }
5046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
5146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  virtual ~BitrateEstimatorTest() {
5246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    EXPECT_TRUE(streams_.empty());
5346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  }
5446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
5546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  virtual void SetUp() {
56ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org    Trace::CreateTrace();
57ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org    Trace::SetTraceCallback(&receiver_trace_);
58ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org    // Reduce the chance that spurious traces will ruin the test.
59ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org    Trace::set_level_filter(kTraceTerseInfo);
60ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org
6146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    Call::Config receiver_call_config(&receive_transport_);
6246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receiver_call_.reset(Call::Create(receiver_call_config));
6346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
6446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    Call::Config sender_call_config(&send_transport_);
6546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    sender_call_.reset(Call::Create(sender_call_config));
6646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
6746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    send_transport_.SetReceiver(receiver_call_->Receiver());
6846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receive_transport_.SetReceiver(sender_call_->Receiver());
6946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
7046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    send_config_ = sender_call_->GetDefaultSendConfig();
7146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    send_config_.rtp.ssrcs.push_back(kSendSsrc);
72e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org    // Encoders will be set separately per stream.
73bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org    send_config_.encoder_settings.encoder = NULL;
74bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org    send_config_.encoder_settings.payload_name = "FAKE";
75bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org    send_config_.encoder_settings.payload_type = kSendPayloadType;
76bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org    video_streams_ = test::CreateVideoStreams(1);
7746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
7846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receive_config_ = receiver_call_->GetDefaultReceiveConfig();
79e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org    assert(receive_config_.codecs.empty());
80e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org    VideoCodec codec =
81e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org        test::CreateDecoderVideoCodec(send_config_.encoder_settings);
82e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org    receive_config_.codecs.push_back(codec);
8346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    // receive_config_.external_decoders will be set by every stream separately.
8446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
8546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
8646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receive_config_.rtp.extensions.push_back(
8746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
8846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receive_config_.rtp.extensions.push_back(
8946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
9046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  }
9146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
9246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  virtual void TearDown() {
9346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    std::for_each(streams_.begin(), streams_.end(),
9446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        std::mem_fun(&Stream::StopSending));
9546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
9646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    send_transport_.StopSending();
9746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receive_transport_.StopSending();
9846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
9946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    while (!streams_.empty()) {
10046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      delete streams_.back();
10146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      streams_.pop_back();
10246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    }
10346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
10446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    receiver_call_.reset();
105ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org
106ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org    Trace::SetTraceCallback(NULL);
107ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.org    Trace::ReturnTrace();
10846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  }
10946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
11046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org protected:
11146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  friend class Stream;
11246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
11346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  class TraceObserver : public TraceCallback {
11446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org   public:
11546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    TraceObserver()
11646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
11746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          received_log_lines_(),
11846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          expected_log_lines_(),
11946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          done_(EventWrapper::Create()) {
12046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    }
12146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
12246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    void PushExpectedLogLine(const std::string& expected_log_line) {
123c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org      CriticalSectionScoped lock(crit_sect_.get());
12446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      expected_log_lines_.push_back(expected_log_line);
12546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    }
12646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
12746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    virtual void Print(TraceLevel level,
12846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org                       const char* message,
12946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org                       int length) OVERRIDE {
130c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org      CriticalSectionScoped lock(crit_sect_.get());
13146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      std::string msg(message);
13246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      if (msg.find("BitrateEstimator") != std::string::npos) {
13346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        received_log_lines_.push_back(msg);
13446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      }
13546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      int num_popped = 0;
13646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      while (!received_log_lines_.empty() && !expected_log_lines_.empty()) {
13746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        std::string a = received_log_lines_.front();
13846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        std::string b = expected_log_lines_.front();
13946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        received_log_lines_.pop_front();
14046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        expected_log_lines_.pop_front();
14146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        num_popped++;
14246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        EXPECT_TRUE(a.find(b) != std::string::npos);
14346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      }
14446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      if (expected_log_lines_.size() <= 0) {
14546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        if (num_popped > 0) {
14646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          done_->Set();
14746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        }
14846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        return;
14946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      }
15046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    }
15146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
15246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
15346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
15446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org   private:
15546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    typedef std::list<std::string> Strings;
156c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org    const scoped_ptr<CriticalSectionWrapper> crit_sect_;
157c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org    Strings received_log_lines_ GUARDED_BY(crit_sect_);
158c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org    Strings expected_log_lines_ GUARDED_BY(crit_sect_);
15946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    scoped_ptr<EventWrapper> done_;
16046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  };
16146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
16246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  class Stream {
16346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org   public:
16446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    explicit Stream(BitrateEstimatorTest* test)
16546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        : test_(test),
16646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          is_sending_receiving_(false),
16746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          send_stream_(NULL),
16846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          receive_stream_(NULL),
16946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          frame_generator_capturer_(),
17046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          fake_encoder_(Clock::GetRealTimeClock()),
17146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          fake_decoder_() {
17246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      test_->send_config_.rtp.ssrcs[0]++;
173e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org      test_->send_config_.encoder_settings.encoder = &fake_encoder_;
174bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org      send_stream_ = test_->sender_call_->CreateVideoSendStream(
175bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org          test_->send_config_, test_->video_streams_, NULL);
176bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org      assert(test_->video_streams_.size() == 1);
177bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org      frame_generator_capturer_.reset(
178bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org          test::FrameGeneratorCapturer::Create(send_stream_->Input(),
179bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org                                               test_->video_streams_[0].width,
180bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org                                               test_->video_streams_[0].height,
181bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org                                               30,
182bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org                                               Clock::GetRealTimeClock()));
18316a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org      send_stream_->Start();
18446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      frame_generator_capturer_->Start();
18546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
18646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      ExternalVideoDecoder decoder;
18746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      decoder.decoder = &fake_decoder_;
188e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org      decoder.payload_type = test_->send_config_.encoder_settings.payload_type;
18946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      test_->receive_config_.rtp.remote_ssrc = test_->send_config_.rtp.ssrcs[0];
19046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      test_->receive_config_.rtp.local_ssrc++;
19146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      test_->receive_config_.external_decoders.push_back(decoder);
19246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream(
19346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org          test_->receive_config_);
19416a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org      receive_stream_->Start();
19546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
19646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      is_sending_receiving_ = true;
19746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    }
19846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
19946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    ~Stream() {
20046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      frame_generator_capturer_.reset(NULL);
20146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      test_->sender_call_->DestroyVideoSendStream(send_stream_);
20246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      send_stream_ = NULL;
20346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      test_->receiver_call_->DestroyVideoReceiveStream(receive_stream_);
20446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      receive_stream_ = NULL;
20546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    }
20646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
20746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    void StopSending() {
20846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      if (is_sending_receiving_) {
20946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        frame_generator_capturer_->Stop();
21016a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org        send_stream_->Stop();
21116a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org        receive_stream_->Stop();
21246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org        is_sending_receiving_ = false;
21346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      }
21446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    }
21546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
21646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org   private:
21746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    BitrateEstimatorTest* test_;
21846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    bool is_sending_receiving_;
21946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    VideoSendStream* send_stream_;
22046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    VideoReceiveStream* receive_stream_;
22146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
22246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    test::FakeEncoder fake_encoder_;
22346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org    test::FakeDecoder fake_decoder_;
22446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  };
22546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
22646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  TraceObserver receiver_trace_;
22746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  test::DirectTransport send_transport_;
22846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  test::DirectTransport receive_transport_;
22946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  scoped_ptr<Call> sender_call_;
23046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  scoped_ptr<Call> receiver_call_;
23146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  VideoSendStream::Config send_config_;
232bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org  std::vector<VideoStream> video_streams_;
23346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  VideoReceiveStream::Config receive_config_;
23446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  std::vector<Stream*> streams_;
23546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org};
23646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
237ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.orgTEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefault) {
23846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  send_config_.rtp.extensions.push_back(
23946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
24046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
24146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
24246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
24346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
24446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_.push_back(new Stream(this));
24546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
24646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org}
24746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
248ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.orgTEST_F(BitrateEstimatorTest, ImmediatelySwitchToAST) {
2490b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org  send_config_.rtp.extensions.push_back(
2500b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org      RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
2510b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org  receiver_trace_.PushExpectedLogLine(
2520b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
2530b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org  receiver_trace_.PushExpectedLogLine(
2540b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
2550b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org  receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
2560b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org  receiver_trace_.PushExpectedLogLine(
2570b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org      "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
2580b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org  streams_.push_back(new Stream(this));
2590b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org  EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
2600b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org}
2610b9d7ced44cffcae24d881e167c61fe38c5b4985solenberg@webrtc.org
262ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.orgTEST_F(BitrateEstimatorTest, SwitchesToAST) {
26346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  send_config_.rtp.extensions.push_back(
26446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
26546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
26646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
26746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
26846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
26946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_.push_back(new Stream(this));
27046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
27146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
27246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  send_config_.rtp.extensions[0] =
27346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
27446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
27546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
27646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
27746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_.push_back(new Stream(this));
27846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
27946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org}
28046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
281ff4e2105ba8ceef51a91ac9ed9722ca275a33d53solenberg@webrtc.orgTEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOF) {
28246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  send_config_.rtp.extensions.push_back(
28346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
28446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
28546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
28646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
28746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
28846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_.push_back(new Stream(this));
28946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
29046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
29146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  send_config_.rtp.extensions[0] =
29246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
29346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
29446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
29546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
29646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_.push_back(new Stream(this));
29746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
29846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org
29946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  send_config_.rtp.extensions[0] =
30046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      RtpExtension(RtpExtension::kTOffset, kTOFExtensionId);
30146f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
30246f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "WrappingBitrateEstimator: Switching to transmission time offset RBE.");
30346f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  receiver_trace_.PushExpectedLogLine(
30446f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org      "RemoteBitrateEstimatorFactory: Instantiating.");
30546f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_.push_back(new Stream(this));
30646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_[0]->StopSending();
30746f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  streams_[1]->StopSending();
30846f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org  EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
30946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org}
31046f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org}  // namespace webrtc
311