blob: 721738393ba11c4f023c4deea64631e6a7549e85 [file] [log] [blame]
Sebastian Janssonc5017132018-02-02 15:24:161/*
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
Mirko Bonadei317a1f02019-09-17 15:06:1811#include <memory>
12
Danil Chapovalov44db4362019-09-30 02:16:2813#include "api/task_queue/task_queue_base.h"
Artem Titov46c4e602018-08-17 12:26:5414#include "api/test/simulated_network.h"
Jiawei Ouc2ebe212018-11-08 18:02:5615#include "api/video/builtin_video_bitrate_allocator_factory.h"
Erik Språngf93eda12019-01-16 16:10:5716#include "api/video/video_bitrate_allocation.h"
Artem Titov4e199e92018-08-20 11:30:3917#include "call/fake_network_pipe.h"
18#include "call/simulated_network.h"
Tomas Gunnarssonfae05622020-06-03 06:54:3919#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
Sebastian Janssonc5017132018-02-02 15:24:1620#include "rtc_base/rate_limiter.h"
Markus Handell9bbff072020-07-07 12:23:1821#include "rtc_base/synchronization/mutex.h"
Danil Chapovalov82a3f0a2019-10-21 07:24:2722#include "rtc_base/task_queue_for_test.h"
Danil Chapovalov85a10002019-10-21 13:00:5323#include "rtc_base/task_utils/to_queued_task.h"
Sebastian Janssonc5017132018-02-02 15:24:1624#include "system_wrappers/include/sleep.h"
25#include "test/call_test.h"
Niels Möller4db138e2018-04-19 07:04:1326#include "test/fake_encoder.h"
Sebastian Janssonc5017132018-02-02 15:24:1627#include "test/field_trial.h"
28#include "test/gtest.h"
29#include "test/rtcp_packet_parser.h"
30#include "test/rtp_rtcp_observer.h"
Niels Möllercbcbc222018-09-28 07:07:2431#include "test/video_encoder_proxy_factory.h"
Sebastian Janssonc5017132018-02-02 15:24:1632
33namespace webrtc {
Elad Alond8d32482019-02-18 22:45:5734namespace {
35enum : int { // The first valid value is 1.
36 kAbsSendTimeExtensionId = 1,
Erik Språng8d65e9a2019-10-30 15:48:2837 kTransportSequenceNumberId,
Elad Alond8d32482019-02-18 22:45:5738};
39} // namespace
Sebastian Janssonc5017132018-02-02 15:24:1640
Ilya Nikolaevskiycb960622018-09-04 09:07:3141class BandwidthEndToEndTest : public test::CallTest {
Sebastian Janssonc5017132018-02-02 15:24:1642 public:
Ilya Nikolaevskiycb960622018-09-04 09:07:3143 BandwidthEndToEndTest() = default;
Sebastian Janssonc5017132018-02-02 15:24:1644};
45
Ilya Nikolaevskiycb960622018-09-04 09:07:3146TEST_F(BandwidthEndToEndTest, ReceiveStreamSendsRemb) {
Sebastian Janssonc5017132018-02-02 15:24:1647 class RembObserver : public test::EndToEndTest {
48 public:
49 RembObserver() : EndToEndTest(kDefaultTimeoutMs) {}
50
51 void ModifyVideoConfigs(
52 VideoSendStream::Config* send_config,
53 std::vector<VideoReceiveStream::Config>* receive_configs,
54 VideoEncoderConfig* encoder_config) override {
55 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 22:45:5756 send_config->rtp.extensions.push_back(
57 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Sebastian Janssonc5017132018-02-02 15:24:1658 (*receive_configs)[0].rtp.transport_cc = false;
59 }
60
61 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
62 test::RtcpPacketParser parser;
63 EXPECT_TRUE(parser.Parse(packet, length));
64
65 if (parser.remb()->num_packets() > 0) {
66 EXPECT_EQ(kReceiverLocalVideoSsrc, parser.remb()->sender_ssrc());
67 EXPECT_LT(0U, parser.remb()->bitrate_bps());
68 EXPECT_EQ(1U, parser.remb()->ssrcs().size());
69 EXPECT_EQ(kVideoSendSsrcs[0], parser.remb()->ssrcs()[0]);
70 observation_complete_.Set();
71 }
72
73 return SEND_PACKET;
74 }
75 void PerformTest() override {
76 EXPECT_TRUE(Wait()) << "Timed out while waiting for a "
77 "receiver RTCP REMB packet to be "
78 "sent.";
79 }
80 } test;
81
82 RunBaseTest(&test);
83}
84
85class BandwidthStatsTest : public test::EndToEndTest {
86 public:
Danil Chapovalov85a10002019-10-21 13:00:5387 BandwidthStatsTest(bool send_side_bwe, TaskQueueBase* task_queue)
Sebastian Janssonc5017132018-02-02 15:24:1688 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
89 sender_call_(nullptr),
90 receiver_call_(nullptr),
91 has_seen_pacer_delay_(false),
Tommie80885a2019-08-05 13:08:1792 send_side_bwe_(send_side_bwe),
93 task_queue_(task_queue) {}
Sebastian Janssonc5017132018-02-02 15:24:1694
Danil Chapovalov2f2049a2019-11-06 12:28:1195 ~BandwidthStatsTest() override {
96 // Block until all already posted tasks run to avoid races when such task
97 // accesses |this|.
98 SendTask(RTC_FROM_HERE, task_queue_, [] {});
99 }
100
Sebastian Janssonc5017132018-02-02 15:24:16101 void ModifyVideoConfigs(
102 VideoSendStream::Config* send_config,
103 std::vector<VideoReceiveStream::Config>* receive_configs,
104 VideoEncoderConfig* encoder_config) override {
Erik Språng8d65e9a2019-10-30 15:48:28105 send_config->rtp.extensions.clear();
Sebastian Janssonc5017132018-02-02 15:24:16106 if (!send_side_bwe_) {
Elad Alond8d32482019-02-18 22:45:57107 send_config->rtp.extensions.push_back(
108 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Sebastian Janssonc5017132018-02-02 15:24:16109 (*receive_configs)[0].rtp.transport_cc = false;
Erik Språng8d65e9a2019-10-30 15:48:28110 } else {
111 send_config->rtp.extensions.push_back(
112 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
113 kTransportSequenceNumberId));
114 (*receive_configs)[0].rtp.transport_cc = true;
Sebastian Janssonc5017132018-02-02 15:24:16115 }
Erik Språng8d65e9a2019-10-30 15:48:28116
117 // Force a too high encoder bitrate to make sure we get pacer delay.
118 encoder_config->number_of_streams = 1;
119 encoder_config->max_bitrate_bps = kMaxBitrateBps * 2;
120 encoder_config->simulcast_layers[0].min_bitrate_bps = kMaxBitrateBps * 2;
121 encoder_config->simulcast_layers[0].target_bitrate_bps = kMaxBitrateBps * 2;
122 encoder_config->simulcast_layers[0].max_bitrate_bps = kMaxBitrateBps * 2;
123 }
124
125 void ModifySenderBitrateConfig(BitrateConstraints* bitrate_config) override {
126 bitrate_config->max_bitrate_bps = kMaxBitrateBps;
Sebastian Janssonc5017132018-02-02 15:24:16127 }
128
Tommie80885a2019-08-05 13:08:17129 // Called on the pacer thread.
Sebastian Janssonc5017132018-02-02 15:24:16130 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Tommie80885a2019-08-05 13:08:17131 // Stats need to be fetched on the thread where the caller objects were
132 // constructed.
Danil Chapovalov85a10002019-10-21 13:00:53133 task_queue_->PostTask(ToQueuedTask([this]() {
Erik Språng8d65e9a2019-10-30 15:48:28134 if (!sender_call_ || !receiver_call_) {
135 return;
136 }
137
Tommie80885a2019-08-05 13:08:17138 Call::Stats sender_stats = sender_call_->GetStats();
Erik Språng8d65e9a2019-10-30 15:48:28139 if (!has_seen_pacer_delay_) {
Tommie80885a2019-08-05 13:08:17140 has_seen_pacer_delay_ = sender_stats.pacer_delay_ms > 0;
Erik Språng8d65e9a2019-10-30 15:48:28141 }
Tommie80885a2019-08-05 13:08:17142
143 if (sender_stats.send_bandwidth_bps > 0 && has_seen_pacer_delay_) {
144 Call::Stats receiver_stats = receiver_call_->GetStats();
Erik Språng8d65e9a2019-10-30 15:48:28145 if (send_side_bwe_ || receiver_stats.recv_bandwidth_bps > 0) {
Tommie80885a2019-08-05 13:08:17146 observation_complete_.Set();
Erik Språng8d65e9a2019-10-30 15:48:28147 }
Tommie80885a2019-08-05 13:08:17148 }
Danil Chapovalov85a10002019-10-21 13:00:53149 }));
Tommie80885a2019-08-05 13:08:17150
Sebastian Janssonc5017132018-02-02 15:24:16151 return SEND_PACKET;
152 }
153
154 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
155 sender_call_ = sender_call;
156 receiver_call_ = receiver_call;
157 }
158
Erik Språng8d65e9a2019-10-30 15:48:28159 void OnStreamsStopped() override {
160 sender_call_ = nullptr;
161 receiver_call_ = nullptr;
162 }
163
Sebastian Janssonc5017132018-02-02 15:24:16164 void PerformTest() override {
165 EXPECT_TRUE(Wait()) << "Timed out while waiting for "
166 "non-zero bandwidth stats.";
167 }
168
169 private:
Erik Språng8d65e9a2019-10-30 15:48:28170 static const int kMaxBitrateBps = 3000000;
Sebastian Janssonc5017132018-02-02 15:24:16171 Call* sender_call_;
172 Call* receiver_call_;
173 bool has_seen_pacer_delay_;
174 const bool send_side_bwe_;
Danil Chapovalov85a10002019-10-21 13:00:53175 TaskQueueBase* const task_queue_;
Sebastian Janssonc5017132018-02-02 15:24:16176};
177
Ilya Nikolaevskiycb960622018-09-04 09:07:31178TEST_F(BandwidthEndToEndTest, VerifySendSideBweStats) {
Danil Chapovalovd15a0282019-10-22 08:48:17179 BandwidthStatsTest test(true, task_queue());
Sebastian Janssonc5017132018-02-02 15:24:16180 RunBaseTest(&test);
181}
182
Ilya Nikolaevskiycb960622018-09-04 09:07:31183TEST_F(BandwidthEndToEndTest, VerifyRecvSideBweStats) {
Danil Chapovalovd15a0282019-10-22 08:48:17184 BandwidthStatsTest test(false, task_queue());
Sebastian Janssonc5017132018-02-02 15:24:16185 RunBaseTest(&test);
186}
187
188// Verifies that it's possible to limit the send BWE by sending a REMB.
189// This is verified by allowing the send BWE to ramp-up to >1000 kbps,
190// then have the test generate a REMB of 500 kbps and verify that the send BWE
191// is reduced to exactly 500 kbps. Then a REMB of 1000 kbps is generated and the
192// test verifies that the send BWE ramps back up to exactly 1000 kbps.
Ilya Nikolaevskiycb960622018-09-04 09:07:31193TEST_F(BandwidthEndToEndTest, RembWithSendSideBwe) {
Sebastian Janssonc5017132018-02-02 15:24:16194 class BweObserver : public test::EndToEndTest {
195 public:
Danil Chapovalov85a10002019-10-21 13:00:53196 explicit BweObserver(TaskQueueBase* task_queue)
Sebastian Janssonc5017132018-02-02 15:24:16197 : EndToEndTest(kDefaultTimeoutMs),
198 sender_call_(nullptr),
199 clock_(Clock::GetRealTimeClock()),
200 sender_ssrc_(0),
201 remb_bitrate_bps_(1000000),
202 receive_transport_(nullptr),
Sebastian Janssonc5017132018-02-02 15:24:16203 state_(kWaitForFirstRampUp),
Tommie80885a2019-08-05 13:08:17204 retransmission_rate_limiter_(clock_, 1000),
205 task_queue_(task_queue) {}
Sebastian Janssonc5017132018-02-02 15:24:16206
Danil Chapovalov2f2049a2019-11-06 12:28:11207 ~BweObserver() override {
208 // Block until all already posted tasks run to avoid races when such task
Tommi3a5742c2020-05-20 07:32:51209 // accesses |this|. Also make sure we free |rtp_rtcp_| on the correct
210 // thread/task queue.
211 SendTask(RTC_FROM_HERE, task_queue_, [this]() { rtp_rtcp_ = nullptr; });
Danil Chapovalov2f2049a2019-11-06 12:28:11212 }
Sebastian Janssonc5017132018-02-02 15:24:16213
Danil Chapovalov44db4362019-09-30 02:16:28214 std::unique_ptr<test::PacketTransport> CreateReceiveTransport(
215 TaskQueueBase* task_queue) override {
216 auto receive_transport = std::make_unique<test::PacketTransport>(
Sebastian Janssonc5017132018-02-02 15:24:16217 task_queue, nullptr, this, test::PacketTransport::kReceiver,
Artem Titov4e199e92018-08-20 11:30:39218 payload_type_map_,
Mirko Bonadei317a1f02019-09-17 15:06:18219 std::make_unique<FakeNetworkPipe>(
220 Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
Artem Titov75e36472018-10-08 10:28:56221 BuiltInNetworkBehaviorConfig())));
Danil Chapovalov44db4362019-09-30 02:16:28222 receive_transport_ = receive_transport.get();
223 return receive_transport;
Sebastian Janssonc5017132018-02-02 15:24:16224 }
225
Niels Möllerde8e6e62018-11-13 14:10:33226 void ModifySenderBitrateConfig(
227 BitrateConstraints* bitrate_config) override {
Sebastian Janssonc5017132018-02-02 15:24:16228 // Set a high start bitrate to reduce the test completion time.
Niels Möllerde8e6e62018-11-13 14:10:33229 bitrate_config->start_bitrate_bps = remb_bitrate_bps_;
Sebastian Janssonc5017132018-02-02 15:24:16230 }
231
232 void ModifyVideoConfigs(
233 VideoSendStream::Config* send_config,
234 std::vector<VideoReceiveStream::Config>* receive_configs,
235 VideoEncoderConfig* encoder_config) override {
236 ASSERT_EQ(1u, send_config->rtp.ssrcs.size());
237 sender_ssrc_ = send_config->rtp.ssrcs[0];
238
239 encoder_config->max_bitrate_bps = 2000000;
240
241 ASSERT_EQ(1u, receive_configs->size());
Tomas Gunnarssonf25761d2020-06-03 20:55:33242 RtpRtcpInterface::Configuration config;
Sebastian Janssonc5017132018-02-02 15:24:16243 config.receiver_only = true;
244 config.clock = clock_;
245 config.outgoing_transport = receive_transport_;
246 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
Erik Språng54d5d2c2019-08-20 15:22:36247 config.local_media_ssrc = (*receive_configs)[0].rtp.local_ssrc;
Niels Moller2accc7d2021-01-12 15:54:16248 rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(config);
Sebastian Janssonc5017132018-02-02 15:24:16249 rtp_rtcp_->SetRemoteSSRC((*receive_configs)[0].rtp.remote_ssrc);
Sebastian Janssonc5017132018-02-02 15:24:16250 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
251 }
252
253 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommie80885a2019-08-05 13:08:17254 RTC_DCHECK(sender_call);
Sebastian Janssonc5017132018-02-02 15:24:16255 sender_call_ = sender_call;
Danil Chapovalov85a10002019-10-21 13:00:53256 task_queue_->PostTask(ToQueuedTask([this]() { PollStats(); }));
Sebastian Janssonc5017132018-02-02 15:24:16257 }
258
259 void PollStats() {
Tommie80885a2019-08-05 13:08:17260 Call::Stats stats = sender_call_->GetStats();
261 switch (state_) {
262 case kWaitForFirstRampUp:
263 if (stats.send_bandwidth_bps >= remb_bitrate_bps_) {
264 state_ = kWaitForRemb;
265 remb_bitrate_bps_ /= 2;
266 rtp_rtcp_->SetRemb(
267 remb_bitrate_bps_,
268 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
269 rtp_rtcp_->SendRTCP(kRtcpRr);
Sebastian Janssonc5017132018-02-02 15:24:16270 }
Tommie80885a2019-08-05 13:08:17271 break;
272
273 case kWaitForRemb:
274 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
275 state_ = kWaitForSecondRampUp;
276 remb_bitrate_bps_ *= 2;
277 rtp_rtcp_->SetRemb(
278 remb_bitrate_bps_,
279 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
280 rtp_rtcp_->SendRTCP(kRtcpRr);
281 }
282 break;
283
284 case kWaitForSecondRampUp:
285 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
286 observation_complete_.Set();
287 return;
288 }
289 break;
290 }
291
Danil Chapovalov85a10002019-10-21 13:00:53292 task_queue_->PostDelayedTask(ToQueuedTask([this] { PollStats(); }), 1000);
Sebastian Janssonc5017132018-02-02 15:24:16293 }
294
295 void PerformTest() override {
Sebastian Janssonc5017132018-02-02 15:24:16296 EXPECT_TRUE(Wait())
297 << "Timed out while waiting for bitrate to change according to REMB.";
Sebastian Janssonc5017132018-02-02 15:24:16298 }
299
300 private:
301 enum TestState { kWaitForFirstRampUp, kWaitForRemb, kWaitForSecondRampUp };
302
303 Call* sender_call_;
304 Clock* const clock_;
305 uint32_t sender_ssrc_;
306 int remb_bitrate_bps_;
Tomas Gunnarssonf25761d2020-06-03 20:55:33307 std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_;
Sebastian Janssonc5017132018-02-02 15:24:16308 test::PacketTransport* receive_transport_;
Sebastian Janssonc5017132018-02-02 15:24:16309 TestState state_;
310 RateLimiter retransmission_rate_limiter_;
Danil Chapovalov85a10002019-10-21 13:00:53311 TaskQueueBase* const task_queue_;
Danil Chapovalovd15a0282019-10-22 08:48:17312 } test(task_queue());
Sebastian Janssonc5017132018-02-02 15:24:16313
314 RunBaseTest(&test);
315}
316
Ilya Nikolaevskiycb960622018-09-04 09:07:31317TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) {
Erik Språng7ca375c2019-02-06 15:20:17318 // If these fields trial are on, we get lower bitrates than expected by this
319 // test, due to the packetization overhead and encoder pushback.
320 webrtc::test::ScopedFieldTrials field_trials(
321 std::string(field_trial::GetFieldTrialString()) +
Erik Språng7ca375c2019-02-06 15:20:17322 "WebRTC-VideoRateControl/bitrate_adjuster:false/");
Sebastian Janssonc5017132018-02-02 15:24:16323 class EncoderRateStatsTest : public test::EndToEndTest,
324 public test::FakeEncoder {
325 public:
Danil Chapovalov85a10002019-10-21 13:00:53326 explicit EncoderRateStatsTest(TaskQueueBase* task_queue)
Sebastian Janssonc5017132018-02-02 15:24:16327 : EndToEndTest(kDefaultTimeoutMs),
328 FakeEncoder(Clock::GetRealTimeClock()),
329 task_queue_(task_queue),
330 send_stream_(nullptr),
Niels Möller4db138e2018-04-19 07:04:13331 encoder_factory_(this),
Jiawei Ouc2ebe212018-11-08 18:02:56332 bitrate_allocator_factory_(
333 CreateBuiltinVideoBitrateAllocatorFactory()),
Sebastian Janssonc5017132018-02-02 15:24:16334 bitrate_kbps_(0) {}
335
336 void OnVideoStreamsCreated(
337 VideoSendStream* send_stream,
338 const std::vector<VideoReceiveStream*>& receive_streams) override {
339 send_stream_ = send_stream;
340 }
341
342 void ModifyVideoConfigs(
343 VideoSendStream::Config* send_config,
344 std::vector<VideoReceiveStream::Config>* receive_configs,
345 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 07:04:13346 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Jiawei Ouc2ebe212018-11-08 18:02:56347 send_config->encoder_settings.bitrate_allocator_factory =
348 bitrate_allocator_factory_.get();
Sebastian Janssonc5017132018-02-02 15:24:16349 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
350 }
351
Erik Språng16cb8f52019-04-12 11:59:09352 void SetRates(const RateControlParameters& parameters) override {
Sebastian Janssonc5017132018-02-02 15:24:16353 // Make sure not to trigger on any default zero bitrates.
Erik Språng16cb8f52019-04-12 11:59:09354 if (parameters.bitrate.get_sum_bps() == 0)
355 return;
Markus Handell9bbff072020-07-07 12:23:18356 MutexLock lock(&mutex_);
Erik Språng16cb8f52019-04-12 11:59:09357 bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
Sebastian Janssonc5017132018-02-02 15:24:16358 observation_complete_.Set();
Sebastian Janssonc5017132018-02-02 15:24:16359 }
360
361 void PerformTest() override {
362 ASSERT_TRUE(Wait())
363 << "Timed out while waiting for encoder SetRates() call.";
364
Danil Chapovalov82a3f0a2019-10-21 07:24:27365 SendTask(RTC_FROM_HERE, task_queue_, [this]() {
Sebastian Janssonc5017132018-02-02 15:24:16366 WaitForEncoderTargetBitrateMatchStats();
367 send_stream_->Stop();
368 WaitForStatsReportZeroTargetBitrate();
369 send_stream_->Start();
370 WaitForEncoderTargetBitrateMatchStats();
371 });
372 }
373
374 void WaitForEncoderTargetBitrateMatchStats() {
375 for (int i = 0; i < kDefaultTimeoutMs; ++i) {
376 VideoSendStream::Stats stats = send_stream_->GetStats();
377 {
Markus Handell9bbff072020-07-07 12:23:18378 MutexLock lock(&mutex_);
Sebastian Janssonc5017132018-02-02 15:24:16379 if ((stats.target_media_bitrate_bps + 500) / 1000 ==
380 static_cast<int>(bitrate_kbps_)) {
381 return;
382 }
383 }
384 SleepMs(1);
385 }
386 FAIL()
387 << "Timed out waiting for stats reporting the currently set bitrate.";
388 }
389
390 void WaitForStatsReportZeroTargetBitrate() {
391 for (int i = 0; i < kDefaultTimeoutMs; ++i) {
392 if (send_stream_->GetStats().target_media_bitrate_bps == 0) {
393 return;
394 }
395 SleepMs(1);
396 }
397 FAIL() << "Timed out waiting for stats reporting zero bitrate.";
398 }
399
400 private:
Danil Chapovalov85a10002019-10-21 13:00:53401 TaskQueueBase* const task_queue_;
Markus Handell9bbff072020-07-07 12:23:18402 Mutex mutex_;
Sebastian Janssonc5017132018-02-02 15:24:16403 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 07:07:24404 test::VideoEncoderProxyFactory encoder_factory_;
Jiawei Ouc2ebe212018-11-08 18:02:56405 std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
Markus Handell9bbff072020-07-07 12:23:18406 uint32_t bitrate_kbps_ RTC_GUARDED_BY(mutex_);
Danil Chapovalovd15a0282019-10-22 08:48:17407 } test(task_queue());
Sebastian Janssonc5017132018-02-02 15:24:16408
409 RunBaseTest(&test);
410}
411} // namespace webrtc