blob: cae3b86cc08730ff3de3a2d2e4841f32d2931c07 [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
Steve Anton40d55332019-01-07 10:21:47 -080013#include "absl/memory/memory.h"
Elad Alon8b60e8b2019-04-08 14:14:05 +020014#include "absl/types/optional.h"
Stefan Holmer9416ef82018-07-19 10:34:38 +020015#include "call/rtp_video_sender.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020016#include "call/test/mock_bitrate_allocator.h"
17#include "call/test/mock_rtp_transport_controller_send.h"
18#include "logging/rtc_event_log/rtc_event_log.h"
Elad Alon8b60e8b2019-04-08 14:14:05 +020019#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h"
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020020#include "modules/utility/include/process_thread.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020021#include "modules/video_coding/fec_controller_default.h"
22#include "rtc_base/experiments/alr_experiment.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/fake_clock.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020024#include "rtc_base/task_queue_for_test.h"
25#include "test/field_trial.h"
26#include "test/gmock.h"
27#include "test/gtest.h"
28#include "test/mock_transport.h"
29#include "video/test/mock_video_stream_encoder.h"
30#include "video/video_send_stream_impl.h"
31
32namespace webrtc {
33namespace internal {
34namespace {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020035using ::testing::_;
36using ::testing::Invoke;
37using ::testing::NiceMock;
38using ::testing::Return;
Sebastian Jansson652dc912018-04-19 17:09:15 +020039
40constexpr int64_t kDefaultInitialBitrateBps = 333000;
41const double kDefaultBitratePriority = 0.5;
42
43const float kAlrProbingExperimentPaceMultiplier = 1.0f;
44std::string GetAlrProbingExperimentString() {
45 return std::string(
46 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
47 "/1.0,2875,80,40,-60,3/";
48}
Stefan Holmer64be7fa2018-10-04 15:21:55 +020049class MockRtpVideoSender : public RtpVideoSenderInterface {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020050 public:
51 MOCK_METHOD1(RegisterProcessThread, void(ProcessThread*));
52 MOCK_METHOD0(DeRegisterProcessThread, void());
53 MOCK_METHOD1(SetActive, void(bool));
54 MOCK_METHOD1(SetActiveModules, void(const std::vector<bool>));
55 MOCK_METHOD0(IsActive, bool());
56 MOCK_METHOD1(OnNetworkAvailability, void(bool));
57 MOCK_CONST_METHOD0(GetRtpStates, std::map<uint32_t, RtpState>());
58 MOCK_CONST_METHOD0(GetRtpPayloadStates,
59 std::map<uint32_t, RtpPayloadState>());
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020060 MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020061 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
62 MOCK_METHOD3(OnEncodedImage,
63 EncodedImageCallback::Result(const EncodedImage&,
64 const CodecSpecificInfo*,
65 const RTPFragmentationHeader*));
Stefan Holmer64be7fa2018-10-04 15:21:55 +020066 MOCK_METHOD1(OnTransportOverheadChanged, void(size_t));
67 MOCK_METHOD1(OnOverheadChanged, void(size_t));
68 MOCK_METHOD4(OnBitrateUpdated, void(uint32_t, uint8_t, int64_t, int));
69 MOCK_CONST_METHOD0(GetPayloadBitrateBps, uint32_t());
70 MOCK_CONST_METHOD0(GetProtectionBitrateBps, uint32_t());
71 MOCK_METHOD3(SetEncodingData, void(size_t, size_t, size_t));
Elad Alon898395d2019-04-10 15:55:00 +020072 MOCK_CONST_METHOD2(GetSentRtpPacketInfos,
73 std::vector<RtpSequenceNumberMap::Info>(
74 uint32_t ssrc,
75 rtc::ArrayView<const uint16_t> sequence_numbers));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020076};
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020077
78BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {
79 BitrateAllocationUpdate update;
Sebastian Jansson13e59032018-11-21 19:13:07 +010080 update.target_bitrate = DataRate::bps(bitrate_bps);
81 update.packet_loss_ratio = 0;
82 update.round_trip_time = TimeDelta::Zero();
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020083 return update;
84}
Sebastian Jansson652dc912018-04-19 17:09:15 +020085} // namespace
86
87class VideoSendStreamImplTest : public ::testing::Test {
88 protected:
89 VideoSendStreamImplTest()
90 : clock_(1000 * 1000 * 1000),
91 config_(&transport_),
92 send_delay_stats_(&clock_),
Sebastian Jansson652dc912018-04-19 17:09:15 +020093 test_queue_("test_queue"),
94 process_thread_(ProcessThread::Create("test_thread")),
95 call_stats_(&clock_, process_thread_.get()),
96 stats_proxy_(&clock_,
97 config_,
98 VideoEncoderConfig::ContentType::kRealtimeVideo) {
99 config_.rtp.ssrcs.push_back(8080);
100 config_.rtp.payload_type = 1;
101
Sebastian Jansson652dc912018-04-19 17:09:15 +0200102 EXPECT_CALL(transport_controller_, packet_router())
103 .WillRepeatedly(Return(&packet_router_));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200104 EXPECT_CALL(transport_controller_,
Oleh Prypine8964902019-03-29 15:33:01 +0000105 CreateRtpVideoSender(_, _, _, _, _, _, _, _, _))
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200106 .WillRepeatedly(Return(&rtp_video_sender_));
107 EXPECT_CALL(rtp_video_sender_, SetActive(_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200108 .WillRepeatedly(::testing::Invoke(
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200109 [&](bool active) { rtp_video_sender_active_ = active; }));
110 EXPECT_CALL(rtp_video_sender_, IsActive())
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200111 .WillRepeatedly(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200112 ::testing::Invoke([&]() { return rtp_video_sender_active_; }));
Sebastian Jansson652dc912018-04-19 17:09:15 +0200113 }
114 ~VideoSendStreamImplTest() {}
115
116 std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
117 int initial_encoder_max_bitrate,
118 double initial_encoder_bitrate_priority,
119 VideoEncoderConfig::ContentType content_type) {
120 EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
121 .WillOnce(Return(123000));
122 std::map<uint32_t, RtpState> suspended_ssrcs;
123 std::map<uint32_t, RtpPayloadState> suspended_payload_states;
Karl Wiberg918f50c2018-07-05 11:40:33 +0200124 return absl::make_unique<VideoSendStreamImpl>(
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100125 &clock_, &stats_proxy_, &test_queue_, &call_stats_,
126 &transport_controller_, &bitrate_allocator_, &send_delay_stats_,
127 &video_stream_encoder_, &event_log_, &config_,
128 initial_encoder_max_bitrate, initial_encoder_bitrate_priority,
129 suspended_ssrcs, suspended_payload_states, content_type,
Niels Möller46879152019-01-07 15:54:47 +0100130 absl::make_unique<FecControllerDefault>(&clock_),
131 /*media_transport=*/nullptr);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200132 }
133
134 protected:
135 NiceMock<MockTransport> transport_;
136 NiceMock<MockRtpTransportControllerSend> transport_controller_;
137 NiceMock<MockBitrateAllocator> bitrate_allocator_;
138 NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200139 NiceMock<MockRtpVideoSender> rtp_video_sender_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200140
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200141 bool rtp_video_sender_active_ = false;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200142 SimulatedClock clock_;
143 RtcEventLogNullImpl event_log_;
144 VideoSendStream::Config config_;
145 SendDelayStats send_delay_stats_;
Danil Chapovalovd26a9162019-03-19 18:08:37 +0100146 TaskQueueForTest test_queue_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200147 std::unique_ptr<ProcessThread> process_thread_;
148 CallStats call_stats_;
149 SendStatisticsProxy stats_proxy_;
150 PacketRouter packet_router_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200151};
152
153TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
154 test_queue_.SendTask([this] {
155 config_.track_id = "test";
156 const bool kSuspend = false;
157 config_.suspend_below_min_bitrate = kSuspend;
158 auto vss_impl = CreateVideoSendStreamImpl(
159 kDefaultInitialBitrateBps, kDefaultBitratePriority,
160 VideoEncoderConfig::ContentType::kRealtimeVideo);
161 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
162 .WillOnce(Invoke(
163 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
164 EXPECT_EQ(config.min_bitrate_bps, 0u);
165 EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
166 EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
167 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
168 EXPECT_EQ(config.track_id, "test");
169 EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200170 }));
171 vss_impl->Start();
172 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
173 vss_impl->Stop();
174 });
175}
176
Erik Språngb57ab382018-09-13 10:52:38 +0200177TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
178 test_queue_.SendTask([this] {
179 config_.track_id = "test";
180 const bool kSuspend = false;
181 config_.suspend_below_min_bitrate = kSuspend;
182 config_.rtp.extensions.emplace_back(
183 RtpExtension::kTransportSequenceNumberUri, 1);
184 auto vss_impl = CreateVideoSendStreamImpl(
185 kDefaultInitialBitrateBps, kDefaultBitratePriority,
186 VideoEncoderConfig::ContentType::kRealtimeVideo);
187 vss_impl->Start();
188
189 // QVGA + VGA configuration matching defaults in media/engine/simulcast.cc.
190 VideoStream qvga_stream;
191 qvga_stream.width = 320;
192 qvga_stream.height = 180;
193 qvga_stream.max_framerate = 30;
194 qvga_stream.min_bitrate_bps = 30000;
195 qvga_stream.target_bitrate_bps = 150000;
196 qvga_stream.max_bitrate_bps = 200000;
197 qvga_stream.max_qp = 56;
198 qvga_stream.bitrate_priority = 1;
199
200 VideoStream vga_stream;
201 vga_stream.width = 640;
202 vga_stream.height = 360;
203 vga_stream.max_framerate = 30;
204 vga_stream.min_bitrate_bps = 150000;
205 vga_stream.target_bitrate_bps = 500000;
206 vga_stream.max_bitrate_bps = 700000;
207 vga_stream.max_qp = 56;
208 vga_stream.bitrate_priority = 1;
209
210 int min_transmit_bitrate_bps = 30000;
211
212 config_.rtp.ssrcs.emplace_back(1);
213 config_.rtp.ssrcs.emplace_back(2);
214
215 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
216 .WillOnce(Invoke(
217 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
218 EXPECT_EQ(config.min_bitrate_bps,
219 static_cast<uint32_t>(min_transmit_bitrate_bps));
220 EXPECT_EQ(config.max_bitrate_bps,
221 static_cast<uint32_t>(qvga_stream.max_bitrate_bps +
222 vga_stream.max_bitrate_bps));
223 EXPECT_EQ(config.pad_up_bitrate_bps,
224 static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
225 vga_stream.min_bitrate_bps));
226 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200227 }));
228
229 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
230 ->OnEncoderConfigurationChanged(
231 std::vector<VideoStream>{qvga_stream, vga_stream},
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100232 VideoEncoderConfig::ContentType::kRealtimeVideo,
Erik Språngb57ab382018-09-13 10:52:38 +0200233 min_transmit_bitrate_bps);
234 vss_impl->Stop();
235 });
236}
237
238TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
239 test_queue_.SendTask([this] {
240 config_.track_id = "test";
241 const bool kSuspend = false;
242 config_.suspend_below_min_bitrate = kSuspend;
243 config_.rtp.extensions.emplace_back(
244 RtpExtension::kTransportSequenceNumberUri, 1);
245 config_.periodic_alr_bandwidth_probing = true;
246 auto vss_impl = CreateVideoSendStreamImpl(
247 kDefaultInitialBitrateBps, kDefaultBitratePriority,
248 VideoEncoderConfig::ContentType::kScreen);
249 vss_impl->Start();
250
251 // Simulcast screenshare.
252 VideoStream low_stream;
253 low_stream.width = 1920;
254 low_stream.height = 1080;
255 low_stream.max_framerate = 5;
256 low_stream.min_bitrate_bps = 30000;
257 low_stream.target_bitrate_bps = 200000;
258 low_stream.max_bitrate_bps = 1000000;
259 low_stream.num_temporal_layers = 2;
260 low_stream.max_qp = 56;
261 low_stream.bitrate_priority = 1;
262
263 VideoStream high_stream;
264 high_stream.width = 1920;
265 high_stream.height = 1080;
266 high_stream.max_framerate = 30;
267 high_stream.min_bitrate_bps = 60000;
268 high_stream.target_bitrate_bps = 1250000;
269 high_stream.max_bitrate_bps = 1250000;
270 high_stream.num_temporal_layers = 2;
271 high_stream.max_qp = 56;
272 high_stream.bitrate_priority = 1;
273
274 // With ALR probing, this will be the padding target instead of
275 // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
276 int min_transmit_bitrate_bps = 400000;
277
278 config_.rtp.ssrcs.emplace_back(1);
279 config_.rtp.ssrcs.emplace_back(2);
280
281 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
282 .WillOnce(Invoke(
283 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
284 EXPECT_EQ(config.min_bitrate_bps,
285 static_cast<uint32_t>(low_stream.min_bitrate_bps));
286 EXPECT_EQ(config.max_bitrate_bps,
287 static_cast<uint32_t>(low_stream.max_bitrate_bps +
288 high_stream.max_bitrate_bps));
289 EXPECT_EQ(config.pad_up_bitrate_bps,
290 static_cast<uint32_t>(min_transmit_bitrate_bps));
291 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200292 }));
293
294 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
295 ->OnEncoderConfigurationChanged(
296 std::vector<VideoStream>{low_stream, high_stream},
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100297 VideoEncoderConfig::ContentType::kScreen, min_transmit_bitrate_bps);
298 vss_impl->Stop();
299 });
300}
301
302TEST_F(VideoSendStreamImplTest,
303 UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis) {
304 test::ScopedFieldTrials hysteresis_experiment(
305 "WebRTC-VideoRateControl/video_hysteresis:1.25/");
306
307 test_queue_.SendTask([this] {
308 auto vss_impl = CreateVideoSendStreamImpl(
309 kDefaultInitialBitrateBps, kDefaultBitratePriority,
310 VideoEncoderConfig::ContentType::kRealtimeVideo);
311 vss_impl->Start();
312
313 // 2-layer video simulcast.
314 VideoStream low_stream;
315 low_stream.width = 320;
316 low_stream.height = 240;
317 low_stream.max_framerate = 30;
318 low_stream.min_bitrate_bps = 30000;
319 low_stream.target_bitrate_bps = 100000;
320 low_stream.max_bitrate_bps = 200000;
321 low_stream.max_qp = 56;
322 low_stream.bitrate_priority = 1;
323
324 VideoStream high_stream;
325 high_stream.width = 640;
326 high_stream.height = 480;
327 high_stream.max_framerate = 30;
328 high_stream.min_bitrate_bps = 150000;
329 high_stream.target_bitrate_bps = 500000;
330 high_stream.max_bitrate_bps = 750000;
331 high_stream.max_qp = 56;
332 high_stream.bitrate_priority = 1;
333
334 config_.rtp.ssrcs.emplace_back(1);
335 config_.rtp.ssrcs.emplace_back(2);
336
337 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
338 .WillOnce(Invoke([&](BitrateAllocatorObserver*,
339 MediaStreamAllocationConfig config) {
340 EXPECT_EQ(config.min_bitrate_bps,
341 static_cast<uint32_t>(low_stream.min_bitrate_bps));
342 EXPECT_EQ(config.max_bitrate_bps,
343 static_cast<uint32_t>(low_stream.max_bitrate_bps +
344 high_stream.max_bitrate_bps));
345 EXPECT_EQ(config.pad_up_bitrate_bps,
346 static_cast<uint32_t>(low_stream.target_bitrate_bps +
347 1.25 * high_stream.min_bitrate_bps));
348 }));
349
350 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
351 ->OnEncoderConfigurationChanged(
352 std::vector<VideoStream>{low_stream, high_stream},
353 VideoEncoderConfig::ContentType::kRealtimeVideo,
354 /*min_transmit_bitrate_bps=*/0);
Erik Språngb57ab382018-09-13 10:52:38 +0200355 vss_impl->Stop();
356 });
357}
358
Sebastian Jansson652dc912018-04-19 17:09:15 +0200359TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
360 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
361
362 test_queue_.SendTask([this] {
Elad Alon157540a2019-02-08 23:37:52 +0100363 constexpr int kId = 1;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200364 config_.rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +0100365 RtpExtension::kTransportSequenceNumberUri, kId);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200366 EXPECT_CALL(transport_controller_,
367 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
368 .Times(1);
369 auto vss_impl = CreateVideoSendStreamImpl(
370 kDefaultInitialBitrateBps, kDefaultBitratePriority,
371 VideoEncoderConfig::ContentType::kScreen);
372 vss_impl->Start();
373 vss_impl->Stop();
374 });
375}
376
377TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
378 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
379 test_queue_.SendTask([this] {
380 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
381 auto vss_impl = CreateVideoSendStreamImpl(
382 kDefaultInitialBitrateBps, kDefaultBitratePriority,
383 VideoEncoderConfig::ContentType::kScreen);
384 vss_impl->Start();
385 vss_impl->Stop();
386 });
387}
Erik Språng4e193e42018-09-14 19:01:58 +0200388
389TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
390 test_queue_.SendTask([this] {
391 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
392 auto vss_impl = CreateVideoSendStreamImpl(
393 kDefaultInitialBitrateBps, kDefaultBitratePriority,
394 VideoEncoderConfig::ContentType::kScreen);
395 vss_impl->Start();
396 VideoBitrateAllocationObserver* const observer =
397 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
398
399 // Populate a test instance of video bitrate allocation.
400 VideoBitrateAllocation alloc;
401 alloc.SetBitrate(0, 0, 10000);
402 alloc.SetBitrate(0, 1, 20000);
403 alloc.SetBitrate(1, 0, 30000);
404 alloc.SetBitrate(1, 1, 40000);
405
406 // Encoder starts out paused, don't forward allocation.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200407 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200408 observer->OnBitrateAllocationUpdated(alloc);
409
410 // Unpause encoder, allocation should be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200411 const uint32_t kBitrateBps = 100000;
412 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
413 .Times(1)
414 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200415 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200416 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200417 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200418 observer->OnBitrateAllocationUpdated(alloc);
419
420 // Pause encoder again, and block allocations.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200421 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
422 .Times(1)
423 .WillOnce(Return(0));
Erik Språng4e193e42018-09-14 19:01:58 +0200424 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200425 ->OnBitrateUpdated(CreateAllocation(0));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200426 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200427 observer->OnBitrateAllocationUpdated(alloc);
428
429 vss_impl->Stop();
430 });
431}
432
433TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
434 test_queue_.SendTask([this] {
435 auto vss_impl = CreateVideoSendStreamImpl(
436 kDefaultInitialBitrateBps, kDefaultBitratePriority,
437 VideoEncoderConfig::ContentType::kScreen);
438 vss_impl->Start();
439 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200440 const uint32_t kBitrateBps = 100000;
441 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
442 .Times(1)
443 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200444 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200445 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200446 VideoBitrateAllocationObserver* const observer =
447 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
448
449 // Populate a test instance of video bitrate allocation.
450 VideoBitrateAllocation alloc;
451 alloc.SetBitrate(0, 0, 10000);
452 alloc.SetBitrate(0, 1, 20000);
453 alloc.SetBitrate(1, 0, 30000);
454 alloc.SetBitrate(1, 1, 40000);
455
456 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200457 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200458 observer->OnBitrateAllocationUpdated(alloc);
459
460 VideoBitrateAllocation updated_alloc = alloc;
461 // Needs 10% increase in bitrate to trigger immediate forward.
462 const uint32_t base_layer_min_update_bitrate_bps =
463 alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
464
465 // Too small increase, don't forward.
466 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200467 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200468 observer->OnBitrateAllocationUpdated(updated_alloc);
469
470 // Large enough increase, do forward.
471 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200472 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200473 .Times(1);
474 observer->OnBitrateAllocationUpdated(updated_alloc);
475
476 // This is now a decrease compared to last forward allocation, forward
477 // immediately.
478 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200479 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200480 .Times(1);
481 observer->OnBitrateAllocationUpdated(updated_alloc);
482
483 vss_impl->Stop();
484 });
485}
486
487TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
488 test_queue_.SendTask([this] {
489 auto vss_impl = CreateVideoSendStreamImpl(
490 kDefaultInitialBitrateBps, kDefaultBitratePriority,
491 VideoEncoderConfig::ContentType::kScreen);
492 vss_impl->Start();
493 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200494 const uint32_t kBitrateBps = 100000;
495 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
496 .Times(1)
497 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200498 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200499 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200500 VideoBitrateAllocationObserver* const observer =
501 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
502
503 // Populate a test instance of video bitrate allocation.
504 VideoBitrateAllocation alloc;
505 alloc.SetBitrate(0, 0, 10000);
506 alloc.SetBitrate(0, 1, 20000);
507 alloc.SetBitrate(1, 0, 30000);
508 alloc.SetBitrate(1, 1, 40000);
509
510 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200511 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200512 observer->OnBitrateAllocationUpdated(alloc);
513
514 // Move some bitrate from one layer to a new one, but keep sum the same.
515 // Since layout has changed, immediately trigger forward.
516 VideoBitrateAllocation updated_alloc = alloc;
517 updated_alloc.SetBitrate(2, 0, 10000);
518 updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
519 EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200520 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200521 .Times(1);
522 observer->OnBitrateAllocationUpdated(updated_alloc);
523
524 vss_impl->Stop();
525 });
526}
527
528TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
529 test_queue_.SendTask([this] {
Erik Språng4e193e42018-09-14 19:01:58 +0200530 auto vss_impl = CreateVideoSendStreamImpl(
531 kDefaultInitialBitrateBps, kDefaultBitratePriority,
532 VideoEncoderConfig::ContentType::kScreen);
533 vss_impl->Start();
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200534 const uint32_t kBitrateBps = 100000;
Erik Språng4e193e42018-09-14 19:01:58 +0200535 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200536 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
537 .Times(1)
538 .WillRepeatedly(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200539 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200540 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200541 VideoBitrateAllocationObserver* const observer =
542 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
543
544 // Populate a test instance of video bitrate allocation.
545 VideoBitrateAllocation alloc;
546 alloc.SetBitrate(0, 0, 10000);
547 alloc.SetBitrate(0, 1, 20000);
548 alloc.SetBitrate(1, 0, 30000);
549 alloc.SetBitrate(1, 1, 40000);
550
551 EncodedImage encoded_image;
552 CodecSpecificInfo codec_specific;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200553 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
Erik Språng4e193e42018-09-14 19:01:58 +0200554 .WillRepeatedly(Return(
555 EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
556
557 // Max time we will throttle similar video bitrate allocations.
558 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
559
560 {
561 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200562 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
563 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200564 observer->OnBitrateAllocationUpdated(alloc);
565 }
566
567 {
568 // Sending same allocation again, this one should be throttled.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200569 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
570 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200571 observer->OnBitrateAllocationUpdated(alloc);
572 }
573
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100574 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Erik Språng4e193e42018-09-14 19:01:58 +0200575
576 {
577 // Sending similar allocation again after timeout, should forward.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200578 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
579 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200580 observer->OnBitrateAllocationUpdated(alloc);
581 }
582
583 {
584 // Sending similar allocation again without timeout, throttle.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200585 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
586 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200587 observer->OnBitrateAllocationUpdated(alloc);
588 }
589
590 {
591 // Send encoded image, should be a noop.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200592 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
593 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200594 static_cast<EncodedImageCallback*>(vss_impl.get())
595 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
596 }
597
598 {
599 // Advance time and send encoded image, this should wake up and send
600 // cached bitrate allocation.
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100601 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200602 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
603 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200604 static_cast<EncodedImageCallback*>(vss_impl.get())
605 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
606 }
607
608 {
609 // Advance time and send encoded image, there should be no cached
610 // allocation to send.
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100611 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200612 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
613 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200614 static_cast<EncodedImageCallback*>(vss_impl.get())
615 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
616 }
617
618 vss_impl->Stop();
619 });
620}
621
Erik Språng610c7632019-03-06 15:37:33 +0100622TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
623 test_queue_.SendTask([this] {
624 config_.track_id = "test";
625 const bool kSuspend = false;
626 config_.suspend_below_min_bitrate = kSuspend;
627 config_.rtp.extensions.emplace_back(
628 RtpExtension::kTransportSequenceNumberUri, 1);
629 auto vss_impl = CreateVideoSendStreamImpl(
630 kDefaultInitialBitrateBps, kDefaultBitratePriority,
631 VideoEncoderConfig::ContentType::kRealtimeVideo);
632 vss_impl->Start();
633
634 VideoStream qvga_stream;
635 qvga_stream.width = 320;
636 qvga_stream.height = 180;
637 qvga_stream.max_framerate = 30;
638 qvga_stream.min_bitrate_bps = 30000;
639 qvga_stream.target_bitrate_bps = 150000;
640 qvga_stream.max_bitrate_bps = 200000;
641 qvga_stream.max_qp = 56;
642 qvga_stream.bitrate_priority = 1;
643
644 int min_transmit_bitrate_bps = 30000;
645
646 config_.rtp.ssrcs.emplace_back(1);
647
648 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
649 ->OnEncoderConfigurationChanged(
650 std::vector<VideoStream>{qvga_stream},
651 VideoEncoderConfig::ContentType::kRealtimeVideo,
652 min_transmit_bitrate_bps);
653
654 const DataRate network_constrained_rate =
655 DataRate::bps(qvga_stream.target_bitrate_bps);
656 BitrateAllocationUpdate update;
657 update.target_bitrate = network_constrained_rate;
658 update.link_capacity = network_constrained_rate;
659 update.round_trip_time = TimeDelta::ms(1);
660 EXPECT_CALL(rtp_video_sender_,
661 OnBitrateUpdated(network_constrained_rate.bps(), _,
662 update.round_trip_time.ms(), _));
663 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
664 .WillOnce(Return(network_constrained_rate.bps()));
Erik Språng4c6ca302019-04-08 15:14:01 +0200665 EXPECT_CALL(video_stream_encoder_,
666 OnBitrateUpdated(network_constrained_rate,
667 network_constrained_rate, 0, _));
Erik Språng610c7632019-03-06 15:37:33 +0100668 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
669 ->OnBitrateUpdated(update);
670
Erik Språng4c6ca302019-04-08 15:14:01 +0200671 // Test allocation where the link allocation is larger than the target,
672 // meaning we have some headroom on the link.
Erik Språng610c7632019-03-06 15:37:33 +0100673 const DataRate qvga_max_bitrate =
674 DataRate::bps(qvga_stream.max_bitrate_bps);
675 const DataRate headroom = DataRate::bps(50000);
676 const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
677 EXPECT_CALL(rtp_video_sender_,
678 OnBitrateUpdated(rate_with_headroom.bps(), _,
679 update.round_trip_time.ms(), _));
680 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
681 .WillOnce(Return(rate_with_headroom.bps()));
682 EXPECT_CALL(video_stream_encoder_,
Erik Språng4c6ca302019-04-08 15:14:01 +0200683 OnBitrateUpdated(qvga_max_bitrate, rate_with_headroom, 0, _));
Erik Språng610c7632019-03-06 15:37:33 +0100684 update.target_bitrate = rate_with_headroom;
685 update.link_capacity = rate_with_headroom;
686 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
687 ->OnBitrateUpdated(update);
688
Erik Språng26111642019-03-26 11:09:04 +0100689 // Add protection bitrate to the mix, this should be subtracted from the
690 // headroom.
691 const uint32_t protection_bitrate_bps = 10000;
692 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
693 .WillOnce(Return(protection_bitrate_bps));
694
695 EXPECT_CALL(rtp_video_sender_,
696 OnBitrateUpdated(rate_with_headroom.bps(), _,
697 update.round_trip_time.ms(), _));
698 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
699 .WillOnce(Return(rate_with_headroom.bps()));
700 const DataRate headroom_minus_protection =
Erik Språng4c6ca302019-04-08 15:14:01 +0200701 rate_with_headroom - DataRate::bps(protection_bitrate_bps);
Erik Språng26111642019-03-26 11:09:04 +0100702 EXPECT_CALL(
703 video_stream_encoder_,
704 OnBitrateUpdated(qvga_max_bitrate, headroom_minus_protection, 0, _));
705 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
706 ->OnBitrateUpdated(update);
707
Erik Språng4c6ca302019-04-08 15:14:01 +0200708 // Protection bitrate exceeds head room, link allocation should be capped to
709 // target bitrate.
Erik Språng26111642019-03-26 11:09:04 +0100710 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
711 .WillOnce(Return(headroom.bps() + 1000));
712 EXPECT_CALL(rtp_video_sender_,
713 OnBitrateUpdated(rate_with_headroom.bps(), _,
714 update.round_trip_time.ms(), _));
715 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
716 .WillOnce(Return(rate_with_headroom.bps()));
717 EXPECT_CALL(video_stream_encoder_,
Erik Språng4c6ca302019-04-08 15:14:01 +0200718 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, 0, _));
Erik Språng26111642019-03-26 11:09:04 +0100719 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
720 ->OnBitrateUpdated(update);
721
Erik Språng610c7632019-03-06 15:37:33 +0100722 // Set rates to zero on stop.
723 EXPECT_CALL(video_stream_encoder_,
724 OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), 0, 0));
725 vss_impl->Stop();
726 });
727}
728
Sebastian Jansson652dc912018-04-19 17:09:15 +0200729} // namespace internal
730} // namespace webrtc