blob: 66deb680d575a186f3b3b72f2579de507c9e39f2 [file] [log] [blame]
Sebastian Jansson652dc912018-04-19 17:09:15 +02001/*
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 <string>
12
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020013#include "call/payload_router.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020014#include "call/test/mock_bitrate_allocator.h"
15#include "call/test/mock_rtp_transport_controller_send.h"
16#include "logging/rtc_event_log/rtc_event_log.h"
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020017#include "modules/utility/include/process_thread.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020018#include "modules/video_coding/fec_controller_default.h"
19#include "rtc_base/experiments/alr_experiment.h"
20#include "rtc_base/task_queue_for_test.h"
21#include "test/field_trial.h"
22#include "test/gmock.h"
23#include "test/gtest.h"
24#include "test/mock_transport.h"
25#include "video/test/mock_video_stream_encoder.h"
26#include "video/video_send_stream_impl.h"
27
28namespace webrtc {
29namespace internal {
30namespace {
31using testing::NiceMock;
32using testing::StrictMock;
33using testing::ReturnRef;
34using testing::Return;
35using testing::Invoke;
36using testing::_;
37
38constexpr int64_t kDefaultInitialBitrateBps = 333000;
39const double kDefaultBitratePriority = 0.5;
40
41const float kAlrProbingExperimentPaceMultiplier = 1.0f;
42std::string GetAlrProbingExperimentString() {
43 return std::string(
44 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
45 "/1.0,2875,80,40,-60,3/";
46}
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020047class MockPayloadRouter : public VideoRtpSenderInterface {
48 public:
49 MOCK_METHOD1(RegisterProcessThread, void(ProcessThread*));
50 MOCK_METHOD0(DeRegisterProcessThread, void());
51 MOCK_METHOD1(SetActive, void(bool));
52 MOCK_METHOD1(SetActiveModules, void(const std::vector<bool>));
53 MOCK_METHOD0(IsActive, bool());
54 MOCK_METHOD1(OnNetworkAvailability, void(bool));
55 MOCK_CONST_METHOD0(GetRtpStates, std::map<uint32_t, RtpState>());
56 MOCK_CONST_METHOD0(GetRtpPayloadStates,
57 std::map<uint32_t, RtpPayloadState>());
58 MOCK_CONST_METHOD0(FecEnabled, bool());
59 MOCK_CONST_METHOD0(NackEnabled, bool());
60 MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
61 MOCK_METHOD5(ProtectionRequest,
62 void(const FecProtectionParams*,
63 const FecProtectionParams*,
64 uint32_t*,
65 uint32_t*,
66 uint32_t*));
67 MOCK_METHOD1(SetMaxRtpPacketSize, void(size_t));
68 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
69 MOCK_METHOD3(OnEncodedImage,
70 EncodedImageCallback::Result(const EncodedImage&,
71 const CodecSpecificInfo*,
72 const RTPFragmentationHeader*));
73};
Sebastian Jansson652dc912018-04-19 17:09:15 +020074} // namespace
75
76class VideoSendStreamImplTest : public ::testing::Test {
77 protected:
78 VideoSendStreamImplTest()
79 : clock_(1000 * 1000 * 1000),
80 config_(&transport_),
81 send_delay_stats_(&clock_),
Sebastian Jansson652dc912018-04-19 17:09:15 +020082 test_queue_("test_queue"),
83 process_thread_(ProcessThread::Create("test_thread")),
84 call_stats_(&clock_, process_thread_.get()),
85 stats_proxy_(&clock_,
86 config_,
87 VideoEncoderConfig::ContentType::kRealtimeVideo) {
88 config_.rtp.ssrcs.push_back(8080);
89 config_.rtp.payload_type = 1;
90
91 EXPECT_CALL(transport_controller_, keepalive_config())
92 .WillRepeatedly(ReturnRef(keepalive_config_));
93 EXPECT_CALL(transport_controller_, packet_router())
94 .WillRepeatedly(Return(&packet_router_));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020095 EXPECT_CALL(transport_controller_,
96 CreateVideoRtpSender(_, _, _, _, _, _, _, _))
97 .WillRepeatedly(Return(&payload_router_));
98 EXPECT_CALL(payload_router_, SetActive(_))
99 .WillRepeatedly(testing::Invoke(
100 [&](bool active) { payload_router_active_ = active; }));
101 EXPECT_CALL(payload_router_, IsActive())
102 .WillRepeatedly(
103 testing::Invoke([&]() { return payload_router_active_; }));
Sebastian Jansson652dc912018-04-19 17:09:15 +0200104 }
105 ~VideoSendStreamImplTest() {}
106
107 std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
108 int initial_encoder_max_bitrate,
109 double initial_encoder_bitrate_priority,
110 VideoEncoderConfig::ContentType content_type) {
111 EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
112 .WillOnce(Return(123000));
113 std::map<uint32_t, RtpState> suspended_ssrcs;
114 std::map<uint32_t, RtpPayloadState> suspended_payload_states;
Karl Wiberg918f50c2018-07-05 11:40:33 +0200115 return absl::make_unique<VideoSendStreamImpl>(
Sebastian Jansson652dc912018-04-19 17:09:15 +0200116 &stats_proxy_, &test_queue_, &call_stats_, &transport_controller_,
117 &bitrate_allocator_, &send_delay_stats_, &video_stream_encoder_,
118 &event_log_, &config_, initial_encoder_max_bitrate,
119 initial_encoder_bitrate_priority, suspended_ssrcs,
120 suspended_payload_states, content_type,
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200121 absl::make_unique<FecControllerDefault>(&clock_));
Sebastian Jansson652dc912018-04-19 17:09:15 +0200122 }
123
124 protected:
125 NiceMock<MockTransport> transport_;
126 NiceMock<MockRtpTransportControllerSend> transport_controller_;
127 NiceMock<MockBitrateAllocator> bitrate_allocator_;
128 NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200129 NiceMock<MockPayloadRouter> payload_router_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200130
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200131 bool payload_router_active_ = false;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200132 SimulatedClock clock_;
133 RtcEventLogNullImpl event_log_;
134 VideoSendStream::Config config_;
135 SendDelayStats send_delay_stats_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200136 rtc::test::TaskQueueForTest test_queue_;
137 std::unique_ptr<ProcessThread> process_thread_;
138 CallStats call_stats_;
139 SendStatisticsProxy stats_proxy_;
140 PacketRouter packet_router_;
141 RtpKeepAliveConfig keepalive_config_;
142};
143
144TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
145 test_queue_.SendTask([this] {
146 config_.track_id = "test";
147 const bool kSuspend = false;
148 config_.suspend_below_min_bitrate = kSuspend;
149 auto vss_impl = CreateVideoSendStreamImpl(
150 kDefaultInitialBitrateBps, kDefaultBitratePriority,
151 VideoEncoderConfig::ContentType::kRealtimeVideo);
152 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
153 .WillOnce(Invoke(
154 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
155 EXPECT_EQ(config.min_bitrate_bps, 0u);
156 EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
157 EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
158 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
159 EXPECT_EQ(config.track_id, "test");
160 EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
161 EXPECT_EQ(config.has_packet_feedback, false);
162 }));
163 vss_impl->Start();
164 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
165 vss_impl->Stop();
166 });
167}
168
169TEST_F(VideoSendStreamImplTest, ReportFeedbackAvailability) {
170 test_queue_.SendTask([this] {
171 config_.rtp.extensions.emplace_back(
172 RtpExtension::kTransportSequenceNumberUri,
173 RtpExtension::kTransportSequenceNumberDefaultId);
174
175 auto vss_impl = CreateVideoSendStreamImpl(
176 kDefaultInitialBitrateBps, kDefaultBitratePriority,
177 VideoEncoderConfig::ContentType::kRealtimeVideo);
178 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
179 .WillOnce(Invoke(
180 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
181 EXPECT_EQ(config.has_packet_feedback, true);
182 }));
183 vss_impl->Start();
184 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
185 vss_impl->Stop();
186 });
187}
188
189TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
190 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
191
192 test_queue_.SendTask([this] {
193 config_.rtp.extensions.emplace_back(
194 RtpExtension::kTransportSequenceNumberUri,
195 RtpExtension::kTransportSequenceNumberDefaultId);
196 EXPECT_CALL(transport_controller_,
197 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
198 .Times(1);
199 auto vss_impl = CreateVideoSendStreamImpl(
200 kDefaultInitialBitrateBps, kDefaultBitratePriority,
201 VideoEncoderConfig::ContentType::kScreen);
202 vss_impl->Start();
203 vss_impl->Stop();
204 });
205}
206
207TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
208 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
209 test_queue_.SendTask([this] {
210 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
211 auto vss_impl = CreateVideoSendStreamImpl(
212 kDefaultInitialBitrateBps, kDefaultBitratePriority,
213 VideoEncoderConfig::ContentType::kScreen);
214 vss_impl->Start();
215 vss_impl->Stop();
216 });
217}
218} // namespace internal
219} // namespace webrtc