blob: 0dee93ca84119bb9fde184989198fefc354eacf4 [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"
Danil Chapovalov95eeaa72022-07-06 08:14:2915#include "api/units/time_delta.h"
Jiawei Ouc2ebe212018-11-08 18:02:5616#include "api/video/builtin_video_bitrate_allocator_factory.h"
Erik Språngf93eda12019-01-16 16:10:5717#include "api/video/video_bitrate_allocation.h"
Artem Titov4e199e92018-08-20 11:30:3918#include "call/fake_network_pipe.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"
Sebastian Janssonc5017132018-02-02 15:24:1623#include "system_wrappers/include/sleep.h"
24#include "test/call_test.h"
Niels Möller4db138e2018-04-19 07:04:1325#include "test/fake_encoder.h"
Sebastian Janssonc5017132018-02-02 15:24:1626#include "test/field_trial.h"
27#include "test/gtest.h"
Per K569849e2024-04-29 08:37:3728#include "test/network/simulated_network.h"
Sebastian Janssonc5017132018-02-02 15:24:1629#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"
Artem Titov8a9f3a82023-04-25 07:56:4932#include "test/video_test_constants.h"
Sebastian Janssonc5017132018-02-02 15:24:1633
34namespace webrtc {
Elad Alond8d32482019-02-18 22:45:5735namespace {
36enum : int { // The first valid value is 1.
37 kAbsSendTimeExtensionId = 1,
Erik Språng8d65e9a2019-10-30 15:48:2838 kTransportSequenceNumberId,
Elad Alond8d32482019-02-18 22:45:5739};
40} // namespace
Sebastian Janssonc5017132018-02-02 15:24:1641
Ilya Nikolaevskiycb960622018-09-04 09:07:3142class BandwidthEndToEndTest : public test::CallTest {
Sebastian Janssonc5017132018-02-02 15:24:1643 public:
Ilya Nikolaevskiycb960622018-09-04 09:07:3144 BandwidthEndToEndTest() = default;
Sebastian Janssonc5017132018-02-02 15:24:1645};
46
Ilya Nikolaevskiycb960622018-09-04 09:07:3147TEST_F(BandwidthEndToEndTest, ReceiveStreamSendsRemb) {
Sebastian Janssonc5017132018-02-02 15:24:1648 class RembObserver : public test::EndToEndTest {
49 public:
Artem Titov8a9f3a82023-04-25 07:56:4950 RembObserver() : EndToEndTest(test::VideoTestConstants::kDefaultTimeout) {}
Sebastian Janssonc5017132018-02-02 15:24:1651
52 void ModifyVideoConfigs(
53 VideoSendStream::Config* send_config,
Tommif6f45432022-05-20 13:21:2054 std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
Sebastian Janssonc5017132018-02-02 15:24:1655 VideoEncoderConfig* encoder_config) override {
56 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 22:45:5757 send_config->rtp.extensions.push_back(
58 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Sebastian Janssonc5017132018-02-02 15:24:1659 }
60
Harald Alvestrandd43af912023-08-15 11:41:4561 Action OnReceiveRtcp(rtc::ArrayView<const uint8_t> packet) override {
Sebastian Janssonc5017132018-02-02 15:24:1662 test::RtcpPacketParser parser;
Harald Alvestrandd43af912023-08-15 11:41:4563 EXPECT_TRUE(parser.Parse(packet));
Sebastian Janssonc5017132018-02-02 15:24:1664
65 if (parser.remb()->num_packets() > 0) {
Artem Titov8a9f3a82023-04-25 07:56:4966 EXPECT_EQ(test::VideoTestConstants::kReceiverLocalVideoSsrc,
67 parser.remb()->sender_ssrc());
Sebastian Janssonc5017132018-02-02 15:24:1668 EXPECT_LT(0U, parser.remb()->bitrate_bps());
69 EXPECT_EQ(1U, parser.remb()->ssrcs().size());
Artem Titov8a9f3a82023-04-25 07:56:4970 EXPECT_EQ(test::VideoTestConstants::kVideoSendSsrcs[0],
71 parser.remb()->ssrcs()[0]);
Sebastian Janssonc5017132018-02-02 15:24:1672 observation_complete_.Set();
73 }
74
75 return SEND_PACKET;
76 }
77 void PerformTest() override {
78 EXPECT_TRUE(Wait()) << "Timed out while waiting for a "
79 "receiver RTCP REMB packet to be "
80 "sent.";
81 }
82 } test;
83
84 RunBaseTest(&test);
85}
86
87class BandwidthStatsTest : public test::EndToEndTest {
88 public:
Danil Chapovalov85a10002019-10-21 13:00:5389 BandwidthStatsTest(bool send_side_bwe, TaskQueueBase* task_queue)
Artem Titov8a9f3a82023-04-25 07:56:4990 : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
Sebastian Janssonc5017132018-02-02 15:24:1691 sender_call_(nullptr),
92 receiver_call_(nullptr),
93 has_seen_pacer_delay_(false),
Tommie80885a2019-08-05 13:08:1794 send_side_bwe_(send_side_bwe),
95 task_queue_(task_queue) {}
Sebastian Janssonc5017132018-02-02 15:24:1696
Danil Chapovalov2f2049a2019-11-06 12:28:1197 ~BandwidthStatsTest() override {
98 // Block until all already posted tasks run to avoid races when such task
Artem Titovab30d722021-07-27 14:22:1199 // accesses `this`.
Danil Chapovalove519f382022-08-11 10:26:09100 SendTask(task_queue_, [] {});
Danil Chapovalov2f2049a2019-11-06 12:28:11101 }
102
Sebastian Janssonc5017132018-02-02 15:24:16103 void ModifyVideoConfigs(
104 VideoSendStream::Config* send_config,
Tommif6f45432022-05-20 13:21:20105 std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
Sebastian Janssonc5017132018-02-02 15:24:16106 VideoEncoderConfig* encoder_config) override {
Erik Språng8d65e9a2019-10-30 15:48:28107 send_config->rtp.extensions.clear();
Sebastian Janssonc5017132018-02-02 15:24:16108 if (!send_side_bwe_) {
Elad Alond8d32482019-02-18 22:45:57109 send_config->rtp.extensions.push_back(
110 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Erik Språng8d65e9a2019-10-30 15:48:28111 } else {
112 send_config->rtp.extensions.push_back(
113 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
114 kTransportSequenceNumberId));
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.
Harald Alvestrandd43af912023-08-15 11:41:45130 Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
Tommie80885a2019-08-05 13:08:17131 // Stats need to be fetched on the thread where the caller objects were
132 // constructed.
Danil Chapovalov95eeaa72022-07-06 08:14:29133 task_queue_->PostTask([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 Chapovalov95eeaa72022-07-06 08:14:29149 });
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)
Artem Titov8a9f3a82023-04-25 07:56:49197 : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
Sebastian Janssonc5017132018-02-02 15:24:16198 sender_call_(nullptr),
199 clock_(Clock::GetRealTimeClock()),
200 sender_ssrc_(0),
201 remb_bitrate_bps_(1000000),
Sebastian Janssonc5017132018-02-02 15:24:16202 state_(kWaitForFirstRampUp),
Tommie80885a2019-08-05 13:08:17203 retransmission_rate_limiter_(clock_, 1000),
204 task_queue_(task_queue) {}
Sebastian Janssonc5017132018-02-02 15:24:16205
Markus Handell3da25772021-11-05 15:48:38206 void OnStreamsStopped() override { rtp_rtcp_ = nullptr; }
Sebastian Janssonc5017132018-02-02 15:24:16207
Niels Möllerde8e6e62018-11-13 14:10:33208 void ModifySenderBitrateConfig(
209 BitrateConstraints* bitrate_config) override {
Sebastian Janssonc5017132018-02-02 15:24:16210 // Set a high start bitrate to reduce the test completion time.
Niels Möllerde8e6e62018-11-13 14:10:33211 bitrate_config->start_bitrate_bps = remb_bitrate_bps_;
Sebastian Janssonc5017132018-02-02 15:24:16212 }
213
214 void ModifyVideoConfigs(
215 VideoSendStream::Config* send_config,
Tommif6f45432022-05-20 13:21:20216 std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
Sebastian Janssonc5017132018-02-02 15:24:16217 VideoEncoderConfig* encoder_config) override {
218 ASSERT_EQ(1u, send_config->rtp.ssrcs.size());
219 sender_ssrc_ = send_config->rtp.ssrcs[0];
220
221 encoder_config->max_bitrate_bps = 2000000;
222
223 ASSERT_EQ(1u, receive_configs->size());
Per Kjellander89870ff2023-01-19 15:45:58224 remb_sender_local_ssrc_ = (*receive_configs)[0].rtp.local_ssrc;
225 remb_sender_remote_ssrc_ = (*receive_configs)[0].rtp.remote_ssrc;
Sebastian Janssonc5017132018-02-02 15:24:16226 }
227
228 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommie80885a2019-08-05 13:08:17229 RTC_DCHECK(sender_call);
Sebastian Janssonc5017132018-02-02 15:24:16230 sender_call_ = sender_call;
Danil Chapovalov95eeaa72022-07-06 08:14:29231 task_queue_->PostTask([this]() { PollStats(); });
Sebastian Janssonc5017132018-02-02 15:24:16232 }
233
Per Kjellander89870ff2023-01-19 15:45:58234 void OnTransportCreated(
235 test::PacketTransport* /*to_receiver*/,
236 SimulatedNetworkInterface* /*sender_network*/,
237 test::PacketTransport* to_sender,
238 SimulatedNetworkInterface* /*receiver_network*/) override {
239 RtpRtcpInterface::Configuration config;
240 config.receiver_only = true;
241 config.clock = clock_;
242 config.outgoing_transport = to_sender;
243 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
244 config.local_media_ssrc = remb_sender_local_ssrc_;
245
246 rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(config);
247 rtp_rtcp_->SetRemoteSSRC(remb_sender_remote_ssrc_);
248 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
249 }
250
Sebastian Janssonc5017132018-02-02 15:24:16251 void PollStats() {
Tommie80885a2019-08-05 13:08:17252 Call::Stats stats = sender_call_->GetStats();
253 switch (state_) {
254 case kWaitForFirstRampUp:
255 if (stats.send_bandwidth_bps >= remb_bitrate_bps_) {
256 state_ = kWaitForRemb;
257 remb_bitrate_bps_ /= 2;
258 rtp_rtcp_->SetRemb(
259 remb_bitrate_bps_,
260 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
261 rtp_rtcp_->SendRTCP(kRtcpRr);
Sebastian Janssonc5017132018-02-02 15:24:16262 }
Tommie80885a2019-08-05 13:08:17263 break;
264
265 case kWaitForRemb:
266 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
267 state_ = kWaitForSecondRampUp;
268 remb_bitrate_bps_ *= 2;
269 rtp_rtcp_->SetRemb(
270 remb_bitrate_bps_,
271 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
272 rtp_rtcp_->SendRTCP(kRtcpRr);
273 }
274 break;
275
276 case kWaitForSecondRampUp:
277 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
278 observation_complete_.Set();
279 return;
280 }
281 break;
282 }
283
Danil Chapovalov95eeaa72022-07-06 08:14:29284 task_queue_->PostDelayedTask([this] { PollStats(); },
285 TimeDelta::Seconds(1));
Sebastian Janssonc5017132018-02-02 15:24:16286 }
287
288 void PerformTest() override {
Sebastian Janssonc5017132018-02-02 15:24:16289 EXPECT_TRUE(Wait())
290 << "Timed out while waiting for bitrate to change according to REMB.";
Sebastian Janssonc5017132018-02-02 15:24:16291 }
292
293 private:
294 enum TestState { kWaitForFirstRampUp, kWaitForRemb, kWaitForSecondRampUp };
295
296 Call* sender_call_;
297 Clock* const clock_;
298 uint32_t sender_ssrc_;
Per Kjellander89870ff2023-01-19 15:45:58299 uint32_t remb_sender_local_ssrc_ = 0;
300 uint32_t remb_sender_remote_ssrc_ = 0;
Sebastian Janssonc5017132018-02-02 15:24:16301 int remb_bitrate_bps_;
Tomas Gunnarssonf25761d2020-06-03 20:55:33302 std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_;
Sebastian Janssonc5017132018-02-02 15:24:16303 TestState state_;
304 RateLimiter retransmission_rate_limiter_;
Danil Chapovalov85a10002019-10-21 13:00:53305 TaskQueueBase* const task_queue_;
Danil Chapovalovd15a0282019-10-22 08:48:17306 } test(task_queue());
Sebastian Janssonc5017132018-02-02 15:24:16307
308 RunBaseTest(&test);
309}
310
Ilya Nikolaevskiycb960622018-09-04 09:07:31311TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) {
Erik Språng7ca375c2019-02-06 15:20:17312 // If these fields trial are on, we get lower bitrates than expected by this
313 // test, due to the packetization overhead and encoder pushback.
314 webrtc::test::ScopedFieldTrials field_trials(
315 std::string(field_trial::GetFieldTrialString()) +
Erik Språng7ca375c2019-02-06 15:20:17316 "WebRTC-VideoRateControl/bitrate_adjuster:false/");
Sebastian Janssonc5017132018-02-02 15:24:16317 class EncoderRateStatsTest : public test::EndToEndTest,
318 public test::FakeEncoder {
319 public:
Danil Chapovalovb065f1b2024-04-15 11:53:03320 explicit EncoderRateStatsTest(const Environment& env,
321 TaskQueueBase* task_queue)
Artem Titov8a9f3a82023-04-25 07:56:49322 : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
Danil Chapovalovb065f1b2024-04-15 11:53:03323 FakeEncoder(env),
Sebastian Janssonc5017132018-02-02 15:24:16324 task_queue_(task_queue),
325 send_stream_(nullptr),
Niels Möller4db138e2018-04-19 07:04:13326 encoder_factory_(this),
Jiawei Ouc2ebe212018-11-08 18:02:56327 bitrate_allocator_factory_(
328 CreateBuiltinVideoBitrateAllocatorFactory()),
Sebastian Janssonc5017132018-02-02 15:24:16329 bitrate_kbps_(0) {}
330
Tommif6f45432022-05-20 13:21:20331 void OnVideoStreamsCreated(VideoSendStream* send_stream,
332 const std::vector<VideoReceiveStreamInterface*>&
333 receive_streams) override {
Sebastian Janssonc5017132018-02-02 15:24:16334 send_stream_ = send_stream;
335 }
336
337 void ModifyVideoConfigs(
338 VideoSendStream::Config* send_config,
Tommif6f45432022-05-20 13:21:20339 std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
Sebastian Janssonc5017132018-02-02 15:24:16340 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 07:04:13341 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Jiawei Ouc2ebe212018-11-08 18:02:56342 send_config->encoder_settings.bitrate_allocator_factory =
343 bitrate_allocator_factory_.get();
Sebastian Janssonc5017132018-02-02 15:24:16344 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
345 }
346
Erik Språng16cb8f52019-04-12 11:59:09347 void SetRates(const RateControlParameters& parameters) override {
Sebastian Janssonc5017132018-02-02 15:24:16348 // Make sure not to trigger on any default zero bitrates.
Erik Språng16cb8f52019-04-12 11:59:09349 if (parameters.bitrate.get_sum_bps() == 0)
350 return;
Markus Handell9bbff072020-07-07 12:23:18351 MutexLock lock(&mutex_);
Erik Språng16cb8f52019-04-12 11:59:09352 bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
Sebastian Janssonc5017132018-02-02 15:24:16353 observation_complete_.Set();
Sebastian Janssonc5017132018-02-02 15:24:16354 }
355
356 void PerformTest() override {
357 ASSERT_TRUE(Wait())
358 << "Timed out while waiting for encoder SetRates() call.";
359
Danil Chapovalove519f382022-08-11 10:26:09360 SendTask(task_queue_, [this]() {
Sebastian Janssonc5017132018-02-02 15:24:16361 WaitForEncoderTargetBitrateMatchStats();
362 send_stream_->Stop();
363 WaitForStatsReportZeroTargetBitrate();
364 send_stream_->Start();
365 WaitForEncoderTargetBitrateMatchStats();
366 });
367 }
368
369 void WaitForEncoderTargetBitrateMatchStats() {
Artem Titov8a9f3a82023-04-25 07:56:49370 for (int i = 0; i < test::VideoTestConstants::kDefaultTimeout.ms(); ++i) {
Sebastian Janssonc5017132018-02-02 15:24:16371 VideoSendStream::Stats stats = send_stream_->GetStats();
372 {
Markus Handell9bbff072020-07-07 12:23:18373 MutexLock lock(&mutex_);
Sebastian Janssonc5017132018-02-02 15:24:16374 if ((stats.target_media_bitrate_bps + 500) / 1000 ==
375 static_cast<int>(bitrate_kbps_)) {
376 return;
377 }
378 }
379 SleepMs(1);
380 }
381 FAIL()
382 << "Timed out waiting for stats reporting the currently set bitrate.";
383 }
384
385 void WaitForStatsReportZeroTargetBitrate() {
Artem Titov8a9f3a82023-04-25 07:56:49386 for (int i = 0; i < test::VideoTestConstants::kDefaultTimeout.ms(); ++i) {
Sebastian Janssonc5017132018-02-02 15:24:16387 if (send_stream_->GetStats().target_media_bitrate_bps == 0) {
388 return;
389 }
390 SleepMs(1);
391 }
392 FAIL() << "Timed out waiting for stats reporting zero bitrate.";
393 }
394
395 private:
Danil Chapovalov85a10002019-10-21 13:00:53396 TaskQueueBase* const task_queue_;
Markus Handell9bbff072020-07-07 12:23:18397 Mutex mutex_;
Sebastian Janssonc5017132018-02-02 15:24:16398 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 07:07:24399 test::VideoEncoderProxyFactory encoder_factory_;
Jiawei Ouc2ebe212018-11-08 18:02:56400 std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
Markus Handell9bbff072020-07-07 12:23:18401 uint32_t bitrate_kbps_ RTC_GUARDED_BY(mutex_);
Danil Chapovalovb065f1b2024-04-15 11:53:03402 } test(env(), task_queue());
Sebastian Janssonc5017132018-02-02 15:24:16403
404 RunBaseTest(&test);
405}
406} // namespace webrtc