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 |