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