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