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: 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 50 ~TraceObserver() { 51 Trace::SetTraceCallback(NULL); 52 Trace::ReturnTrace(); 53 } 54 55 void PushExpectedLogLine(const std::string& expected_log_line) { 56 callback_.PushExpectedLogLine(expected_log_line); 57 } 58 59 EventTypeWrapper Wait() { 60 return callback_.Wait(); 61 } 62 63 private: 64 class Callback : public TraceCallback { 65 public: 66 Callback() 67 : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 68 done_(EventWrapper::Create()) {} 69 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 95 EventTypeWrapper Wait() { 96 return done_->Wait(test::CallTest::kDefaultTimeoutMs); 97 } 98 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: 121 BitrateEstimatorTest() 122 : receiver_trace_(), 123 send_transport_(), 124 receive_transport_(), 125 sender_call_(), 126 receiver_call_(), 127 receive_config_(), 128 streams_() { 129 } 130 131 virtual ~BitrateEstimatorTest() { 132 EXPECT_TRUE(streams_.empty()); 133 } 134 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 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: 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 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 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 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 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 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 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