blob: fdf0024105c68633678b5c43c5edee2a175230a1 [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 {
34namespace internal {
35namespace {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020036using ::testing::_;
37using ::testing::Invoke;
38using ::testing::NiceMock;
39using ::testing::Return;
Sebastian Jansson652dc912018-04-19 17:09:15 +020040
41constexpr int64_t kDefaultInitialBitrateBps = 333000;
42const double kDefaultBitratePriority = 0.5;
43
44const float kAlrProbingExperimentPaceMultiplier = 1.0f;
45std::string GetAlrProbingExperimentString() {
46 return std::string(
47 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
48 "/1.0,2875,80,40,-60,3/";
49}
Stefan Holmer64be7fa2018-10-04 15:21:55 +020050class MockRtpVideoSender : public RtpVideoSenderInterface {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020051 public:
52 MOCK_METHOD1(RegisterProcessThread, void(ProcessThread*));
53 MOCK_METHOD0(DeRegisterProcessThread, void());
54 MOCK_METHOD1(SetActive, void(bool));
55 MOCK_METHOD1(SetActiveModules, void(const std::vector<bool>));
56 MOCK_METHOD0(IsActive, bool());
57 MOCK_METHOD1(OnNetworkAvailability, void(bool));
58 MOCK_CONST_METHOD0(GetRtpStates, std::map<uint32_t, RtpState>());
59 MOCK_CONST_METHOD0(GetRtpPayloadStates,
60 std::map<uint32_t, RtpPayloadState>());
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020061 MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020062 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
63 MOCK_METHOD3(OnEncodedImage,
64 EncodedImageCallback::Result(const EncodedImage&,
65 const CodecSpecificInfo*,
66 const RTPFragmentationHeader*));
Stefan Holmer64be7fa2018-10-04 15:21:55 +020067 MOCK_METHOD1(OnTransportOverheadChanged, void(size_t));
68 MOCK_METHOD1(OnOverheadChanged, void(size_t));
69 MOCK_METHOD4(OnBitrateUpdated, void(uint32_t, uint8_t, int64_t, int));
70 MOCK_CONST_METHOD0(GetPayloadBitrateBps, uint32_t());
71 MOCK_CONST_METHOD0(GetProtectionBitrateBps, uint32_t());
72 MOCK_METHOD3(SetEncodingData, void(size_t, size_t, size_t));
Elad Alon898395d2019-04-10 15:55:00 +020073 MOCK_CONST_METHOD2(GetSentRtpPacketInfos,
74 std::vector<RtpSequenceNumberMap::Info>(
75 uint32_t ssrc,
76 rtc::ArrayView<const uint16_t> sequence_numbers));
Elad Alon8f01c4e2019-06-28 15:19:43 +020077
78 MOCK_METHOD1(SetFecAllowed, void(bool fec_allowed));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020079};
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020080
81BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {
82 BitrateAllocationUpdate update;
Sebastian Jansson13e59032018-11-21 19:13:07 +010083 update.target_bitrate = DataRate::bps(bitrate_bps);
84 update.packet_loss_ratio = 0;
85 update.round_trip_time = TimeDelta::Zero();
Sebastian Janssonc0e4d452018-10-25 15:08:32 +020086 return update;
87}
Sebastian Jansson652dc912018-04-19 17:09:15 +020088} // namespace
89
90class VideoSendStreamImplTest : public ::testing::Test {
91 protected:
92 VideoSendStreamImplTest()
93 : clock_(1000 * 1000 * 1000),
94 config_(&transport_),
95 send_delay_stats_(&clock_),
Sebastian Jansson652dc912018-04-19 17:09:15 +020096 test_queue_("test_queue"),
97 process_thread_(ProcessThread::Create("test_thread")),
98 call_stats_(&clock_, process_thread_.get()),
99 stats_proxy_(&clock_,
100 config_,
101 VideoEncoderConfig::ContentType::kRealtimeVideo) {
102 config_.rtp.ssrcs.push_back(8080);
103 config_.rtp.payload_type = 1;
104
Sebastian Jansson652dc912018-04-19 17:09:15 +0200105 EXPECT_CALL(transport_controller_, packet_router())
106 .WillRepeatedly(Return(&packet_router_));
Elad Alon8f01c4e2019-06-28 15:19:43 +0200107 EXPECT_CALL(transport_controller_, CreateRtpVideoSender)
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200108 .WillRepeatedly(Return(&rtp_video_sender_));
109 EXPECT_CALL(rtp_video_sender_, SetActive(_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200110 .WillRepeatedly(::testing::Invoke(
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200111 [&](bool active) { rtp_video_sender_active_ = active; }));
112 EXPECT_CALL(rtp_video_sender_, IsActive())
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200113 .WillRepeatedly(
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200114 ::testing::Invoke([&]() { return rtp_video_sender_active_; }));
Sebastian Jansson652dc912018-04-19 17:09:15 +0200115 }
116 ~VideoSendStreamImplTest() {}
117
118 std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
119 int initial_encoder_max_bitrate,
120 double initial_encoder_bitrate_priority,
121 VideoEncoderConfig::ContentType content_type) {
122 EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
123 .WillOnce(Return(123000));
124 std::map<uint32_t, RtpState> suspended_ssrcs;
125 std::map<uint32_t, RtpPayloadState> suspended_payload_states;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200126 return std::make_unique<VideoSendStreamImpl>(
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100127 &clock_, &stats_proxy_, &test_queue_, &call_stats_,
128 &transport_controller_, &bitrate_allocator_, &send_delay_stats_,
129 &video_stream_encoder_, &event_log_, &config_,
130 initial_encoder_max_bitrate, initial_encoder_bitrate_priority,
131 suspended_ssrcs, suspended_payload_states, content_type,
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200132 std::make_unique<FecControllerDefault>(&clock_),
Niels Möller46879152019-01-07 15:54:47 +0100133 /*media_transport=*/nullptr);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200134 }
135
136 protected:
137 NiceMock<MockTransport> transport_;
138 NiceMock<MockRtpTransportControllerSend> transport_controller_;
139 NiceMock<MockBitrateAllocator> bitrate_allocator_;
140 NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200141 NiceMock<MockRtpVideoSender> rtp_video_sender_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200142
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200143 bool rtp_video_sender_active_ = false;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200144 SimulatedClock clock_;
Danil Chapovalov83bbe912019-08-07 12:24:53 +0200145 RtcEventLogNull event_log_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200146 VideoSendStream::Config config_;
147 SendDelayStats send_delay_stats_;
Danil Chapovalovd26a9162019-03-19 18:08:37 +0100148 TaskQueueForTest test_queue_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200149 std::unique_ptr<ProcessThread> process_thread_;
150 CallStats call_stats_;
151 SendStatisticsProxy stats_proxy_;
152 PacketRouter packet_router_;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200153};
154
155TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200156 test_queue_.SendTask(
157 [this] {
158 const bool kSuspend = false;
159 config_.suspend_below_min_bitrate = kSuspend;
160 auto vss_impl = CreateVideoSendStreamImpl(
161 kDefaultInitialBitrateBps, kDefaultBitratePriority,
162 VideoEncoderConfig::ContentType::kRealtimeVideo);
163 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
164 .WillOnce(Invoke([&](BitrateAllocatorObserver*,
165 MediaStreamAllocationConfig config) {
Sebastian Jansson652dc912018-04-19 17:09:15 +0200166 EXPECT_EQ(config.min_bitrate_bps, 0u);
167 EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
168 EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
169 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200170 EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200171 }));
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200172 vss_impl->Start();
173 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
174 .Times(1);
175 vss_impl->Stop();
176 },
177 RTC_FROM_HERE);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200178}
179
Erik Språngb57ab382018-09-13 10:52:38 +0200180TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200181 test_queue_.SendTask(
182 [this] {
183 const bool kSuspend = false;
184 config_.suspend_below_min_bitrate = kSuspend;
185 config_.rtp.extensions.emplace_back(
186 RtpExtension::kTransportSequenceNumberUri, 1);
187 auto vss_impl = CreateVideoSendStreamImpl(
188 kDefaultInitialBitrateBps, kDefaultBitratePriority,
189 VideoEncoderConfig::ContentType::kRealtimeVideo);
190 vss_impl->Start();
Erik Språngb57ab382018-09-13 10:52:38 +0200191
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200192 // QVGA + VGA configuration matching defaults in
193 // media/engine/simulcast.cc.
194 VideoStream qvga_stream;
195 qvga_stream.width = 320;
196 qvga_stream.height = 180;
197 qvga_stream.max_framerate = 30;
198 qvga_stream.min_bitrate_bps = 30000;
199 qvga_stream.target_bitrate_bps = 150000;
200 qvga_stream.max_bitrate_bps = 200000;
201 qvga_stream.max_qp = 56;
202 qvga_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200203
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200204 VideoStream vga_stream;
205 vga_stream.width = 640;
206 vga_stream.height = 360;
207 vga_stream.max_framerate = 30;
208 vga_stream.min_bitrate_bps = 150000;
209 vga_stream.target_bitrate_bps = 500000;
210 vga_stream.max_bitrate_bps = 700000;
211 vga_stream.max_qp = 56;
212 vga_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200213
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200214 int min_transmit_bitrate_bps = 30000;
Erik Språngb57ab382018-09-13 10:52:38 +0200215
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200216 config_.rtp.ssrcs.emplace_back(1);
217 config_.rtp.ssrcs.emplace_back(2);
Erik Språngb57ab382018-09-13 10:52:38 +0200218
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200219 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
220 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
221 MediaStreamAllocationConfig config) {
Erik Språngb57ab382018-09-13 10:52:38 +0200222 EXPECT_EQ(config.min_bitrate_bps,
223 static_cast<uint32_t>(min_transmit_bitrate_bps));
224 EXPECT_EQ(config.max_bitrate_bps,
225 static_cast<uint32_t>(qvga_stream.max_bitrate_bps +
226 vga_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200227 if (config.pad_up_bitrate_bps != 0) {
228 EXPECT_EQ(config.pad_up_bitrate_bps,
229 static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
230 vga_stream.min_bitrate_bps));
231 }
Erik Språngb57ab382018-09-13 10:52:38 +0200232 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200233 }));
234
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200235 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
236 ->OnEncoderConfigurationChanged(
237 std::vector<VideoStream>{qvga_stream, vga_stream},
238 VideoEncoderConfig::ContentType::kRealtimeVideo,
239 min_transmit_bitrate_bps);
240 vss_impl->Stop();
241 },
242 RTC_FROM_HERE);
Erik Språngb57ab382018-09-13 10:52:38 +0200243}
244
245TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200246 test_queue_.SendTask(
247 [this] {
248 const bool kSuspend = false;
249 config_.suspend_below_min_bitrate = kSuspend;
250 config_.rtp.extensions.emplace_back(
251 RtpExtension::kTransportSequenceNumberUri, 1);
252 config_.periodic_alr_bandwidth_probing = true;
253 auto vss_impl = CreateVideoSendStreamImpl(
254 kDefaultInitialBitrateBps, kDefaultBitratePriority,
255 VideoEncoderConfig::ContentType::kScreen);
256 vss_impl->Start();
Erik Språngb57ab382018-09-13 10:52:38 +0200257
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200258 // Simulcast screenshare.
259 VideoStream low_stream;
260 low_stream.width = 1920;
261 low_stream.height = 1080;
262 low_stream.max_framerate = 5;
263 low_stream.min_bitrate_bps = 30000;
264 low_stream.target_bitrate_bps = 200000;
265 low_stream.max_bitrate_bps = 1000000;
266 low_stream.num_temporal_layers = 2;
267 low_stream.max_qp = 56;
268 low_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200269
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200270 VideoStream high_stream;
271 high_stream.width = 1920;
272 high_stream.height = 1080;
273 high_stream.max_framerate = 30;
274 high_stream.min_bitrate_bps = 60000;
275 high_stream.target_bitrate_bps = 1250000;
276 high_stream.max_bitrate_bps = 1250000;
277 high_stream.num_temporal_layers = 2;
278 high_stream.max_qp = 56;
279 high_stream.bitrate_priority = 1;
Erik Språngb57ab382018-09-13 10:52:38 +0200280
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200281 // With ALR probing, this will be the padding target instead of
282 // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
283 int min_transmit_bitrate_bps = 400000;
Erik Språngb57ab382018-09-13 10:52:38 +0200284
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200285 config_.rtp.ssrcs.emplace_back(1);
286 config_.rtp.ssrcs.emplace_back(2);
Erik Språngb57ab382018-09-13 10:52:38 +0200287
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200288 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
289 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
290 MediaStreamAllocationConfig config) {
Erik Språngb57ab382018-09-13 10:52:38 +0200291 EXPECT_EQ(config.min_bitrate_bps,
292 static_cast<uint32_t>(low_stream.min_bitrate_bps));
293 EXPECT_EQ(config.max_bitrate_bps,
294 static_cast<uint32_t>(low_stream.max_bitrate_bps +
295 high_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200296 if (config.pad_up_bitrate_bps != 0) {
297 EXPECT_EQ(config.pad_up_bitrate_bps,
298 static_cast<uint32_t>(min_transmit_bitrate_bps));
299 }
Erik Språngb57ab382018-09-13 10:52:38 +0200300 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200301 }));
302
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200303 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
304 ->OnEncoderConfigurationChanged(
305 std::vector<VideoStream>{low_stream, high_stream},
306 VideoEncoderConfig::ContentType::kScreen,
307 min_transmit_bitrate_bps);
308 vss_impl->Stop();
309 },
310 RTC_FROM_HERE);
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100311}
312
313TEST_F(VideoSendStreamImplTest,
314 UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis) {
315 test::ScopedFieldTrials hysteresis_experiment(
316 "WebRTC-VideoRateControl/video_hysteresis:1.25/");
317
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200318 test_queue_.SendTask(
319 [this] {
320 auto vss_impl = CreateVideoSendStreamImpl(
321 kDefaultInitialBitrateBps, kDefaultBitratePriority,
322 VideoEncoderConfig::ContentType::kRealtimeVideo);
323 vss_impl->Start();
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100324
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200325 // 2-layer video simulcast.
326 VideoStream low_stream;
327 low_stream.width = 320;
328 low_stream.height = 240;
329 low_stream.max_framerate = 30;
330 low_stream.min_bitrate_bps = 30000;
331 low_stream.target_bitrate_bps = 100000;
332 low_stream.max_bitrate_bps = 200000;
333 low_stream.max_qp = 56;
334 low_stream.bitrate_priority = 1;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100335
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200336 VideoStream high_stream;
337 high_stream.width = 640;
338 high_stream.height = 480;
339 high_stream.max_framerate = 30;
340 high_stream.min_bitrate_bps = 150000;
341 high_stream.target_bitrate_bps = 500000;
342 high_stream.max_bitrate_bps = 750000;
343 high_stream.max_qp = 56;
344 high_stream.bitrate_priority = 1;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100345
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200346 config_.rtp.ssrcs.emplace_back(1);
347 config_.rtp.ssrcs.emplace_back(2);
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100348
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200349 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
350 .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
351 MediaStreamAllocationConfig config) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200352 EXPECT_EQ(config.min_bitrate_bps,
353 static_cast<uint32_t>(low_stream.min_bitrate_bps));
354 EXPECT_EQ(config.max_bitrate_bps,
355 static_cast<uint32_t>(low_stream.max_bitrate_bps +
356 high_stream.max_bitrate_bps));
357 if (config.pad_up_bitrate_bps != 0) {
358 EXPECT_EQ(
359 config.pad_up_bitrate_bps,
360 static_cast<uint32_t>(low_stream.target_bitrate_bps +
361 1.25 * high_stream.min_bitrate_bps));
362 }
363 }));
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100364
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200365 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
366 ->OnEncoderConfigurationChanged(
367 std::vector<VideoStream>{low_stream, high_stream},
368 VideoEncoderConfig::ContentType::kRealtimeVideo,
369 /*min_transmit_bitrate_bps=*/0);
370 vss_impl->Stop();
371 },
372 RTC_FROM_HERE);
Erik Språngb57ab382018-09-13 10:52:38 +0200373}
374
Sebastian Jansson652dc912018-04-19 17:09:15 +0200375TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
376 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
377
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200378 test_queue_.SendTask(
379 [this] {
380 constexpr int kId = 1;
381 config_.rtp.extensions.emplace_back(
382 RtpExtension::kTransportSequenceNumberUri, kId);
383 EXPECT_CALL(transport_controller_,
384 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
385 .Times(1);
386 auto vss_impl = CreateVideoSendStreamImpl(
387 kDefaultInitialBitrateBps, kDefaultBitratePriority,
388 VideoEncoderConfig::ContentType::kScreen);
389 vss_impl->Start();
390 vss_impl->Stop();
391 },
392 RTC_FROM_HERE);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200393}
394
395TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
396 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200397 test_queue_.SendTask(
398 [this] {
399 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
400 auto vss_impl = CreateVideoSendStreamImpl(
401 kDefaultInitialBitrateBps, kDefaultBitratePriority,
402 VideoEncoderConfig::ContentType::kScreen);
403 vss_impl->Start();
404 vss_impl->Stop();
405 },
406 RTC_FROM_HERE);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200407}
Erik Språng4e193e42018-09-14 19:01:58 +0200408
409TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200410 test_queue_.SendTask(
411 [this] {
412 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
413 auto vss_impl = CreateVideoSendStreamImpl(
414 kDefaultInitialBitrateBps, kDefaultBitratePriority,
415 VideoEncoderConfig::ContentType::kScreen);
416 vss_impl->Start();
417 VideoBitrateAllocationObserver* const observer =
418 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200419
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200420 // Populate a test instance of video bitrate allocation.
421 VideoBitrateAllocation alloc;
422 alloc.SetBitrate(0, 0, 10000);
423 alloc.SetBitrate(0, 1, 20000);
424 alloc.SetBitrate(1, 0, 30000);
425 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200426
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200427 // Encoder starts out paused, don't forward allocation.
428 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
429 .Times(0);
430 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200431
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200432 // Unpause encoder, allocation should be passed through.
433 const uint32_t kBitrateBps = 100000;
434 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
435 .Times(1)
436 .WillOnce(Return(kBitrateBps));
437 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
438 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
439 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
440 .Times(1);
441 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200442
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200443 // Pause encoder again, and block allocations.
444 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
445 .Times(1)
446 .WillOnce(Return(0));
447 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
448 ->OnBitrateUpdated(CreateAllocation(0));
449 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
450 .Times(0);
451 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200452
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200453 vss_impl->Stop();
454 },
455 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200456}
457
458TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200459 test_queue_.SendTask(
460 [this] {
461 auto vss_impl = CreateVideoSendStreamImpl(
462 kDefaultInitialBitrateBps, kDefaultBitratePriority,
463 VideoEncoderConfig::ContentType::kScreen);
464 vss_impl->Start();
465 // Unpause encoder, to allows allocations to be passed through.
466 const uint32_t kBitrateBps = 100000;
467 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
468 .Times(1)
469 .WillOnce(Return(kBitrateBps));
470 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
471 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
472 VideoBitrateAllocationObserver* const observer =
473 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200474
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200475 // Populate a test instance of video bitrate allocation.
476 VideoBitrateAllocation alloc;
477 alloc.SetBitrate(0, 0, 10000);
478 alloc.SetBitrate(0, 1, 20000);
479 alloc.SetBitrate(1, 0, 30000);
480 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200481
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200482 // Initial value.
483 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
484 .Times(1);
485 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200486
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200487 VideoBitrateAllocation updated_alloc = alloc;
488 // Needs 10% increase in bitrate to trigger immediate forward.
489 const uint32_t base_layer_min_update_bitrate_bps =
490 alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
Erik Språng4e193e42018-09-14 19:01:58 +0200491
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200492 // Too small increase, don't forward.
493 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
494 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
495 observer->OnBitrateAllocationUpdated(updated_alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200496
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200497 // Large enough increase, do forward.
498 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
499 EXPECT_CALL(rtp_video_sender_,
500 OnBitrateAllocationUpdated(updated_alloc))
501 .Times(1);
502 observer->OnBitrateAllocationUpdated(updated_alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200503
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200504 // This is now a decrease compared to last forward allocation, forward
505 // immediately.
506 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
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 vss_impl->Stop();
513 },
514 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200515}
516
517TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200518 test_queue_.SendTask(
519 [this] {
520 auto vss_impl = CreateVideoSendStreamImpl(
521 kDefaultInitialBitrateBps, kDefaultBitratePriority,
522 VideoEncoderConfig::ContentType::kScreen);
523 vss_impl->Start();
524 // Unpause encoder, to allows allocations to be passed through.
525 const uint32_t kBitrateBps = 100000;
526 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
527 .Times(1)
528 .WillOnce(Return(kBitrateBps));
529 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
530 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
531 VideoBitrateAllocationObserver* const observer =
532 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200533
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200534 // Populate a test instance of video bitrate allocation.
535 VideoBitrateAllocation alloc;
536 alloc.SetBitrate(0, 0, 10000);
537 alloc.SetBitrate(0, 1, 20000);
538 alloc.SetBitrate(1, 0, 30000);
539 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200540
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200541 // Initial value.
542 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
543 .Times(1);
544 observer->OnBitrateAllocationUpdated(alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200545
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200546 // Move some bitrate from one layer to a new one, but keep sum the same.
547 // Since layout has changed, immediately trigger forward.
548 VideoBitrateAllocation updated_alloc = alloc;
549 updated_alloc.SetBitrate(2, 0, 10000);
550 updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
551 EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
552 EXPECT_CALL(rtp_video_sender_,
553 OnBitrateAllocationUpdated(updated_alloc))
554 .Times(1);
555 observer->OnBitrateAllocationUpdated(updated_alloc);
Erik Språng4e193e42018-09-14 19:01:58 +0200556
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200557 vss_impl->Stop();
558 },
559 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200560}
561
562TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200563 test_queue_.SendTask(
564 [this] {
565 auto vss_impl = CreateVideoSendStreamImpl(
566 kDefaultInitialBitrateBps, kDefaultBitratePriority,
567 VideoEncoderConfig::ContentType::kScreen);
568 vss_impl->Start();
569 const uint32_t kBitrateBps = 100000;
570 // Unpause encoder, to allows allocations to be passed through.
571 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
572 .Times(1)
573 .WillRepeatedly(Return(kBitrateBps));
574 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
575 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
576 VideoBitrateAllocationObserver* const observer =
577 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
Erik Språng4e193e42018-09-14 19:01:58 +0200578
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200579 // Populate a test instance of video bitrate allocation.
580 VideoBitrateAllocation alloc;
581 alloc.SetBitrate(0, 0, 10000);
582 alloc.SetBitrate(0, 1, 20000);
583 alloc.SetBitrate(1, 0, 30000);
584 alloc.SetBitrate(1, 1, 40000);
Erik Språng4e193e42018-09-14 19:01:58 +0200585
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200586 EncodedImage encoded_image;
587 CodecSpecificInfo codec_specific;
588 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
589 .WillRepeatedly(Return(EncodedImageCallback::Result(
590 EncodedImageCallback::Result::OK)));
Erik Språng4e193e42018-09-14 19:01:58 +0200591
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200592 // Max time we will throttle similar video bitrate allocations.
593 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
Erik Språng4e193e42018-09-14 19:01:58 +0200594
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200595 {
596 // Initial value.
597 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
598 .Times(1);
599 observer->OnBitrateAllocationUpdated(alloc);
600 }
Erik Språng4e193e42018-09-14 19:01:58 +0200601
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200602 {
603 // Sending same allocation again, this one should be throttled.
604 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
605 .Times(0);
606 observer->OnBitrateAllocationUpdated(alloc);
607 }
Erik Språng4e193e42018-09-14 19:01:58 +0200608
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200609 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Erik Språng4e193e42018-09-14 19:01:58 +0200610
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200611 {
612 // Sending similar allocation again after timeout, should forward.
613 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
614 .Times(1);
615 observer->OnBitrateAllocationUpdated(alloc);
616 }
Erik Språng4e193e42018-09-14 19:01:58 +0200617
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200618 {
619 // Sending similar allocation again without timeout, throttle.
620 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
621 .Times(0);
622 observer->OnBitrateAllocationUpdated(alloc);
623 }
Erik Språng4e193e42018-09-14 19:01:58 +0200624
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200625 {
626 // Send encoded image, should be a noop.
627 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
628 .Times(0);
629 static_cast<EncodedImageCallback*>(vss_impl.get())
630 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
631 }
Erik Språng4e193e42018-09-14 19:01:58 +0200632
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200633 {
634 // Advance time and send encoded image, this should wake up and send
635 // cached bitrate allocation.
636 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
637 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
638 .Times(1);
639 static_cast<EncodedImageCallback*>(vss_impl.get())
640 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
641 }
Erik Språng4e193e42018-09-14 19:01:58 +0200642
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200643 {
644 // Advance time and send encoded image, there should be no cached
645 // allocation to send.
646 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
647 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
648 .Times(0);
649 static_cast<EncodedImageCallback*>(vss_impl.get())
650 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
651 }
Erik Språng4e193e42018-09-14 19:01:58 +0200652
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200653 vss_impl->Stop();
654 },
655 RTC_FROM_HERE);
Erik Språng4e193e42018-09-14 19:01:58 +0200656}
657
Erik Språng610c7632019-03-06 15:37:33 +0100658TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200659 test_queue_.SendTask(
660 [this] {
661 const bool kSuspend = false;
662 config_.suspend_below_min_bitrate = kSuspend;
663 config_.rtp.extensions.emplace_back(
664 RtpExtension::kTransportSequenceNumberUri, 1);
665 auto vss_impl = CreateVideoSendStreamImpl(
666 kDefaultInitialBitrateBps, kDefaultBitratePriority,
667 VideoEncoderConfig::ContentType::kRealtimeVideo);
668 vss_impl->Start();
Erik Språng610c7632019-03-06 15:37:33 +0100669
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200670 VideoStream qvga_stream;
671 qvga_stream.width = 320;
672 qvga_stream.height = 180;
673 qvga_stream.max_framerate = 30;
674 qvga_stream.min_bitrate_bps = 30000;
675 qvga_stream.target_bitrate_bps = 150000;
676 qvga_stream.max_bitrate_bps = 200000;
677 qvga_stream.max_qp = 56;
678 qvga_stream.bitrate_priority = 1;
Erik Språng610c7632019-03-06 15:37:33 +0100679
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200680 int min_transmit_bitrate_bps = 30000;
Erik Språng610c7632019-03-06 15:37:33 +0100681
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200682 config_.rtp.ssrcs.emplace_back(1);
Erik Språng610c7632019-03-06 15:37:33 +0100683
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200684 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
685 ->OnEncoderConfigurationChanged(
686 std::vector<VideoStream>{qvga_stream},
687 VideoEncoderConfig::ContentType::kRealtimeVideo,
688 min_transmit_bitrate_bps);
Erik Språng610c7632019-03-06 15:37:33 +0100689
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200690 const DataRate network_constrained_rate =
691 DataRate::bps(qvga_stream.target_bitrate_bps);
692 BitrateAllocationUpdate update;
693 update.target_bitrate = network_constrained_rate;
694 update.stable_target_bitrate = network_constrained_rate;
695 update.round_trip_time = TimeDelta::ms(1);
696 EXPECT_CALL(rtp_video_sender_,
697 OnBitrateUpdated(network_constrained_rate.bps(), _,
698 update.round_trip_time.ms(), _));
699 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
700 .WillOnce(Return(network_constrained_rate.bps()));
701 EXPECT_CALL(
702 video_stream_encoder_,
703 OnBitrateUpdated(network_constrained_rate, network_constrained_rate,
704 network_constrained_rate, 0, _));
705 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
706 ->OnBitrateUpdated(update);
Erik Språng610c7632019-03-06 15:37:33 +0100707
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200708 // Test allocation where the link allocation is larger than the target,
709 // meaning we have some headroom on the link.
710 const DataRate qvga_max_bitrate =
711 DataRate::bps(qvga_stream.max_bitrate_bps);
712 const DataRate headroom = DataRate::bps(50000);
713 const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
714 EXPECT_CALL(rtp_video_sender_,
715 OnBitrateUpdated(rate_with_headroom.bps(), _,
716 update.round_trip_time.ms(), _));
717 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
718 .WillOnce(Return(rate_with_headroom.bps()));
719 EXPECT_CALL(video_stream_encoder_,
720 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
721 rate_with_headroom, 0, _));
722 update.target_bitrate = rate_with_headroom;
723 update.stable_target_bitrate = rate_with_headroom;
724 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
725 ->OnBitrateUpdated(update);
Erik Språng610c7632019-03-06 15:37:33 +0100726
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200727 // Add protection bitrate to the mix, this should be subtracted from the
728 // headroom.
729 const uint32_t protection_bitrate_bps = 10000;
730 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
731 .WillOnce(Return(protection_bitrate_bps));
Erik Språng26111642019-03-26 11:09:04 +0100732
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200733 EXPECT_CALL(rtp_video_sender_,
734 OnBitrateUpdated(rate_with_headroom.bps(), _,
735 update.round_trip_time.ms(), _));
736 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
737 .WillOnce(Return(rate_with_headroom.bps()));
738 const DataRate headroom_minus_protection =
739 rate_with_headroom - DataRate::bps(protection_bitrate_bps);
740 EXPECT_CALL(video_stream_encoder_,
741 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
742 headroom_minus_protection, 0, _));
743 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
744 ->OnBitrateUpdated(update);
Erik Språng26111642019-03-26 11:09:04 +0100745
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200746 // Protection bitrate exceeds head room, link allocation should be
747 // capped to target bitrate.
748 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
749 .WillOnce(Return(headroom.bps() + 1000));
750 EXPECT_CALL(rtp_video_sender_,
751 OnBitrateUpdated(rate_with_headroom.bps(), _,
752 update.round_trip_time.ms(), _));
753 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
Sebastian Jansson652dc912018-04-19 17:09:15 +0200861} // namespace internal
862} // namespace webrtc