blob: ce88a36470f48ed3702721cc59df3cd8332369bd [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "video/video_send_stream_impl.h"
12
Mirko Bonadei317a1f02019-09-17 17:06:18 +020013#include <memory>
Sebastian Jansson652dc912018-04-19 17:09:15 +020014#include <string>
15
Elad Alon8b60e8b2019-04-08 14:14:05 +020016#include "absl/types/optional.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020017#include "api/rtc_event_log/rtc_event_log.h"
Stefan Holmer9416ef82018-07-19 10:34:38 +020018#include "call/rtp_video_sender.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020019#include "call/test/mock_bitrate_allocator.h"
20#include "call/test/mock_rtp_transport_controller_send.h"
Elad Alon8b60e8b2019-04-08 14:14:05 +020021#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h"
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020022#include "modules/utility/include/process_thread.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020023#include "modules/video_coding/fec_controller_default.h"
24#include "rtc_base/experiments/alr_experiment.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/fake_clock.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020026#include "rtc_base/task_queue_for_test.h"
27#include "test/field_trial.h"
28#include "test/gmock.h"
29#include "test/gtest.h"
30#include "test/mock_transport.h"
31#include "video/test/mock_video_stream_encoder.h"
Sebastian Jansson652dc912018-04-19 17:09:15 +020032
33namespace webrtc {
Sebastian Jansson82ed2e82019-10-15 15:58:37 +020034
35bool operator==(const BitrateAllocationUpdate& a,
36 const BitrateAllocationUpdate& b) {
37 return a.target_bitrate == b.target_bitrate &&
38 a.round_trip_time == b.round_trip_time &&
39 a.packet_loss_ratio == b.packet_loss_ratio;
40}
41
Sebastian Jansson652dc912018-04-19 17:09:15 +020042namespace internal {
43namespace {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020044using ::testing::_;
45using ::testing::Invoke;
46using ::testing::NiceMock;
47using ::testing::Return;
Sebastian Jansson652dc912018-04-19 17:09:15 +020048
49constexpr int64_t kDefaultInitialBitrateBps = 333000;
50const double kDefaultBitratePriority = 0.5;
51
52const float kAlrProbingExperimentPaceMultiplier = 1.0f;
53std::string GetAlrProbingExperimentString() {
54 return std::string(
55 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
56 "/1.0,2875,80,40,-60,3/";
57}
Stefan Holmer64be7fa2018-10-04 15:21:55 +020058class MockRtpVideoSender : public RtpVideoSenderInterface {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020059 public:
60 MOCK_METHOD1(RegisterProcessThread, void(ProcessThread*));
61 MOCK_METHOD0(DeRegisterProcessThread, void());
62 MOCK_METHOD1(SetActive, void(bool));
63 MOCK_METHOD1(SetActiveModules, void(const std::vector<bool>));
64 MOCK_METHOD0(IsActive, bool());
65 MOCK_METHOD1(OnNetworkAvailability, void(bool));
66 MOCK_CONST_METHOD0(GetRtpStates, std::map<uint32_t, RtpState>());
67 MOCK_CONST_METHOD0(GetRtpPayloadStates,
68 std::map<uint32_t, RtpPayloadState>());
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020069 MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020070 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
71 MOCK_METHOD3(OnEncodedImage,
72 EncodedImageCallback::Result(const EncodedImage&,
73 const CodecSpecificInfo*,
74 const RTPFragmentationHeader*));
Stefan Holmer64be7fa2018-10-04 15:21:55 +020075 MOCK_METHOD1(OnTransportOverheadChanged, void(size_t));
76 MOCK_METHOD1(OnOverheadChanged, void(size_t));
Sebastian Jansson82ed2e82019-10-15 15:58:37 +020077 MOCK_METHOD2(OnBitrateUpdated, void(BitrateAllocationUpdate, int));
Stefan Holmer64be7fa2018-10-04 15:21:55 +020078 MOCK_CONST_METHOD0(GetPayloadBitrateBps, uint32_t());
79 MOCK_CONST_METHOD0(GetProtectionBitrateBps, uint32_t());
80 MOCK_METHOD3(SetEncodingData, void(size_t, size_t, size_t));
Elad Alon898395d2019-04-10 15:55:00 +020081 MOCK_CONST_METHOD2(GetSentRtpPacketInfos,
82 std::vector<RtpSequenceNumberMap::Info>(
83 uint32_t ssrc,
84 rtc::ArrayView<const uint16_t> sequence_numbers));
Elad Alon8f01c4e2019-06-28 15:19:43 +020085
86 MOCK_METHOD1(SetFecAllowed, void(bool fec_allowed));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020087};
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020088
89BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {
90 BitrateAllocationUpdate update;
Sebastian Jansson13e59032018-11-21 19:13:07 +010091 update.target_bitrate = DataRate::bps(bitrate_bps);
92 update.packet_loss_ratio = 0;
93 update.round_trip_time = TimeDelta::Zero();
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020094 return update;
95}
Sebastian Jansson652dc912018-04-19 17:09:15 +020096} // namespace
97
98class VideoSendStreamImplTest : public ::testing::Test {
99 protected:
100 VideoSendStreamImplTest()
101 : clock_(1000 * 1000 * 1000),
102 config_(&transport_),
103 send_delay_stats_(&clock_),
Sebastian Jansson652dc912018-04-19 17:09:15 +0200104 test_queue_("test_queue"),
105 process_thread_(ProcessThread::Create("test_thread")),
106 call_stats_(&clock_, process_thread_.get()),
107 stats_proxy_(&clock_,
108 config_,
109 VideoEncoderConfig::ContentType::kRealtimeVideo) {
110 config_.rtp.ssrcs.push_back(8080);
111 config_.rtp.payload_type = 1;
112
Sebastian Jansson652dc912018-04-19 17:09:15 +0200113 EXPECT_CALL(transport_controller_, packet_router())
114 .WillRepeatedly(Return(&packet_router_));
Elad Alon8f01c4e2019-06-28 15:19:43 +0200115 EXPECT_CALL(transport_controller_, CreateRtpVideoSender)
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200116 .WillRepeatedly(Return(&rtp_video_sender_));
117 EXPECT_CALL(rtp_video_sender_, SetActive(_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200118 .WillRepeatedly(::testing::Invoke(
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200119 [&](bool active) { rtp_video_sender_active_ = active; }));
120 EXPECT_CALL(rtp_video_sender_, IsActive())
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200121 .WillRepeatedly(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200122 ::testing::Invoke([&]() { return rtp_video_sender_active_; }));
Sebastian Jansson652dc912018-04-19 17:09:15 +0200123 }
124 ~VideoSendStreamImplTest() {}
125
126 std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
127 int initial_encoder_max_bitrate,
128 double initial_encoder_bitrate_priority,
129 VideoEncoderConfig::ContentType content_type) {
130 EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
131 .WillOnce(Return(123000));
132 std::map<uint32_t, RtpState> suspended_ssrcs;
133 std::map<uint32_t, RtpPayloadState> suspended_payload_states;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200134 return std::make_unique<VideoSendStreamImpl>(
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100135 &clock_, &stats_proxy_, &test_queue_, &call_stats_,
136 &transport_controller_, &bitrate_allocator_, &send_delay_stats_,
137 &video_stream_encoder_, &event_log_, &config_,
138 initial_encoder_max_bitrate, initial_encoder_bitrate_priority,
139 suspended_ssrcs, suspended_payload_states, content_type,
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200140 std::make_unique<FecControllerDefault>(&clock_),
Niels Möller46879152019-01-07 15:54:47 +0100141 /*media_transport=*/nullptr);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200142 }
143
144 protected:
145 NiceMock<MockTransport> transport_;
146 NiceMock<MockRtpTransportControllerSend> transport_controller_;
147 NiceMock<MockBitrateAllocator> bitrate_allocator_;
148 NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200149 NiceMock<MockRtpVideoSender> rtp_video_sender_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200150
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200151 bool rtp_video_sender_active_ = false;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200152 SimulatedClock clock_;
Danil Chapovalov83bbe912019-08-07 12:24:53 +0200153 RtcEventLogNull event_log_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200154 VideoSendStream::Config config_;
155 SendDelayStats send_delay_stats_;
Danil Chapovalovd26a9162019-03-19 18:08:37 +0100156 TaskQueueForTest test_queue_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200157 std::unique_ptr<ProcessThread> process_thread_;
158 CallStats call_stats_;
159 SendStatisticsProxy stats_proxy_;
160 PacketRouter packet_router_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200161};
162
163TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200164 test_queue_.SendTask(
165 [this] {
166 const bool kSuspend = false;
167 config_.suspend_below_min_bitrate = kSuspend;
168 auto vss_impl = CreateVideoSendStreamImpl(
169 kDefaultInitialBitrateBps, kDefaultBitratePriority,
170 VideoEncoderConfig::ContentType::kRealtimeVideo);
171 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
172 .WillOnce(Invoke([&](BitrateAllocatorObserver*,
173 MediaStreamAllocationConfig config) {
Sebastian Jansson652dc912018-04-19 17:09:15 +0200174 EXPECT_EQ(config.min_bitrate_bps, 0u);
175 EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
176 EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
177 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200178 EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200179 }));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200180 vss_impl->Start();
181 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
182 .Times(1);
183 vss_impl->Stop();
184 },
185 RTC_FROM_HERE);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200186}
187
Erik Språngb57ab382018-09-13 10:52:38 +0200188TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200189 test_queue_.SendTask(
190 [this] {
191 const bool kSuspend = false;
192 config_.suspend_below_min_bitrate = kSuspend;
193 config_.rtp.extensions.emplace_back(
194 RtpExtension::kTransportSequenceNumberUri, 1);
195 auto vss_impl = CreateVideoSendStreamImpl(
196 kDefaultInitialBitrateBps, kDefaultBitratePriority,
197 VideoEncoderConfig::ContentType::kRealtimeVideo);
198 vss_impl->Start();
Erik Språngb57ab382018-09-13 10:52:38 +0200199
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200200 // QVGA + VGA configuration matching defaults in
201 // media/engine/simulcast.cc.
202 VideoStream qvga_stream;
203 qvga_stream.width = 320;
204 qvga_stream.height = 180;
205 qvga_stream.max_framerate = 30;
206 qvga_stream.min_bitrate_bps = 30000;
207 qvga_stream.target_bitrate_bps = 150000;
208 qvga_stream.max_bitrate_bps = 200000;
209 qvga_stream.max_qp = 56;
210 qvga_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200211
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200212 VideoStream vga_stream;
213 vga_stream.width = 640;
214 vga_stream.height = 360;
215 vga_stream.max_framerate = 30;
216 vga_stream.min_bitrate_bps = 150000;
217 vga_stream.target_bitrate_bps = 500000;
218 vga_stream.max_bitrate_bps = 700000;
219 vga_stream.max_qp = 56;
220 vga_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200221
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200222 int min_transmit_bitrate_bps = 30000;
Erik Språngb57ab382018-09-13 10:52:38 +0200223
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200224 config_.rtp.ssrcs.emplace_back(1);
225 config_.rtp.ssrcs.emplace_back(2);
Erik Språngb57ab382018-09-13 10:52:38 +0200226
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200227 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
228 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
229 MediaStreamAllocationConfig config) {
Erik Språngb57ab382018-09-13 10:52:38 +0200230 EXPECT_EQ(config.min_bitrate_bps,
231 static_cast<uint32_t>(min_transmit_bitrate_bps));
232 EXPECT_EQ(config.max_bitrate_bps,
233 static_cast<uint32_t>(qvga_stream.max_bitrate_bps +
234 vga_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200235 if (config.pad_up_bitrate_bps != 0) {
236 EXPECT_EQ(config.pad_up_bitrate_bps,
237 static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
238 vga_stream.min_bitrate_bps));
239 }
Erik Språngb57ab382018-09-13 10:52:38 +0200240 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200241 }));
242
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200243 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
244 ->OnEncoderConfigurationChanged(
245 std::vector<VideoStream>{qvga_stream, vga_stream},
246 VideoEncoderConfig::ContentType::kRealtimeVideo,
247 min_transmit_bitrate_bps);
248 vss_impl->Stop();
249 },
250 RTC_FROM_HERE);
Erik Språngb57ab382018-09-13 10:52:38 +0200251}
252
253TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200254 test_queue_.SendTask(
255 [this] {
256 const bool kSuspend = false;
257 config_.suspend_below_min_bitrate = kSuspend;
258 config_.rtp.extensions.emplace_back(
259 RtpExtension::kTransportSequenceNumberUri, 1);
260 config_.periodic_alr_bandwidth_probing = true;
261 auto vss_impl = CreateVideoSendStreamImpl(
262 kDefaultInitialBitrateBps, kDefaultBitratePriority,
263 VideoEncoderConfig::ContentType::kScreen);
264 vss_impl->Start();
Erik Språngb57ab382018-09-13 10:52:38 +0200265
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200266 // Simulcast screenshare.
267 VideoStream low_stream;
268 low_stream.width = 1920;
269 low_stream.height = 1080;
270 low_stream.max_framerate = 5;
271 low_stream.min_bitrate_bps = 30000;
272 low_stream.target_bitrate_bps = 200000;
273 low_stream.max_bitrate_bps = 1000000;
274 low_stream.num_temporal_layers = 2;
275 low_stream.max_qp = 56;
276 low_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200277
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200278 VideoStream high_stream;
279 high_stream.width = 1920;
280 high_stream.height = 1080;
281 high_stream.max_framerate = 30;
282 high_stream.min_bitrate_bps = 60000;
283 high_stream.target_bitrate_bps = 1250000;
284 high_stream.max_bitrate_bps = 1250000;
285 high_stream.num_temporal_layers = 2;
286 high_stream.max_qp = 56;
287 high_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200288
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200289 // With ALR probing, this will be the padding target instead of
290 // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
291 int min_transmit_bitrate_bps = 400000;
Erik Språngb57ab382018-09-13 10:52:38 +0200292
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200293 config_.rtp.ssrcs.emplace_back(1);
294 config_.rtp.ssrcs.emplace_back(2);
Erik Språngb57ab382018-09-13 10:52:38 +0200295
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200296 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
297 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
298 MediaStreamAllocationConfig config) {
Erik Språngb57ab382018-09-13 10:52:38 +0200299 EXPECT_EQ(config.min_bitrate_bps,
300 static_cast<uint32_t>(low_stream.min_bitrate_bps));
301 EXPECT_EQ(config.max_bitrate_bps,
302 static_cast<uint32_t>(low_stream.max_bitrate_bps +
303 high_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200304 if (config.pad_up_bitrate_bps != 0) {
305 EXPECT_EQ(config.pad_up_bitrate_bps,
306 static_cast<uint32_t>(min_transmit_bitrate_bps));
307 }
Erik Språngb57ab382018-09-13 10:52:38 +0200308 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200309 }));
310
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200311 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
312 ->OnEncoderConfigurationChanged(
313 std::vector<VideoStream>{low_stream, high_stream},
314 VideoEncoderConfig::ContentType::kScreen,
315 min_transmit_bitrate_bps);
316 vss_impl->Stop();
317 },
318 RTC_FROM_HERE);
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100319}
320
321TEST_F(VideoSendStreamImplTest,
322 UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis) {
323 test::ScopedFieldTrials hysteresis_experiment(
324 "WebRTC-VideoRateControl/video_hysteresis:1.25/");
325
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200326 test_queue_.SendTask(
327 [this] {
328 auto vss_impl = CreateVideoSendStreamImpl(
329 kDefaultInitialBitrateBps, kDefaultBitratePriority,
330 VideoEncoderConfig::ContentType::kRealtimeVideo);
331 vss_impl->Start();
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100332
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200333 // 2-layer video simulcast.
334 VideoStream low_stream;
335 low_stream.width = 320;
336 low_stream.height = 240;
337 low_stream.max_framerate = 30;
338 low_stream.min_bitrate_bps = 30000;
339 low_stream.target_bitrate_bps = 100000;
340 low_stream.max_bitrate_bps = 200000;
341 low_stream.max_qp = 56;
342 low_stream.bitrate_priority = 1;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100343
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200344 VideoStream high_stream;
345 high_stream.width = 640;
346 high_stream.height = 480;
347 high_stream.max_framerate = 30;
348 high_stream.min_bitrate_bps = 150000;
349 high_stream.target_bitrate_bps = 500000;
350 high_stream.max_bitrate_bps = 750000;
351 high_stream.max_qp = 56;
352 high_stream.bitrate_priority = 1;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100353
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200354 config_.rtp.ssrcs.emplace_back(1);
355 config_.rtp.ssrcs.emplace_back(2);
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100356
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200357 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
358 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
359 MediaStreamAllocationConfig config) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200360 EXPECT_EQ(config.min_bitrate_bps,
361 static_cast<uint32_t>(low_stream.min_bitrate_bps));
362 EXPECT_EQ(config.max_bitrate_bps,
363 static_cast<uint32_t>(low_stream.max_bitrate_bps +
364 high_stream.max_bitrate_bps));
365 if (config.pad_up_bitrate_bps != 0) {
366 EXPECT_EQ(
367 config.pad_up_bitrate_bps,
368 static_cast<uint32_t>(low_stream.target_bitrate_bps +
369 1.25 * high_stream.min_bitrate_bps));
370 }
371 }));
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100372
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200373 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
374 ->OnEncoderConfigurationChanged(
375 std::vector<VideoStream>{low_stream, high_stream},
376 VideoEncoderConfig::ContentType::kRealtimeVideo,
377 /*min_transmit_bitrate_bps=*/0);
378 vss_impl->Stop();
379 },
380 RTC_FROM_HERE);
Erik Språngb57ab382018-09-13 10:52:38 +0200381}
382
Sebastian Jansson652dc912018-04-19 17:09:15 +0200383TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
384 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
385
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200386 test_queue_.SendTask(
387 [this] {
388 constexpr int kId = 1;
389 config_.rtp.extensions.emplace_back(
390 RtpExtension::kTransportSequenceNumberUri, kId);
391 EXPECT_CALL(transport_controller_,
392 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
393 .Times(1);
394 auto vss_impl = CreateVideoSendStreamImpl(
395 kDefaultInitialBitrateBps, kDefaultBitratePriority,
396 VideoEncoderConfig::ContentType::kScreen);
397 vss_impl->Start();
398 vss_impl->Stop();
399 },
400 RTC_FROM_HERE);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200401}
402
403TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
404 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200405 test_queue_.SendTask(
406 [this] {
407 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
408 auto vss_impl = CreateVideoSendStreamImpl(
409 kDefaultInitialBitrateBps, kDefaultBitratePriority,
410 VideoEncoderConfig::ContentType::kScreen);
411 vss_impl->Start();
412 vss_impl->Stop();
413 },
414 RTC_FROM_HERE);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200415}
Erik Språng4e193e42018-09-14 19:01:58 +0200416
417TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200418 test_queue_.SendTask(
419 [this] {
420 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
421 auto vss_impl = CreateVideoSendStreamImpl(
422 kDefaultInitialBitrateBps, kDefaultBitratePriority,
423 VideoEncoderConfig::ContentType::kScreen);
424 vss_impl->Start();
425 VideoBitrateAllocationObserver* const observer =
426 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200427
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200428 // Populate a test instance of video bitrate allocation.
429 VideoBitrateAllocation alloc;
430 alloc.SetBitrate(0, 0, 10000);
431 alloc.SetBitrate(0, 1, 20000);
432 alloc.SetBitrate(1, 0, 30000);
433 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200434
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200435 // Encoder starts out paused, don't forward allocation.
436 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
437 .Times(0);
438 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200439
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200440 // Unpause encoder, allocation should be passed through.
441 const uint32_t kBitrateBps = 100000;
442 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
443 .Times(1)
444 .WillOnce(Return(kBitrateBps));
445 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
446 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
447 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
448 .Times(1);
449 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200450
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200451 // Pause encoder again, and block allocations.
452 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
453 .Times(1)
454 .WillOnce(Return(0));
455 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
456 ->OnBitrateUpdated(CreateAllocation(0));
457 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
458 .Times(0);
459 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200460
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200461 vss_impl->Stop();
462 },
463 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200464}
465
466TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200467 test_queue_.SendTask(
468 [this] {
469 auto vss_impl = CreateVideoSendStreamImpl(
470 kDefaultInitialBitrateBps, kDefaultBitratePriority,
471 VideoEncoderConfig::ContentType::kScreen);
472 vss_impl->Start();
473 // Unpause encoder, to allows allocations to be passed through.
474 const uint32_t kBitrateBps = 100000;
475 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
476 .Times(1)
477 .WillOnce(Return(kBitrateBps));
478 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
479 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
480 VideoBitrateAllocationObserver* const observer =
481 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200482
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200483 // Populate a test instance of video bitrate allocation.
484 VideoBitrateAllocation alloc;
485 alloc.SetBitrate(0, 0, 10000);
486 alloc.SetBitrate(0, 1, 20000);
487 alloc.SetBitrate(1, 0, 30000);
488 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200489
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200490 // Initial value.
491 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
492 .Times(1);
493 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200494
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200495 VideoBitrateAllocation updated_alloc = alloc;
496 // Needs 10% increase in bitrate to trigger immediate forward.
497 const uint32_t base_layer_min_update_bitrate_bps =
498 alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
Erik Språng4e193e42018-09-14 19:01:58 +0200499
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200500 // Too small increase, don't forward.
501 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
502 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
503 observer->OnBitrateAllocationUpdated(updated_alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200504
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200505 // Large enough increase, do forward.
506 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
507 EXPECT_CALL(rtp_video_sender_,
508 OnBitrateAllocationUpdated(updated_alloc))
509 .Times(1);
510 observer->OnBitrateAllocationUpdated(updated_alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200511
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200512 // This is now a decrease compared to last forward allocation, forward
513 // immediately.
514 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
515 EXPECT_CALL(rtp_video_sender_,
516 OnBitrateAllocationUpdated(updated_alloc))
517 .Times(1);
518 observer->OnBitrateAllocationUpdated(updated_alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200519
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200520 vss_impl->Stop();
521 },
522 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200523}
524
525TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200526 test_queue_.SendTask(
527 [this] {
528 auto vss_impl = CreateVideoSendStreamImpl(
529 kDefaultInitialBitrateBps, kDefaultBitratePriority,
530 VideoEncoderConfig::ContentType::kScreen);
531 vss_impl->Start();
532 // Unpause encoder, to allows allocations to be passed through.
533 const uint32_t kBitrateBps = 100000;
534 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
535 .Times(1)
536 .WillOnce(Return(kBitrateBps));
537 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
538 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
539 VideoBitrateAllocationObserver* const observer =
540 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200541
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200542 // Populate a test instance of video bitrate allocation.
543 VideoBitrateAllocation alloc;
544 alloc.SetBitrate(0, 0, 10000);
545 alloc.SetBitrate(0, 1, 20000);
546 alloc.SetBitrate(1, 0, 30000);
547 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200548
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200549 // Initial value.
550 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
551 .Times(1);
552 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200553
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200554 // Move some bitrate from one layer to a new one, but keep sum the same.
555 // Since layout has changed, immediately trigger forward.
556 VideoBitrateAllocation updated_alloc = alloc;
557 updated_alloc.SetBitrate(2, 0, 10000);
558 updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
559 EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
560 EXPECT_CALL(rtp_video_sender_,
561 OnBitrateAllocationUpdated(updated_alloc))
562 .Times(1);
563 observer->OnBitrateAllocationUpdated(updated_alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200564
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200565 vss_impl->Stop();
566 },
567 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200568}
569
570TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200571 test_queue_.SendTask(
572 [this] {
573 auto vss_impl = CreateVideoSendStreamImpl(
574 kDefaultInitialBitrateBps, kDefaultBitratePriority,
575 VideoEncoderConfig::ContentType::kScreen);
576 vss_impl->Start();
577 const uint32_t kBitrateBps = 100000;
578 // Unpause encoder, to allows allocations to be passed through.
579 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
580 .Times(1)
581 .WillRepeatedly(Return(kBitrateBps));
582 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
583 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
584 VideoBitrateAllocationObserver* const observer =
585 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200586
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200587 // Populate a test instance of video bitrate allocation.
588 VideoBitrateAllocation alloc;
589 alloc.SetBitrate(0, 0, 10000);
590 alloc.SetBitrate(0, 1, 20000);
591 alloc.SetBitrate(1, 0, 30000);
592 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200593
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200594 EncodedImage encoded_image;
595 CodecSpecificInfo codec_specific;
596 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
597 .WillRepeatedly(Return(EncodedImageCallback::Result(
598 EncodedImageCallback::Result::OK)));
Erik Språng4e193e42018-09-14 19:01:58 +0200599
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200600 // Max time we will throttle similar video bitrate allocations.
601 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
Erik Språng4e193e42018-09-14 19:01:58 +0200602
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200603 {
604 // Initial value.
605 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
606 .Times(1);
607 observer->OnBitrateAllocationUpdated(alloc);
608 }
Erik Språng4e193e42018-09-14 19:01:58 +0200609
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200610 {
611 // Sending same allocation again, this one should be throttled.
612 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
613 .Times(0);
614 observer->OnBitrateAllocationUpdated(alloc);
615 }
Erik Språng4e193e42018-09-14 19:01:58 +0200616
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200617 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Erik Språng4e193e42018-09-14 19:01:58 +0200618
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200619 {
620 // Sending similar allocation again after timeout, should forward.
621 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
622 .Times(1);
623 observer->OnBitrateAllocationUpdated(alloc);
624 }
Erik Språng4e193e42018-09-14 19:01:58 +0200625
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200626 {
627 // Sending similar allocation again without timeout, throttle.
628 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
629 .Times(0);
630 observer->OnBitrateAllocationUpdated(alloc);
631 }
Erik Språng4e193e42018-09-14 19:01:58 +0200632
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200633 {
634 // Send encoded image, should be a noop.
635 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
636 .Times(0);
637 static_cast<EncodedImageCallback*>(vss_impl.get())
638 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
639 }
Erik Språng4e193e42018-09-14 19:01:58 +0200640
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200641 {
642 // Advance time and send encoded image, this should wake up and send
643 // cached bitrate allocation.
644 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
645 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
646 .Times(1);
647 static_cast<EncodedImageCallback*>(vss_impl.get())
648 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
649 }
Erik Språng4e193e42018-09-14 19:01:58 +0200650
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200651 {
652 // Advance time and send encoded image, there should be no cached
653 // allocation to send.
654 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
655 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
656 .Times(0);
657 static_cast<EncodedImageCallback*>(vss_impl.get())
658 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
659 }
Erik Språng4e193e42018-09-14 19:01:58 +0200660
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200661 vss_impl->Stop();
662 },
663 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200664}
665
Erik Språng610c7632019-03-06 15:37:33 +0100666TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200667 test_queue_.SendTask(
668 [this] {
669 const bool kSuspend = false;
670 config_.suspend_below_min_bitrate = kSuspend;
671 config_.rtp.extensions.emplace_back(
672 RtpExtension::kTransportSequenceNumberUri, 1);
673 auto vss_impl = CreateVideoSendStreamImpl(
674 kDefaultInitialBitrateBps, kDefaultBitratePriority,
675 VideoEncoderConfig::ContentType::kRealtimeVideo);
676 vss_impl->Start();
Erik Språng610c7632019-03-06 15:37:33 +0100677
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200678 VideoStream qvga_stream;
679 qvga_stream.width = 320;
680 qvga_stream.height = 180;
681 qvga_stream.max_framerate = 30;
682 qvga_stream.min_bitrate_bps = 30000;
683 qvga_stream.target_bitrate_bps = 150000;
684 qvga_stream.max_bitrate_bps = 200000;
685 qvga_stream.max_qp = 56;
686 qvga_stream.bitrate_priority = 1;
Erik Språng610c7632019-03-06 15:37:33 +0100687
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200688 int min_transmit_bitrate_bps = 30000;
Erik Språng610c7632019-03-06 15:37:33 +0100689
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200690 config_.rtp.ssrcs.emplace_back(1);
Erik Språng610c7632019-03-06 15:37:33 +0100691
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200692 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
693 ->OnEncoderConfigurationChanged(
694 std::vector<VideoStream>{qvga_stream},
695 VideoEncoderConfig::ContentType::kRealtimeVideo,
696 min_transmit_bitrate_bps);
Erik Språng610c7632019-03-06 15:37:33 +0100697
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200698 const DataRate network_constrained_rate =
699 DataRate::bps(qvga_stream.target_bitrate_bps);
700 BitrateAllocationUpdate update;
701 update.target_bitrate = network_constrained_rate;
702 update.stable_target_bitrate = network_constrained_rate;
703 update.round_trip_time = TimeDelta::ms(1);
Sebastian Jansson82ed2e82019-10-15 15:58:37 +0200704 EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200705 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
706 .WillOnce(Return(network_constrained_rate.bps()));
707 EXPECT_CALL(
708 video_stream_encoder_,
709 OnBitrateUpdated(network_constrained_rate, network_constrained_rate,
710 network_constrained_rate, 0, _));
711 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
712 ->OnBitrateUpdated(update);
Erik Språng610c7632019-03-06 15:37:33 +0100713
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200714 // Test allocation where the link allocation is larger than the target,
715 // meaning we have some headroom on the link.
716 const DataRate qvga_max_bitrate =
717 DataRate::bps(qvga_stream.max_bitrate_bps);
718 const DataRate headroom = DataRate::bps(50000);
719 const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
Sebastian Jansson82ed2e82019-10-15 15:58:37 +0200720 update.target_bitrate = rate_with_headroom;
721 update.stable_target_bitrate = rate_with_headroom;
722 EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200723 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
724 .WillOnce(Return(rate_with_headroom.bps()));
725 EXPECT_CALL(video_stream_encoder_,
726 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
727 rate_with_headroom, 0, _));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200728 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
729 ->OnBitrateUpdated(update);
Erik Språng610c7632019-03-06 15:37:33 +0100730
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200731 // Add protection bitrate to the mix, this should be subtracted from the
732 // headroom.
733 const uint32_t protection_bitrate_bps = 10000;
734 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
735 .WillOnce(Return(protection_bitrate_bps));
Erik Språng26111642019-03-26 11:09:04 +0100736
Sebastian Jansson82ed2e82019-10-15 15:58:37 +0200737 EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200738 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
739 .WillOnce(Return(rate_with_headroom.bps()));
740 const DataRate headroom_minus_protection =
741 rate_with_headroom - DataRate::bps(protection_bitrate_bps);
742 EXPECT_CALL(video_stream_encoder_,
743 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
744 headroom_minus_protection, 0, _));
745 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
746 ->OnBitrateUpdated(update);
Erik Språng26111642019-03-26 11:09:04 +0100747
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200748 // Protection bitrate exceeds head room, link allocation should be
749 // capped to target bitrate.
750 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
751 .WillOnce(Return(headroom.bps() + 1000));
Sebastian Jansson82ed2e82019-10-15 15:58:37 +0200752 EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200753 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
754 .WillOnce(Return(rate_with_headroom.bps()));
755 EXPECT_CALL(video_stream_encoder_,
756 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
757 qvga_max_bitrate, 0, _));
758 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
759 ->OnBitrateUpdated(update);
Erik Språng26111642019-03-26 11:09:04 +0100760
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200761 // Set rates to zero on stop.
762 EXPECT_CALL(video_stream_encoder_,
763 OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(),
764 DataRate::Zero(), 0, 0));
765 vss_impl->Stop();
766 },
767 RTC_FROM_HERE);
Erik Språng610c7632019-03-06 15:37:33 +0100768}
769
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200770TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
771 int padding_bitrate = 0;
772 std::unique_ptr<VideoSendStreamImpl> vss_impl;
773
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200774 test_queue_.SendTask(
775 [&] {
776 vss_impl = CreateVideoSendStreamImpl(
777 kDefaultInitialBitrateBps, kDefaultBitratePriority,
778 VideoEncoderConfig::ContentType::kRealtimeVideo);
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200779
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200780 // Capture padding bitrate for testing.
781 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
782 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
783 MediaStreamAllocationConfig config) {
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200784 padding_bitrate = config.pad_up_bitrate_bps;
785 }));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200786 // If observer is removed, no padding will be sent.
787 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
788 .WillRepeatedly(Invoke(
789 [&](BitrateAllocatorObserver*) { padding_bitrate = 0; }));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200790
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200791 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
792 .WillRepeatedly(Return(EncodedImageCallback::Result(
793 EncodedImageCallback::Result::OK)));
794 const bool kSuspend = false;
795 config_.suspend_below_min_bitrate = kSuspend;
796 config_.rtp.extensions.emplace_back(
797 RtpExtension::kTransportSequenceNumberUri, 1);
798 VideoStream qvga_stream;
799 qvga_stream.width = 320;
800 qvga_stream.height = 180;
801 qvga_stream.max_framerate = 30;
802 qvga_stream.min_bitrate_bps = 30000;
803 qvga_stream.target_bitrate_bps = 150000;
804 qvga_stream.max_bitrate_bps = 200000;
805 qvga_stream.max_qp = 56;
806 qvga_stream.bitrate_priority = 1;
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200807
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200808 int min_transmit_bitrate_bps = 30000;
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200809
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200810 config_.rtp.ssrcs.emplace_back(1);
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200811
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200812 vss_impl->Start();
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200813
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200814 // Starts without padding.
815 EXPECT_EQ(0, padding_bitrate);
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200816
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200817 // Reconfigure e.g. due to a fake frame.
818 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
819 ->OnEncoderConfigurationChanged(
820 std::vector<VideoStream>{qvga_stream},
821 VideoEncoderConfig::ContentType::kRealtimeVideo,
822 min_transmit_bitrate_bps);
823 // Still no padding because no actual frames were passed, only
824 // reconfiguration happened.
825 EXPECT_EQ(0, padding_bitrate);
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200826
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200827 // Unpause encoder.
828 const uint32_t kBitrateBps = 100000;
829 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
830 .Times(1)
831 .WillOnce(Return(kBitrateBps));
832 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
833 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200834
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200835 // A frame is encoded.
836 EncodedImage encoded_image;
837 CodecSpecificInfo codec_specific;
838 static_cast<EncodedImageCallback*>(vss_impl.get())
839 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
840 // Only after actual frame is encoded are we enabling the padding.
841 EXPECT_GT(padding_bitrate, 0);
842 },
843 RTC_FROM_HERE);
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200844
845 rtc::Event done;
846 test_queue_.PostDelayedTask(
847 [&] {
848 // No padding supposed to be sent for paused observer
849 EXPECT_EQ(0, padding_bitrate);
850 testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
851 vss_impl->Stop();
852 vss_impl.reset();
853 done.Set();
854 },
855 5000);
856
857 // Pause the test suite so that the last delayed task executes.
858 ASSERT_TRUE(done.Wait(10000));
859}
860
Jakob Ivarsson159b4172019-10-30 14:02:14 +0100861TEST_F(VideoSendStreamImplTest, KeepAliveOnDroppedFrame) {
862 std::unique_ptr<VideoSendStreamImpl> vss_impl;
863 test_queue_.SendTask(
864 [&] {
865 vss_impl = CreateVideoSendStreamImpl(
866 kDefaultInitialBitrateBps, kDefaultBitratePriority,
867 VideoEncoderConfig::ContentType::kRealtimeVideo);
868 vss_impl->Start();
869 const uint32_t kBitrateBps = 100000;
870 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
871 .Times(1)
872 .WillOnce(Return(kBitrateBps));
873 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
874 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
875
876 // Keep the stream from deallocating by dropping a frame.
877 static_cast<EncodedImageCallback*>(vss_impl.get())
878 ->OnDroppedFrame(
879 EncodedImageCallback::DropReason::kDroppedByEncoder);
880 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
881 .Times(0);
882 },
883 RTC_FROM_HERE);
884
885 rtc::Event done;
886 test_queue_.PostDelayedTask(
887 [&] {
888 testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
889 vss_impl->Stop();
890 vss_impl.reset();
891 done.Set();
892 },
893 2000);
894 ASSERT_TRUE(done.Wait(5000));
895}
896
Sebastian Jansson652dc912018-04-19 17:09:15 +0200897} // namespace internal
898} // namespace webrtc