summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/pc/peer_connection_adaptation_integrationtest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/pc/peer_connection_adaptation_integrationtest.cc')
-rw-r--r--third_party/libwebrtc/pc/peer_connection_adaptation_integrationtest.cc172
1 files changed, 172 insertions, 0 deletions
diff --git a/third_party/libwebrtc/pc/peer_connection_adaptation_integrationtest.cc b/third_party/libwebrtc/pc/peer_connection_adaptation_integrationtest.cc
new file mode 100644
index 0000000000..5922e15034
--- /dev/null
+++ b/third_party/libwebrtc/pc/peer_connection_adaptation_integrationtest.cc
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2020 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 <stdint.h>
+
+#include <memory>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/adaptation/resource.h"
+#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/audio_codecs/builtin_audio_encoder_factory.h"
+#include "api/media_stream_interface.h"
+#include "api/peer_connection_interface.h"
+#include "api/rtc_error.h"
+#include "api/rtp_parameters.h"
+#include "api/rtp_sender_interface.h"
+#include "api/scoped_refptr.h"
+#include "api/video/video_source_interface.h"
+#include "call/adaptation/test/fake_resource.h"
+#include "pc/test/fake_periodic_video_source.h"
+#include "pc/test/fake_periodic_video_track_source.h"
+#include "pc/test/peer_connection_test_wrapper.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/gunit.h"
+#include "rtc_base/thread.h"
+#include "rtc_base/time_utils.h"
+#include "rtc_base/virtual_socket_server.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+const int64_t kDefaultTimeoutMs = 5000;
+
+struct TrackWithPeriodicSource {
+ rtc::scoped_refptr<VideoTrackInterface> track;
+ rtc::scoped_refptr<FakePeriodicVideoTrackSource> periodic_track_source;
+};
+
+// Performs an O/A exchange and waits until the signaling state is stable again.
+void Negotiate(rtc::scoped_refptr<PeerConnectionTestWrapper> caller,
+ rtc::scoped_refptr<PeerConnectionTestWrapper> callee) {
+ // Wire up callbacks and listeners such that a full O/A is performed in
+ // response to CreateOffer().
+ PeerConnectionTestWrapper::Connect(caller.get(), callee.get());
+ caller->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions());
+ caller->WaitForNegotiation();
+}
+
+TrackWithPeriodicSource CreateTrackWithPeriodicSource(
+ rtc::scoped_refptr<PeerConnectionFactoryInterface> factory) {
+ FakePeriodicVideoSource::Config periodic_track_source_config;
+ periodic_track_source_config.frame_interval_ms = 100;
+ periodic_track_source_config.timestamp_offset_ms = rtc::TimeMillis();
+ rtc::scoped_refptr<FakePeriodicVideoTrackSource> periodic_track_source =
+ rtc::make_ref_counted<FakePeriodicVideoTrackSource>(
+ periodic_track_source_config, /* remote */ false);
+ TrackWithPeriodicSource track_with_source;
+ track_with_source.track =
+ factory->CreateVideoTrack("PeriodicTrack", periodic_track_source.get());
+ track_with_source.periodic_track_source = periodic_track_source;
+ return track_with_source;
+}
+
+// Triggers overuse and obtains VideoSinkWants. Adaptation processing happens in
+// parallel and this function makes no guarantee that the returnd VideoSinkWants
+// have yet to reflect the overuse signal. Used together with EXPECT_TRUE_WAIT
+// to "spam overuse until a change is observed".
+rtc::VideoSinkWants TriggerOveruseAndGetSinkWants(
+ rtc::scoped_refptr<FakeResource> fake_resource,
+ const FakePeriodicVideoSource& source) {
+ fake_resource->SetUsageState(ResourceUsageState::kOveruse);
+ return source.wants();
+}
+
+class PeerConnectionAdaptationIntegrationTest : public ::testing::Test {
+ public:
+ PeerConnectionAdaptationIntegrationTest()
+ : virtual_socket_server_(),
+ network_thread_(new rtc::Thread(&virtual_socket_server_)),
+ worker_thread_(rtc::Thread::Create()) {
+ RTC_CHECK(network_thread_->Start());
+ RTC_CHECK(worker_thread_->Start());
+ }
+
+ rtc::scoped_refptr<PeerConnectionTestWrapper> CreatePcWrapper(
+ const char* name) {
+ rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper =
+ rtc::make_ref_counted<PeerConnectionTestWrapper>(
+ name, &virtual_socket_server_, network_thread_.get(),
+ worker_thread_.get());
+ PeerConnectionInterface::RTCConfiguration config;
+ config.sdp_semantics = SdpSemantics::kUnifiedPlan;
+ EXPECT_TRUE(pc_wrapper->CreatePc(config, CreateBuiltinAudioEncoderFactory(),
+ CreateBuiltinAudioDecoderFactory()));
+ return pc_wrapper;
+ }
+
+ protected:
+ rtc::VirtualSocketServer virtual_socket_server_;
+ std::unique_ptr<rtc::Thread> network_thread_;
+ std::unique_ptr<rtc::Thread> worker_thread_;
+};
+
+TEST_F(PeerConnectionAdaptationIntegrationTest,
+ ResouceInjectedAfterNegotiationCausesReductionInResolution) {
+ auto caller_wrapper = CreatePcWrapper("caller");
+ auto caller = caller_wrapper->pc();
+ auto callee_wrapper = CreatePcWrapper("callee");
+
+ // Adding a track and negotiating ensures that a VideoSendStream exists.
+ TrackWithPeriodicSource track_with_source =
+ CreateTrackWithPeriodicSource(caller_wrapper->pc_factory());
+ auto sender = caller->AddTrack(track_with_source.track, {}).value();
+ Negotiate(caller_wrapper, callee_wrapper);
+ // Prefer degrading resolution.
+ auto parameters = sender->GetParameters();
+ parameters.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE;
+ sender->SetParameters(parameters);
+
+ const auto& source =
+ track_with_source.periodic_track_source->fake_periodic_source();
+ int pixel_count_before_overuse = source.wants().max_pixel_count;
+
+ // Inject a fake resource and spam kOveruse until resolution becomes limited.
+ auto fake_resource = FakeResource::Create("FakeResource");
+ caller->AddAdaptationResource(fake_resource);
+ EXPECT_TRUE_WAIT(
+ TriggerOveruseAndGetSinkWants(fake_resource, source).max_pixel_count <
+ pixel_count_before_overuse,
+ kDefaultTimeoutMs);
+}
+
+TEST_F(PeerConnectionAdaptationIntegrationTest,
+ ResouceInjectedBeforeNegotiationCausesReductionInResolution) {
+ auto caller_wrapper = CreatePcWrapper("caller");
+ auto caller = caller_wrapper->pc();
+ auto callee_wrapper = CreatePcWrapper("callee");
+
+ // Inject a fake resource before adding any tracks or negotiating.
+ auto fake_resource = FakeResource::Create("FakeResource");
+ caller->AddAdaptationResource(fake_resource);
+
+ // Adding a track and negotiating ensures that a VideoSendStream exists.
+ TrackWithPeriodicSource track_with_source =
+ CreateTrackWithPeriodicSource(caller_wrapper->pc_factory());
+ auto sender = caller->AddTrack(track_with_source.track, {}).value();
+ Negotiate(caller_wrapper, callee_wrapper);
+ // Prefer degrading resolution.
+ auto parameters = sender->GetParameters();
+ parameters.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE;
+ sender->SetParameters(parameters);
+
+ const auto& source =
+ track_with_source.periodic_track_source->fake_periodic_source();
+ int pixel_count_before_overuse = source.wants().max_pixel_count;
+
+ // Spam kOveruse until resolution becomes limited.
+ EXPECT_TRUE_WAIT(
+ TriggerOveruseAndGetSinkWants(fake_resource, source).max_pixel_count <
+ pixel_count_before_overuse,
+ kDefaultTimeoutMs);
+}
+
+} // namespace webrtc