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