blob: 81268350004c93222d5498a943a639721ca39e96 [file] [log] [blame]
Sebastian Jansson652dc912018-04-19 15:09:151/*
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 18:21:4713#include "absl/memory/memory.h"
Elad Alon8b60e8b2019-04-08 12:14:0514#include "absl/types/optional.h"
Stefan Holmer9416ef82018-07-19 08:34:3815#include "call/rtp_video_sender.h"
Sebastian Jansson652dc912018-04-19 15:09:1516#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 12:14:0519#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h"
Stefan Holmerdbdb3a02018-07-17 14:03:4620#include "modules/utility/include/process_thread.h"
Sebastian Jansson652dc912018-04-19 15:09:1521#include "modules/video_coding/fec_controller_default.h"
22#include "rtc_base/experiments/alr_experiment.h"
Steve Anton10542f22019-01-11 17:11:0023#include "rtc_base/fake_clock.h"
Sebastian Jansson652dc912018-04-19 15:09:1524#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 13:11:1235using ::testing::_;
36using ::testing::Invoke;
37using ::testing::NiceMock;
38using ::testing::Return;
Sebastian Jansson652dc912018-04-19 15:09:1539
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 13:21:5549class MockRtpVideoSender : public RtpVideoSenderInterface {
Stefan Holmerdbdb3a02018-07-17 14:03:4650 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 14:03:4660 MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
Stefan Holmerdbdb3a02018-07-17 14:03:4661 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 13:21:5566 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 13:55:0072 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 14:03:4676};
Sebastian Janssonc0e4d452018-10-25 13:08:3277
78BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {
79 BitrateAllocationUpdate update;
Sebastian Jansson13e59032018-11-21 18:13:0780 update.target_bitrate = DataRate::bps(bitrate_bps);
81 update.packet_loss_ratio = 0;
82 update.round_trip_time = TimeDelta::Zero();
Sebastian Janssonc0e4d452018-10-25 13:08:3283 return update;
84}
Sebastian Jansson652dc912018-04-19 15:09:1585} // 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 15:09:1593 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 15:09:15102 EXPECT_CALL(transport_controller_, packet_router())
103 .WillRepeatedly(Return(&packet_router_));
Stefan Holmerdbdb3a02018-07-17 14:03:46104 EXPECT_CALL(transport_controller_,
Oleh Prypine8964902019-03-29 15:33:01105 CreateRtpVideoSender(_, _, _, _, _, _, _, _, _))
Stefan Holmer64be7fa2018-10-04 13:21:55106 .WillRepeatedly(Return(&rtp_video_sender_));
107 EXPECT_CALL(rtp_video_sender_, SetActive(_))
Mirko Bonadei6a489f22019-04-09 13:11:12108 .WillRepeatedly(::testing::Invoke(
Stefan Holmer64be7fa2018-10-04 13:21:55109 [&](bool active) { rtp_video_sender_active_ = active; }));
110 EXPECT_CALL(rtp_video_sender_, IsActive())
Stefan Holmerdbdb3a02018-07-17 14:03:46111 .WillRepeatedly(
Mirko Bonadei6a489f22019-04-09 13:11:12112 ::testing::Invoke([&]() { return rtp_video_sender_active_; }));
Sebastian Jansson652dc912018-04-19 15:09:15113 }
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 09:40:33124 return absl::make_unique<VideoSendStreamImpl>(
Sebastian Jansson572c60f2019-03-04 17:30:41125 &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 14:54:47130 absl::make_unique<FecControllerDefault>(&clock_),
131 /*media_transport=*/nullptr);
Sebastian Jansson652dc912018-04-19 15:09:15132 }
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 13:21:55139 NiceMock<MockRtpVideoSender> rtp_video_sender_;
Sebastian Jansson652dc912018-04-19 15:09:15140
Stefan Holmer64be7fa2018-10-04 13:21:55141 bool rtp_video_sender_active_ = false;
Sebastian Jansson652dc912018-04-19 15:09:15142 SimulatedClock clock_;
143 RtcEventLogNullImpl event_log_;
144 VideoSendStream::Config config_;
145 SendDelayStats send_delay_stats_;
Danil Chapovalovd26a9162019-03-19 17:08:37146 TaskQueueForTest test_queue_;
Sebastian Jansson652dc912018-04-19 15:09:15147 std::unique_ptr<ProcessThread> process_thread_;
148 CallStats call_stats_;
149 SendStatisticsProxy stats_proxy_;
150 PacketRouter packet_router_;
Sebastian Jansson652dc912018-04-19 15:09:15151};
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 15:09:15170 }));
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 08:52:38177TEST_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(), _))
Ilya Nikolaevskiyaa9aa572019-04-11 07:20:24216 .WillRepeatedly(Invoke(
Erik Språngb57ab382018-09-13 08:52:38217 [&](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));
Ilya Nikolaevskiyaa9aa572019-04-11 07:20:24223 if (config.pad_up_bitrate_bps != 0) {
224 EXPECT_EQ(config.pad_up_bitrate_bps,
225 static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
226 vga_stream.min_bitrate_bps));
227 }
Erik Språngb57ab382018-09-13 08:52:38228 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 08:52:38229 }));
230
231 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
232 ->OnEncoderConfigurationChanged(
233 std::vector<VideoStream>{qvga_stream, vga_stream},
Rasmus Brandtc402dbe2019-02-04 10:09:46234 VideoEncoderConfig::ContentType::kRealtimeVideo,
Erik Språngb57ab382018-09-13 08:52:38235 min_transmit_bitrate_bps);
236 vss_impl->Stop();
237 });
238}
239
240TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
241 test_queue_.SendTask([this] {
242 config_.track_id = "test";
243 const bool kSuspend = false;
244 config_.suspend_below_min_bitrate = kSuspend;
245 config_.rtp.extensions.emplace_back(
246 RtpExtension::kTransportSequenceNumberUri, 1);
247 config_.periodic_alr_bandwidth_probing = true;
248 auto vss_impl = CreateVideoSendStreamImpl(
249 kDefaultInitialBitrateBps, kDefaultBitratePriority,
250 VideoEncoderConfig::ContentType::kScreen);
251 vss_impl->Start();
252
253 // Simulcast screenshare.
254 VideoStream low_stream;
255 low_stream.width = 1920;
256 low_stream.height = 1080;
257 low_stream.max_framerate = 5;
258 low_stream.min_bitrate_bps = 30000;
259 low_stream.target_bitrate_bps = 200000;
260 low_stream.max_bitrate_bps = 1000000;
261 low_stream.num_temporal_layers = 2;
262 low_stream.max_qp = 56;
263 low_stream.bitrate_priority = 1;
264
265 VideoStream high_stream;
266 high_stream.width = 1920;
267 high_stream.height = 1080;
268 high_stream.max_framerate = 30;
269 high_stream.min_bitrate_bps = 60000;
270 high_stream.target_bitrate_bps = 1250000;
271 high_stream.max_bitrate_bps = 1250000;
272 high_stream.num_temporal_layers = 2;
273 high_stream.max_qp = 56;
274 high_stream.bitrate_priority = 1;
275
276 // With ALR probing, this will be the padding target instead of
277 // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
278 int min_transmit_bitrate_bps = 400000;
279
280 config_.rtp.ssrcs.emplace_back(1);
281 config_.rtp.ssrcs.emplace_back(2);
282
283 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
Ilya Nikolaevskiyaa9aa572019-04-11 07:20:24284 .WillRepeatedly(Invoke(
Erik Språngb57ab382018-09-13 08:52:38285 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
286 EXPECT_EQ(config.min_bitrate_bps,
287 static_cast<uint32_t>(low_stream.min_bitrate_bps));
288 EXPECT_EQ(config.max_bitrate_bps,
289 static_cast<uint32_t>(low_stream.max_bitrate_bps +
290 high_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 07:20:24291 if (config.pad_up_bitrate_bps != 0) {
292 EXPECT_EQ(config.pad_up_bitrate_bps,
293 static_cast<uint32_t>(min_transmit_bitrate_bps));
294 }
Erik Språngb57ab382018-09-13 08:52:38295 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 08:52:38296 }));
297
298 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
299 ->OnEncoderConfigurationChanged(
300 std::vector<VideoStream>{low_stream, high_stream},
Rasmus Brandtc402dbe2019-02-04 10:09:46301 VideoEncoderConfig::ContentType::kScreen, min_transmit_bitrate_bps);
302 vss_impl->Stop();
303 });
304}
305
306TEST_F(VideoSendStreamImplTest,
307 UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis) {
308 test::ScopedFieldTrials hysteresis_experiment(
309 "WebRTC-VideoRateControl/video_hysteresis:1.25/");
310
311 test_queue_.SendTask([this] {
312 auto vss_impl = CreateVideoSendStreamImpl(
313 kDefaultInitialBitrateBps, kDefaultBitratePriority,
314 VideoEncoderConfig::ContentType::kRealtimeVideo);
315 vss_impl->Start();
316
317 // 2-layer video simulcast.
318 VideoStream low_stream;
319 low_stream.width = 320;
320 low_stream.height = 240;
321 low_stream.max_framerate = 30;
322 low_stream.min_bitrate_bps = 30000;
323 low_stream.target_bitrate_bps = 100000;
324 low_stream.max_bitrate_bps = 200000;
325 low_stream.max_qp = 56;
326 low_stream.bitrate_priority = 1;
327
328 VideoStream high_stream;
329 high_stream.width = 640;
330 high_stream.height = 480;
331 high_stream.max_framerate = 30;
332 high_stream.min_bitrate_bps = 150000;
333 high_stream.target_bitrate_bps = 500000;
334 high_stream.max_bitrate_bps = 750000;
335 high_stream.max_qp = 56;
336 high_stream.bitrate_priority = 1;
337
338 config_.rtp.ssrcs.emplace_back(1);
339 config_.rtp.ssrcs.emplace_back(2);
340
341 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
Ilya Nikolaevskiyaa9aa572019-04-11 07:20:24342 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
343 MediaStreamAllocationConfig config) {
Rasmus Brandtc402dbe2019-02-04 10:09:46344 EXPECT_EQ(config.min_bitrate_bps,
345 static_cast<uint32_t>(low_stream.min_bitrate_bps));
346 EXPECT_EQ(config.max_bitrate_bps,
347 static_cast<uint32_t>(low_stream.max_bitrate_bps +
348 high_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 07:20:24349 if (config.pad_up_bitrate_bps != 0) {
350 EXPECT_EQ(
351 config.pad_up_bitrate_bps,
352 static_cast<uint32_t>(low_stream.target_bitrate_bps +
353 1.25 * high_stream.min_bitrate_bps));
354 }
Rasmus Brandtc402dbe2019-02-04 10:09:46355 }));
356
357 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
358 ->OnEncoderConfigurationChanged(
359 std::vector<VideoStream>{low_stream, high_stream},
360 VideoEncoderConfig::ContentType::kRealtimeVideo,
361 /*min_transmit_bitrate_bps=*/0);
Erik Språngb57ab382018-09-13 08:52:38362 vss_impl->Stop();
363 });
364}
365
Sebastian Jansson652dc912018-04-19 15:09:15366TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
367 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
368
369 test_queue_.SendTask([this] {
Elad Alon157540a2019-02-08 22:37:52370 constexpr int kId = 1;
Sebastian Jansson652dc912018-04-19 15:09:15371 config_.rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 22:37:52372 RtpExtension::kTransportSequenceNumberUri, kId);
Sebastian Jansson652dc912018-04-19 15:09:15373 EXPECT_CALL(transport_controller_,
374 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
375 .Times(1);
376 auto vss_impl = CreateVideoSendStreamImpl(
377 kDefaultInitialBitrateBps, kDefaultBitratePriority,
378 VideoEncoderConfig::ContentType::kScreen);
379 vss_impl->Start();
380 vss_impl->Stop();
381 });
382}
383
384TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
385 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
386 test_queue_.SendTask([this] {
387 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
388 auto vss_impl = CreateVideoSendStreamImpl(
389 kDefaultInitialBitrateBps, kDefaultBitratePriority,
390 VideoEncoderConfig::ContentType::kScreen);
391 vss_impl->Start();
392 vss_impl->Stop();
393 });
394}
Erik Språng4e193e42018-09-14 17:01:58395
396TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
397 test_queue_.SendTask([this] {
398 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
399 auto vss_impl = CreateVideoSendStreamImpl(
400 kDefaultInitialBitrateBps, kDefaultBitratePriority,
401 VideoEncoderConfig::ContentType::kScreen);
402 vss_impl->Start();
403 VideoBitrateAllocationObserver* const observer =
404 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
405
406 // Populate a test instance of video bitrate allocation.
407 VideoBitrateAllocation alloc;
408 alloc.SetBitrate(0, 0, 10000);
409 alloc.SetBitrate(0, 1, 20000);
410 alloc.SetBitrate(1, 0, 30000);
411 alloc.SetBitrate(1, 1, 40000);
412
413 // Encoder starts out paused, don't forward allocation.
Stefan Holmer64be7fa2018-10-04 13:21:55414 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 17:01:58415 observer->OnBitrateAllocationUpdated(alloc);
416
417 // Unpause encoder, allocation should be passed through.
Stefan Holmer64be7fa2018-10-04 13:21:55418 const uint32_t kBitrateBps = 100000;
419 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
420 .Times(1)
421 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 17:01:58422 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 13:08:32423 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Stefan Holmer64be7fa2018-10-04 13:21:55424 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 17:01:58425 observer->OnBitrateAllocationUpdated(alloc);
426
427 // Pause encoder again, and block allocations.
Stefan Holmer64be7fa2018-10-04 13:21:55428 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
429 .Times(1)
430 .WillOnce(Return(0));
Erik Språng4e193e42018-09-14 17:01:58431 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 13:08:32432 ->OnBitrateUpdated(CreateAllocation(0));
Stefan Holmer64be7fa2018-10-04 13:21:55433 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 17:01:58434 observer->OnBitrateAllocationUpdated(alloc);
435
436 vss_impl->Stop();
437 });
438}
439
440TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
441 test_queue_.SendTask([this] {
442 auto vss_impl = CreateVideoSendStreamImpl(
443 kDefaultInitialBitrateBps, kDefaultBitratePriority,
444 VideoEncoderConfig::ContentType::kScreen);
445 vss_impl->Start();
446 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 13:21:55447 const uint32_t kBitrateBps = 100000;
448 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
449 .Times(1)
450 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 17:01:58451 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 13:08:32452 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 17:01:58453 VideoBitrateAllocationObserver* const observer =
454 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
455
456 // Populate a test instance of video bitrate allocation.
457 VideoBitrateAllocation alloc;
458 alloc.SetBitrate(0, 0, 10000);
459 alloc.SetBitrate(0, 1, 20000);
460 alloc.SetBitrate(1, 0, 30000);
461 alloc.SetBitrate(1, 1, 40000);
462
463 // Initial value.
Stefan Holmer64be7fa2018-10-04 13:21:55464 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 17:01:58465 observer->OnBitrateAllocationUpdated(alloc);
466
467 VideoBitrateAllocation updated_alloc = alloc;
468 // Needs 10% increase in bitrate to trigger immediate forward.
469 const uint32_t base_layer_min_update_bitrate_bps =
470 alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
471
472 // Too small increase, don't forward.
473 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 13:21:55474 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
Erik Språng4e193e42018-09-14 17:01:58475 observer->OnBitrateAllocationUpdated(updated_alloc);
476
477 // Large enough increase, do forward.
478 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
Stefan Holmer64be7fa2018-10-04 13:21:55479 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 17:01:58480 .Times(1);
481 observer->OnBitrateAllocationUpdated(updated_alloc);
482
483 // This is now a decrease compared to last forward allocation, forward
484 // immediately.
485 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 13:21:55486 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 17:01:58487 .Times(1);
488 observer->OnBitrateAllocationUpdated(updated_alloc);
489
490 vss_impl->Stop();
491 });
492}
493
494TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
495 test_queue_.SendTask([this] {
496 auto vss_impl = CreateVideoSendStreamImpl(
497 kDefaultInitialBitrateBps, kDefaultBitratePriority,
498 VideoEncoderConfig::ContentType::kScreen);
499 vss_impl->Start();
500 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 13:21:55501 const uint32_t kBitrateBps = 100000;
502 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
503 .Times(1)
504 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 17:01:58505 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 13:08:32506 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 17:01:58507 VideoBitrateAllocationObserver* const observer =
508 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
509
510 // Populate a test instance of video bitrate allocation.
511 VideoBitrateAllocation alloc;
512 alloc.SetBitrate(0, 0, 10000);
513 alloc.SetBitrate(0, 1, 20000);
514 alloc.SetBitrate(1, 0, 30000);
515 alloc.SetBitrate(1, 1, 40000);
516
517 // Initial value.
Stefan Holmer64be7fa2018-10-04 13:21:55518 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 17:01:58519 observer->OnBitrateAllocationUpdated(alloc);
520
521 // Move some bitrate from one layer to a new one, but keep sum the same.
522 // Since layout has changed, immediately trigger forward.
523 VideoBitrateAllocation updated_alloc = alloc;
524 updated_alloc.SetBitrate(2, 0, 10000);
525 updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
526 EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
Stefan Holmer64be7fa2018-10-04 13:21:55527 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 17:01:58528 .Times(1);
529 observer->OnBitrateAllocationUpdated(updated_alloc);
530
531 vss_impl->Stop();
532 });
533}
534
535TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
536 test_queue_.SendTask([this] {
Erik Språng4e193e42018-09-14 17:01:58537 auto vss_impl = CreateVideoSendStreamImpl(
538 kDefaultInitialBitrateBps, kDefaultBitratePriority,
539 VideoEncoderConfig::ContentType::kScreen);
540 vss_impl->Start();
Stefan Holmer64be7fa2018-10-04 13:21:55541 const uint32_t kBitrateBps = 100000;
Erik Språng4e193e42018-09-14 17:01:58542 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 13:21:55543 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
544 .Times(1)
545 .WillRepeatedly(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 17:01:58546 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 13:08:32547 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 17:01:58548 VideoBitrateAllocationObserver* const observer =
549 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
550
551 // Populate a test instance of video bitrate allocation.
552 VideoBitrateAllocation alloc;
553 alloc.SetBitrate(0, 0, 10000);
554 alloc.SetBitrate(0, 1, 20000);
555 alloc.SetBitrate(1, 0, 30000);
556 alloc.SetBitrate(1, 1, 40000);
557
558 EncodedImage encoded_image;
559 CodecSpecificInfo codec_specific;
Stefan Holmer64be7fa2018-10-04 13:21:55560 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
Erik Språng4e193e42018-09-14 17:01:58561 .WillRepeatedly(Return(
562 EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
563
564 // Max time we will throttle similar video bitrate allocations.
565 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
566
567 {
568 // Initial value.
Stefan Holmer64be7fa2018-10-04 13:21:55569 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
570 .Times(1);
Erik Språng4e193e42018-09-14 17:01:58571 observer->OnBitrateAllocationUpdated(alloc);
572 }
573
574 {
575 // Sending same allocation again, this one should be throttled.
Stefan Holmer64be7fa2018-10-04 13:21:55576 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
577 .Times(0);
Erik Språng4e193e42018-09-14 17:01:58578 observer->OnBitrateAllocationUpdated(alloc);
579 }
580
Sebastian Jansson572c60f2019-03-04 17:30:41581 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Erik Språng4e193e42018-09-14 17:01:58582
583 {
584 // Sending similar allocation again after timeout, should forward.
Stefan Holmer64be7fa2018-10-04 13:21:55585 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
586 .Times(1);
Erik Språng4e193e42018-09-14 17:01:58587 observer->OnBitrateAllocationUpdated(alloc);
588 }
589
590 {
591 // Sending similar allocation again without timeout, throttle.
Stefan Holmer64be7fa2018-10-04 13:21:55592 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
593 .Times(0);
Erik Språng4e193e42018-09-14 17:01:58594 observer->OnBitrateAllocationUpdated(alloc);
595 }
596
597 {
598 // Send encoded image, should be a noop.
Stefan Holmer64be7fa2018-10-04 13:21:55599 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
600 .Times(0);
Erik Språng4e193e42018-09-14 17:01:58601 static_cast<EncodedImageCallback*>(vss_impl.get())
602 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
603 }
604
605 {
606 // Advance time and send encoded image, this should wake up and send
607 // cached bitrate allocation.
Sebastian Jansson572c60f2019-03-04 17:30:41608 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 13:21:55609 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
610 .Times(1);
Erik Språng4e193e42018-09-14 17:01:58611 static_cast<EncodedImageCallback*>(vss_impl.get())
612 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
613 }
614
615 {
616 // Advance time and send encoded image, there should be no cached
617 // allocation to send.
Sebastian Jansson572c60f2019-03-04 17:30:41618 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 13:21:55619 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
620 .Times(0);
Erik Språng4e193e42018-09-14 17:01:58621 static_cast<EncodedImageCallback*>(vss_impl.get())
622 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
623 }
624
625 vss_impl->Stop();
626 });
627}
628
Erik Språng610c7632019-03-06 14:37:33629TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
630 test_queue_.SendTask([this] {
631 config_.track_id = "test";
632 const bool kSuspend = false;
633 config_.suspend_below_min_bitrate = kSuspend;
634 config_.rtp.extensions.emplace_back(
635 RtpExtension::kTransportSequenceNumberUri, 1);
636 auto vss_impl = CreateVideoSendStreamImpl(
637 kDefaultInitialBitrateBps, kDefaultBitratePriority,
638 VideoEncoderConfig::ContentType::kRealtimeVideo);
639 vss_impl->Start();
640
641 VideoStream qvga_stream;
642 qvga_stream.width = 320;
643 qvga_stream.height = 180;
644 qvga_stream.max_framerate = 30;
645 qvga_stream.min_bitrate_bps = 30000;
646 qvga_stream.target_bitrate_bps = 150000;
647 qvga_stream.max_bitrate_bps = 200000;
648 qvga_stream.max_qp = 56;
649 qvga_stream.bitrate_priority = 1;
650
651 int min_transmit_bitrate_bps = 30000;
652
653 config_.rtp.ssrcs.emplace_back(1);
654
655 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
656 ->OnEncoderConfigurationChanged(
657 std::vector<VideoStream>{qvga_stream},
658 VideoEncoderConfig::ContentType::kRealtimeVideo,
659 min_transmit_bitrate_bps);
660
661 const DataRate network_constrained_rate =
662 DataRate::bps(qvga_stream.target_bitrate_bps);
663 BitrateAllocationUpdate update;
664 update.target_bitrate = network_constrained_rate;
665 update.link_capacity = network_constrained_rate;
666 update.round_trip_time = TimeDelta::ms(1);
667 EXPECT_CALL(rtp_video_sender_,
668 OnBitrateUpdated(network_constrained_rate.bps(), _,
669 update.round_trip_time.ms(), _));
670 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
671 .WillOnce(Return(network_constrained_rate.bps()));
Erik Språng4c6ca302019-04-08 13:14:01672 EXPECT_CALL(video_stream_encoder_,
673 OnBitrateUpdated(network_constrained_rate,
674 network_constrained_rate, 0, _));
Erik Språng610c7632019-03-06 14:37:33675 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
676 ->OnBitrateUpdated(update);
677
Erik Språng4c6ca302019-04-08 13:14:01678 // Test allocation where the link allocation is larger than the target,
679 // meaning we have some headroom on the link.
Erik Språng610c7632019-03-06 14:37:33680 const DataRate qvga_max_bitrate =
681 DataRate::bps(qvga_stream.max_bitrate_bps);
682 const DataRate headroom = DataRate::bps(50000);
683 const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
684 EXPECT_CALL(rtp_video_sender_,
685 OnBitrateUpdated(rate_with_headroom.bps(), _,
686 update.round_trip_time.ms(), _));
687 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
688 .WillOnce(Return(rate_with_headroom.bps()));
689 EXPECT_CALL(video_stream_encoder_,
Erik Språng4c6ca302019-04-08 13:14:01690 OnBitrateUpdated(qvga_max_bitrate, rate_with_headroom, 0, _));
Erik Språng610c7632019-03-06 14:37:33691 update.target_bitrate = rate_with_headroom;
692 update.link_capacity = rate_with_headroom;
693 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
694 ->OnBitrateUpdated(update);
695
Erik Språng26111642019-03-26 10:09:04696 // Add protection bitrate to the mix, this should be subtracted from the
697 // headroom.
698 const uint32_t protection_bitrate_bps = 10000;
699 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
700 .WillOnce(Return(protection_bitrate_bps));
701
702 EXPECT_CALL(rtp_video_sender_,
703 OnBitrateUpdated(rate_with_headroom.bps(), _,
704 update.round_trip_time.ms(), _));
705 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
706 .WillOnce(Return(rate_with_headroom.bps()));
707 const DataRate headroom_minus_protection =
Erik Språng4c6ca302019-04-08 13:14:01708 rate_with_headroom - DataRate::bps(protection_bitrate_bps);
Erik Språng26111642019-03-26 10:09:04709 EXPECT_CALL(
710 video_stream_encoder_,
711 OnBitrateUpdated(qvga_max_bitrate, headroom_minus_protection, 0, _));
712 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
713 ->OnBitrateUpdated(update);
714
Erik Språng4c6ca302019-04-08 13:14:01715 // Protection bitrate exceeds head room, link allocation should be capped to
716 // target bitrate.
Erik Språng26111642019-03-26 10:09:04717 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
718 .WillOnce(Return(headroom.bps() + 1000));
719 EXPECT_CALL(rtp_video_sender_,
720 OnBitrateUpdated(rate_with_headroom.bps(), _,
721 update.round_trip_time.ms(), _));
722 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
723 .WillOnce(Return(rate_with_headroom.bps()));
724 EXPECT_CALL(video_stream_encoder_,
Erik Språng4c6ca302019-04-08 13:14:01725 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, 0, _));
Erik Språng26111642019-03-26 10:09:04726 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
727 ->OnBitrateUpdated(update);
728
Erik Språng610c7632019-03-06 14:37:33729 // Set rates to zero on stop.
730 EXPECT_CALL(video_stream_encoder_,
731 OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), 0, 0));
732 vss_impl->Stop();
733 });
734}
735
Ilya Nikolaevskiyaa9aa572019-04-11 07:20:24736TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
737 int padding_bitrate = 0;
738 std::unique_ptr<VideoSendStreamImpl> vss_impl;
739
740 test_queue_.SendTask([&] {
741 vss_impl = CreateVideoSendStreamImpl(
742 kDefaultInitialBitrateBps, kDefaultBitratePriority,
743 VideoEncoderConfig::ContentType::kRealtimeVideo);
744
745 // Capture padding bitrate for testing.
746 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
747 .WillRepeatedly(Invoke(
748 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
749 padding_bitrate = config.pad_up_bitrate_bps;
750 }));
751 // If observer is removed, no padding will be sent.
752 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
753 .WillRepeatedly(
754 Invoke([&](BitrateAllocatorObserver*) { padding_bitrate = 0; }));
755
756 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
757 .WillRepeatedly(Return(
758 EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
759
760 config_.track_id = "test";
761 const bool kSuspend = false;
762 config_.suspend_below_min_bitrate = kSuspend;
763 config_.rtp.extensions.emplace_back(
764 RtpExtension::kTransportSequenceNumberUri, 1);
765 VideoStream qvga_stream;
766 qvga_stream.width = 320;
767 qvga_stream.height = 180;
768 qvga_stream.max_framerate = 30;
769 qvga_stream.min_bitrate_bps = 30000;
770 qvga_stream.target_bitrate_bps = 150000;
771 qvga_stream.max_bitrate_bps = 200000;
772 qvga_stream.max_qp = 56;
773 qvga_stream.bitrate_priority = 1;
774
775 int min_transmit_bitrate_bps = 30000;
776
777 config_.rtp.ssrcs.emplace_back(1);
778
779 vss_impl->Start();
780
781 // Starts without padding.
782 EXPECT_EQ(0, padding_bitrate);
783
784 // Reconfigure e.g. due to a fake frame.
785 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
786 ->OnEncoderConfigurationChanged(
787 std::vector<VideoStream>{qvga_stream},
788 VideoEncoderConfig::ContentType::kRealtimeVideo,
789 min_transmit_bitrate_bps);
790 // Still no padding because no actual frames were passed, only
791 // reconfiguration happened.
792 EXPECT_EQ(0, padding_bitrate);
793
794 // Unpause encoder.
795 const uint32_t kBitrateBps = 100000;
796 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
797 .Times(1)
798 .WillOnce(Return(kBitrateBps));
799 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
800 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
801
802 // A frame is encoded.
803 EncodedImage encoded_image;
804 CodecSpecificInfo codec_specific;
805 static_cast<EncodedImageCallback*>(vss_impl.get())
806 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
807 // Only after actual frame is encoded are we enabling the padding.
808 EXPECT_GT(padding_bitrate, 0);
809 });
810
811 rtc::Event done;
812 test_queue_.PostDelayedTask(
813 [&] {
814 // No padding supposed to be sent for paused observer
815 EXPECT_EQ(0, padding_bitrate);
816 testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
817 vss_impl->Stop();
818 vss_impl.reset();
819 done.Set();
820 },
821 5000);
822
823 // Pause the test suite so that the last delayed task executes.
824 ASSERT_TRUE(done.Wait(10000));
825}
826
Sebastian Jansson652dc912018-04-19 15:09:15827} // namespace internal
828} // namespace webrtc