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/audio_state.h" 17 #include "webrtc/base/checks.h" 18 #include "webrtc/base/event.h" 19 #include "webrtc/base/logging.h" 20 #include "webrtc/base/scoped_ptr.h" 21 #include "webrtc/base/thread_annotations.h" 22 #include "webrtc/call.h" 23 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 24 #include "webrtc/system_wrappers/include/trace.h" 25 #include "webrtc/test/call_test.h" 26 #include "webrtc/test/direct_transport.h" 27 #include "webrtc/test/encoder_settings.h" 28 #include "webrtc/test/fake_decoder.h" 29 #include "webrtc/test/fake_encoder.h" 30 #include "webrtc/test/mock_voice_engine.h" 31 #include "webrtc/test/frame_generator_capturer.h" 32 33 namespace webrtc { 34 namespace { 35 // Note: If you consider to re-use this class, think twice and instead consider 36 // writing tests that don't depend on the logging system. 37 class LogObserver { 38 public: 39 LogObserver() { rtc::LogMessage::AddLogToStream(&callback_, rtc::LS_INFO); } 40 41 ~LogObserver() { rtc::LogMessage::RemoveLogToStream(&callback_); } 42 43 void PushExpectedLogLine(const std::string& expected_log_line) { 44 callback_.PushExpectedLogLine(expected_log_line); 45 } 46 47 bool Wait() { return callback_.Wait(); } 48 49 private: 50 class Callback : public rtc::LogSink { 51 public: 52 Callback() : done_(false, false) {} 53 54 void OnLogMessage(const std::string& message) override { 55 rtc::CritScope lock(&crit_sect_); 56 // Ignore log lines that are due to missing AST extensions, these are 57 // logged when we switch back from AST to TOF until the wrapping bitrate 58 // estimator gives up on using AST. 59 if (message.find("BitrateEstimator") != std::string::npos && 60 message.find("packet is missing") == std::string::npos) { 61 received_log_lines_.push_back(message); 62 } 63 64 int num_popped = 0; 65 while (!received_log_lines_.empty() && !expected_log_lines_.empty()) { 66 std::string a = received_log_lines_.front(); 67 std::string b = expected_log_lines_.front(); 68 received_log_lines_.pop_front(); 69 expected_log_lines_.pop_front(); 70 num_popped++; 71 EXPECT_TRUE(a.find(b) != std::string::npos) << a << " != " << b; 72 } 73 if (expected_log_lines_.size() <= 0) { 74 if (num_popped > 0) { 75 done_.Set(); 76 } 77 return; 78 } 79 } 80 81 bool Wait() { return done_.Wait(test::CallTest::kDefaultTimeoutMs); } 82 83 void PushExpectedLogLine(const std::string& expected_log_line) { 84 rtc::CritScope lock(&crit_sect_); 85 expected_log_lines_.push_back(expected_log_line); 86 } 87 88 private: 89 typedef std::list<std::string> Strings; 90 rtc::CriticalSection crit_sect_; 91 Strings received_log_lines_ GUARDED_BY(crit_sect_); 92 Strings expected_log_lines_ GUARDED_BY(crit_sect_); 93 rtc::Event done_; 94 }; 95 96 Callback callback_; 97 }; 98 } // namespace 99 100 static const int kTOFExtensionId = 4; 101 static const int kASTExtensionId = 5; 102 103 class BitrateEstimatorTest : public test::CallTest { 104 public: 105 BitrateEstimatorTest() : receive_config_(nullptr) {} 106 107 virtual ~BitrateEstimatorTest() { EXPECT_TRUE(streams_.empty()); } 108 109 virtual void SetUp() { 110 AudioState::Config audio_state_config; 111 audio_state_config.voice_engine = &mock_voice_engine_; 112 Call::Config config; 113 config.audio_state = AudioState::Create(audio_state_config); 114 receiver_call_.reset(Call::Create(config)); 115 sender_call_.reset(Call::Create(config)); 116 117 send_transport_.reset(new test::DirectTransport(sender_call_.get())); 118 send_transport_->SetReceiver(receiver_call_->Receiver()); 119 receive_transport_.reset(new test::DirectTransport(receiver_call_.get())); 120 receive_transport_->SetReceiver(sender_call_->Receiver()); 121 122 video_send_config_ = VideoSendStream::Config(send_transport_.get()); 123 video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[0]); 124 // Encoders will be set separately per stream. 125 video_send_config_.encoder_settings.encoder = nullptr; 126 video_send_config_.encoder_settings.payload_name = "FAKE"; 127 video_send_config_.encoder_settings.payload_type = 128 kFakeVideoSendPayloadType; 129 video_encoder_config_.streams = test::CreateVideoStreams(1); 130 131 receive_config_ = VideoReceiveStream::Config(receive_transport_.get()); 132 // receive_config_.decoders will be set by every stream separately. 133 receive_config_.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[0]; 134 receive_config_.rtp.local_ssrc = kReceiverLocalVideoSsrc; 135 receive_config_.rtp.remb = true; 136 receive_config_.rtp.extensions.push_back( 137 RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); 138 receive_config_.rtp.extensions.push_back( 139 RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId)); 140 } 141 142 virtual void TearDown() { 143 std::for_each(streams_.begin(), streams_.end(), 144 std::mem_fun(&Stream::StopSending)); 145 146 send_transport_->StopSending(); 147 receive_transport_->StopSending(); 148 149 while (!streams_.empty()) { 150 delete streams_.back(); 151 streams_.pop_back(); 152 } 153 154 receiver_call_.reset(); 155 sender_call_.reset(); 156 } 157 158 protected: 159 friend class Stream; 160 161 class Stream { 162 public: 163 Stream(BitrateEstimatorTest* test, bool receive_audio) 164 : test_(test), 165 is_sending_receiving_(false), 166 send_stream_(nullptr), 167 audio_receive_stream_(nullptr), 168 video_receive_stream_(nullptr), 169 frame_generator_capturer_(), 170 fake_encoder_(Clock::GetRealTimeClock()), 171 fake_decoder_() { 172 test_->video_send_config_.rtp.ssrcs[0]++; 173 test_->video_send_config_.encoder_settings.encoder = &fake_encoder_; 174 send_stream_ = test_->sender_call_->CreateVideoSendStream( 175 test_->video_send_config_, test_->video_encoder_config_); 176 RTC_DCHECK_EQ(1u, test_->video_encoder_config_.streams.size()); 177 frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create( 178 send_stream_->Input(), test_->video_encoder_config_.streams[0].width, 179 test_->video_encoder_config_.streams[0].height, 30, 180 Clock::GetRealTimeClock())); 181 send_stream_->Start(); 182 frame_generator_capturer_->Start(); 183 184 if (receive_audio) { 185 AudioReceiveStream::Config receive_config; 186 receive_config.rtp.remote_ssrc = test_->video_send_config_.rtp.ssrcs[0]; 187 // Bogus non-default id to prevent hitting a RTC_DCHECK when creating 188 // the AudioReceiveStream. Every receive stream has to correspond to 189 // an underlying channel id. 190 receive_config.voe_channel_id = 0; 191 receive_config.rtp.extensions.push_back( 192 RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId)); 193 receive_config.combined_audio_video_bwe = true; 194 audio_receive_stream_ = 195 test_->receiver_call_->CreateAudioReceiveStream(receive_config); 196 } else { 197 VideoReceiveStream::Decoder decoder; 198 decoder.decoder = &fake_decoder_; 199 decoder.payload_type = 200 test_->video_send_config_.encoder_settings.payload_type; 201 decoder.payload_name = 202 test_->video_send_config_.encoder_settings.payload_name; 203 test_->receive_config_.decoders.clear(); 204 test_->receive_config_.decoders.push_back(decoder); 205 test_->receive_config_.rtp.remote_ssrc = 206 test_->video_send_config_.rtp.ssrcs[0]; 207 test_->receive_config_.rtp.local_ssrc++; 208 video_receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream( 209 test_->receive_config_); 210 video_receive_stream_->Start(); 211 } 212 is_sending_receiving_ = true; 213 } 214 215 ~Stream() { 216 EXPECT_FALSE(is_sending_receiving_); 217 frame_generator_capturer_.reset(nullptr); 218 test_->sender_call_->DestroyVideoSendStream(send_stream_); 219 send_stream_ = nullptr; 220 if (audio_receive_stream_) { 221 test_->receiver_call_->DestroyAudioReceiveStream(audio_receive_stream_); 222 audio_receive_stream_ = nullptr; 223 } 224 if (video_receive_stream_) { 225 test_->receiver_call_->DestroyVideoReceiveStream(video_receive_stream_); 226 video_receive_stream_ = nullptr; 227 } 228 } 229 230 void StopSending() { 231 if (is_sending_receiving_) { 232 frame_generator_capturer_->Stop(); 233 send_stream_->Stop(); 234 if (video_receive_stream_) { 235 video_receive_stream_->Stop(); 236 } 237 is_sending_receiving_ = false; 238 } 239 } 240 241 private: 242 BitrateEstimatorTest* test_; 243 bool is_sending_receiving_; 244 VideoSendStream* send_stream_; 245 AudioReceiveStream* audio_receive_stream_; 246 VideoReceiveStream* video_receive_stream_; 247 rtc::scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_; 248 test::FakeEncoder fake_encoder_; 249 test::FakeDecoder fake_decoder_; 250 }; 251 252 testing::NiceMock<test::MockVoiceEngine> mock_voice_engine_; 253 LogObserver receiver_log_; 254 rtc::scoped_ptr<test::DirectTransport> send_transport_; 255 rtc::scoped_ptr<test::DirectTransport> receive_transport_; 256 rtc::scoped_ptr<Call> sender_call_; 257 rtc::scoped_ptr<Call> receiver_call_; 258 VideoReceiveStream::Config receive_config_; 259 std::vector<Stream*> streams_; 260 }; 261 262 static const char* kAbsSendTimeLog = 263 "RemoteBitrateEstimatorAbsSendTime: Instantiating."; 264 static const char* kSingleStreamLog = 265 "RemoteBitrateEstimatorSingleStream: Instantiating."; 266 267 TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) { 268 video_send_config_.rtp.extensions.push_back( 269 RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); 270 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 271 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 272 streams_.push_back(new Stream(this, false)); 273 EXPECT_TRUE(receiver_log_.Wait()); 274 } 275 276 TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForAudio) { 277 video_send_config_.rtp.extensions.push_back( 278 RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId)); 279 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 280 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 281 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE."); 282 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog); 283 streams_.push_back(new Stream(this, true)); 284 EXPECT_TRUE(receiver_log_.Wait()); 285 } 286 287 TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForVideo) { 288 video_send_config_.rtp.extensions.push_back( 289 RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId)); 290 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 291 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 292 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE."); 293 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog); 294 streams_.push_back(new Stream(this, false)); 295 EXPECT_TRUE(receiver_log_.Wait()); 296 } 297 298 TEST_F(BitrateEstimatorTest, SwitchesToASTForAudio) { 299 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 300 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 301 streams_.push_back(new Stream(this, true)); 302 EXPECT_TRUE(receiver_log_.Wait()); 303 304 video_send_config_.rtp.extensions.push_back( 305 RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId)); 306 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE."); 307 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog); 308 streams_.push_back(new Stream(this, true)); 309 EXPECT_TRUE(receiver_log_.Wait()); 310 } 311 312 TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) { 313 video_send_config_.rtp.extensions.push_back( 314 RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); 315 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 316 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 317 streams_.push_back(new Stream(this, false)); 318 EXPECT_TRUE(receiver_log_.Wait()); 319 320 video_send_config_.rtp.extensions[0] = 321 RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId); 322 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE."); 323 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog); 324 streams_.push_back(new Stream(this, false)); 325 EXPECT_TRUE(receiver_log_.Wait()); 326 } 327 328 TEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOFForVideo) { 329 video_send_config_.rtp.extensions.push_back( 330 RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); 331 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 332 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 333 streams_.push_back(new Stream(this, false)); 334 EXPECT_TRUE(receiver_log_.Wait()); 335 336 video_send_config_.rtp.extensions[0] = 337 RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId); 338 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE."); 339 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog); 340 streams_.push_back(new Stream(this, false)); 341 EXPECT_TRUE(receiver_log_.Wait()); 342 343 video_send_config_.rtp.extensions[0] = 344 RtpExtension(RtpExtension::kTOffset, kTOFExtensionId); 345 receiver_log_.PushExpectedLogLine( 346 "WrappingBitrateEstimator: Switching to transmission time offset RBE."); 347 receiver_log_.PushExpectedLogLine(kSingleStreamLog); 348 streams_.push_back(new Stream(this, false)); 349 streams_[0]->StopSending(); 350 streams_[1]->StopSending(); 351 EXPECT_TRUE(receiver_log_.Wait()); 352 } 353 } // namespace webrtc 354