blob: e57e36ddc8a31f96d6f365f4a88d5c2f1f442802 [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 {
33using testing::NiceMock;
34using testing::StrictMock;
35using testing::ReturnRef;
36using testing::Return;
37using testing::Invoke;
38using testing::_;
39
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));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020072};
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020073
74BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {
75 BitrateAllocationUpdate update;
Sebastian Jansson13e59032018-11-21 19:13:07 +010076 update.target_bitrate = DataRate::bps(bitrate_bps);
77 update.packet_loss_ratio = 0;
78 update.round_trip_time = TimeDelta::Zero();
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020079 return update;
80}
Sebastian Jansson652dc912018-04-19 17:09:15 +020081} // namespace
82
83class VideoSendStreamImplTest : public ::testing::Test {
84 protected:
85 VideoSendStreamImplTest()
86 : clock_(1000 * 1000 * 1000),
87 config_(&transport_),
88 send_delay_stats_(&clock_),
Sebastian Jansson652dc912018-04-19 17:09:15 +020089 test_queue_("test_queue"),
90 process_thread_(ProcessThread::Create("test_thread")),
91 call_stats_(&clock_, process_thread_.get()),
92 stats_proxy_(&clock_,
93 config_,
94 VideoEncoderConfig::ContentType::kRealtimeVideo) {
95 config_.rtp.ssrcs.push_back(8080);
96 config_.rtp.payload_type = 1;
97
98 EXPECT_CALL(transport_controller_, keepalive_config())
99 .WillRepeatedly(ReturnRef(keepalive_config_));
100 EXPECT_CALL(transport_controller_, packet_router())
101 .WillRepeatedly(Return(&packet_router_));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200102 EXPECT_CALL(transport_controller_,
Amit Hilbuch0fc28432018-12-18 13:01:47 -0800103 CreateRtpVideoSender(_, _, _, _, _, _, _, _, _))
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200104 .WillRepeatedly(Return(&rtp_video_sender_));
105 EXPECT_CALL(rtp_video_sender_, SetActive(_))
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200106 .WillRepeatedly(testing::Invoke(
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200107 [&](bool active) { rtp_video_sender_active_ = active; }));
108 EXPECT_CALL(rtp_video_sender_, IsActive())
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200109 .WillRepeatedly(
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200110 testing::Invoke([&]() { return rtp_video_sender_active_; }));
Sebastian Jansson652dc912018-04-19 17:09:15 +0200111 }
112 ~VideoSendStreamImplTest() {}
113
114 std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
115 int initial_encoder_max_bitrate,
116 double initial_encoder_bitrate_priority,
117 VideoEncoderConfig::ContentType content_type) {
118 EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
119 .WillOnce(Return(123000));
120 std::map<uint32_t, RtpState> suspended_ssrcs;
121 std::map<uint32_t, RtpPayloadState> suspended_payload_states;
Karl Wiberg918f50c2018-07-05 11:40:33 +0200122 return absl::make_unique<VideoSendStreamImpl>(
Sebastian Jansson652dc912018-04-19 17:09:15 +0200123 &stats_proxy_, &test_queue_, &call_stats_, &transport_controller_,
124 &bitrate_allocator_, &send_delay_stats_, &video_stream_encoder_,
125 &event_log_, &config_, initial_encoder_max_bitrate,
126 initial_encoder_bitrate_priority, suspended_ssrcs,
127 suspended_payload_states, content_type,
Niels Möller46879152019-01-07 15:54:47 +0100128 absl::make_unique<FecControllerDefault>(&clock_),
129 /*media_transport=*/nullptr);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200130 }
131
132 protected:
133 NiceMock<MockTransport> transport_;
134 NiceMock<MockRtpTransportControllerSend> transport_controller_;
135 NiceMock<MockBitrateAllocator> bitrate_allocator_;
136 NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200137 NiceMock<MockRtpVideoSender> rtp_video_sender_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200138
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200139 bool rtp_video_sender_active_ = false;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200140 SimulatedClock clock_;
141 RtcEventLogNullImpl event_log_;
142 VideoSendStream::Config config_;
143 SendDelayStats send_delay_stats_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200144 rtc::test::TaskQueueForTest test_queue_;
145 std::unique_ptr<ProcessThread> process_thread_;
146 CallStats call_stats_;
147 SendStatisticsProxy stats_proxy_;
148 PacketRouter packet_router_;
149 RtpKeepAliveConfig keepalive_config_;
150};
151
152TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
153 test_queue_.SendTask([this] {
154 config_.track_id = "test";
155 const bool kSuspend = false;
156 config_.suspend_below_min_bitrate = kSuspend;
157 auto vss_impl = CreateVideoSendStreamImpl(
158 kDefaultInitialBitrateBps, kDefaultBitratePriority,
159 VideoEncoderConfig::ContentType::kRealtimeVideo);
160 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
161 .WillOnce(Invoke(
162 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
163 EXPECT_EQ(config.min_bitrate_bps, 0u);
164 EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
165 EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
166 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
167 EXPECT_EQ(config.track_id, "test");
168 EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200169 }));
170 vss_impl->Start();
171 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
172 vss_impl->Stop();
173 });
174}
175
Erik Språngb57ab382018-09-13 10:52:38 +0200176TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
177 test_queue_.SendTask([this] {
178 config_.track_id = "test";
179 const bool kSuspend = false;
180 config_.suspend_below_min_bitrate = kSuspend;
181 config_.rtp.extensions.emplace_back(
182 RtpExtension::kTransportSequenceNumberUri, 1);
183 auto vss_impl = CreateVideoSendStreamImpl(
184 kDefaultInitialBitrateBps, kDefaultBitratePriority,
185 VideoEncoderConfig::ContentType::kRealtimeVideo);
186 vss_impl->Start();
187
188 // QVGA + VGA configuration matching defaults in media/engine/simulcast.cc.
189 VideoStream qvga_stream;
190 qvga_stream.width = 320;
191 qvga_stream.height = 180;
192 qvga_stream.max_framerate = 30;
193 qvga_stream.min_bitrate_bps = 30000;
194 qvga_stream.target_bitrate_bps = 150000;
195 qvga_stream.max_bitrate_bps = 200000;
196 qvga_stream.max_qp = 56;
197 qvga_stream.bitrate_priority = 1;
198
199 VideoStream vga_stream;
200 vga_stream.width = 640;
201 vga_stream.height = 360;
202 vga_stream.max_framerate = 30;
203 vga_stream.min_bitrate_bps = 150000;
204 vga_stream.target_bitrate_bps = 500000;
205 vga_stream.max_bitrate_bps = 700000;
206 vga_stream.max_qp = 56;
207 vga_stream.bitrate_priority = 1;
208
209 int min_transmit_bitrate_bps = 30000;
210
211 config_.rtp.ssrcs.emplace_back(1);
212 config_.rtp.ssrcs.emplace_back(2);
213
214 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
215 .WillOnce(Invoke(
216 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
217 EXPECT_EQ(config.min_bitrate_bps,
218 static_cast<uint32_t>(min_transmit_bitrate_bps));
219 EXPECT_EQ(config.max_bitrate_bps,
220 static_cast<uint32_t>(qvga_stream.max_bitrate_bps +
221 vga_stream.max_bitrate_bps));
222 EXPECT_EQ(config.pad_up_bitrate_bps,
223 static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
224 vga_stream.min_bitrate_bps));
225 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200226 }));
227
228 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
229 ->OnEncoderConfigurationChanged(
230 std::vector<VideoStream>{qvga_stream, vga_stream},
231 min_transmit_bitrate_bps);
232 vss_impl->Stop();
233 });
234}
235
236TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
237 test_queue_.SendTask([this] {
238 config_.track_id = "test";
239 const bool kSuspend = false;
240 config_.suspend_below_min_bitrate = kSuspend;
241 config_.rtp.extensions.emplace_back(
242 RtpExtension::kTransportSequenceNumberUri, 1);
243 config_.periodic_alr_bandwidth_probing = true;
244 auto vss_impl = CreateVideoSendStreamImpl(
245 kDefaultInitialBitrateBps, kDefaultBitratePriority,
246 VideoEncoderConfig::ContentType::kScreen);
247 vss_impl->Start();
248
249 // Simulcast screenshare.
250 VideoStream low_stream;
251 low_stream.width = 1920;
252 low_stream.height = 1080;
253 low_stream.max_framerate = 5;
254 low_stream.min_bitrate_bps = 30000;
255 low_stream.target_bitrate_bps = 200000;
256 low_stream.max_bitrate_bps = 1000000;
257 low_stream.num_temporal_layers = 2;
258 low_stream.max_qp = 56;
259 low_stream.bitrate_priority = 1;
260
261 VideoStream high_stream;
262 high_stream.width = 1920;
263 high_stream.height = 1080;
264 high_stream.max_framerate = 30;
265 high_stream.min_bitrate_bps = 60000;
266 high_stream.target_bitrate_bps = 1250000;
267 high_stream.max_bitrate_bps = 1250000;
268 high_stream.num_temporal_layers = 2;
269 high_stream.max_qp = 56;
270 high_stream.bitrate_priority = 1;
271
272 // With ALR probing, this will be the padding target instead of
273 // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
274 int min_transmit_bitrate_bps = 400000;
275
276 config_.rtp.ssrcs.emplace_back(1);
277 config_.rtp.ssrcs.emplace_back(2);
278
279 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
280 .WillOnce(Invoke(
281 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
282 EXPECT_EQ(config.min_bitrate_bps,
283 static_cast<uint32_t>(low_stream.min_bitrate_bps));
284 EXPECT_EQ(config.max_bitrate_bps,
285 static_cast<uint32_t>(low_stream.max_bitrate_bps +
286 high_stream.max_bitrate_bps));
287 EXPECT_EQ(config.pad_up_bitrate_bps,
288 static_cast<uint32_t>(min_transmit_bitrate_bps));
289 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200290 }));
291
292 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
293 ->OnEncoderConfigurationChanged(
294 std::vector<VideoStream>{low_stream, high_stream},
295 min_transmit_bitrate_bps);
296 vss_impl->Stop();
297 });
298}
299
Sebastian Jansson652dc912018-04-19 17:09:15 +0200300TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
301 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
302
303 test_queue_.SendTask([this] {
304 config_.rtp.extensions.emplace_back(
305 RtpExtension::kTransportSequenceNumberUri,
306 RtpExtension::kTransportSequenceNumberDefaultId);
307 EXPECT_CALL(transport_controller_,
308 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
309 .Times(1);
310 auto vss_impl = CreateVideoSendStreamImpl(
311 kDefaultInitialBitrateBps, kDefaultBitratePriority,
312 VideoEncoderConfig::ContentType::kScreen);
313 vss_impl->Start();
314 vss_impl->Stop();
315 });
316}
317
318TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
319 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
320 test_queue_.SendTask([this] {
321 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
322 auto vss_impl = CreateVideoSendStreamImpl(
323 kDefaultInitialBitrateBps, kDefaultBitratePriority,
324 VideoEncoderConfig::ContentType::kScreen);
325 vss_impl->Start();
326 vss_impl->Stop();
327 });
328}
Erik Språng4e193e42018-09-14 19:01:58 +0200329
330TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
331 test_queue_.SendTask([this] {
332 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
333 auto vss_impl = CreateVideoSendStreamImpl(
334 kDefaultInitialBitrateBps, kDefaultBitratePriority,
335 VideoEncoderConfig::ContentType::kScreen);
336 vss_impl->Start();
337 VideoBitrateAllocationObserver* const observer =
338 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
339
340 // Populate a test instance of video bitrate allocation.
341 VideoBitrateAllocation alloc;
342 alloc.SetBitrate(0, 0, 10000);
343 alloc.SetBitrate(0, 1, 20000);
344 alloc.SetBitrate(1, 0, 30000);
345 alloc.SetBitrate(1, 1, 40000);
346
347 // Encoder starts out paused, don't forward allocation.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200348 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200349 observer->OnBitrateAllocationUpdated(alloc);
350
351 // Unpause encoder, allocation should be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200352 const uint32_t kBitrateBps = 100000;
353 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
354 .Times(1)
355 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200356 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200357 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200358 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200359 observer->OnBitrateAllocationUpdated(alloc);
360
361 // Pause encoder again, and block allocations.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200362 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
363 .Times(1)
364 .WillOnce(Return(0));
Erik Språng4e193e42018-09-14 19:01:58 +0200365 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200366 ->OnBitrateUpdated(CreateAllocation(0));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200367 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200368 observer->OnBitrateAllocationUpdated(alloc);
369
370 vss_impl->Stop();
371 });
372}
373
374TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
375 test_queue_.SendTask([this] {
376 auto vss_impl = CreateVideoSendStreamImpl(
377 kDefaultInitialBitrateBps, kDefaultBitratePriority,
378 VideoEncoderConfig::ContentType::kScreen);
379 vss_impl->Start();
380 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200381 const uint32_t kBitrateBps = 100000;
382 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
383 .Times(1)
384 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200385 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200386 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200387 VideoBitrateAllocationObserver* const observer =
388 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
389
390 // Populate a test instance of video bitrate allocation.
391 VideoBitrateAllocation alloc;
392 alloc.SetBitrate(0, 0, 10000);
393 alloc.SetBitrate(0, 1, 20000);
394 alloc.SetBitrate(1, 0, 30000);
395 alloc.SetBitrate(1, 1, 40000);
396
397 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200398 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200399 observer->OnBitrateAllocationUpdated(alloc);
400
401 VideoBitrateAllocation updated_alloc = alloc;
402 // Needs 10% increase in bitrate to trigger immediate forward.
403 const uint32_t base_layer_min_update_bitrate_bps =
404 alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
405
406 // Too small increase, don't forward.
407 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200408 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200409 observer->OnBitrateAllocationUpdated(updated_alloc);
410
411 // Large enough increase, do forward.
412 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200413 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200414 .Times(1);
415 observer->OnBitrateAllocationUpdated(updated_alloc);
416
417 // This is now a decrease compared to last forward allocation, forward
418 // immediately.
419 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200420 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200421 .Times(1);
422 observer->OnBitrateAllocationUpdated(updated_alloc);
423
424 vss_impl->Stop();
425 });
426}
427
428TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
429 test_queue_.SendTask([this] {
430 auto vss_impl = CreateVideoSendStreamImpl(
431 kDefaultInitialBitrateBps, kDefaultBitratePriority,
432 VideoEncoderConfig::ContentType::kScreen);
433 vss_impl->Start();
434 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200435 const uint32_t kBitrateBps = 100000;
436 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
437 .Times(1)
438 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200439 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200440 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200441 VideoBitrateAllocationObserver* const observer =
442 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
443
444 // Populate a test instance of video bitrate allocation.
445 VideoBitrateAllocation alloc;
446 alloc.SetBitrate(0, 0, 10000);
447 alloc.SetBitrate(0, 1, 20000);
448 alloc.SetBitrate(1, 0, 30000);
449 alloc.SetBitrate(1, 1, 40000);
450
451 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200452 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200453 observer->OnBitrateAllocationUpdated(alloc);
454
455 // Move some bitrate from one layer to a new one, but keep sum the same.
456 // Since layout has changed, immediately trigger forward.
457 VideoBitrateAllocation updated_alloc = alloc;
458 updated_alloc.SetBitrate(2, 0, 10000);
459 updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
460 EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200461 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200462 .Times(1);
463 observer->OnBitrateAllocationUpdated(updated_alloc);
464
465 vss_impl->Stop();
466 });
467}
468
469TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
470 test_queue_.SendTask([this] {
471 rtc::ScopedFakeClock fake_clock;
472 fake_clock.SetTimeMicros(clock_.TimeInMicroseconds());
473
474 auto vss_impl = CreateVideoSendStreamImpl(
475 kDefaultInitialBitrateBps, kDefaultBitratePriority,
476 VideoEncoderConfig::ContentType::kScreen);
477 vss_impl->Start();
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200478 const uint32_t kBitrateBps = 100000;
Erik Språng4e193e42018-09-14 19:01:58 +0200479 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200480 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
481 .Times(1)
482 .WillRepeatedly(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200483 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200484 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200485 VideoBitrateAllocationObserver* const observer =
486 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
487
488 // Populate a test instance of video bitrate allocation.
489 VideoBitrateAllocation alloc;
490 alloc.SetBitrate(0, 0, 10000);
491 alloc.SetBitrate(0, 1, 20000);
492 alloc.SetBitrate(1, 0, 30000);
493 alloc.SetBitrate(1, 1, 40000);
494
495 EncodedImage encoded_image;
496 CodecSpecificInfo codec_specific;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200497 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
Erik Språng4e193e42018-09-14 19:01:58 +0200498 .WillRepeatedly(Return(
499 EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
500
501 // Max time we will throttle similar video bitrate allocations.
502 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
503
504 {
505 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200506 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
507 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200508 observer->OnBitrateAllocationUpdated(alloc);
509 }
510
511 {
512 // Sending same allocation again, this one should be throttled.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200513 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
514 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200515 observer->OnBitrateAllocationUpdated(alloc);
516 }
517
518 fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
519
520 {
521 // Sending similar allocation again after timeout, should forward.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200522 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
523 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200524 observer->OnBitrateAllocationUpdated(alloc);
525 }
526
527 {
528 // Sending similar allocation again without timeout, throttle.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200529 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
530 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200531 observer->OnBitrateAllocationUpdated(alloc);
532 }
533
534 {
535 // Send encoded image, should be a noop.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200536 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
537 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200538 static_cast<EncodedImageCallback*>(vss_impl.get())
539 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
540 }
541
542 {
543 // Advance time and send encoded image, this should wake up and send
544 // cached bitrate allocation.
545 fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200546 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
547 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200548 static_cast<EncodedImageCallback*>(vss_impl.get())
549 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
550 }
551
552 {
553 // Advance time and send encoded image, there should be no cached
554 // allocation to send.
555 fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200556 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
557 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200558 static_cast<EncodedImageCallback*>(vss_impl.get())
559 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
560 }
561
562 vss_impl->Stop();
563 });
564}
565
Sebastian Jansson652dc912018-04-19 17:09:15 +0200566} // namespace internal
567} // namespace webrtc