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