1 /*
2  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "video/video_send_stream_impl.h"
12 
13 #include <algorithm>
14 #include <memory>
15 #include <string>
16 
17 #include "absl/types/optional.h"
18 #include "api/rtc_event_log/rtc_event_log.h"
19 #include "call/rtp_video_sender.h"
20 #include "call/test/mock_bitrate_allocator.h"
21 #include "call/test/mock_rtp_transport_controller_send.h"
22 #include "modules/rtp_rtcp/source/rtp_sequence_number_map.h"
23 #include "modules/utility/include/process_thread.h"
24 #include "modules/video_coding/fec_controller_default.h"
25 #include "rtc_base/experiments/alr_experiment.h"
26 #include "rtc_base/fake_clock.h"
27 #include "rtc_base/task_queue_for_test.h"
28 #include "test/field_trial.h"
29 #include "test/gmock.h"
30 #include "test/gtest.h"
31 #include "test/mock_transport.h"
32 #include "video/call_stats.h"
33 #include "video/test/mock_video_stream_encoder.h"
34 
35 namespace webrtc {
36 
operator ==(const BitrateAllocationUpdate & a,const BitrateAllocationUpdate & b)37 bool operator==(const BitrateAllocationUpdate& a,
38                 const BitrateAllocationUpdate& b) {
39   return a.target_bitrate == b.target_bitrate &&
40          a.round_trip_time == b.round_trip_time &&
41          a.packet_loss_ratio == b.packet_loss_ratio;
42 }
43 
44 namespace internal {
45 namespace {
46 using ::testing::_;
47 using ::testing::AllOf;
48 using ::testing::Field;
49 using ::testing::Invoke;
50 using ::testing::NiceMock;
51 using ::testing::Return;
52 
53 constexpr int64_t kDefaultInitialBitrateBps = 333000;
54 const double kDefaultBitratePriority = 0.5;
55 
56 const float kAlrProbingExperimentPaceMultiplier = 1.0f;
GetAlrProbingExperimentString()57 std::string GetAlrProbingExperimentString() {
58   return std::string(
59              AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
60          "/1.0,2875,80,40,-60,3/";
61 }
62 class MockRtpVideoSender : public RtpVideoSenderInterface {
63  public:
64   MOCK_METHOD(void, RegisterProcessThread, (ProcessThread*), (override));
65   MOCK_METHOD(void, DeRegisterProcessThread, (), (override));
66   MOCK_METHOD(void, SetActive, (bool), (override));
67   MOCK_METHOD(void, SetActiveModules, (const std::vector<bool>), (override));
68   MOCK_METHOD(bool, IsActive, (), (override));
69   MOCK_METHOD(void, OnNetworkAvailability, (bool), (override));
70   MOCK_METHOD((std::map<uint32_t, RtpState>),
71               GetRtpStates,
72               (),
73               (const, override));
74   MOCK_METHOD((std::map<uint32_t, RtpPayloadState>),
75               GetRtpPayloadStates,
76               (),
77               (const, override));
78   MOCK_METHOD(void, DeliverRtcp, (const uint8_t*, size_t), (override));
79   MOCK_METHOD(void,
80               OnBitrateAllocationUpdated,
81               (const VideoBitrateAllocation&),
82               (override));
83   MOCK_METHOD(EncodedImageCallback::Result,
84               OnEncodedImage,
85               (const EncodedImage&,
86                const CodecSpecificInfo*,
87                const RTPFragmentationHeader*),
88               (override));
89   MOCK_METHOD(void, OnTransportOverheadChanged, (size_t), (override));
90   MOCK_METHOD(void,
91               OnBitrateUpdated,
92               (BitrateAllocationUpdate, int),
93               (override));
94   MOCK_METHOD(uint32_t, GetPayloadBitrateBps, (), (const, override));
95   MOCK_METHOD(uint32_t, GetProtectionBitrateBps, (), (const, override));
96   MOCK_METHOD(void, SetEncodingData, (size_t, size_t, size_t), (override));
97   MOCK_METHOD(std::vector<RtpSequenceNumberMap::Info>,
98               GetSentRtpPacketInfos,
99               (uint32_t ssrc, rtc::ArrayView<const uint16_t> sequence_numbers),
100               (const, override));
101 
102   MOCK_METHOD(void, SetFecAllowed, (bool fec_allowed), (override));
103 };
104 
CreateAllocation(int bitrate_bps)105 BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {
106   BitrateAllocationUpdate update;
107   update.target_bitrate = DataRate::BitsPerSec(bitrate_bps);
108   update.packet_loss_ratio = 0;
109   update.round_trip_time = TimeDelta::Zero();
110   return update;
111 }
112 }  // namespace
113 
114 class VideoSendStreamImplTest : public ::testing::Test {
115  protected:
VideoSendStreamImplTest()116   VideoSendStreamImplTest()
117       : clock_(1000 * 1000 * 1000),
118         config_(&transport_),
119         send_delay_stats_(&clock_),
120         test_queue_("test_queue"),
121         process_thread_(ProcessThread::Create("test_thread")),
122         call_stats_(&clock_, process_thread_.get()),
123         stats_proxy_(&clock_,
124                      config_,
125                      VideoEncoderConfig::ContentType::kRealtimeVideo) {
126     config_.rtp.ssrcs.push_back(8080);
127     config_.rtp.payload_type = 1;
128 
129     EXPECT_CALL(transport_controller_, packet_router())
130         .WillRepeatedly(Return(&packet_router_));
131     EXPECT_CALL(transport_controller_, CreateRtpVideoSender)
132         .WillRepeatedly(Return(&rtp_video_sender_));
133     EXPECT_CALL(rtp_video_sender_, SetActive(_))
134         .WillRepeatedly(::testing::Invoke(
135             [&](bool active) { rtp_video_sender_active_ = active; }));
136     EXPECT_CALL(rtp_video_sender_, IsActive())
137         .WillRepeatedly(
138             ::testing::Invoke([&]() { return rtp_video_sender_active_; }));
139   }
~VideoSendStreamImplTest()140   ~VideoSendStreamImplTest() {}
141 
CreateVideoSendStreamImpl(int initial_encoder_max_bitrate,double initial_encoder_bitrate_priority,VideoEncoderConfig::ContentType content_type)142   std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
143       int initial_encoder_max_bitrate,
144       double initial_encoder_bitrate_priority,
145       VideoEncoderConfig::ContentType content_type) {
146     EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
147         .WillOnce(Return(123000));
148     std::map<uint32_t, RtpState> suspended_ssrcs;
149     std::map<uint32_t, RtpPayloadState> suspended_payload_states;
150     return std::make_unique<VideoSendStreamImpl>(
151         &clock_, &stats_proxy_, &test_queue_, &call_stats_,
152         &transport_controller_, &bitrate_allocator_, &send_delay_stats_,
153         &video_stream_encoder_, &event_log_, &config_,
154         initial_encoder_max_bitrate, initial_encoder_bitrate_priority,
155         suspended_ssrcs, suspended_payload_states, content_type,
156         std::make_unique<FecControllerDefault>(&clock_));
157   }
158 
159  protected:
160   NiceMock<MockTransport> transport_;
161   NiceMock<MockRtpTransportControllerSend> transport_controller_;
162   NiceMock<MockBitrateAllocator> bitrate_allocator_;
163   NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
164   NiceMock<MockRtpVideoSender> rtp_video_sender_;
165 
166   bool rtp_video_sender_active_ = false;
167   SimulatedClock clock_;
168   RtcEventLogNull event_log_;
169   VideoSendStream::Config config_;
170   SendDelayStats send_delay_stats_;
171   TaskQueueForTest test_queue_;
172   std::unique_ptr<ProcessThread> process_thread_;
173   // TODO(tommi): Use internal::CallStats
174   CallStats call_stats_;
175   SendStatisticsProxy stats_proxy_;
176   PacketRouter packet_router_;
177 };
178 
TEST_F(VideoSendStreamImplTest,RegistersAsBitrateObserverOnStart)179 TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
180   test_queue_.SendTask(
181       [this] {
182         const bool kSuspend = false;
183         config_.suspend_below_min_bitrate = kSuspend;
184         auto vss_impl = CreateVideoSendStreamImpl(
185             kDefaultInitialBitrateBps, kDefaultBitratePriority,
186             VideoEncoderConfig::ContentType::kRealtimeVideo);
187         EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
188             .WillOnce(Invoke([&](BitrateAllocatorObserver*,
189                                  MediaStreamAllocationConfig config) {
190               EXPECT_EQ(config.min_bitrate_bps, 0u);
191               EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
192               EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
193               EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
194               EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
195             }));
196         vss_impl->Start();
197         EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
198             .Times(1);
199         vss_impl->Stop();
200       },
201       RTC_FROM_HERE);
202 }
203 
TEST_F(VideoSendStreamImplTest,UpdatesObserverOnConfigurationChange)204 TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
205   test_queue_.SendTask(
206       [this] {
207         const bool kSuspend = false;
208         config_.suspend_below_min_bitrate = kSuspend;
209         config_.rtp.extensions.emplace_back(
210             RtpExtension::kTransportSequenceNumberUri, 1);
211         auto vss_impl = CreateVideoSendStreamImpl(
212             kDefaultInitialBitrateBps, kDefaultBitratePriority,
213             VideoEncoderConfig::ContentType::kRealtimeVideo);
214         vss_impl->Start();
215 
216         // QVGA + VGA configuration matching defaults in
217         // media/engine/simulcast.cc.
218         VideoStream qvga_stream;
219         qvga_stream.width = 320;
220         qvga_stream.height = 180;
221         qvga_stream.max_framerate = 30;
222         qvga_stream.min_bitrate_bps = 30000;
223         qvga_stream.target_bitrate_bps = 150000;
224         qvga_stream.max_bitrate_bps = 200000;
225         qvga_stream.max_qp = 56;
226         qvga_stream.bitrate_priority = 1;
227 
228         VideoStream vga_stream;
229         vga_stream.width = 640;
230         vga_stream.height = 360;
231         vga_stream.max_framerate = 30;
232         vga_stream.min_bitrate_bps = 150000;
233         vga_stream.target_bitrate_bps = 500000;
234         vga_stream.max_bitrate_bps = 700000;
235         vga_stream.max_qp = 56;
236         vga_stream.bitrate_priority = 1;
237 
238         int min_transmit_bitrate_bps = 30000;
239 
240         config_.rtp.ssrcs.emplace_back(1);
241         config_.rtp.ssrcs.emplace_back(2);
242 
243         EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
244             .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
245                                        MediaStreamAllocationConfig config) {
246               EXPECT_EQ(config.min_bitrate_bps,
247                         static_cast<uint32_t>(min_transmit_bitrate_bps));
248               EXPECT_EQ(config.max_bitrate_bps,
249                         static_cast<uint32_t>(qvga_stream.max_bitrate_bps +
250                                               vga_stream.max_bitrate_bps));
251               if (config.pad_up_bitrate_bps != 0) {
252                 EXPECT_EQ(config.pad_up_bitrate_bps,
253                           static_cast<uint32_t>(qvga_stream.target_bitrate_bps +
254                                                 vga_stream.min_bitrate_bps));
255               }
256               EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
257             }));
258 
259         static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
260             ->OnEncoderConfigurationChanged(
261                 std::vector<VideoStream>{qvga_stream, vga_stream}, false,
262                 VideoEncoderConfig::ContentType::kRealtimeVideo,
263                 min_transmit_bitrate_bps);
264         vss_impl->Stop();
265       },
266       RTC_FROM_HERE);
267 }
268 
TEST_F(VideoSendStreamImplTest,UpdatesObserverOnConfigurationChangeWithAlr)269 TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
270   test_queue_.SendTask(
271       [this] {
272         const bool kSuspend = false;
273         config_.suspend_below_min_bitrate = kSuspend;
274         config_.rtp.extensions.emplace_back(
275             RtpExtension::kTransportSequenceNumberUri, 1);
276         config_.periodic_alr_bandwidth_probing = true;
277         auto vss_impl = CreateVideoSendStreamImpl(
278             kDefaultInitialBitrateBps, kDefaultBitratePriority,
279             VideoEncoderConfig::ContentType::kScreen);
280         vss_impl->Start();
281 
282         // Simulcast screenshare.
283         VideoStream low_stream;
284         low_stream.width = 1920;
285         low_stream.height = 1080;
286         low_stream.max_framerate = 5;
287         low_stream.min_bitrate_bps = 30000;
288         low_stream.target_bitrate_bps = 200000;
289         low_stream.max_bitrate_bps = 1000000;
290         low_stream.num_temporal_layers = 2;
291         low_stream.max_qp = 56;
292         low_stream.bitrate_priority = 1;
293 
294         VideoStream high_stream;
295         high_stream.width = 1920;
296         high_stream.height = 1080;
297         high_stream.max_framerate = 30;
298         high_stream.min_bitrate_bps = 60000;
299         high_stream.target_bitrate_bps = 1250000;
300         high_stream.max_bitrate_bps = 1250000;
301         high_stream.num_temporal_layers = 2;
302         high_stream.max_qp = 56;
303         high_stream.bitrate_priority = 1;
304 
305         // With ALR probing, this will be the padding target instead of
306         // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps.
307         int min_transmit_bitrate_bps = 400000;
308 
309         config_.rtp.ssrcs.emplace_back(1);
310         config_.rtp.ssrcs.emplace_back(2);
311 
312         EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
313             .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
314                                        MediaStreamAllocationConfig config) {
315               EXPECT_EQ(config.min_bitrate_bps,
316                         static_cast<uint32_t>(low_stream.min_bitrate_bps));
317               EXPECT_EQ(config.max_bitrate_bps,
318                         static_cast<uint32_t>(low_stream.max_bitrate_bps +
319                                               high_stream.max_bitrate_bps));
320               if (config.pad_up_bitrate_bps != 0) {
321                 EXPECT_EQ(config.pad_up_bitrate_bps,
322                           static_cast<uint32_t>(min_transmit_bitrate_bps));
323               }
324               EXPECT_EQ(config.enforce_min_bitrate, !kSuspend);
325             }));
326 
327         static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
328             ->OnEncoderConfigurationChanged(
329                 std::vector<VideoStream>{low_stream, high_stream}, false,
330                 VideoEncoderConfig::ContentType::kScreen,
331                 min_transmit_bitrate_bps);
332         vss_impl->Stop();
333       },
334       RTC_FROM_HERE);
335 }
336 
TEST_F(VideoSendStreamImplTest,UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis)337 TEST_F(VideoSendStreamImplTest,
338        UpdatesObserverOnConfigurationChangeWithSimulcastVideoHysteresis) {
339   test::ScopedFieldTrials hysteresis_experiment(
340       "WebRTC-VideoRateControl/video_hysteresis:1.25/");
341 
342   test_queue_.SendTask(
343       [this] {
344         auto vss_impl = CreateVideoSendStreamImpl(
345             kDefaultInitialBitrateBps, kDefaultBitratePriority,
346             VideoEncoderConfig::ContentType::kRealtimeVideo);
347         vss_impl->Start();
348 
349         // 2-layer video simulcast.
350         VideoStream low_stream;
351         low_stream.width = 320;
352         low_stream.height = 240;
353         low_stream.max_framerate = 30;
354         low_stream.min_bitrate_bps = 30000;
355         low_stream.target_bitrate_bps = 100000;
356         low_stream.max_bitrate_bps = 200000;
357         low_stream.max_qp = 56;
358         low_stream.bitrate_priority = 1;
359 
360         VideoStream high_stream;
361         high_stream.width = 640;
362         high_stream.height = 480;
363         high_stream.max_framerate = 30;
364         high_stream.min_bitrate_bps = 150000;
365         high_stream.target_bitrate_bps = 500000;
366         high_stream.max_bitrate_bps = 750000;
367         high_stream.max_qp = 56;
368         high_stream.bitrate_priority = 1;
369 
370         config_.rtp.ssrcs.emplace_back(1);
371         config_.rtp.ssrcs.emplace_back(2);
372 
373         EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
374             .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
375                                        MediaStreamAllocationConfig config) {
376               EXPECT_EQ(config.min_bitrate_bps,
377                         static_cast<uint32_t>(low_stream.min_bitrate_bps));
378               EXPECT_EQ(config.max_bitrate_bps,
379                         static_cast<uint32_t>(low_stream.max_bitrate_bps +
380                                               high_stream.max_bitrate_bps));
381               if (config.pad_up_bitrate_bps != 0) {
382                 EXPECT_EQ(
383                     config.pad_up_bitrate_bps,
384                     static_cast<uint32_t>(low_stream.target_bitrate_bps +
385                                           1.25 * high_stream.min_bitrate_bps));
386               }
387             }));
388 
389         static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
390             ->OnEncoderConfigurationChanged(
391                 std::vector<VideoStream>{low_stream, high_stream}, false,
392                 VideoEncoderConfig::ContentType::kRealtimeVideo,
393                 /*min_transmit_bitrate_bps=*/0);
394         vss_impl->Stop();
395       },
396       RTC_FROM_HERE);
397 }
398 
TEST_F(VideoSendStreamImplTest,SetsScreensharePacingFactorWithFeedback)399 TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
400   test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
401 
402   test_queue_.SendTask(
403       [this] {
404         constexpr int kId = 1;
405         config_.rtp.extensions.emplace_back(
406             RtpExtension::kTransportSequenceNumberUri, kId);
407         EXPECT_CALL(transport_controller_,
408                     SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
409             .Times(1);
410         auto vss_impl = CreateVideoSendStreamImpl(
411             kDefaultInitialBitrateBps, kDefaultBitratePriority,
412             VideoEncoderConfig::ContentType::kScreen);
413         vss_impl->Start();
414         vss_impl->Stop();
415       },
416       RTC_FROM_HERE);
417 }
418 
TEST_F(VideoSendStreamImplTest,DoesNotSetPacingFactorWithoutFeedback)419 TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
420   test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
421   test_queue_.SendTask(
422       [this] {
423         EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
424         auto vss_impl = CreateVideoSendStreamImpl(
425             kDefaultInitialBitrateBps, kDefaultBitratePriority,
426             VideoEncoderConfig::ContentType::kScreen);
427         vss_impl->Start();
428         vss_impl->Stop();
429       },
430       RTC_FROM_HERE);
431 }
432 
TEST_F(VideoSendStreamImplTest,ForwardsVideoBitrateAllocationWhenEnabled)433 TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
434   test_queue_.SendTask(
435       [this] {
436         EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
437         auto vss_impl = CreateVideoSendStreamImpl(
438             kDefaultInitialBitrateBps, kDefaultBitratePriority,
439             VideoEncoderConfig::ContentType::kScreen);
440         vss_impl->Start();
441         VideoBitrateAllocationObserver* const observer =
442             static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
443 
444         // Populate a test instance of video bitrate allocation.
445         VideoBitrateAllocation alloc;
446         alloc.SetBitrate(0, 0, 10000);
447         alloc.SetBitrate(0, 1, 20000);
448         alloc.SetBitrate(1, 0, 30000);
449         alloc.SetBitrate(1, 1, 40000);
450 
451         // Encoder starts out paused, don't forward allocation.
452         EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
453             .Times(0);
454         observer->OnBitrateAllocationUpdated(alloc);
455 
456         // Unpause encoder, allocation should be passed through.
457         const uint32_t kBitrateBps = 100000;
458         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
459             .Times(1)
460             .WillOnce(Return(kBitrateBps));
461         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
462             ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
463         EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
464             .Times(1);
465         observer->OnBitrateAllocationUpdated(alloc);
466 
467         // Pause encoder again, and block allocations.
468         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
469             .Times(1)
470             .WillOnce(Return(0));
471         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
472             ->OnBitrateUpdated(CreateAllocation(0));
473         EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
474             .Times(0);
475         observer->OnBitrateAllocationUpdated(alloc);
476 
477         vss_impl->Stop();
478       },
479       RTC_FROM_HERE);
480 }
481 
TEST_F(VideoSendStreamImplTest,ThrottlesVideoBitrateAllocationWhenTooSimilar)482 TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
483   test_queue_.SendTask(
484       [this] {
485         auto vss_impl = CreateVideoSendStreamImpl(
486             kDefaultInitialBitrateBps, kDefaultBitratePriority,
487             VideoEncoderConfig::ContentType::kScreen);
488         vss_impl->Start();
489         // Unpause encoder, to allows allocations to be passed through.
490         const uint32_t kBitrateBps = 100000;
491         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
492             .Times(1)
493             .WillOnce(Return(kBitrateBps));
494         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
495             ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
496         VideoBitrateAllocationObserver* const observer =
497             static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
498 
499         // Populate a test instance of video bitrate allocation.
500         VideoBitrateAllocation alloc;
501         alloc.SetBitrate(0, 0, 10000);
502         alloc.SetBitrate(0, 1, 20000);
503         alloc.SetBitrate(1, 0, 30000);
504         alloc.SetBitrate(1, 1, 40000);
505 
506         // Initial value.
507         EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
508             .Times(1);
509         observer->OnBitrateAllocationUpdated(alloc);
510 
511         VideoBitrateAllocation updated_alloc = alloc;
512         // Needs 10% increase in bitrate to trigger immediate forward.
513         const uint32_t base_layer_min_update_bitrate_bps =
514             alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10;
515 
516         // Too small increase, don't forward.
517         updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
518         EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
519         observer->OnBitrateAllocationUpdated(updated_alloc);
520 
521         // Large enough increase, do forward.
522         updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
523         EXPECT_CALL(rtp_video_sender_,
524                     OnBitrateAllocationUpdated(updated_alloc))
525             .Times(1);
526         observer->OnBitrateAllocationUpdated(updated_alloc);
527 
528         // This is now a decrease compared to last forward allocation, forward
529         // immediately.
530         updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
531         EXPECT_CALL(rtp_video_sender_,
532                     OnBitrateAllocationUpdated(updated_alloc))
533             .Times(1);
534         observer->OnBitrateAllocationUpdated(updated_alloc);
535 
536         vss_impl->Stop();
537       },
538       RTC_FROM_HERE);
539 }
540 
TEST_F(VideoSendStreamImplTest,ForwardsVideoBitrateAllocationOnLayerChange)541 TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
542   test_queue_.SendTask(
543       [this] {
544         auto vss_impl = CreateVideoSendStreamImpl(
545             kDefaultInitialBitrateBps, kDefaultBitratePriority,
546             VideoEncoderConfig::ContentType::kScreen);
547         vss_impl->Start();
548         // Unpause encoder, to allows allocations to be passed through.
549         const uint32_t kBitrateBps = 100000;
550         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
551             .Times(1)
552             .WillOnce(Return(kBitrateBps));
553         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
554             ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
555         VideoBitrateAllocationObserver* const observer =
556             static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
557 
558         // Populate a test instance of video bitrate allocation.
559         VideoBitrateAllocation alloc;
560         alloc.SetBitrate(0, 0, 10000);
561         alloc.SetBitrate(0, 1, 20000);
562         alloc.SetBitrate(1, 0, 30000);
563         alloc.SetBitrate(1, 1, 40000);
564 
565         // Initial value.
566         EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
567             .Times(1);
568         observer->OnBitrateAllocationUpdated(alloc);
569 
570         // Move some bitrate from one layer to a new one, but keep sum the same.
571         // Since layout has changed, immediately trigger forward.
572         VideoBitrateAllocation updated_alloc = alloc;
573         updated_alloc.SetBitrate(2, 0, 10000);
574         updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
575         EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
576         EXPECT_CALL(rtp_video_sender_,
577                     OnBitrateAllocationUpdated(updated_alloc))
578             .Times(1);
579         observer->OnBitrateAllocationUpdated(updated_alloc);
580 
581         vss_impl->Stop();
582       },
583       RTC_FROM_HERE);
584 }
585 
TEST_F(VideoSendStreamImplTest,ForwardsVideoBitrateAllocationAfterTimeout)586 TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
587   test_queue_.SendTask(
588       [this] {
589         auto vss_impl = CreateVideoSendStreamImpl(
590             kDefaultInitialBitrateBps, kDefaultBitratePriority,
591             VideoEncoderConfig::ContentType::kScreen);
592         vss_impl->Start();
593         const uint32_t kBitrateBps = 100000;
594         // Unpause encoder, to allows allocations to be passed through.
595         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
596             .Times(1)
597             .WillRepeatedly(Return(kBitrateBps));
598         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
599             ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
600         VideoBitrateAllocationObserver* const observer =
601             static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
602 
603         // Populate a test instance of video bitrate allocation.
604         VideoBitrateAllocation alloc;
605         alloc.SetBitrate(0, 0, 10000);
606         alloc.SetBitrate(0, 1, 20000);
607         alloc.SetBitrate(1, 0, 30000);
608         alloc.SetBitrate(1, 1, 40000);
609 
610         EncodedImage encoded_image;
611         CodecSpecificInfo codec_specific;
612         EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
613             .WillRepeatedly(Return(EncodedImageCallback::Result(
614                 EncodedImageCallback::Result::OK)));
615 
616         // Max time we will throttle similar video bitrate allocations.
617         static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
618 
619         {
620           // Initial value.
621           EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
622               .Times(1);
623           observer->OnBitrateAllocationUpdated(alloc);
624         }
625 
626         {
627           // Sending same allocation again, this one should be throttled.
628           EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
629               .Times(0);
630           observer->OnBitrateAllocationUpdated(alloc);
631         }
632 
633         clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
634 
635         {
636           // Sending similar allocation again after timeout, should forward.
637           EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
638               .Times(1);
639           observer->OnBitrateAllocationUpdated(alloc);
640         }
641 
642         {
643           // Sending similar allocation again without timeout, throttle.
644           EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
645               .Times(0);
646           observer->OnBitrateAllocationUpdated(alloc);
647         }
648 
649         {
650           // Send encoded image, should be a noop.
651           EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
652               .Times(0);
653           static_cast<EncodedImageCallback*>(vss_impl.get())
654               ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
655         }
656 
657         {
658           // Advance time and send encoded image, this should wake up and send
659           // cached bitrate allocation.
660           clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
661           EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
662               .Times(1);
663           static_cast<EncodedImageCallback*>(vss_impl.get())
664               ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
665         }
666 
667         {
668           // Advance time and send encoded image, there should be no cached
669           // allocation to send.
670           clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000);
671           EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
672               .Times(0);
673           static_cast<EncodedImageCallback*>(vss_impl.get())
674               ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
675         }
676 
677         vss_impl->Stop();
678       },
679       RTC_FROM_HERE);
680 }
681 
TEST_F(VideoSendStreamImplTest,CallsVideoStreamEncoderOnBitrateUpdate)682 TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
683   test_queue_.SendTask(
684       [this] {
685         const bool kSuspend = false;
686         config_.suspend_below_min_bitrate = kSuspend;
687         config_.rtp.extensions.emplace_back(
688             RtpExtension::kTransportSequenceNumberUri, 1);
689         auto vss_impl = CreateVideoSendStreamImpl(
690             kDefaultInitialBitrateBps, kDefaultBitratePriority,
691             VideoEncoderConfig::ContentType::kRealtimeVideo);
692         vss_impl->Start();
693 
694         VideoStream qvga_stream;
695         qvga_stream.width = 320;
696         qvga_stream.height = 180;
697         qvga_stream.max_framerate = 30;
698         qvga_stream.min_bitrate_bps = 30000;
699         qvga_stream.target_bitrate_bps = 150000;
700         qvga_stream.max_bitrate_bps = 200000;
701         qvga_stream.max_qp = 56;
702         qvga_stream.bitrate_priority = 1;
703 
704         int min_transmit_bitrate_bps = 30000;
705 
706         config_.rtp.ssrcs.emplace_back(1);
707 
708         static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
709             ->OnEncoderConfigurationChanged(
710                 std::vector<VideoStream>{qvga_stream}, false,
711                 VideoEncoderConfig::ContentType::kRealtimeVideo,
712                 min_transmit_bitrate_bps);
713 
714         const DataRate network_constrained_rate =
715             DataRate::BitsPerSec(qvga_stream.target_bitrate_bps);
716         BitrateAllocationUpdate update;
717         update.target_bitrate = network_constrained_rate;
718         update.stable_target_bitrate = network_constrained_rate;
719         update.round_trip_time = TimeDelta::Millis(1);
720         EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
721         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
722             .WillOnce(Return(network_constrained_rate.bps()));
723         EXPECT_CALL(
724             video_stream_encoder_,
725             OnBitrateUpdated(network_constrained_rate, network_constrained_rate,
726                              network_constrained_rate, 0, _, 0));
727         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
728             ->OnBitrateUpdated(update);
729 
730         // Test allocation where the link allocation is larger than the target,
731         // meaning we have some headroom on the link.
732         const DataRate qvga_max_bitrate =
733             DataRate::BitsPerSec(qvga_stream.max_bitrate_bps);
734         const DataRate headroom = DataRate::BitsPerSec(50000);
735         const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
736         update.target_bitrate = rate_with_headroom;
737         update.stable_target_bitrate = rate_with_headroom;
738         EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
739         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
740             .WillOnce(Return(rate_with_headroom.bps()));
741         EXPECT_CALL(video_stream_encoder_,
742                     OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
743                                      rate_with_headroom, 0, _, 0));
744         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
745             ->OnBitrateUpdated(update);
746 
747         // Add protection bitrate to the mix, this should be subtracted from the
748         // headroom.
749         const uint32_t protection_bitrate_bps = 10000;
750         EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
751             .WillOnce(Return(protection_bitrate_bps));
752 
753         EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
754         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
755             .WillOnce(Return(rate_with_headroom.bps()));
756         const DataRate headroom_minus_protection =
757             rate_with_headroom - DataRate::BitsPerSec(protection_bitrate_bps);
758         EXPECT_CALL(video_stream_encoder_,
759                     OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
760                                      headroom_minus_protection, 0, _, 0));
761         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
762             ->OnBitrateUpdated(update);
763 
764         // Protection bitrate exceeds head room, link allocation should be
765         // capped to target bitrate.
766         EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
767             .WillOnce(Return(headroom.bps() + 1000));
768         EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _));
769         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
770             .WillOnce(Return(rate_with_headroom.bps()));
771         EXPECT_CALL(video_stream_encoder_,
772                     OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate,
773                                      qvga_max_bitrate, 0, _, 0));
774         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
775             ->OnBitrateUpdated(update);
776 
777         // Set rates to zero on stop.
778         EXPECT_CALL(video_stream_encoder_,
779                     OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(),
780                                      DataRate::Zero(), 0, 0, 0));
781         vss_impl->Stop();
782       },
783       RTC_FROM_HERE);
784 }
785 
TEST_F(VideoSendStreamImplTest,DisablesPaddingOnPausedEncoder)786 TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
787   int padding_bitrate = 0;
788   std::unique_ptr<VideoSendStreamImpl> vss_impl;
789 
790   test_queue_.SendTask(
791       [&] {
792         vss_impl = CreateVideoSendStreamImpl(
793             kDefaultInitialBitrateBps, kDefaultBitratePriority,
794             VideoEncoderConfig::ContentType::kRealtimeVideo);
795 
796         // Capture padding bitrate for testing.
797         EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
798             .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
799                                        MediaStreamAllocationConfig config) {
800               padding_bitrate = config.pad_up_bitrate_bps;
801             }));
802         // If observer is removed, no padding will be sent.
803         EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
804             .WillRepeatedly(Invoke(
805                 [&](BitrateAllocatorObserver*) { padding_bitrate = 0; }));
806 
807         EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
808             .WillRepeatedly(Return(EncodedImageCallback::Result(
809                 EncodedImageCallback::Result::OK)));
810         const bool kSuspend = false;
811         config_.suspend_below_min_bitrate = kSuspend;
812         config_.rtp.extensions.emplace_back(
813             RtpExtension::kTransportSequenceNumberUri, 1);
814         VideoStream qvga_stream;
815         qvga_stream.width = 320;
816         qvga_stream.height = 180;
817         qvga_stream.max_framerate = 30;
818         qvga_stream.min_bitrate_bps = 30000;
819         qvga_stream.target_bitrate_bps = 150000;
820         qvga_stream.max_bitrate_bps = 200000;
821         qvga_stream.max_qp = 56;
822         qvga_stream.bitrate_priority = 1;
823 
824         int min_transmit_bitrate_bps = 30000;
825 
826         config_.rtp.ssrcs.emplace_back(1);
827 
828         vss_impl->Start();
829 
830         // Starts without padding.
831         EXPECT_EQ(0, padding_bitrate);
832 
833         // Reconfigure e.g. due to a fake frame.
834         static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
835             ->OnEncoderConfigurationChanged(
836                 std::vector<VideoStream>{qvga_stream}, false,
837                 VideoEncoderConfig::ContentType::kRealtimeVideo,
838                 min_transmit_bitrate_bps);
839         // Still no padding because no actual frames were passed, only
840         // reconfiguration happened.
841         EXPECT_EQ(0, padding_bitrate);
842 
843         // Unpause encoder.
844         const uint32_t kBitrateBps = 100000;
845         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
846             .Times(1)
847             .WillOnce(Return(kBitrateBps));
848         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
849             ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
850 
851         // A frame is encoded.
852         EncodedImage encoded_image;
853         CodecSpecificInfo codec_specific;
854         static_cast<EncodedImageCallback*>(vss_impl.get())
855             ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
856         // Only after actual frame is encoded are we enabling the padding.
857         EXPECT_GT(padding_bitrate, 0);
858       },
859       RTC_FROM_HERE);
860 
861   rtc::Event done;
862   test_queue_.PostDelayedTask(
863       [&] {
864         // No padding supposed to be sent for paused observer
865         EXPECT_EQ(0, padding_bitrate);
866         testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
867         vss_impl->Stop();
868         vss_impl.reset();
869         done.Set();
870       },
871       5000);
872 
873   // Pause the test suite so that the last delayed task executes.
874   ASSERT_TRUE(done.Wait(10000));
875 }
876 
TEST_F(VideoSendStreamImplTest,KeepAliveOnDroppedFrame)877 TEST_F(VideoSendStreamImplTest, KeepAliveOnDroppedFrame) {
878   std::unique_ptr<VideoSendStreamImpl> vss_impl;
879   test_queue_.SendTask(
880       [&] {
881         vss_impl = CreateVideoSendStreamImpl(
882             kDefaultInitialBitrateBps, kDefaultBitratePriority,
883             VideoEncoderConfig::ContentType::kRealtimeVideo);
884         vss_impl->Start();
885         const uint32_t kBitrateBps = 100000;
886         EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
887             .Times(1)
888             .WillOnce(Return(kBitrateBps));
889         static_cast<BitrateAllocatorObserver*>(vss_impl.get())
890             ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
891 
892         // Keep the stream from deallocating by dropping a frame.
893         static_cast<EncodedImageCallback*>(vss_impl.get())
894             ->OnDroppedFrame(
895                 EncodedImageCallback::DropReason::kDroppedByEncoder);
896         EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
897             .Times(0);
898       },
899       RTC_FROM_HERE);
900 
901   rtc::Event done;
902   test_queue_.PostDelayedTask(
903       [&] {
904         testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
905         vss_impl->Stop();
906         vss_impl.reset();
907         done.Set();
908       },
909       2000);
910   ASSERT_TRUE(done.Wait(5000));
911 }
912 
TEST_F(VideoSendStreamImplTest,ConfiguresBitratesForSvc)913 TEST_F(VideoSendStreamImplTest, ConfiguresBitratesForSvc) {
914   struct TestConfig {
915     bool screenshare = false;
916     bool alr = false;
917     int min_padding_bitrate_bps = 0;
918   };
919 
920   std::vector<TestConfig> test_variants;
921   for (bool screenshare : {false, true}) {
922     for (bool alr : {false, true}) {
923       for (int min_padding : {0, 400000}) {
924         test_variants.push_back({screenshare, alr, min_padding});
925       }
926     }
927   }
928 
929   for (const TestConfig& test_config : test_variants) {
930     test_queue_.SendTask(
931         [this, test_config] {
932           const bool kSuspend = false;
933           config_.suspend_below_min_bitrate = kSuspend;
934           config_.rtp.extensions.emplace_back(
935               RtpExtension::kTransportSequenceNumberUri, 1);
936           config_.periodic_alr_bandwidth_probing = test_config.alr;
937           auto vss_impl = CreateVideoSendStreamImpl(
938               kDefaultInitialBitrateBps, kDefaultBitratePriority,
939               test_config.screenshare
940                   ? VideoEncoderConfig::ContentType::kScreen
941                   : VideoEncoderConfig::ContentType::kRealtimeVideo);
942           vss_impl->Start();
943 
944           // Svc
945           VideoStream stream;
946           stream.width = 1920;
947           stream.height = 1080;
948           stream.max_framerate = 30;
949           stream.min_bitrate_bps = 60000;
950           stream.target_bitrate_bps = 6000000;
951           stream.max_bitrate_bps = 1250000;
952           stream.num_temporal_layers = 2;
953           stream.max_qp = 56;
954           stream.bitrate_priority = 1;
955 
956           config_.rtp.ssrcs.emplace_back(1);
957           config_.rtp.ssrcs.emplace_back(2);
958 
959           EXPECT_CALL(
960               bitrate_allocator_,
961               AddObserver(
962                   vss_impl.get(),
963                   AllOf(Field(&MediaStreamAllocationConfig::min_bitrate_bps,
964                               static_cast<uint32_t>(stream.min_bitrate_bps)),
965                         Field(&MediaStreamAllocationConfig::max_bitrate_bps,
966                               static_cast<uint32_t>(stream.max_bitrate_bps)),
967                         // Stream not yet active - no padding.
968                         Field(&MediaStreamAllocationConfig::pad_up_bitrate_bps,
969                               0u),
970                         Field(&MediaStreamAllocationConfig::enforce_min_bitrate,
971                               !kSuspend))));
972 
973           static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
974               ->OnEncoderConfigurationChanged(
975                   std::vector<VideoStream>{stream}, true,
976                   test_config.screenshare
977                       ? VideoEncoderConfig::ContentType::kScreen
978                       : VideoEncoderConfig::ContentType::kRealtimeVideo,
979                   test_config.min_padding_bitrate_bps);
980           ::testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
981 
982           // Simulate an encoded image, this will turn the stream active and
983           // enable padding.
984           EncodedImage encoded_image;
985           CodecSpecificInfo codec_specific;
986           EXPECT_CALL(rtp_video_sender_, OnEncodedImage)
987               .WillRepeatedly(Return(EncodedImageCallback::Result(
988                   EncodedImageCallback::Result::OK)));
989 
990           // Screensharing implicitly forces ALR.
991           const bool using_alr = test_config.alr || test_config.screenshare;
992           // If ALR is used, pads only to min bitrate as rampup is handled by
993           // probing. Otherwise target_bitrate contains the padding target.
994           int expected_padding =
995               using_alr ? stream.min_bitrate_bps : stream.target_bitrate_bps;
996           // Min padding bitrate may override padding target.
997           expected_padding =
998               std::max(expected_padding, test_config.min_padding_bitrate_bps);
999           EXPECT_CALL(
1000               bitrate_allocator_,
1001               AddObserver(
1002                   vss_impl.get(),
1003                   AllOf(Field(&MediaStreamAllocationConfig::min_bitrate_bps,
1004                               static_cast<uint32_t>(stream.min_bitrate_bps)),
1005                         Field(&MediaStreamAllocationConfig::max_bitrate_bps,
1006                               static_cast<uint32_t>(stream.max_bitrate_bps)),
1007                         // Stream now active - min bitrate use as padding target
1008                         // when ALR is active.
1009                         Field(&MediaStreamAllocationConfig::pad_up_bitrate_bps,
1010                               expected_padding),
1011                         Field(&MediaStreamAllocationConfig::enforce_min_bitrate,
1012                               !kSuspend))));
1013           static_cast<EncodedImageCallback*>(vss_impl.get())
1014               ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
1015           ::testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
1016 
1017           vss_impl->Stop();
1018         },
1019         RTC_FROM_HERE);
1020   }
1021 }
1022 }  // namespace internal
1023 }  // namespace webrtc
1024