blob: d874c4d1fc33aec90b5e700d3534e7d49ef78e66 [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"
Stefan Holmer9416ef82018-07-19 10:34:38 +020014#include "call/rtp_video_sender.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020015#include "call/test/mock_bitrate_allocator.h"
16#include "call/test/mock_rtp_transport_controller_send.h"
17#include "logging/rtc_event_log/rtc_event_log.h"
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020018#include "modules/utility/include/process_thread.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020019#include "modules/video_coding/fec_controller_default.h"
20#include "rtc_base/experiments/alr_experiment.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/fake_clock.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020022#include "rtc_base/task_queue_for_test.h"
23#include "test/field_trial.h"
24#include "test/gmock.h"
25#include "test/gtest.h"
26#include "test/mock_transport.h"
27#include "video/test/mock_video_stream_encoder.h"
28#include "video/video_send_stream_impl.h"
29
30namespace webrtc {
31namespace internal {
32namespace {
Sebastian Jansson652dc912018-04-19 17:09:15 +020033using testing::_;
Benjamin Wright1f4173e2019-03-13 17:59:32 -070034using testing::Invoke;
35using testing::NiceMock;
36using testing::Return;
Sebastian Jansson652dc912018-04-19 17:09:15 +020037
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 Holmer64be7fa2018-10-04 15:21:55 +020047class MockRtpVideoSender : public RtpVideoSenderInterface {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020048 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>());
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020058 MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020059 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
60 MOCK_METHOD3(OnEncodedImage,
61 EncodedImageCallback::Result(const EncodedImage&,
62 const CodecSpecificInfo*,
63 const RTPFragmentationHeader*));
Stefan Holmer64be7fa2018-10-04 15:21:55 +020064 MOCK_METHOD1(OnTransportOverheadChanged, void(size_t));
65 MOCK_METHOD1(OnOverheadChanged, void(size_t));
66 MOCK_METHOD4(OnBitrateUpdated, void(uint32_t, uint8_t, int64_t, int));
67 MOCK_CONST_METHOD0(GetPayloadBitrateBps, uint32_t());
68 MOCK_CONST_METHOD0(GetProtectionBitrateBps, uint32_t());
69 MOCK_METHOD3(SetEncodingData, void(size_t, size_t, size_t));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020070};
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020071
72BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {
73 BitrateAllocationUpdate update;
Sebastian Jansson13e59032018-11-21 19:13:07 +010074 update.target_bitrate = DataRate::bps(bitrate_bps);
75 update.packet_loss_ratio = 0;
76 update.round_trip_time = TimeDelta::Zero();
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020077 return update;
78}
Sebastian Jansson652dc912018-04-19 17:09:15 +020079} // namespace
80
81class VideoSendStreamImplTest : public ::testing::Test {
82 protected:
83 VideoSendStreamImplTest()
84 : clock_(1000 * 1000 * 1000),
85 config_(&transport_),
86 send_delay_stats_(&clock_),
Sebastian Jansson652dc912018-04-19 17:09:15 +020087 test_queue_("test_queue"),
88 process_thread_(ProcessThread::Create("test_thread")),
89 call_stats_(&clock_, process_thread_.get()),
90 stats_proxy_(&clock_,
91 config_,
92 VideoEncoderConfig::ContentType::kRealtimeVideo) {
93 config_.rtp.ssrcs.push_back(8080);
94 config_.rtp.payload_type = 1;
95
Sebastian Jansson652dc912018-04-19 17:09:15 +020096 EXPECT_CALL(transport_controller_, packet_router())
97 .WillRepeatedly(Return(&packet_router_));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020098 EXPECT_CALL(transport_controller_,
Amit Hilbuch0fc28432018-12-18 13:01:47 -080099 CreateRtpVideoSender(_, _, _, _, _, _, _, _, _))
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200100 .WillRepeatedly(Return(&rtp_video_sender_));
101 EXPECT_CALL(rtp_video_sender_, SetActive(_))
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200102 .WillRepeatedly(testing::Invoke(
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200103 [&](bool active) { rtp_video_sender_active_ = active; }));
104 EXPECT_CALL(rtp_video_sender_, IsActive())
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200105 .WillRepeatedly(
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200106 testing::Invoke([&]() { return rtp_video_sender_active_; }));
Sebastian Jansson652dc912018-04-19 17:09:15 +0200107 }
108 ~VideoSendStreamImplTest() {}
109
110 std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
111 int initial_encoder_max_bitrate,
112 double initial_encoder_bitrate_priority,
113 VideoEncoderConfig::ContentType content_type) {
114 EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
115 .WillOnce(Return(123000));
116 std::map<uint32_t, RtpState> suspended_ssrcs;
117 std::map<uint32_t, RtpPayloadState> suspended_payload_states;
Karl Wiberg918f50c2018-07-05 11:40:33 +0200118 return absl::make_unique<VideoSendStreamImpl>(
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100119 &clock_, &stats_proxy_, &test_queue_, &call_stats_,
120 &transport_controller_, &bitrate_allocator_, &send_delay_stats_,
121 &video_stream_encoder_, &event_log_, &config_,
122 initial_encoder_max_bitrate, initial_encoder_bitrate_priority,
123 suspended_ssrcs, suspended_payload_states, content_type,
Niels Möller46879152019-01-07 15:54:47 +0100124 absl::make_unique<FecControllerDefault>(&clock_),
125 /*media_transport=*/nullptr);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200126 }
127
128 protected:
129 NiceMock<MockTransport> transport_;
130 NiceMock<MockRtpTransportControllerSend> transport_controller_;
131 NiceMock<MockBitrateAllocator> bitrate_allocator_;
132 NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200133 NiceMock<MockRtpVideoSender> rtp_video_sender_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200134
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200135 bool rtp_video_sender_active_ = false;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200136 SimulatedClock clock_;
137 RtcEventLogNullImpl event_log_;
138 VideoSendStream::Config config_;
139 SendDelayStats send_delay_stats_;
Danil Chapovalovd26a9162019-03-19 18:08:37 +0100140 TaskQueueForTest test_queue_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200141 std::unique_ptr<ProcessThread> process_thread_;
142 CallStats call_stats_;
143 SendStatisticsProxy stats_proxy_;
144 PacketRouter packet_router_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200145};
146
147TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
148 test_queue_.SendTask([this] {
149 config_.track_id = "test";
150 const bool kSuspend = false;
151 config_.suspend_below_min_bitrate = kSuspend;
152 auto vss_impl = CreateVideoSendStreamImpl(
153 kDefaultInitialBitrateBps, kDefaultBitratePriority,
154 VideoEncoderConfig::ContentType::kRealtimeVideo);
155 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
156 .WillOnce(Invoke(
157 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
158 EXPECT_EQ(config.min_bitrate_bps, 0u);
159 EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
160 EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
161 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
162 EXPECT_EQ(config.track_id, "test");
163 EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200164 }));
165 vss_impl->Start();
166 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
167 vss_impl->Stop();
168 });
169}
170
Erik Språngb57ab382018-09-13 10:52:38 +0200171TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
172 test_queue_.SendTask([this] {
173 config_.track_id = "test";
174 const bool kSuspend = false;
175 config_.suspend_below_min_bitrate = kSuspend;
176 config_.rtp.extensions.emplace_back(
177 RtpExtension::kTransportSequenceNumberUri, 1);
178 auto vss_impl = CreateVideoSendStreamImpl(
179 kDefaultInitialBitrateBps, kDefaultBitratePriority,
180 VideoEncoderConfig::ContentType::kRealtimeVideo);
181 vss_impl->Start();
182
183 // QVGA + VGA configuration matching defaults in media/engine/simulcast.cc.
184 VideoStream qvga_stream;
185 qvga_stream.width = 320;
186 qvga_stream.height = 180;
187 qvga_stream.max_framerate = 30;
188 qvga_stream.min_bitrate_bps = 30000;
189 qvga_stream.target_bitrate_bps = 150000;
190 qvga_stream.max_bitrate_bps = 200000;
191 qvga_stream.max_qp = 56;
192 qvga_stream.bitrate_priority = 1;
193
194 VideoStream vga_stream;
195 vga_stream.width = 640;
196 vga_stream.height = 360;
197 vga_stream.max_framerate = 30;
198 vga_stream.min_bitrate_bps = 150000;
199 vga_stream.target_bitrate_bps = 500000;
200 vga_stream.max_bitrate_bps = 700000;
201 vga_stream.max_qp = 56;
202 vga_stream.bitrate_priority = 1;
203
204 int min_transmit_bitrate_bps = 30000;
205
206 config_.rtp.ssrcs.emplace_back(1);
207 config_.rtp.ssrcs.emplace_back(2);
208
209 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
210 .WillOnce(Invoke(
211 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
212 EXPECT_EQ(config.min_bitrate_bps,
213 static_cast<uint32_t>(min_transmit_bitrate_bps));
214 EXPECT_EQ(config.max_bitrate_bps,
215 static_cast<uint32_t>(qvga_stream.max_bitrate_bps +
216 vga_stream.max_bitrate_bps));
217 EXPECT_EQ(config.pad_up_bitrate_bps,
218 static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
219 vga_stream.min_bitrate_bps));
220 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200221 }));
222
223 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
224 ->OnEncoderConfigurationChanged(
225 std::vector<VideoStream>{qvga_stream, vga_stream},
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100226 VideoEncoderConfig::ContentType::kRealtimeVideo,
Erik Språngb57ab382018-09-13 10:52:38 +0200227 min_transmit_bitrate_bps);
228 vss_impl->Stop();
229 });
230}
231
232TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
233 test_queue_.SendTask([this] {
234 config_.track_id = "test";
235 const bool kSuspend = false;
236 config_.suspend_below_min_bitrate = kSuspend;
237 config_.rtp.extensions.emplace_back(
238 RtpExtension::kTransportSequenceNumberUri, 1);
239 config_.periodic_alr_bandwidth_probing = true;
240 auto vss_impl = CreateVideoSendStreamImpl(
241 kDefaultInitialBitrateBps, kDefaultBitratePriority,
242 VideoEncoderConfig::ContentType::kScreen);
243 vss_impl->Start();
244
245 // Simulcast screenshare.
246 VideoStream low_stream;
247 low_stream.width = 1920;
248 low_stream.height = 1080;
249 low_stream.max_framerate = 5;
250 low_stream.min_bitrate_bps = 30000;
251 low_stream.target_bitrate_bps = 200000;
252 low_stream.max_bitrate_bps = 1000000;
253 low_stream.num_temporal_layers = 2;
254 low_stream.max_qp = 56;
255 low_stream.bitrate_priority = 1;
256
257 VideoStream high_stream;
258 high_stream.width = 1920;
259 high_stream.height = 1080;
260 high_stream.max_framerate = 30;
261 high_stream.min_bitrate_bps = 60000;
262 high_stream.target_bitrate_bps = 1250000;
263 high_stream.max_bitrate_bps = 1250000;
264 high_stream.num_temporal_layers = 2;
265 high_stream.max_qp = 56;
266 high_stream.bitrate_priority = 1;
267
268 // With ALR probing, this will be the padding target instead of
269 // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
270 int min_transmit_bitrate_bps = 400000;
271
272 config_.rtp.ssrcs.emplace_back(1);
273 config_.rtp.ssrcs.emplace_back(2);
274
275 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
276 .WillOnce(Invoke(
277 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
278 EXPECT_EQ(config.min_bitrate_bps,
279 static_cast<uint32_t>(low_stream.min_bitrate_bps));
280 EXPECT_EQ(config.max_bitrate_bps,
281 static_cast<uint32_t>(low_stream.max_bitrate_bps +
282 high_stream.max_bitrate_bps));
283 EXPECT_EQ(config.pad_up_bitrate_bps,
284 static_cast<uint32_t>(min_transmit_bitrate_bps));
285 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200286 }));
287
288 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
289 ->OnEncoderConfigurationChanged(
290 std::vector<VideoStream>{low_stream, high_stream},
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100291 VideoEncoderConfig::ContentType::kScreen, min_transmit_bitrate_bps);
292 vss_impl->Stop();
293 });
294}
295
296TEST_F(VideoSendStreamImplTest,
297 UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis) {
298 test::ScopedFieldTrials hysteresis_experiment(
299 "WebRTC-VideoRateControl/video_hysteresis:1.25/");
300
301 test_queue_.SendTask([this] {
302 auto vss_impl = CreateVideoSendStreamImpl(
303 kDefaultInitialBitrateBps, kDefaultBitratePriority,
304 VideoEncoderConfig::ContentType::kRealtimeVideo);
305 vss_impl->Start();
306
307 // 2-layer video simulcast.
308 VideoStream low_stream;
309 low_stream.width = 320;
310 low_stream.height = 240;
311 low_stream.max_framerate = 30;
312 low_stream.min_bitrate_bps = 30000;
313 low_stream.target_bitrate_bps = 100000;
314 low_stream.max_bitrate_bps = 200000;
315 low_stream.max_qp = 56;
316 low_stream.bitrate_priority = 1;
317
318 VideoStream high_stream;
319 high_stream.width = 640;
320 high_stream.height = 480;
321 high_stream.max_framerate = 30;
322 high_stream.min_bitrate_bps = 150000;
323 high_stream.target_bitrate_bps = 500000;
324 high_stream.max_bitrate_bps = 750000;
325 high_stream.max_qp = 56;
326 high_stream.bitrate_priority = 1;
327
328 config_.rtp.ssrcs.emplace_back(1);
329 config_.rtp.ssrcs.emplace_back(2);
330
331 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
332 .WillOnce(Invoke([&](BitrateAllocatorObserver*,
333 MediaStreamAllocationConfig config) {
334 EXPECT_EQ(config.min_bitrate_bps,
335 static_cast<uint32_t>(low_stream.min_bitrate_bps));
336 EXPECT_EQ(config.max_bitrate_bps,
337 static_cast<uint32_t>(low_stream.max_bitrate_bps +
338 high_stream.max_bitrate_bps));
339 EXPECT_EQ(config.pad_up_bitrate_bps,
340 static_cast<uint32_t>(low_stream.target_bitrate_bps +
341 1.25 * high_stream.min_bitrate_bps));
342 }));
343
344 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
345 ->OnEncoderConfigurationChanged(
346 std::vector<VideoStream>{low_stream, high_stream},
347 VideoEncoderConfig::ContentType::kRealtimeVideo,
348 /*min_transmit_bitrate_bps=*/0);
Erik Språngb57ab382018-09-13 10:52:38 +0200349 vss_impl->Stop();
350 });
351}
352
Sebastian Jansson652dc912018-04-19 17:09:15 +0200353TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
354 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
355
356 test_queue_.SendTask([this] {
Elad Alon157540a2019-02-08 23:37:52 +0100357 constexpr int kId = 1;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200358 config_.rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +0100359 RtpExtension::kTransportSequenceNumberUri, kId);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200360 EXPECT_CALL(transport_controller_,
361 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
362 .Times(1);
363 auto vss_impl = CreateVideoSendStreamImpl(
364 kDefaultInitialBitrateBps, kDefaultBitratePriority,
365 VideoEncoderConfig::ContentType::kScreen);
366 vss_impl->Start();
367 vss_impl->Stop();
368 });
369}
370
371TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
372 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
373 test_queue_.SendTask([this] {
374 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
375 auto vss_impl = CreateVideoSendStreamImpl(
376 kDefaultInitialBitrateBps, kDefaultBitratePriority,
377 VideoEncoderConfig::ContentType::kScreen);
378 vss_impl->Start();
379 vss_impl->Stop();
380 });
381}
Erik Språng4e193e42018-09-14 19:01:58 +0200382
383TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
384 test_queue_.SendTask([this] {
385 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
386 auto vss_impl = CreateVideoSendStreamImpl(
387 kDefaultInitialBitrateBps, kDefaultBitratePriority,
388 VideoEncoderConfig::ContentType::kScreen);
389 vss_impl->Start();
390 VideoBitrateAllocationObserver* const observer =
391 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
392
393 // Populate a test instance of video bitrate allocation.
394 VideoBitrateAllocation alloc;
395 alloc.SetBitrate(0, 0, 10000);
396 alloc.SetBitrate(0, 1, 20000);
397 alloc.SetBitrate(1, 0, 30000);
398 alloc.SetBitrate(1, 1, 40000);
399
400 // Encoder starts out paused, don't forward allocation.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200401 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200402 observer->OnBitrateAllocationUpdated(alloc);
403
404 // Unpause encoder, allocation should be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200405 const uint32_t kBitrateBps = 100000;
406 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
407 .Times(1)
408 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200409 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200410 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200411 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200412 observer->OnBitrateAllocationUpdated(alloc);
413
414 // Pause encoder again, and block allocations.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200415 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
416 .Times(1)
417 .WillOnce(Return(0));
Erik Språng4e193e42018-09-14 19:01:58 +0200418 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200419 ->OnBitrateUpdated(CreateAllocation(0));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200420 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200421 observer->OnBitrateAllocationUpdated(alloc);
422
423 vss_impl->Stop();
424 });
425}
426
427TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
428 test_queue_.SendTask([this] {
429 auto vss_impl = CreateVideoSendStreamImpl(
430 kDefaultInitialBitrateBps, kDefaultBitratePriority,
431 VideoEncoderConfig::ContentType::kScreen);
432 vss_impl->Start();
433 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200434 const uint32_t kBitrateBps = 100000;
435 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
436 .Times(1)
437 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200438 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200439 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200440 VideoBitrateAllocationObserver* const observer =
441 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
442
443 // Populate a test instance of video bitrate allocation.
444 VideoBitrateAllocation alloc;
445 alloc.SetBitrate(0, 0, 10000);
446 alloc.SetBitrate(0, 1, 20000);
447 alloc.SetBitrate(1, 0, 30000);
448 alloc.SetBitrate(1, 1, 40000);
449
450 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200451 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200452 observer->OnBitrateAllocationUpdated(alloc);
453
454 VideoBitrateAllocation updated_alloc = alloc;
455 // Needs 10% increase in bitrate to trigger immediate forward.
456 const uint32_t base_layer_min_update_bitrate_bps =
457 alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
458
459 // Too small increase, don't forward.
460 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200461 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200462 observer->OnBitrateAllocationUpdated(updated_alloc);
463
464 // Large enough increase, do forward.
465 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200466 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200467 .Times(1);
468 observer->OnBitrateAllocationUpdated(updated_alloc);
469
470 // This is now a decrease compared to last forward allocation, forward
471 // immediately.
472 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200473 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200474 .Times(1);
475 observer->OnBitrateAllocationUpdated(updated_alloc);
476
477 vss_impl->Stop();
478 });
479}
480
481TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
482 test_queue_.SendTask([this] {
483 auto vss_impl = CreateVideoSendStreamImpl(
484 kDefaultInitialBitrateBps, kDefaultBitratePriority,
485 VideoEncoderConfig::ContentType::kScreen);
486 vss_impl->Start();
487 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200488 const uint32_t kBitrateBps = 100000;
489 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
490 .Times(1)
491 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200492 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200493 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200494 VideoBitrateAllocationObserver* const observer =
495 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
496
497 // Populate a test instance of video bitrate allocation.
498 VideoBitrateAllocation alloc;
499 alloc.SetBitrate(0, 0, 10000);
500 alloc.SetBitrate(0, 1, 20000);
501 alloc.SetBitrate(1, 0, 30000);
502 alloc.SetBitrate(1, 1, 40000);
503
504 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200505 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200506 observer->OnBitrateAllocationUpdated(alloc);
507
508 // Move some bitrate from one layer to a new one, but keep sum the same.
509 // Since layout has changed, immediately trigger forward.
510 VideoBitrateAllocation updated_alloc = alloc;
511 updated_alloc.SetBitrate(2, 0, 10000);
512 updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
513 EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200514 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200515 .Times(1);
516 observer->OnBitrateAllocationUpdated(updated_alloc);
517
518 vss_impl->Stop();
519 });
520}
521
522TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
523 test_queue_.SendTask([this] {
Erik Språng4e193e42018-09-14 19:01:58 +0200524 auto vss_impl = CreateVideoSendStreamImpl(
525 kDefaultInitialBitrateBps, kDefaultBitratePriority,
526 VideoEncoderConfig::ContentType::kScreen);
527 vss_impl->Start();
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200528 const uint32_t kBitrateBps = 100000;
Erik Språng4e193e42018-09-14 19:01:58 +0200529 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200530 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
531 .Times(1)
532 .WillRepeatedly(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200533 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200534 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200535 VideoBitrateAllocationObserver* const observer =
536 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
537
538 // Populate a test instance of video bitrate allocation.
539 VideoBitrateAllocation alloc;
540 alloc.SetBitrate(0, 0, 10000);
541 alloc.SetBitrate(0, 1, 20000);
542 alloc.SetBitrate(1, 0, 30000);
543 alloc.SetBitrate(1, 1, 40000);
544
545 EncodedImage encoded_image;
546 CodecSpecificInfo codec_specific;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200547 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
Erik Språng4e193e42018-09-14 19:01:58 +0200548 .WillRepeatedly(Return(
549 EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
550
551 // Max time we will throttle similar video bitrate allocations.
552 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
553
554 {
555 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200556 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
557 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200558 observer->OnBitrateAllocationUpdated(alloc);
559 }
560
561 {
562 // Sending same allocation again, this one should be throttled.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200563 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
564 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200565 observer->OnBitrateAllocationUpdated(alloc);
566 }
567
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100568 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Erik Språng4e193e42018-09-14 19:01:58 +0200569
570 {
571 // Sending similar allocation again after timeout, should forward.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200572 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
573 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200574 observer->OnBitrateAllocationUpdated(alloc);
575 }
576
577 {
578 // Sending similar allocation again without timeout, throttle.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200579 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
580 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200581 observer->OnBitrateAllocationUpdated(alloc);
582 }
583
584 {
585 // Send encoded image, should be a noop.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200586 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
587 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200588 static_cast<EncodedImageCallback*>(vss_impl.get())
589 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
590 }
591
592 {
593 // Advance time and send encoded image, this should wake up and send
594 // cached bitrate allocation.
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100595 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200596 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
597 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200598 static_cast<EncodedImageCallback*>(vss_impl.get())
599 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
600 }
601
602 {
603 // Advance time and send encoded image, there should be no cached
604 // allocation to send.
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100605 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200606 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
607 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200608 static_cast<EncodedImageCallback*>(vss_impl.get())
609 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
610 }
611
612 vss_impl->Stop();
613 });
614}
615
Erik Språng610c7632019-03-06 15:37:33 +0100616TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
617 test_queue_.SendTask([this] {
618 config_.track_id = "test";
619 const bool kSuspend = false;
620 config_.suspend_below_min_bitrate = kSuspend;
621 config_.rtp.extensions.emplace_back(
622 RtpExtension::kTransportSequenceNumberUri, 1);
623 auto vss_impl = CreateVideoSendStreamImpl(
624 kDefaultInitialBitrateBps, kDefaultBitratePriority,
625 VideoEncoderConfig::ContentType::kRealtimeVideo);
626 vss_impl->Start();
627
628 VideoStream qvga_stream;
629 qvga_stream.width = 320;
630 qvga_stream.height = 180;
631 qvga_stream.max_framerate = 30;
632 qvga_stream.min_bitrate_bps = 30000;
633 qvga_stream.target_bitrate_bps = 150000;
634 qvga_stream.max_bitrate_bps = 200000;
635 qvga_stream.max_qp = 56;
636 qvga_stream.bitrate_priority = 1;
637
638 int min_transmit_bitrate_bps = 30000;
639
640 config_.rtp.ssrcs.emplace_back(1);
641
642 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
643 ->OnEncoderConfigurationChanged(
644 std::vector<VideoStream>{qvga_stream},
645 VideoEncoderConfig::ContentType::kRealtimeVideo,
646 min_transmit_bitrate_bps);
647
648 const DataRate network_constrained_rate =
649 DataRate::bps(qvga_stream.target_bitrate_bps);
650 BitrateAllocationUpdate update;
651 update.target_bitrate = network_constrained_rate;
652 update.link_capacity = network_constrained_rate;
653 update.round_trip_time = TimeDelta::ms(1);
654 EXPECT_CALL(rtp_video_sender_,
655 OnBitrateUpdated(network_constrained_rate.bps(), _,
656 update.round_trip_time.ms(), _));
657 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
658 .WillOnce(Return(network_constrained_rate.bps()));
659 EXPECT_CALL(
660 video_stream_encoder_,
661 OnBitrateUpdated(network_constrained_rate, DataRate::Zero(), 0, _));
662 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
663 ->OnBitrateUpdated(update);
664
665 const DataRate qvga_max_bitrate =
666 DataRate::bps(qvga_stream.max_bitrate_bps);
667 const DataRate headroom = DataRate::bps(50000);
668 const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
669 EXPECT_CALL(rtp_video_sender_,
670 OnBitrateUpdated(rate_with_headroom.bps(), _,
671 update.round_trip_time.ms(), _));
672 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
673 .WillOnce(Return(rate_with_headroom.bps()));
674 EXPECT_CALL(video_stream_encoder_,
675 OnBitrateUpdated(qvga_max_bitrate, headroom, 0, _));
676 update.target_bitrate = rate_with_headroom;
677 update.link_capacity = rate_with_headroom;
678 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
679 ->OnBitrateUpdated(update);
680
681 // Set rates to zero on stop.
682 EXPECT_CALL(video_stream_encoder_,
683 OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), 0, 0));
684 vss_impl->Stop();
685 });
686}
687
Sebastian Jansson652dc912018-04-19 17:09:15 +0200688} // namespace internal
689} // namespace webrtc