xref: /aosp_15_r20/external/webrtc/video/end_to_end_tests/network_state_tests.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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