diff options
Diffstat (limited to 'third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc')
-rw-r--r-- | third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc new file mode 100644 index 0000000000..2897212e0b --- /dev/null +++ b/third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc @@ -0,0 +1,264 @@ +/* + * Copyright 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stddef.h> +#include <stdint.h> + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "absl/types/optional.h" +#include "api/rtp_headers.h" +#include "api/task_queue/task_queue_base.h" +#include "api/test/simulated_network.h" +#include "api/video_codecs/sdp_video_format.h" +#include "call/call.h" +#include "call/fake_network_pipe.h" +#include "call/rtp_config.h" +#include "call/simulated_network.h" +#include "call/simulated_packet_receiver.h" +#include "call/video_receive_stream.h" +#include "call/video_send_stream.h" +#include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" +#include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h" +#include "rtc_base/event.h" +#include "rtc_base/synchronization/mutex.h" +#include "rtc_base/thread_annotations.h" +#include "system_wrappers/include/clock.h" +#include "test/call_test.h" +#include "test/field_trial.h" +#include "test/gtest.h" +#include "test/rtcp_packet_parser.h" +#include "test/rtp_rtcp_observer.h" +#include "video/config/video_encoder_config.h" + +namespace webrtc { +namespace { +enum : int { // The first valid value is 1. + kColorSpaceExtensionId = 1, + kTransportSequenceNumberExtensionId, +}; +} // namespace + +class ExtendedReportsEndToEndTest : public test::CallTest { + public: + ExtendedReportsEndToEndTest() { + RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri, + kTransportSequenceNumberExtensionId)); + } +}; + +class RtcpXrObserver : public test::EndToEndTest { + public: + RtcpXrObserver(bool enable_rrtr, + bool expect_target_bitrate, + bool enable_zero_target_bitrate, + VideoEncoderConfig::ContentType content_type) + : EndToEndTest(test::CallTest::kDefaultTimeout), + enable_rrtr_(enable_rrtr), + expect_target_bitrate_(expect_target_bitrate), + enable_zero_target_bitrate_(enable_zero_target_bitrate), + content_type_(content_type), + sent_rtcp_sr_(0), + sent_rtcp_rr_(0), + sent_rtcp_rrtr_(0), + sent_rtcp_target_bitrate_(false), + sent_zero_rtcp_target_bitrate_(false), + sent_rtcp_dlrr_(0), + send_simulated_network_(nullptr) { + forward_transport_config_.link_capacity_kbps = 500; + forward_transport_config_.queue_delay_ms = 0; + forward_transport_config_.loss_percent = 0; + } + + private: + // Receive stream should send RR packets (and RRTR packets if enabled). + Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { + MutexLock lock(&mutex_); + test::RtcpPacketParser parser; + EXPECT_TRUE(parser.Parse(packet, length)); + + sent_rtcp_rr_ += parser.receiver_report()->num_packets(); + EXPECT_EQ(0, parser.sender_report()->num_packets()); + EXPECT_GE(1, parser.xr()->num_packets()); + if (parser.xr()->num_packets() > 0) { + if (parser.xr()->rrtr()) + ++sent_rtcp_rrtr_; + EXPECT_FALSE(parser.xr()->dlrr()); + } + + return SEND_PACKET; + } + // Send stream should send SR packets (and DLRR packets if enabled). + Action OnSendRtcp(const uint8_t* packet, size_t length) override { + MutexLock lock(&mutex_); + test::RtcpPacketParser parser; + EXPECT_TRUE(parser.Parse(packet, length)); + + if (parser.sender_ssrc() == test::CallTest::kVideoSendSsrcs[1] && + enable_zero_target_bitrate_) { + // Reduce bandwidth restriction to disable second stream after it was + // enabled for some time. + forward_transport_config_.link_capacity_kbps = 200; + send_simulated_network_->SetConfig(forward_transport_config_); + } + + sent_rtcp_sr_ += parser.sender_report()->num_packets(); + EXPECT_LE(parser.xr()->num_packets(), 1); + if (parser.xr()->num_packets() > 0) { + EXPECT_FALSE(parser.xr()->rrtr()); + if (parser.xr()->dlrr()) + ++sent_rtcp_dlrr_; + if (parser.xr()->target_bitrate()) { + sent_rtcp_target_bitrate_ = true; + auto target_bitrates = + parser.xr()->target_bitrate()->GetTargetBitrates(); + if (target_bitrates.empty()) { + sent_zero_rtcp_target_bitrate_ = true; + } + for (const rtcp::TargetBitrate::BitrateItem& item : target_bitrates) { + if (item.target_bitrate_kbps == 0) { + sent_zero_rtcp_target_bitrate_ = true; + break; + } + } + } + } + + if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve && + sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve && + (sent_rtcp_target_bitrate_ || !expect_target_bitrate_) && + (sent_zero_rtcp_target_bitrate_ || !enable_zero_target_bitrate_)) { + if (enable_rrtr_) { + EXPECT_GT(sent_rtcp_rrtr_, 0); + EXPECT_GT(sent_rtcp_dlrr_, 0); + } else { + EXPECT_EQ(sent_rtcp_rrtr_, 0); + EXPECT_EQ(sent_rtcp_dlrr_, 0); + } + EXPECT_EQ(expect_target_bitrate_, sent_rtcp_target_bitrate_); + EXPECT_EQ(enable_zero_target_bitrate_, sent_zero_rtcp_target_bitrate_); + observation_complete_.Set(); + } + return SEND_PACKET; + } + + size_t GetNumVideoStreams() const override { + // When sending a zero target bitrate, we use two spatial layers so that + // we'll still have a layer with non-zero bitrate. + return enable_zero_target_bitrate_ ? 2 : 1; + } + + BuiltInNetworkBehaviorConfig GetSendTransportConfig() const override { + return forward_transport_config_; + } + + void OnTransportCreated( + test::PacketTransport* to_receiver, + SimulatedNetworkInterface* sender_network, + test::PacketTransport* to_sender, + SimulatedNetworkInterface* receiver_network) override { + send_simulated_network_ = sender_network; + } + + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector<VideoReceiveStreamInterface::Config>* receive_configs, + VideoEncoderConfig* encoder_config) override { + if (enable_zero_target_bitrate_) { + // Configure VP8 to be able to use simulcast. + send_config->rtp.payload_name = "VP8"; + encoder_config->codec_type = kVideoCodecVP8; + (*receive_configs)[0].decoders.resize(1); + (*receive_configs)[0].decoders[0].payload_type = + send_config->rtp.payload_type; + (*receive_configs)[0].decoders[0].video_format = + SdpVideoFormat(send_config->rtp.payload_name); + } + encoder_config->content_type = content_type_; + (*receive_configs)[0].rtp.rtcp_mode = RtcpMode::kReducedSize; + (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report = + enable_rrtr_; + } + + void PerformTest() override { + EXPECT_TRUE(Wait()) + << "Timed out while waiting for RTCP SR/RR packets to be sent."; + } + + static const int kNumRtcpReportPacketsToObserve = 5; + + Mutex mutex_; + const bool enable_rrtr_; + const bool expect_target_bitrate_; + const bool enable_zero_target_bitrate_; + const VideoEncoderConfig::ContentType content_type_; + int sent_rtcp_sr_; + int sent_rtcp_rr_ RTC_GUARDED_BY(&mutex_); + int sent_rtcp_rrtr_ RTC_GUARDED_BY(&mutex_); + bool sent_rtcp_target_bitrate_ RTC_GUARDED_BY(&mutex_); + bool sent_zero_rtcp_target_bitrate_ RTC_GUARDED_BY(&mutex_); + int sent_rtcp_dlrr_; + BuiltInNetworkBehaviorConfig forward_transport_config_; + SimulatedNetworkInterface* send_simulated_network_ = nullptr; +}; + +TEST_F(ExtendedReportsEndToEndTest, + TestExtendedReportsWithRrtrWithoutTargetBitrate) { + RtcpXrObserver test(/*enable_rrtr=*/true, /*expect_target_bitrate=*/false, + /*enable_zero_target_bitrate=*/false, + VideoEncoderConfig::ContentType::kRealtimeVideo); + RunBaseTest(&test); +} + +TEST_F(ExtendedReportsEndToEndTest, + TestExtendedReportsWithoutRrtrWithoutTargetBitrate) { + RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/false, + /*enable_zero_target_bitrate=*/false, + VideoEncoderConfig::ContentType::kRealtimeVideo); + RunBaseTest(&test); +} + +TEST_F(ExtendedReportsEndToEndTest, + TestExtendedReportsWithRrtrWithTargetBitrate) { + RtcpXrObserver test(/*enable_rrtr=*/true, /*expect_target_bitrate=*/true, + /*enable_zero_target_bitrate=*/false, + VideoEncoderConfig::ContentType::kScreen); + RunBaseTest(&test); +} + +TEST_F(ExtendedReportsEndToEndTest, + TestExtendedReportsWithoutRrtrWithTargetBitrate) { + RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/true, + /*enable_zero_target_bitrate=*/false, + VideoEncoderConfig::ContentType::kScreen); + RunBaseTest(&test); +} + +TEST_F(ExtendedReportsEndToEndTest, + TestExtendedReportsWithoutRrtrWithTargetBitrateExplicitlySet) { + test::ScopedKeyValueConfig field_trials( + field_trials_, "WebRTC-Target-Bitrate-Rtcp/Enabled/"); + RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/true, + /*enable_zero_target_bitrate=*/false, + VideoEncoderConfig::ContentType::kRealtimeVideo); + RunBaseTest(&test); +} + +TEST_F(ExtendedReportsEndToEndTest, + TestExtendedReportsCanSignalZeroTargetBitrate) { + RtcpXrObserver test(/*enable_rrtr=*/false, /*expect_target_bitrate=*/true, + /*enable_zero_target_bitrate=*/true, + VideoEncoderConfig::ContentType::kScreen); + RunBaseTest(&test); +} +} // namespace webrtc |