1 /*
2 * Copyright 2018 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
11 #include <memory>
12
13 #include "api/media_types.h"
14 #include "api/task_queue/default_task_queue_factory.h"
15 #include "api/task_queue/task_queue_base.h"
16 #include "api/task_queue/task_queue_factory.h"
17 #include "api/test/simulated_network.h"
18 #include "api/video_codecs/video_encoder.h"
19 #include "call/fake_network_pipe.h"
20 #include "call/simulated_network.h"
21 #include "modules/rtp_rtcp/source/rtp_packet.h"
22 #include "rtc_base/synchronization/mutex.h"
23 #include "rtc_base/task_queue_for_test.h"
24 #include "system_wrappers/include/sleep.h"
25 #include "test/call_test.h"
26 #include "test/fake_encoder.h"
27 #include "test/gtest.h"
28 #include "test/video_encoder_proxy_factory.h"
29
30 namespace webrtc {
31 namespace {
32 constexpr int kSilenceTimeoutMs = 2000;
33 }
34
35 class NetworkStateEndToEndTest : public test::CallTest {
36 protected:
37 class UnusedTransport : public Transport {
38 private:
SendRtp(const uint8_t * packet,size_t length,const PacketOptions & options)39 bool SendRtp(const uint8_t* packet,
40 size_t length,
41 const PacketOptions& options) override {
42 ADD_FAILURE() << "Unexpected RTP sent.";
43 return false;
44 }
45
SendRtcp(const uint8_t * packet,size_t length)46 bool SendRtcp(const uint8_t* packet, size_t length) override {
47 ADD_FAILURE() << "Unexpected RTCP sent.";
48 return false;
49 }
50 };
51 class RequiredTransport : public Transport {
52 public:
RequiredTransport(bool rtp_required,bool rtcp_required)53 RequiredTransport(bool rtp_required, bool rtcp_required)
54 : need_rtp_(rtp_required), need_rtcp_(rtcp_required) {}
~RequiredTransport()55 ~RequiredTransport() {
56 if (need_rtp_) {
57 ADD_FAILURE() << "Expected RTP packet not sent.";
58 }
59 if (need_rtcp_) {
60 ADD_FAILURE() << "Expected RTCP packet not sent.";
61 }
62 }
63
64 private:
SendRtp(const uint8_t * packet,size_t length,const PacketOptions & options)65 bool SendRtp(const uint8_t* packet,
66 size_t length,
67 const PacketOptions& options) override {
68 MutexLock lock(&mutex_);
69 need_rtp_ = false;
70 return true;
71 }
72
SendRtcp(const uint8_t * packet,size_t length)73 bool SendRtcp(const uint8_t* packet, size_t length) override {
74 MutexLock lock(&mutex_);
75 need_rtcp_ = false;
76 return true;
77 }
78 bool need_rtp_;
79 bool need_rtcp_;
80 Mutex mutex_;
81 };
82 void VerifyNewVideoSendStreamsRespectNetworkState(
83 MediaType network_to_bring_up,
84 VideoEncoder* encoder,
85 Transport* transport);
86 void VerifyNewVideoReceiveStreamsRespectNetworkState(
87 MediaType network_to_bring_up,
88 Transport* transport);
89 };
90
VerifyNewVideoSendStreamsRespectNetworkState(MediaType network_to_bring_up,VideoEncoder * encoder,Transport * transport)91 void NetworkStateEndToEndTest::VerifyNewVideoSendStreamsRespectNetworkState(
92 MediaType network_to_bring_up,
93 VideoEncoder* encoder,
94 Transport* transport) {
95 test::VideoEncoderProxyFactory encoder_factory(encoder);
96
97 SendTask(task_queue(),
98 [this, network_to_bring_up, &encoder_factory, transport]() {
99 CreateSenderCall(Call::Config(send_event_log_.get()));
100 sender_call_->SignalChannelNetworkState(network_to_bring_up,
101 kNetworkUp);
102
103 CreateSendConfig(1, 0, 0, transport);
104 GetVideoSendConfig()->encoder_settings.encoder_factory =
105 &encoder_factory;
106 CreateVideoStreams();
107 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
108 kDefaultHeight);
109
110 Start();
111 });
112
113 SleepMs(kSilenceTimeoutMs);
114
115 SendTask(task_queue(), [this]() {
116 Stop();
117 DestroyStreams();
118 DestroyCalls();
119 });
120 }
121
VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType network_to_bring_up,Transport * transport)122 void NetworkStateEndToEndTest::VerifyNewVideoReceiveStreamsRespectNetworkState(
123 MediaType network_to_bring_up,
124 Transport* transport) {
125 std::unique_ptr<test::DirectTransport> sender_transport;
126
127 SendTask(
128 task_queue(),
129 [this, &sender_transport, network_to_bring_up, transport]() {
130 CreateCalls();
131 receiver_call_->SignalChannelNetworkState(network_to_bring_up,
132 kNetworkUp);
133 sender_transport = std::make_unique<test::DirectTransport>(
134 task_queue(),
135 std::make_unique<FakeNetworkPipe>(
136 Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
137 BuiltInNetworkBehaviorConfig())),
138 sender_call_.get(), payload_type_map_);
139 sender_transport->SetReceiver(receiver_call_->Receiver());
140 CreateSendConfig(1, 0, 0, sender_transport.get());
141 CreateMatchingReceiveConfigs(transport);
142 CreateVideoStreams();
143 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
144 kDefaultHeight);
145 Start();
146 });
147
148 SleepMs(kSilenceTimeoutMs);
149
150 SendTask(task_queue(), [this, &sender_transport]() {
151 Stop();
152 DestroyStreams();
153 sender_transport.reset();
154 DestroyCalls();
155 });
156 }
157
TEST_F(NetworkStateEndToEndTest,RespectsNetworkState)158 TEST_F(NetworkStateEndToEndTest, RespectsNetworkState) {
159 // TODO(pbos): Remove accepted downtime packets etc. when signaling network
160 // down blocks until no more packets will be sent.
161
162 // Pacer will send from its packet list and then send required padding before
163 // checking paused_ again. This should be enough for one round of pacing,
164 // otherwise increase.
165 static const int kNumAcceptedDowntimeRtp = 5;
166 // A single RTCP may be in the pipeline.
167 static const int kNumAcceptedDowntimeRtcp = 1;
168 class NetworkStateTest : public test::EndToEndTest, public test::FakeEncoder {
169 public:
170 explicit NetworkStateTest(TaskQueueBase* task_queue)
171 : EndToEndTest(kDefaultTimeout),
172 FakeEncoder(Clock::GetRealTimeClock()),
173 e2e_test_task_queue_(task_queue),
174 task_queue_(CreateDefaultTaskQueueFactory()->CreateTaskQueue(
175 "NetworkStateTest",
176 TaskQueueFactory::Priority::NORMAL)),
177 sender_call_(nullptr),
178 receiver_call_(nullptr),
179 encoder_factory_(this),
180 sender_state_(kNetworkUp),
181 sender_rtp_(0),
182 sender_padding_(0),
183 sender_rtcp_(0),
184 receiver_rtcp_(0),
185 down_frames_(0) {}
186
187 Action OnSendRtp(const uint8_t* packet, size_t length) override {
188 MutexLock lock(&test_mutex_);
189 RtpPacket rtp_packet;
190 EXPECT_TRUE(rtp_packet.Parse(packet, length));
191 if (rtp_packet.payload_size() == 0)
192 ++sender_padding_;
193 ++sender_rtp_;
194 packet_event_.Set();
195 return SEND_PACKET;
196 }
197
198 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
199 MutexLock lock(&test_mutex_);
200 ++sender_rtcp_;
201 packet_event_.Set();
202 return SEND_PACKET;
203 }
204
205 Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
206 ADD_FAILURE() << "Unexpected receiver RTP, should not be sending.";
207 return SEND_PACKET;
208 }
209
210 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
211 MutexLock lock(&test_mutex_);
212 ++receiver_rtcp_;
213 packet_event_.Set();
214 return SEND_PACKET;
215 }
216
217 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
218 sender_call_ = sender_call;
219 receiver_call_ = receiver_call;
220 }
221
222 void ModifyVideoConfigs(
223 VideoSendStream::Config* send_config,
224 std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
225 VideoEncoderConfig* encoder_config) override {
226 send_config->encoder_settings.encoder_factory = &encoder_factory_;
227 }
228
229 void SignalChannelNetworkState(Call* call,
230 MediaType media_type,
231 NetworkState network_state) {
232 SendTask(e2e_test_task_queue_, [call, media_type, network_state] {
233 call->SignalChannelNetworkState(media_type, network_state);
234 });
235 }
236
237 void PerformTest() override {
238 EXPECT_TRUE(encoded_frames_.Wait(kDefaultTimeout))
239 << "No frames received by the encoder.";
240
241 SendTask(task_queue_.get(), [this]() {
242 // Wait for packets from both sender/receiver.
243 WaitForPacketsOrSilence(false, false);
244
245 // Sender-side network down for audio; there should be no effect on
246 // video
247 SignalChannelNetworkState(sender_call_, MediaType::AUDIO, kNetworkDown);
248
249 WaitForPacketsOrSilence(false, false);
250
251 // Receiver-side network down for audio; no change expected
252 SignalChannelNetworkState(receiver_call_, MediaType::AUDIO,
253 kNetworkDown);
254 WaitForPacketsOrSilence(false, false);
255
256 // Sender-side network down.
257 SignalChannelNetworkState(sender_call_, MediaType::VIDEO, kNetworkDown);
258 {
259 MutexLock lock(&test_mutex_);
260 // After network goes down we shouldn't be encoding more frames.
261 sender_state_ = kNetworkDown;
262 }
263 // Wait for receiver-packets and no sender packets.
264 WaitForPacketsOrSilence(true, false);
265
266 // Receiver-side network down.
267 SignalChannelNetworkState(receiver_call_, MediaType::VIDEO,
268 kNetworkDown);
269 WaitForPacketsOrSilence(true, true);
270
271 // Network up for audio for both sides; video is still not expected to
272 // start
273 SignalChannelNetworkState(sender_call_, MediaType::AUDIO, kNetworkUp);
274 SignalChannelNetworkState(receiver_call_, MediaType::AUDIO, kNetworkUp);
275 WaitForPacketsOrSilence(true, true);
276
277 // Network back up again for both.
278 {
279 MutexLock lock(&test_mutex_);
280 // It's OK to encode frames again, as we're about to bring up the
281 // network.
282 sender_state_ = kNetworkUp;
283 }
284 SignalChannelNetworkState(sender_call_, MediaType::VIDEO, kNetworkUp);
285 SignalChannelNetworkState(receiver_call_, MediaType::VIDEO, kNetworkUp);
286 WaitForPacketsOrSilence(false, false);
287
288 // TODO(skvlad): add tests to verify that the audio streams are stopped
289 // when the network goes down for audio once the workaround in
290 // paced_sender.cc is removed.
291 });
292 }
293
294 int32_t Encode(const VideoFrame& input_image,
295 const std::vector<VideoFrameType>* frame_types) override {
296 {
297 MutexLock lock(&test_mutex_);
298 if (sender_state_ == kNetworkDown) {
299 ++down_frames_;
300 EXPECT_LE(down_frames_, 1)
301 << "Encoding more than one frame while network is down.";
302 if (down_frames_ > 1)
303 encoded_frames_.Set();
304 } else {
305 encoded_frames_.Set();
306 }
307 }
308 return test::FakeEncoder::Encode(input_image, frame_types);
309 }
310
311 private:
312 void WaitForPacketsOrSilence(bool sender_down, bool receiver_down) {
313 int64_t initial_time_ms = clock_->TimeInMilliseconds();
314 int initial_sender_rtp;
315 int initial_sender_rtcp;
316 int initial_receiver_rtcp;
317 {
318 MutexLock lock(&test_mutex_);
319 initial_sender_rtp = sender_rtp_;
320 initial_sender_rtcp = sender_rtcp_;
321 initial_receiver_rtcp = receiver_rtcp_;
322 }
323 bool sender_done = false;
324 bool receiver_done = false;
325 while (!sender_done || !receiver_done) {
326 packet_event_.Wait(TimeDelta::Millis(kSilenceTimeoutMs));
327 int64_t time_now_ms = clock_->TimeInMilliseconds();
328 MutexLock lock(&test_mutex_);
329 if (sender_down) {
330 ASSERT_LE(sender_rtp_ - initial_sender_rtp - sender_padding_,
331 kNumAcceptedDowntimeRtp)
332 << "RTP sent during sender-side downtime.";
333 ASSERT_LE(sender_rtcp_ - initial_sender_rtcp,
334 kNumAcceptedDowntimeRtcp)
335 << "RTCP sent during sender-side downtime.";
336 if (time_now_ms - initial_time_ms >=
337 static_cast<int64_t>(kSilenceTimeoutMs)) {
338 sender_done = true;
339 }
340 } else {
341 if (sender_rtp_ > initial_sender_rtp + kNumAcceptedDowntimeRtp)
342 sender_done = true;
343 }
344 if (receiver_down) {
345 ASSERT_LE(receiver_rtcp_ - initial_receiver_rtcp,
346 kNumAcceptedDowntimeRtcp)
347 << "RTCP sent during receiver-side downtime.";
348 if (time_now_ms - initial_time_ms >=
349 static_cast<int64_t>(kSilenceTimeoutMs)) {
350 receiver_done = true;
351 }
352 } else {
353 if (receiver_rtcp_ > initial_receiver_rtcp + kNumAcceptedDowntimeRtcp)
354 receiver_done = true;
355 }
356 }
357 }
358
359 TaskQueueBase* const e2e_test_task_queue_;
360 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue_;
361 Mutex test_mutex_;
362 rtc::Event encoded_frames_;
363 rtc::Event packet_event_;
364 Call* sender_call_;
365 Call* receiver_call_;
366 test::VideoEncoderProxyFactory encoder_factory_;
367 NetworkState sender_state_ RTC_GUARDED_BY(test_mutex_);
368 int sender_rtp_ RTC_GUARDED_BY(test_mutex_);
369 int sender_padding_ RTC_GUARDED_BY(test_mutex_);
370 int sender_rtcp_ RTC_GUARDED_BY(test_mutex_);
371 int receiver_rtcp_ RTC_GUARDED_BY(test_mutex_);
372 int down_frames_ RTC_GUARDED_BY(test_mutex_);
373 } test(task_queue());
374
375 RunBaseTest(&test);
376 }
377
TEST_F(NetworkStateEndToEndTest,NewVideoSendStreamsRespectVideoNetworkDown)378 TEST_F(NetworkStateEndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) {
379 class UnusedEncoder : public test::FakeEncoder {
380 public:
381 UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {}
382
383 int32_t InitEncode(const VideoCodec* config,
384 const Settings& settings) override {
385 EXPECT_GT(config->startBitrate, 0u);
386 return 0;
387 }
388 int32_t Encode(const VideoFrame& input_image,
389 const std::vector<VideoFrameType>* frame_types) override {
390 ADD_FAILURE() << "Unexpected frame encode.";
391 return test::FakeEncoder::Encode(input_image, frame_types);
392 }
393 };
394
395 UnusedEncoder unused_encoder;
396 UnusedTransport unused_transport;
397 VerifyNewVideoSendStreamsRespectNetworkState(
398 MediaType::AUDIO, &unused_encoder, &unused_transport);
399 }
400
TEST_F(NetworkStateEndToEndTest,NewVideoSendStreamsIgnoreAudioNetworkDown)401 TEST_F(NetworkStateEndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) {
402 class RequiredEncoder : public test::FakeEncoder {
403 public:
404 RequiredEncoder()
405 : FakeEncoder(Clock::GetRealTimeClock()), encoded_frame_(false) {}
406 ~RequiredEncoder() {
407 if (!encoded_frame_) {
408 ADD_FAILURE() << "Didn't encode an expected frame";
409 }
410 }
411 int32_t Encode(const VideoFrame& input_image,
412 const std::vector<VideoFrameType>* frame_types) override {
413 encoded_frame_ = true;
414 return test::FakeEncoder::Encode(input_image, frame_types);
415 }
416
417 private:
418 bool encoded_frame_;
419 };
420
421 RequiredTransport required_transport(true /*rtp*/, false /*rtcp*/);
422 RequiredEncoder required_encoder;
423 VerifyNewVideoSendStreamsRespectNetworkState(
424 MediaType::VIDEO, &required_encoder, &required_transport);
425 }
426
TEST_F(NetworkStateEndToEndTest,NewVideoReceiveStreamsRespectVideoNetworkDown)427 TEST_F(NetworkStateEndToEndTest,
428 NewVideoReceiveStreamsRespectVideoNetworkDown) {
429 UnusedTransport transport;
430 VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport);
431 }
432
TEST_F(NetworkStateEndToEndTest,NewVideoReceiveStreamsIgnoreAudioNetworkDown)433 TEST_F(NetworkStateEndToEndTest, NewVideoReceiveStreamsIgnoreAudioNetworkDown) {
434 RequiredTransport transport(false /*rtp*/, true /*rtcp*/);
435 VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::VIDEO, &transport);
436 }
437
438 } // namespace webrtc
439