blob: 5c19a18b9e6b4ef1dd0dde983a79a6455fd3e6e6 [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) {
156 test_queue_.SendTask([this] {
Sebastian Jansson652dc912018-04-19 17:09:15 +0200157 const bool kSuspend = false;
158 config_.suspend_below_min_bitrate = kSuspend;
159 auto vss_impl = CreateVideoSendStreamImpl(
160 kDefaultInitialBitrateBps, kDefaultBitratePriority,
161 VideoEncoderConfig::ContentType::kRealtimeVideo);
162 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
163 .WillOnce(Invoke(
164 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
165 EXPECT_EQ(config.min_bitrate_bps, 0u);
166 EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
167 EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
168 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200169 EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200170 }));
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 10:52:38 +0200177TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
178 test_queue_.SendTask([this] {
Erik Språngb57ab382018-09-13 10:52:38 +0200179 const bool kSuspend = false;
180 config_.suspend_below_min_bitrate = kSuspend;
181 config_.rtp.extensions.emplace_back(
182 RtpExtension::kTransportSequenceNumberUri, 1);
183 auto vss_impl = CreateVideoSendStreamImpl(
184 kDefaultInitialBitrateBps, kDefaultBitratePriority,
185 VideoEncoderConfig::ContentType::kRealtimeVideo);
186 vss_impl->Start();
187
188 // QVGA + VGA configuration matching defaults in media/engine/simulcast.cc.
189 VideoStream qvga_stream;
190 qvga_stream.width = 320;
191 qvga_stream.height = 180;
192 qvga_stream.max_framerate = 30;
193 qvga_stream.min_bitrate_bps = 30000;
194 qvga_stream.target_bitrate_bps = 150000;
195 qvga_stream.max_bitrate_bps = 200000;
196 qvga_stream.max_qp = 56;
197 qvga_stream.bitrate_priority = 1;
198
199 VideoStream vga_stream;
200 vga_stream.width = 640;
201 vga_stream.height = 360;
202 vga_stream.max_framerate = 30;
203 vga_stream.min_bitrate_bps = 150000;
204 vga_stream.target_bitrate_bps = 500000;
205 vga_stream.max_bitrate_bps = 700000;
206 vga_stream.max_qp = 56;
207 vga_stream.bitrate_priority = 1;
208
209 int min_transmit_bitrate_bps = 30000;
210
211 config_.rtp.ssrcs.emplace_back(1);
212 config_.rtp.ssrcs.emplace_back(2);
213
214 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200215 .WillRepeatedly(Invoke(
Erik Språngb57ab382018-09-13 10:52:38 +0200216 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
217 EXPECT_EQ(config.min_bitrate_bps,
218 static_cast<uint32_t>(min_transmit_bitrate_bps));
219 EXPECT_EQ(config.max_bitrate_bps,
220 static_cast<uint32_t>(qvga_stream.max_bitrate_bps +
221 vga_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200222 if (config.pad_up_bitrate_bps != 0) {
223 EXPECT_EQ(config.pad_up_bitrate_bps,
224 static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
225 vga_stream.min_bitrate_bps));
226 }
Erik Språngb57ab382018-09-13 10:52:38 +0200227 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200228 }));
229
230 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
231 ->OnEncoderConfigurationChanged(
232 std::vector<VideoStream>{qvga_stream, vga_stream},
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100233 VideoEncoderConfig::ContentType::kRealtimeVideo,
Erik Språngb57ab382018-09-13 10:52:38 +0200234 min_transmit_bitrate_bps);
235 vss_impl->Stop();
236 });
237}
238
239TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
240 test_queue_.SendTask([this] {
Erik Språngb57ab382018-09-13 10:52:38 +0200241 const bool kSuspend = false;
242 config_.suspend_below_min_bitrate = kSuspend;
243 config_.rtp.extensions.emplace_back(
244 RtpExtension::kTransportSequenceNumberUri, 1);
245 config_.periodic_alr_bandwidth_probing = true;
246 auto vss_impl = CreateVideoSendStreamImpl(
247 kDefaultInitialBitrateBps, kDefaultBitratePriority,
248 VideoEncoderConfig::ContentType::kScreen);
249 vss_impl->Start();
250
251 // Simulcast screenshare.
252 VideoStream low_stream;
253 low_stream.width = 1920;
254 low_stream.height = 1080;
255 low_stream.max_framerate = 5;
256 low_stream.min_bitrate_bps = 30000;
257 low_stream.target_bitrate_bps = 200000;
258 low_stream.max_bitrate_bps = 1000000;
259 low_stream.num_temporal_layers = 2;
260 low_stream.max_qp = 56;
261 low_stream.bitrate_priority = 1;
262
263 VideoStream high_stream;
264 high_stream.width = 1920;
265 high_stream.height = 1080;
266 high_stream.max_framerate = 30;
267 high_stream.min_bitrate_bps = 60000;
268 high_stream.target_bitrate_bps = 1250000;
269 high_stream.max_bitrate_bps = 1250000;
270 high_stream.num_temporal_layers = 2;
271 high_stream.max_qp = 56;
272 high_stream.bitrate_priority = 1;
273
274 // With ALR probing, this will be the padding target instead of
275 // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
276 int min_transmit_bitrate_bps = 400000;
277
278 config_.rtp.ssrcs.emplace_back(1);
279 config_.rtp.ssrcs.emplace_back(2);
280
281 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200282 .WillRepeatedly(Invoke(
Erik Språngb57ab382018-09-13 10:52:38 +0200283 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
284 EXPECT_EQ(config.min_bitrate_bps,
285 static_cast<uint32_t>(low_stream.min_bitrate_bps));
286 EXPECT_EQ(config.max_bitrate_bps,
287 static_cast<uint32_t>(low_stream.max_bitrate_bps +
288 high_stream.max_bitrate_bps));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200289 if (config.pad_up_bitrate_bps != 0) {
290 EXPECT_EQ(config.pad_up_bitrate_bps,
291 static_cast<uint32_t>(min_transmit_bitrate_bps));
292 }
Erik Språngb57ab382018-09-13 10:52:38 +0200293 EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
Erik Språngb57ab382018-09-13 10:52:38 +0200294 }));
295
296 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
297 ->OnEncoderConfigurationChanged(
298 std::vector<VideoStream>{low_stream, high_stream},
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100299 VideoEncoderConfig::ContentType::kScreen, min_transmit_bitrate_bps);
300 vss_impl->Stop();
301 });
302}
303
304TEST_F(VideoSendStreamImplTest,
305 UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis) {
306 test::ScopedFieldTrials hysteresis_experiment(
307 "WebRTC-VideoRateControl/video_hysteresis:1.25/");
308
309 test_queue_.SendTask([this] {
310 auto vss_impl = CreateVideoSendStreamImpl(
311 kDefaultInitialBitrateBps, kDefaultBitratePriority,
312 VideoEncoderConfig::ContentType::kRealtimeVideo);
313 vss_impl->Start();
314
315 // 2-layer video simulcast.
316 VideoStream low_stream;
317 low_stream.width = 320;
318 low_stream.height = 240;
319 low_stream.max_framerate = 30;
320 low_stream.min_bitrate_bps = 30000;
321 low_stream.target_bitrate_bps = 100000;
322 low_stream.max_bitrate_bps = 200000;
323 low_stream.max_qp = 56;
324 low_stream.bitrate_priority = 1;
325
326 VideoStream high_stream;
327 high_stream.width = 640;
328 high_stream.height = 480;
329 high_stream.max_framerate = 30;
330 high_stream.min_bitrate_bps = 150000;
331 high_stream.target_bitrate_bps = 500000;
332 high_stream.max_bitrate_bps = 750000;
333 high_stream.max_qp = 56;
334 high_stream.bitrate_priority = 1;
335
336 config_.rtp.ssrcs.emplace_back(1);
337 config_.rtp.ssrcs.emplace_back(2);
338
339 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
Jonas Olssona4d87372019-07-05 19:08:33 +0200340 .WillRepeatedly(Invoke(
341 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
342 EXPECT_EQ(config.min_bitrate_bps,
343 static_cast<uint32_t>(low_stream.min_bitrate_bps));
344 EXPECT_EQ(config.max_bitrate_bps,
345 static_cast<uint32_t>(low_stream.max_bitrate_bps +
346 high_stream.max_bitrate_bps));
347 if (config.pad_up_bitrate_bps != 0) {
348 EXPECT_EQ(
349 config.pad_up_bitrate_bps,
350 static_cast<uint32_t>(low_stream.target_bitrate_bps +
351 1.25 * high_stream.min_bitrate_bps));
352 }
353 }));
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100354
355 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
356 ->OnEncoderConfigurationChanged(
357 std::vector<VideoStream>{low_stream, high_stream},
358 VideoEncoderConfig::ContentType::kRealtimeVideo,
359 /*min_transmit_bitrate_bps=*/0);
Erik Språngb57ab382018-09-13 10:52:38 +0200360 vss_impl->Stop();
361 });
362}
363
Sebastian Jansson652dc912018-04-19 17:09:15 +0200364TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
365 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
366
367 test_queue_.SendTask([this] {
Elad Alon157540a2019-02-08 23:37:52 +0100368 constexpr int kId = 1;
Sebastian Jansson652dc912018-04-19 17:09:15 +0200369 config_.rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +0100370 RtpExtension::kTransportSequenceNumberUri, kId);
Sebastian Jansson652dc912018-04-19 17:09:15 +0200371 EXPECT_CALL(transport_controller_,
372 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
373 .Times(1);
374 auto vss_impl = CreateVideoSendStreamImpl(
375 kDefaultInitialBitrateBps, kDefaultBitratePriority,
376 VideoEncoderConfig::ContentType::kScreen);
377 vss_impl->Start();
378 vss_impl->Stop();
379 });
380}
381
382TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
383 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
384 test_queue_.SendTask([this] {
385 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
386 auto vss_impl = CreateVideoSendStreamImpl(
387 kDefaultInitialBitrateBps, kDefaultBitratePriority,
388 VideoEncoderConfig::ContentType::kScreen);
389 vss_impl->Start();
390 vss_impl->Stop();
391 });
392}
Erik Språng4e193e42018-09-14 19:01:58 +0200393
394TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
395 test_queue_.SendTask([this] {
396 EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
397 auto vss_impl = CreateVideoSendStreamImpl(
398 kDefaultInitialBitrateBps, kDefaultBitratePriority,
399 VideoEncoderConfig::ContentType::kScreen);
400 vss_impl->Start();
401 VideoBitrateAllocationObserver* const observer =
402 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
403
404 // Populate a test instance of video bitrate allocation.
405 VideoBitrateAllocation alloc;
406 alloc.SetBitrate(0, 0, 10000);
407 alloc.SetBitrate(0, 1, 20000);
408 alloc.SetBitrate(1, 0, 30000);
409 alloc.SetBitrate(1, 1, 40000);
410
411 // Encoder starts out paused, don't forward allocation.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200412 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200413 observer->OnBitrateAllocationUpdated(alloc);
414
415 // Unpause encoder, allocation should be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200416 const uint32_t kBitrateBps = 100000;
417 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
418 .Times(1)
419 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200420 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200421 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200422 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200423 observer->OnBitrateAllocationUpdated(alloc);
424
425 // Pause encoder again, and block allocations.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200426 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
427 .Times(1)
428 .WillOnce(Return(0));
Erik Språng4e193e42018-09-14 19:01:58 +0200429 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200430 ->OnBitrateUpdated(CreateAllocation(0));
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200431 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200432 observer->OnBitrateAllocationUpdated(alloc);
433
434 vss_impl->Stop();
435 });
436}
437
438TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
439 test_queue_.SendTask([this] {
440 auto vss_impl = CreateVideoSendStreamImpl(
441 kDefaultInitialBitrateBps, kDefaultBitratePriority,
442 VideoEncoderConfig::ContentType::kScreen);
443 vss_impl->Start();
444 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200445 const uint32_t kBitrateBps = 100000;
446 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
447 .Times(1)
448 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200449 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200450 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200451 VideoBitrateAllocationObserver* const observer =
452 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
453
454 // Populate a test instance of video bitrate allocation.
455 VideoBitrateAllocation alloc;
456 alloc.SetBitrate(0, 0, 10000);
457 alloc.SetBitrate(0, 1, 20000);
458 alloc.SetBitrate(1, 0, 30000);
459 alloc.SetBitrate(1, 1, 40000);
460
461 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200462 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200463 observer->OnBitrateAllocationUpdated(alloc);
464
465 VideoBitrateAllocation updated_alloc = alloc;
466 // Needs 10% increase in bitrate to trigger immediate forward.
467 const uint32_t base_layer_min_update_bitrate_bps =
468 alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
469
470 // Too small increase, don't forward.
471 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200472 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200473 observer->OnBitrateAllocationUpdated(updated_alloc);
474
475 // Large enough increase, do forward.
476 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200477 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200478 .Times(1);
479 observer->OnBitrateAllocationUpdated(updated_alloc);
480
481 // This is now a decrease compared to last forward allocation, forward
482 // immediately.
483 updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200484 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200485 .Times(1);
486 observer->OnBitrateAllocationUpdated(updated_alloc);
487
488 vss_impl->Stop();
489 });
490}
491
492TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
493 test_queue_.SendTask([this] {
494 auto vss_impl = CreateVideoSendStreamImpl(
495 kDefaultInitialBitrateBps, kDefaultBitratePriority,
496 VideoEncoderConfig::ContentType::kScreen);
497 vss_impl->Start();
498 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200499 const uint32_t kBitrateBps = 100000;
500 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
501 .Times(1)
502 .WillOnce(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200503 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200504 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200505 VideoBitrateAllocationObserver* const observer =
506 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
507
508 // Populate a test instance of video bitrate allocation.
509 VideoBitrateAllocation alloc;
510 alloc.SetBitrate(0, 0, 10000);
511 alloc.SetBitrate(0, 1, 20000);
512 alloc.SetBitrate(1, 0, 30000);
513 alloc.SetBitrate(1, 1, 40000);
514
515 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200516 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200517 observer->OnBitrateAllocationUpdated(alloc);
518
519 // Move some bitrate from one layer to a new one, but keep sum the same.
520 // Since layout has changed, immediately trigger forward.
521 VideoBitrateAllocation updated_alloc = alloc;
522 updated_alloc.SetBitrate(2, 0, 10000);
523 updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
524 EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200525 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
Erik Språng4e193e42018-09-14 19:01:58 +0200526 .Times(1);
527 observer->OnBitrateAllocationUpdated(updated_alloc);
528
529 vss_impl->Stop();
530 });
531}
532
533TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
534 test_queue_.SendTask([this] {
Erik Språng4e193e42018-09-14 19:01:58 +0200535 auto vss_impl = CreateVideoSendStreamImpl(
536 kDefaultInitialBitrateBps, kDefaultBitratePriority,
537 VideoEncoderConfig::ContentType::kScreen);
538 vss_impl->Start();
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200539 const uint32_t kBitrateBps = 100000;
Erik Språng4e193e42018-09-14 19:01:58 +0200540 // Unpause encoder, to allows allocations to be passed through.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200541 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
542 .Times(1)
543 .WillRepeatedly(Return(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200544 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200545 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
Erik Språng4e193e42018-09-14 19:01:58 +0200546 VideoBitrateAllocationObserver* const observer =
547 static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
548
549 // Populate a test instance of video bitrate allocation.
550 VideoBitrateAllocation alloc;
551 alloc.SetBitrate(0, 0, 10000);
552 alloc.SetBitrate(0, 1, 20000);
553 alloc.SetBitrate(1, 0, 30000);
554 alloc.SetBitrate(1, 1, 40000);
555
556 EncodedImage encoded_image;
557 CodecSpecificInfo codec_specific;
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200558 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
Erik Språng4e193e42018-09-14 19:01:58 +0200559 .WillRepeatedly(Return(
560 EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
561
562 // Max time we will throttle similar video bitrate allocations.
563 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
564
565 {
566 // Initial value.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200567 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
568 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200569 observer->OnBitrateAllocationUpdated(alloc);
570 }
571
572 {
573 // Sending same allocation again, this one should be throttled.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200574 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
575 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200576 observer->OnBitrateAllocationUpdated(alloc);
577 }
578
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100579 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Erik Språng4e193e42018-09-14 19:01:58 +0200580
581 {
582 // Sending similar allocation again after timeout, should forward.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200583 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
584 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200585 observer->OnBitrateAllocationUpdated(alloc);
586 }
587
588 {
589 // Sending similar allocation again without timeout, throttle.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200590 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
591 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200592 observer->OnBitrateAllocationUpdated(alloc);
593 }
594
595 {
596 // Send encoded image, should be a noop.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200597 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
598 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200599 static_cast<EncodedImageCallback*>(vss_impl.get())
600 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
601 }
602
603 {
604 // Advance time and send encoded image, this should wake up and send
605 // cached bitrate allocation.
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100606 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200607 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
608 .Times(1);
Erik Språng4e193e42018-09-14 19:01:58 +0200609 static_cast<EncodedImageCallback*>(vss_impl.get())
610 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
611 }
612
613 {
614 // Advance time and send encoded image, there should be no cached
615 // allocation to send.
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100616 clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200617 EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
618 .Times(0);
Erik Språng4e193e42018-09-14 19:01:58 +0200619 static_cast<EncodedImageCallback*>(vss_impl.get())
620 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
621 }
622
623 vss_impl->Stop();
624 });
625}
626
Erik Språng610c7632019-03-06 15:37:33 +0100627TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
628 test_queue_.SendTask([this] {
Erik Språng610c7632019-03-06 15:37:33 +0100629 const bool kSuspend = false;
630 config_.suspend_below_min_bitrate = kSuspend;
631 config_.rtp.extensions.emplace_back(
632 RtpExtension::kTransportSequenceNumberUri, 1);
633 auto vss_impl = CreateVideoSendStreamImpl(
634 kDefaultInitialBitrateBps, kDefaultBitratePriority,
635 VideoEncoderConfig::ContentType::kRealtimeVideo);
636 vss_impl->Start();
637
638 VideoStream qvga_stream;
639 qvga_stream.width = 320;
640 qvga_stream.height = 180;
641 qvga_stream.max_framerate = 30;
642 qvga_stream.min_bitrate_bps = 30000;
643 qvga_stream.target_bitrate_bps = 150000;
644 qvga_stream.max_bitrate_bps = 200000;
645 qvga_stream.max_qp = 56;
646 qvga_stream.bitrate_priority = 1;
647
648 int min_transmit_bitrate_bps = 30000;
649
650 config_.rtp.ssrcs.emplace_back(1);
651
652 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
653 ->OnEncoderConfigurationChanged(
654 std::vector<VideoStream>{qvga_stream},
655 VideoEncoderConfig::ContentType::kRealtimeVideo,
656 min_transmit_bitrate_bps);
657
658 const DataRate network_constrained_rate =
659 DataRate::bps(qvga_stream.target_bitrate_bps);
660 BitrateAllocationUpdate update;
661 update.target_bitrate = network_constrained_rate;
Florent Castellia8336d32019-09-09 13:36:55 +0200662 update.stable_target_bitrate = network_constrained_rate;
Erik Språng610c7632019-03-06 15:37:33 +0100663 update.round_trip_time = TimeDelta::ms(1);
664 EXPECT_CALL(rtp_video_sender_,
665 OnBitrateUpdated(network_constrained_rate.bps(), _,
666 update.round_trip_time.ms(), _));
667 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
668 .WillOnce(Return(network_constrained_rate.bps()));
Florent Castellia8336d32019-09-09 13:36:55 +0200669 EXPECT_CALL(
670 video_stream_encoder_,
671 OnBitrateUpdated(network_constrained_rate, network_constrained_rate,
672 network_constrained_rate, 0, _));
Erik Språng610c7632019-03-06 15:37:33 +0100673 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
674 ->OnBitrateUpdated(update);
675
Erik Språng4c6ca302019-04-08 15:14:01 +0200676 // Test allocation where the link allocation is larger than the target,
677 // meaning we have some headroom on the link.
Erik Språng610c7632019-03-06 15:37:33 +0100678 const DataRate qvga_max_bitrate =
679 DataRate::bps(qvga_stream.max_bitrate_bps);
680 const DataRate headroom = DataRate::bps(50000);
681 const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
682 EXPECT_CALL(rtp_video_sender_,
683 OnBitrateUpdated(rate_with_headroom.bps(), _,
684 update.round_trip_time.ms(), _));
685 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
686 .WillOnce(Return(rate_with_headroom.bps()));
687 EXPECT_CALL(video_stream_encoder_,
Florent Castellia8336d32019-09-09 13:36:55 +0200688 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
689 rate_with_headroom, 0, _));
Erik Språng610c7632019-03-06 15:37:33 +0100690 update.target_bitrate = rate_with_headroom;
Florent Castellia8336d32019-09-09 13:36:55 +0200691 update.stable_target_bitrate = rate_with_headroom;
Erik Språng610c7632019-03-06 15:37:33 +0100692 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
693 ->OnBitrateUpdated(update);
694
Erik Språng26111642019-03-26 11:09:04 +0100695 // Add protection bitrate to the mix, this should be subtracted from the
696 // headroom.
697 const uint32_t protection_bitrate_bps = 10000;
698 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
699 .WillOnce(Return(protection_bitrate_bps));
700
701 EXPECT_CALL(rtp_video_sender_,
702 OnBitrateUpdated(rate_with_headroom.bps(), _,
703 update.round_trip_time.ms(), _));
704 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
705 .WillOnce(Return(rate_with_headroom.bps()));
706 const DataRate headroom_minus_protection =
Erik Språng4c6ca302019-04-08 15:14:01 +0200707 rate_with_headroom - DataRate::bps(protection_bitrate_bps);
Florent Castellia8336d32019-09-09 13:36:55 +0200708 EXPECT_CALL(video_stream_encoder_,
709 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
710 headroom_minus_protection, 0, _));
Erik Språng26111642019-03-26 11:09:04 +0100711 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
712 ->OnBitrateUpdated(update);
713
Erik Språng4c6ca302019-04-08 15:14:01 +0200714 // Protection bitrate exceeds head room, link allocation should be capped to
715 // target bitrate.
Erik Språng26111642019-03-26 11:09:04 +0100716 EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
717 .WillOnce(Return(headroom.bps() + 1000));
718 EXPECT_CALL(rtp_video_sender_,
719 OnBitrateUpdated(rate_with_headroom.bps(), _,
720 update.round_trip_time.ms(), _));
721 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
722 .WillOnce(Return(rate_with_headroom.bps()));
723 EXPECT_CALL(video_stream_encoder_,
Florent Castellia8336d32019-09-09 13:36:55 +0200724 OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
725 qvga_max_bitrate, 0, _));
Erik Språng26111642019-03-26 11:09:04 +0100726 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
727 ->OnBitrateUpdated(update);
728
Erik Språng610c7632019-03-06 15:37:33 +0100729 // Set rates to zero on stop.
730 EXPECT_CALL(video_stream_encoder_,
Florent Castellia8336d32019-09-09 13:36:55 +0200731 OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(),
732 DataRate::Zero(), 0, 0));
Erik Språng610c7632019-03-06 15:37:33 +0100733 vss_impl->Stop();
734 });
735}
736
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200737TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
738 int padding_bitrate = 0;
739 std::unique_ptr<VideoSendStreamImpl> vss_impl;
740
741 test_queue_.SendTask([&] {
742 vss_impl = CreateVideoSendStreamImpl(
743 kDefaultInitialBitrateBps, kDefaultBitratePriority,
744 VideoEncoderConfig::ContentType::kRealtimeVideo);
745
746 // Capture padding bitrate for testing.
747 EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
748 .WillRepeatedly(Invoke(
749 [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
750 padding_bitrate = config.pad_up_bitrate_bps;
751 }));
752 // If observer is removed, no padding will be sent.
753 EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
754 .WillRepeatedly(
755 Invoke([&](BitrateAllocatorObserver*) { padding_bitrate = 0; }));
756
757 EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
758 .WillRepeatedly(Return(
759 EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
Ilya Nikolaevskiyaa9aa572019-04-11 09:20:24 +0200760 const bool kSuspend = false;
761 config_.suspend_below_min_bitrate = kSuspend;
762 config_.rtp.extensions.emplace_back(
763 RtpExtension::kTransportSequenceNumberUri, 1);
764 VideoStream qvga_stream;
765 qvga_stream.width = 320;
766 qvga_stream.height = 180;
767 qvga_stream.max_framerate = 30;
768 qvga_stream.min_bitrate_bps = 30000;
769 qvga_stream.target_bitrate_bps = 150000;
770 qvga_stream.max_bitrate_bps = 200000;
771 qvga_stream.max_qp = 56;
772 qvga_stream.bitrate_priority = 1;
773
774 int min_transmit_bitrate_bps = 30000;
775
776 config_.rtp.ssrcs.emplace_back(1);
777
778 vss_impl->Start();
779
780 // Starts without padding.
781 EXPECT_EQ(0, padding_bitrate);
782
783 // Reconfigure e.g. due to a fake frame.
784 static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
785 ->OnEncoderConfigurationChanged(
786 std::vector<VideoStream>{qvga_stream},
787 VideoEncoderConfig::ContentType::kRealtimeVideo,
788 min_transmit_bitrate_bps);
789 // Still no padding because no actual frames were passed, only
790 // reconfiguration happened.
791 EXPECT_EQ(0, padding_bitrate);
792
793 // Unpause encoder.
794 const uint32_t kBitrateBps = 100000;
795 EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
796 .Times(1)
797 .WillOnce(Return(kBitrateBps));
798 static_cast<BitrateAllocatorObserver*>(vss_impl.get())
799 ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
800
801 // A frame is encoded.
802 EncodedImage encoded_image;
803 CodecSpecificInfo codec_specific;
804 static_cast<EncodedImageCallback*>(vss_impl.get())
805 ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
806 // Only after actual frame is encoded are we enabling the padding.
807 EXPECT_GT(padding_bitrate, 0);
808 });
809
810 rtc::Event done;
811 test_queue_.PostDelayedTask(
812 [&] {
813 // No padding supposed to be sent for paused observer
814 EXPECT_EQ(0, padding_bitrate);
815 testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
816 vss_impl->Stop();
817 vss_impl.reset();
818 done.Set();
819 },
820 5000);
821
822 // Pause the test suite so that the last delayed task executes.
823 ASSERT_TRUE(done.Wait(10000));
824}
825
Sebastian Jansson652dc912018-04-19 17:09:15 +0200826} // namespace internal
827} // namespace webrtc