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 <stddef.h>
12 #include <stdint.h>
13 
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "absl/types/optional.h"
20 #include "api/rtp_headers.h"
21 #include "api/task_queue/task_queue_base.h"
22 #include "api/test/simulated_network.h"
23 #include "api/video_codecs/sdp_video_format.h"
24 #include "api/video_codecs/video_encoder_config.h"
25 #include "call/call.h"
26 #include "call/fake_network_pipe.h"
27 #include "call/rtp_config.h"
28 #include "call/simulated_network.h"
29 #include "call/simulated_packet_receiver.h"
30 #include "call/video_receive_stream.h"
31 #include "call/video_send_stream.h"
32 #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
33 #include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h"
34 #include "rtc_base/event.h"
35 #include "rtc_base/synchronization/mutex.h"
36 #include "rtc_base/thread_annotations.h"
37 #include "system_wrappers/include/clock.h"
38 #include "test/call_test.h"
39 #include "test/field_trial.h"
40 #include "test/gtest.h"
41 #include "test/rtcp_packet_parser.h"
42 #include "test/rtp_rtcp_observer.h"
43 
44 namespace webrtc {
45 namespace {
46 enum : int {  // The first valid value is 1.
47   kColorSpaceExtensionId = 1,
48   kTransportSequenceNumberExtensionId,
49 };
50 }  // namespace
51 
52 class ExtendedReportsEndToEndTest : public test::CallTest {
53  public:
ExtendedReportsEndToEndTest()54   ExtendedReportsEndToEndTest() {
55     RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
56                                       kTransportSequenceNumberExtensionId));
57   }
58 };
59 
60 class RtcpXrObserver : public test::EndToEndTest {
61  public:
RtcpXrObserver(bool enable_rrtr,bool expect_target_bitrate,bool enable_zero_target_bitrate,VideoEncoderConfig::ContentType content_type)62   RtcpXrObserver(bool enable_rrtr,
63                  bool expect_target_bitrate,
64                  bool enable_zero_target_bitrate,
65                  VideoEncoderConfig::ContentType content_type)
66       : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
67         enable_rrtr_(enable_rrtr),
68         expect_target_bitrate_(expect_target_bitrate),
69         enable_zero_target_bitrate_(enable_zero_target_bitrate),
70         content_type_(content_type),
71         sent_rtcp_sr_(0),
72         sent_rtcp_rr_(0),
73         sent_rtcp_rrtr_(0),
74         sent_rtcp_target_bitrate_(false),
75         sent_zero_rtcp_target_bitrate_(false),
76         sent_rtcp_dlrr_(0),
77         send_simulated_network_(nullptr) {
78     forward_transport_config_.link_capacity_kbps = 500;
79     forward_transport_config_.queue_delay_ms = 0;
80     forward_transport_config_.loss_percent = 0;
81   }
82 
83  private:
84   // Receive stream should send RR packets (and RRTR packets if enabled).
OnReceiveRtcp(const uint8_t * packet,size_t length)85   Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
86     MutexLock lock(&mutex_);
87     test::RtcpPacketParser parser;
88     EXPECT_TRUE(parser.Parse(packet, length));
89 
90     sent_rtcp_rr_ += parser.receiver_report()->num_packets();
91     EXPECT_EQ(0, parser.sender_report()->num_packets());
92     EXPECT_GE(1, parser.xr()->num_packets());
93     if (parser.xr()->num_packets() > 0) {
94       if (parser.xr()->rrtr())
95         ++sent_rtcp_rrtr_;
96       EXPECT_FALSE(parser.xr()->dlrr());
97     }
98 
99     return SEND_PACKET;
100   }
101   // Send stream should send SR packets (and DLRR packets if enabled).
OnSendRtcp(const uint8_t * packet,size_t length)102   Action OnSendRtcp(const uint8_t* packet, size_t length) override {
103     MutexLock lock(&mutex_);
104     test::RtcpPacketParser parser;
105     EXPECT_TRUE(parser.Parse(packet, length));
106 
107     if (parser.sender_ssrc() == test::CallTest::kVideoSendSsrcs[1] &&
108         enable_zero_target_bitrate_) {
109       // Reduce bandwidth restriction to disable second stream after it was
110       // enabled for some time.
111       forward_transport_config_.link_capacity_kbps = 200;
112       send_simulated_network_->SetConfig(forward_transport_config_);
113     }
114 
115     sent_rtcp_sr_ += parser.sender_report()->num_packets();
116     EXPECT_LE(parser.xr()->num_packets(), 1);
117     if (parser.xr()->num_packets() > 0) {
118       EXPECT_FALSE(parser.xr()->rrtr());
119       if (parser.xr()->dlrr())
120         ++sent_rtcp_dlrr_;
121       if (parser.xr()->target_bitrate()) {
122         sent_rtcp_target_bitrate_ = true;
123         auto target_bitrates =
124             parser.xr()->target_bitrate()->GetTargetBitrates();
125         if (target_bitrates.empty()) {
126           sent_zero_rtcp_target_bitrate_ = true;
127         }
128         for (const rtcp::TargetBitrate::BitrateItem& item : target_bitrates) {
129           if (item.target_bitrate_kbps == 0) {
130             sent_zero_rtcp_target_bitrate_ = true;
131             break;
132           }
133         }
134       }
135     }
136 
137     if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
138         sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve &&
139         (sent_rtcp_target_bitrate_ || !expect_target_bitrate_) &&
140         (sent_zero_rtcp_target_bitrate_ || !enable_zero_target_bitrate_)) {
141       if (enable_rrtr_) {
142         EXPECT_GT(sent_rtcp_rrtr_, 0);
143         EXPECT_GT(sent_rtcp_dlrr_, 0);
144       } else {
145         EXPECT_EQ(sent_rtcp_rrtr_, 0);
146         EXPECT_EQ(sent_rtcp_dlrr_, 0);
147       }
148       EXPECT_EQ(expect_target_bitrate_, sent_rtcp_target_bitrate_);
149       EXPECT_EQ(enable_zero_target_bitrate_, sent_zero_rtcp_target_bitrate_);
150       observation_complete_.Set();
151     }
152     return SEND_PACKET;
153   }
154 
GetNumVideoStreams() const155   size_t GetNumVideoStreams() const override {
156     // When sending a zero target bitrate, we use two spatial layers so that
157     // we'll still have a layer with non-zero bitrate.
158     return enable_zero_target_bitrate_ ? 2 : 1;
159   }
160 
CreateSendTransport(TaskQueueBase * task_queue,Call * sender_call)161   std::unique_ptr<test::PacketTransport> CreateSendTransport(
162       TaskQueueBase* task_queue,
163       Call* sender_call) {
164     auto network =
165         std::make_unique<SimulatedNetwork>(forward_transport_config_);
166     send_simulated_network_ = network.get();
167     return std::make_unique<test::PacketTransport>(
168         task_queue, sender_call, this, test::PacketTransport::kSender,
169         test::CallTest::payload_type_map_,
170         std::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
171                                           std::move(network)));
172   }
173 
ModifyVideoConfigs(VideoSendStream::Config * send_config,std::vector<VideoReceiveStream::Config> * receive_configs,VideoEncoderConfig * encoder_config)174   void ModifyVideoConfigs(
175       VideoSendStream::Config* send_config,
176       std::vector<VideoReceiveStream::Config>* receive_configs,
177       VideoEncoderConfig* encoder_config) override {
178     if (enable_zero_target_bitrate_) {
179       // Configure VP8 to be able to use simulcast.
180       send_config->rtp.payload_name = "VP8";
181       encoder_config->codec_type = kVideoCodecVP8;
182       (*receive_configs)[0].decoders.resize(1);
183       (*receive_configs)[0].decoders[0].payload_type =
184           send_config->rtp.payload_type;
185       (*receive_configs)[0].decoders[0].video_format =
186           SdpVideoFormat(send_config->rtp.payload_name);
187     }
188     encoder_config->content_type = content_type_;
189     (*receive_configs)[0].rtp.rtcp_mode = RtcpMode::kReducedSize;
190     (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
191         enable_rrtr_;
192   }
193 
PerformTest()194   void PerformTest() override {
195     EXPECT_TRUE(Wait())
196         << "Timed out while waiting for RTCP SR/RR packets to be sent.";
197   }
198 
199   static const int kNumRtcpReportPacketsToObserve = 5;
200 
201   Mutex mutex_;
202   const bool enable_rrtr_;
203   const bool expect_target_bitrate_;
204   const bool enable_zero_target_bitrate_;
205   const VideoEncoderConfig::ContentType content_type_;
206   int sent_rtcp_sr_;
207   int sent_rtcp_rr_ RTC_GUARDED_BY(&mutex_);
208   int sent_rtcp_rrtr_ RTC_GUARDED_BY(&mutex_);
209   bool sent_rtcp_target_bitrate_ RTC_GUARDED_BY(&mutex_);
210   bool sent_zero_rtcp_target_bitrate_ RTC_GUARDED_BY(&mutex_);
211   int sent_rtcp_dlrr_;
212   BuiltInNetworkBehaviorConfig forward_transport_config_;
213   SimulatedNetwork* send_simulated_network_;
214 };
215 
TEST_F(ExtendedReportsEndToEndTest,TestExtendedReportsWithRrtrWithoutTargetBitrate)216 TEST_F(ExtendedReportsEndToEndTest,
217        TestExtendedReportsWithRrtrWithoutTargetBitrate) {
218   RtcpXrObserver test(/*enable_rrtr=*/true, /*expect_target_bitrate=*/false,
219                       /*enable_zero_target_bitrate=*/false,
220                       VideoEncoderConfig::ContentType::kRealtimeVideo);
221   RunBaseTest(&test);
222 }
223 
TEST_F(ExtendedReportsEndToEndTest,TestExtendedReportsWithoutRrtrWithoutTargetBitrate)224 TEST_F(ExtendedReportsEndToEndTest,
225        TestExtendedReportsWithoutRrtrWithoutTargetBitrate) {
226   RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/false,
227                       /*enable_zero_target_bitrate=*/false,
228                       VideoEncoderConfig::ContentType::kRealtimeVideo);
229   RunBaseTest(&test);
230 }
231 
TEST_F(ExtendedReportsEndToEndTest,TestExtendedReportsWithRrtrWithTargetBitrate)232 TEST_F(ExtendedReportsEndToEndTest,
233        TestExtendedReportsWithRrtrWithTargetBitrate) {
234   RtcpXrObserver test(/*enable_rrtr=*/true, /*expect_target_bitrate=*/true,
235                       /*enable_zero_target_bitrate=*/false,
236                       VideoEncoderConfig::ContentType::kScreen);
237   RunBaseTest(&test);
238 }
239 
TEST_F(ExtendedReportsEndToEndTest,TestExtendedReportsWithoutRrtrWithTargetBitrate)240 TEST_F(ExtendedReportsEndToEndTest,
241        TestExtendedReportsWithoutRrtrWithTargetBitrate) {
242   RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/true,
243                       /*enable_zero_target_bitrate=*/false,
244                       VideoEncoderConfig::ContentType::kScreen);
245   RunBaseTest(&test);
246 }
247 
TEST_F(ExtendedReportsEndToEndTest,TestExtendedReportsWithoutRrtrWithTargetBitrateFromFieldTrial)248 TEST_F(ExtendedReportsEndToEndTest,
249        TestExtendedReportsWithoutRrtrWithTargetBitrateFromFieldTrial) {
250   test::ScopedFieldTrials field_trials("WebRTC-Target-Bitrate-Rtcp/Enabled/");
251   RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/true,
252                       /*enable_zero_target_bitrate=*/false,
253                       VideoEncoderConfig::ContentType::kRealtimeVideo);
254   RunBaseTest(&test);
255 }
256 
TEST_F(ExtendedReportsEndToEndTest,TestExtendedReportsCanSignalZeroTargetBitrate)257 TEST_F(ExtendedReportsEndToEndTest,
258        TestExtendedReportsCanSignalZeroTargetBitrate) {
259   RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/true,
260                       /*enable_zero_target_bitrate=*/true,
261                       VideoEncoderConfig::ContentType::kScreen);
262   RunBaseTest(&test);
263 }
264 }  // namespace webrtc
265