• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include <functional>
11 #include <list>
12 #include <string>
13 
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 #include "webrtc/base/thread_annotations.h"
17 #include "webrtc/call.h"
18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19 #include "webrtc/system_wrappers/interface/event_wrapper.h"
20 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
21 #include "webrtc/system_wrappers/interface/trace.h"
22 #include "webrtc/test/call_test.h"
23 #include "webrtc/test/direct_transport.h"
24 #include "webrtc/test/encoder_settings.h"
25 #include "webrtc/test/fake_decoder.h"
26 #include "webrtc/test/fake_encoder.h"
27 #include "webrtc/test/frame_generator_capturer.h"
28 
29 namespace webrtc {
30 namespace {
31 // Note: consider to write tests that don't depend on the trace system instead
32 // of re-using this class.
33 class TraceObserver {
34  public:
TraceObserver()35   TraceObserver() {
36     Trace::set_level_filter(kTraceTerseInfo);
37 
38     Trace::CreateTrace();
39     Trace::SetTraceCallback(&callback_);
40 
41     // Call webrtc trace to initialize the tracer that would otherwise trigger a
42     // data-race if left to be initialized by multiple threads (i.e. threads
43     // spawned by test::DirectTransport members in BitrateEstimatorTest).
44     WEBRTC_TRACE(kTraceStateInfo,
45                  kTraceUtility,
46                  -1,
47                  "Instantiate without data races.");
48   }
49 
~TraceObserver()50   ~TraceObserver() {
51     Trace::SetTraceCallback(NULL);
52     Trace::ReturnTrace();
53   }
54 
PushExpectedLogLine(const std::string & expected_log_line)55   void PushExpectedLogLine(const std::string& expected_log_line) {
56     callback_.PushExpectedLogLine(expected_log_line);
57   }
58 
Wait()59   EventTypeWrapper Wait() {
60     return callback_.Wait();
61   }
62 
63  private:
64   class Callback : public TraceCallback {
65    public:
Callback()66     Callback()
67         : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
68           done_(EventWrapper::Create()) {}
69 
Print(TraceLevel level,const char * message,int length)70     virtual void Print(TraceLevel level,
71                        const char* message,
72                        int length) OVERRIDE {
73       CriticalSectionScoped lock(crit_sect_.get());
74       std::string msg(message);
75       if (msg.find("BitrateEstimator") != std::string::npos) {
76         received_log_lines_.push_back(msg);
77       }
78       int num_popped = 0;
79       while (!received_log_lines_.empty() && !expected_log_lines_.empty()) {
80         std::string a = received_log_lines_.front();
81         std::string b = expected_log_lines_.front();
82         received_log_lines_.pop_front();
83         expected_log_lines_.pop_front();
84         num_popped++;
85         EXPECT_TRUE(a.find(b) != std::string::npos);
86       }
87       if (expected_log_lines_.size() <= 0) {
88         if (num_popped > 0) {
89           done_->Set();
90         }
91         return;
92       }
93     }
94 
Wait()95     EventTypeWrapper Wait() {
96       return done_->Wait(test::CallTest::kDefaultTimeoutMs);
97     }
98 
PushExpectedLogLine(const std::string & expected_log_line)99     void PushExpectedLogLine(const std::string& expected_log_line) {
100       CriticalSectionScoped lock(crit_sect_.get());
101       expected_log_lines_.push_back(expected_log_line);
102     }
103 
104    private:
105     typedef std::list<std::string> Strings;
106     const scoped_ptr<CriticalSectionWrapper> crit_sect_;
107     Strings received_log_lines_ GUARDED_BY(crit_sect_);
108     Strings expected_log_lines_ GUARDED_BY(crit_sect_);
109     scoped_ptr<EventWrapper> done_;
110   };
111 
112   Callback callback_;
113 };
114 }  // namespace
115 
116 static const int kTOFExtensionId = 4;
117 static const int kASTExtensionId = 5;
118 
119 class BitrateEstimatorTest : public test::CallTest {
120  public:
BitrateEstimatorTest()121   BitrateEstimatorTest()
122       : receiver_trace_(),
123         send_transport_(),
124         receive_transport_(),
125         sender_call_(),
126         receiver_call_(),
127         receive_config_(),
128         streams_() {
129   }
130 
~BitrateEstimatorTest()131   virtual ~BitrateEstimatorTest() {
132     EXPECT_TRUE(streams_.empty());
133   }
134 
SetUp()135   virtual void SetUp() {
136     Call::Config receiver_call_config(&receive_transport_);
137     receiver_call_.reset(Call::Create(receiver_call_config));
138 
139     Call::Config sender_call_config(&send_transport_);
140     sender_call_.reset(Call::Create(sender_call_config));
141 
142     send_transport_.SetReceiver(receiver_call_->Receiver());
143     receive_transport_.SetReceiver(sender_call_->Receiver());
144 
145     send_config_ = VideoSendStream::Config();
146     send_config_.rtp.ssrcs.push_back(kSendSsrcs[0]);
147     // Encoders will be set separately per stream.
148     send_config_.encoder_settings.encoder = NULL;
149     send_config_.encoder_settings.payload_name = "FAKE";
150     send_config_.encoder_settings.payload_type = kFakeSendPayloadType;
151     encoder_config_.streams = test::CreateVideoStreams(1);
152 
153     receive_config_ = VideoReceiveStream::Config();
154     assert(receive_config_.codecs.empty());
155     VideoCodec codec =
156         test::CreateDecoderVideoCodec(send_config_.encoder_settings);
157     receive_config_.codecs.push_back(codec);
158     // receive_config_.external_decoders will be set by every stream separately.
159     receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
160     receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
161     receive_config_.rtp.extensions.push_back(
162         RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
163     receive_config_.rtp.extensions.push_back(
164         RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
165   }
166 
TearDown()167   virtual void TearDown() {
168     std::for_each(streams_.begin(), streams_.end(),
169         std::mem_fun(&Stream::StopSending));
170 
171     send_transport_.StopSending();
172     receive_transport_.StopSending();
173 
174     while (!streams_.empty()) {
175       delete streams_.back();
176       streams_.pop_back();
177     }
178 
179     receiver_call_.reset();
180   }
181 
182  protected:
183   friend class Stream;
184 
185   class Stream {
186    public:
Stream(BitrateEstimatorTest * test)187     explicit Stream(BitrateEstimatorTest* test)
188         : test_(test),
189           is_sending_receiving_(false),
190           send_stream_(NULL),
191           receive_stream_(NULL),
192           frame_generator_capturer_(),
193           fake_encoder_(Clock::GetRealTimeClock()),
194           fake_decoder_() {
195       test_->send_config_.rtp.ssrcs[0]++;
196       test_->send_config_.encoder_settings.encoder = &fake_encoder_;
197       send_stream_ = test_->sender_call_->CreateVideoSendStream(
198           test_->send_config_, test_->encoder_config_);
199       assert(test_->encoder_config_.streams.size() == 1);
200       frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
201           send_stream_->Input(),
202           test_->encoder_config_.streams[0].width,
203           test_->encoder_config_.streams[0].height,
204           30,
205           Clock::GetRealTimeClock()));
206       send_stream_->Start();
207       frame_generator_capturer_->Start();
208 
209       ExternalVideoDecoder decoder;
210       decoder.decoder = &fake_decoder_;
211       decoder.payload_type = test_->send_config_.encoder_settings.payload_type;
212       test_->receive_config_.rtp.remote_ssrc = test_->send_config_.rtp.ssrcs[0];
213       test_->receive_config_.rtp.local_ssrc++;
214       test_->receive_config_.external_decoders.push_back(decoder);
215       receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream(
216           test_->receive_config_);
217       receive_stream_->Start();
218 
219       is_sending_receiving_ = true;
220     }
221 
~Stream()222     ~Stream() {
223       frame_generator_capturer_.reset(NULL);
224       test_->sender_call_->DestroyVideoSendStream(send_stream_);
225       send_stream_ = NULL;
226       test_->receiver_call_->DestroyVideoReceiveStream(receive_stream_);
227       receive_stream_ = NULL;
228     }
229 
StopSending()230     void StopSending() {
231       if (is_sending_receiving_) {
232         frame_generator_capturer_->Stop();
233         send_stream_->Stop();
234         receive_stream_->Stop();
235         is_sending_receiving_ = false;
236       }
237     }
238 
239    private:
240     BitrateEstimatorTest* test_;
241     bool is_sending_receiving_;
242     VideoSendStream* send_stream_;
243     VideoReceiveStream* receive_stream_;
244     scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
245     test::FakeEncoder fake_encoder_;
246     test::FakeDecoder fake_decoder_;
247   };
248 
249   TraceObserver receiver_trace_;
250   test::DirectTransport send_transport_;
251   test::DirectTransport receive_transport_;
252   scoped_ptr<Call> sender_call_;
253   scoped_ptr<Call> receiver_call_;
254   VideoReceiveStream::Config receive_config_;
255   std::vector<Stream*> streams_;
256 };
257 
TEST_F(BitrateEstimatorTest,InstantiatesTOFPerDefault)258 TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefault) {
259   send_config_.rtp.extensions.push_back(
260       RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
261   receiver_trace_.PushExpectedLogLine(
262       "RemoteBitrateEstimatorFactory: Instantiating.");
263   receiver_trace_.PushExpectedLogLine(
264       "RemoteBitrateEstimatorFactory: Instantiating.");
265   streams_.push_back(new Stream(this));
266   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
267 }
268 
TEST_F(BitrateEstimatorTest,ImmediatelySwitchToAST)269 TEST_F(BitrateEstimatorTest, ImmediatelySwitchToAST) {
270   send_config_.rtp.extensions.push_back(
271       RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
272   receiver_trace_.PushExpectedLogLine(
273       "RemoteBitrateEstimatorFactory: Instantiating.");
274   receiver_trace_.PushExpectedLogLine(
275       "RemoteBitrateEstimatorFactory: Instantiating.");
276   receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
277   receiver_trace_.PushExpectedLogLine(
278       "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
279   streams_.push_back(new Stream(this));
280   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
281 }
282 
TEST_F(BitrateEstimatorTest,SwitchesToAST)283 TEST_F(BitrateEstimatorTest, SwitchesToAST) {
284   send_config_.rtp.extensions.push_back(
285       RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
286   receiver_trace_.PushExpectedLogLine(
287       "RemoteBitrateEstimatorFactory: Instantiating.");
288   receiver_trace_.PushExpectedLogLine(
289       "RemoteBitrateEstimatorFactory: Instantiating.");
290   streams_.push_back(new Stream(this));
291   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
292 
293   send_config_.rtp.extensions[0] =
294       RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
295   receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
296   receiver_trace_.PushExpectedLogLine(
297       "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
298   streams_.push_back(new Stream(this));
299   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
300 }
301 
TEST_F(BitrateEstimatorTest,SwitchesToASTThenBackToTOF)302 TEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOF) {
303   send_config_.rtp.extensions.push_back(
304       RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
305   receiver_trace_.PushExpectedLogLine(
306       "RemoteBitrateEstimatorFactory: Instantiating.");
307   receiver_trace_.PushExpectedLogLine(
308       "RemoteBitrateEstimatorFactory: Instantiating.");
309   streams_.push_back(new Stream(this));
310   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
311 
312   send_config_.rtp.extensions[0] =
313       RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
314   receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
315   receiver_trace_.PushExpectedLogLine(
316       "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
317   streams_.push_back(new Stream(this));
318   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
319 
320   send_config_.rtp.extensions[0] =
321       RtpExtension(RtpExtension::kTOffset, kTOFExtensionId);
322   receiver_trace_.PushExpectedLogLine(
323       "WrappingBitrateEstimator: Switching to transmission time offset RBE.");
324   receiver_trace_.PushExpectedLogLine(
325       "RemoteBitrateEstimatorFactory: Instantiating.");
326   streams_.push_back(new Stream(this));
327   streams_[0]->StopSending();
328   streams_[1]->StopSending();
329   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
330 }
331 }  // namespace webrtc
332