blob: 2ffba5d11b25a2e513676a77b0e4d6937117ec03 [file] [log] [blame]
pbos@webrtc.org5ab75672013-12-16 12:24:441/*
2 * Copyright (c) 2013 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 */
Per Kjellander89870ff2023-01-19 15:45:5810#include <cstddef>
pbos@webrtc.org5ab75672013-12-16 12:24:4411#include <functional>
12#include <list>
kwibergb25345e2016-03-12 14:10:4413#include <memory>
pbos@webrtc.org5ab75672013-12-16 12:24:4414#include <string>
15
Ali Tofigh6364d082022-03-14 12:32:0416#include "absl/strings/string_view.h"
Artem Titov33f9d2b2019-12-05 14:59:0017#include "api/test/create_frame_generator.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3118#include "call/call.h"
19#include "rtc_base/checks.h"
20#include "rtc_base/event.h"
21#include "rtc_base/logging.h"
Markus Handell8fe932a2020-07-06 15:41:3522#include "rtc_base/synchronization/mutex.h"
Danil Chapovalov82a3f0a2019-10-21 07:24:2723#include "rtc_base/task_queue_for_test.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3124#include "rtc_base/thread_annotations.h"
25#include "test/call_test.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3126#include "test/encoder_settings.h"
27#include "test/fake_decoder.h"
28#include "test/fake_encoder.h"
29#include "test/frame_generator_capturer.h"
30#include "test/gtest.h"
Artem Titov8a9f3a82023-04-25 07:56:4931#include "test/video_test_constants.h"
pbos@webrtc.org5ab75672013-12-16 12:24:4432
33namespace webrtc {
andresp@webrtc.orgb941fe82014-07-07 08:50:4834namespace {
Fredrik Solenberg23fba1f2015-04-29 13:24:0135// Note: If you consider to re-use this class, think twice and instead consider
Peter Boström7c704b82015-12-04 15:13:0536// writing tests that don't depend on the logging system.
37class LogObserver {
andresp@webrtc.orgb941fe82014-07-07 08:50:4838 public:
Peter Boström7c704b82015-12-04 15:13:0539 LogObserver() { rtc::LogMessage::AddLogToStream(&callback_, rtc::LS_INFO); }
andresp@webrtc.orgb941fe82014-07-07 08:50:4840
Peter Boström7c704b82015-12-04 15:13:0541 ~LogObserver() { rtc::LogMessage::RemoveLogToStream(&callback_); }
andresp@webrtc.orgb941fe82014-07-07 08:50:4842
Ali Tofigh641a1b12022-05-17 09:48:4643 void PushExpectedLogLine(absl::string_view expected_log_line) {
andresp@webrtc.orgb941fe82014-07-07 08:50:4844 callback_.PushExpectedLogLine(expected_log_line);
45 }
46
Peter Boström5811a392015-12-10 12:02:5047 bool Wait() { return callback_.Wait(); }
andresp@webrtc.orgb941fe82014-07-07 08:50:4848
49 private:
Peter Boström7c704b82015-12-04 15:13:0550 class Callback : public rtc::LogSink {
andresp@webrtc.orgb941fe82014-07-07 08:50:4851 public:
Peter Boström7c704b82015-12-04 15:13:0552 void OnLogMessage(const std::string& message) override {
Ali Tofigh6364d082022-03-14 12:32:0453 OnLogMessage(absl::string_view(message));
54 }
55
56 void OnLogMessage(absl::string_view message) override {
Markus Handell8fe932a2020-07-06 15:41:3557 MutexLock lock(&mutex_);
Peter Boström7c704b82015-12-04 15:13:0558 // Ignore log lines that are due to missing AST extensions, these are
59 // logged when we switch back from AST to TOF until the wrapping bitrate
60 // estimator gives up on using AST.
Ali Tofigh6364d082022-03-14 12:32:0461 if (message.find("BitrateEstimator") != absl::string_view::npos &&
62 message.find("packet is missing") == absl::string_view::npos) {
63 received_log_lines_.push_back(std::string(message));
andresp@webrtc.orgb941fe82014-07-07 08:50:4864 }
Peter Boström7c704b82015-12-04 15:13:0565
andresp@webrtc.orgb941fe82014-07-07 08:50:4866 int num_popped = 0;
67 while (!received_log_lines_.empty() && !expected_log_lines_.empty()) {
68 std::string a = received_log_lines_.front();
69 std::string b = expected_log_lines_.front();
70 received_log_lines_.pop_front();
71 expected_log_lines_.pop_front();
72 num_popped++;
Ali Tofigh6364d082022-03-14 12:32:0473 EXPECT_TRUE(a.find(b) != absl::string_view::npos) << a << " != " << b;
andresp@webrtc.orgb941fe82014-07-07 08:50:4874 }
Benjamin Wright41f9f2c2019-03-14 01:03:2975 if (expected_log_lines_.empty()) {
andresp@webrtc.orgb941fe82014-07-07 08:50:4876 if (num_popped > 0) {
Peter Boström5811a392015-12-10 12:02:5077 done_.Set();
andresp@webrtc.orgb941fe82014-07-07 08:50:4878 }
79 return;
80 }
81 }
82
Artem Titov8a9f3a82023-04-25 07:56:4983 bool Wait() {
84 return done_.Wait(test::VideoTestConstants::kDefaultTimeout);
85 }
andresp@webrtc.orgb941fe82014-07-07 08:50:4886
Ali Tofigh641a1b12022-05-17 09:48:4687 void PushExpectedLogLine(absl::string_view expected_log_line) {
Markus Handell8fe932a2020-07-06 15:41:3588 MutexLock lock(&mutex_);
Ali Tofigh641a1b12022-05-17 09:48:4689 expected_log_lines_.emplace_back(expected_log_line);
andresp@webrtc.orgb941fe82014-07-07 08:50:4890 }
91
92 private:
93 typedef std::list<std::string> Strings;
Markus Handell8fe932a2020-07-06 15:41:3594 Mutex mutex_;
95 Strings received_log_lines_ RTC_GUARDED_BY(mutex_);
96 Strings expected_log_lines_ RTC_GUARDED_BY(mutex_);
Peter Boström5811a392015-12-10 12:02:5097 rtc::Event done_;
andresp@webrtc.orgb941fe82014-07-07 08:50:4898 };
99
100 Callback callback_;
101};
102} // namespace
pbos@webrtc.org5ab75672013-12-16 12:24:44103
104static const int kTOFExtensionId = 4;
105static const int kASTExtensionId = 5;
106
pbos@webrtc.org994d0b72014-06-27 08:47:52107class BitrateEstimatorTest : public test::CallTest {
pbos@webrtc.org5ab75672013-12-16 12:24:44108 public:
aleloi5d78e8d2016-11-08 11:44:54109 BitrateEstimatorTest() : receive_config_(nullptr) {}
pbos@webrtc.org5ab75672013-12-16 12:24:44110
Fredrik Solenberg0ccae132015-11-03 09:15:49111 virtual ~BitrateEstimatorTest() { EXPECT_TRUE(streams_.empty()); }
pbos@webrtc.org5ab75672013-12-16 12:24:44112
113 virtual void SetUp() {
Danil Chapovalove519f382022-08-11 10:26:09114 SendTask(task_queue(), [this]() {
Per K664cf142023-01-25 14:19:11115 RegisterRtpExtension(
116 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
117 RegisterRtpExtension(
118 RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId));
119
Sebastian Jansson8e6602f2018-07-13 08:43:20120 CreateCalls();
pbos@webrtc.org5ab75672013-12-16 12:24:44121
Per Kjellander89870ff2023-01-19 15:45:58122 CreateSendTransport(BuiltInNetworkBehaviorConfig(), /*observer=*/nullptr);
123 CreateReceiveTransport(BuiltInNetworkBehaviorConfig(),
124 /*observer=*/nullptr);
pbos@webrtc.org5ab75672013-12-16 12:24:44125
Sebastian Janssonf33905d2018-07-13 07:49:00126 VideoSendStream::Config video_send_config(send_transport_.get());
Artem Titov8a9f3a82023-04-25 07:56:49127 video_send_config.rtp.ssrcs.push_back(
128 test::VideoTestConstants::kVideoSendSsrcs[0]);
Sebastian Janssonf33905d2018-07-13 07:49:00129 video_send_config.encoder_settings.encoder_factory =
Niels Möller4db138e2018-04-19 07:04:13130 &fake_encoder_factory_;
Jiawei Ouc2ebe212018-11-08 18:02:56131 video_send_config.encoder_settings.bitrate_allocator_factory =
132 bitrate_allocator_factory_.get();
Sebastian Janssonf33905d2018-07-13 07:49:00133 video_send_config.rtp.payload_name = "FAKE";
Artem Titov8a9f3a82023-04-25 07:56:49134 video_send_config.rtp.payload_type =
135 test::VideoTestConstants::kFakeVideoSendPayloadType;
Sebastian Janssonf33905d2018-07-13 07:49:00136 SetVideoSendConfig(video_send_config);
137 VideoEncoderConfig video_encoder_config;
138 test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
139 SetVideoEncoderConfig(video_encoder_config);
pbos@webrtc.org5ab75672013-12-16 12:24:44140
Tommif6f45432022-05-20 13:21:20141 receive_config_ =
142 VideoReceiveStreamInterface::Config(receive_transport_.get());
eladalon413ee9a2017-08-22 11:02:52143 // receive_config_.decoders will be set by every stream separately.
Sebastian Janssonf33905d2018-07-13 07:49:00144 receive_config_.rtp.remote_ssrc = GetVideoSendConfig()->rtp.ssrcs[0];
Artem Titov8a9f3a82023-04-25 07:56:49145 receive_config_.rtp.local_ssrc =
146 test::VideoTestConstants::kReceiverLocalVideoSsrc;
eladalon413ee9a2017-08-22 11:02:52147 });
pbos@webrtc.org5ab75672013-12-16 12:24:44148 }
149
150 virtual void TearDown() {
Danil Chapovalove519f382022-08-11 10:26:09151 SendTask(task_queue(), [this]() {
Yusuke Suzukif8d8d6d2018-05-17 13:01:13152 for (auto* stream : streams_) {
153 stream->StopSending();
154 delete stream;
eladalon413ee9a2017-08-22 11:02:52155 }
Yusuke Suzukif8d8d6d2018-05-17 13:01:13156 streams_.clear();
Sebastian Jansson8e6602f2018-07-13 08:43:20157 DestroyCalls();
eladalon413ee9a2017-08-22 11:02:52158 });
pbos@webrtc.org5ab75672013-12-16 12:24:44159 }
160
161 protected:
162 friend class Stream;
163
pbos@webrtc.org5ab75672013-12-16 12:24:44164 class Stream {
165 public:
aleloi5d78e8d2016-11-08 11:44:54166 explicit Stream(BitrateEstimatorTest* test)
pbos@webrtc.org5ab75672013-12-16 12:24:44167 : test_(test),
168 is_sending_receiving_(false),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24169 send_stream_(nullptr),
pbos@webrtc.org5ab75672013-12-16 12:24:44170 frame_generator_capturer_(),
Niels Möllercbcbc222018-09-28 07:07:24171 decoder_factory_(
Mirko Bonadei317a1f02019-09-17 15:06:18172 []() { return std::make_unique<test::FakeDecoder>(); }) {
Sebastian Janssonf33905d2018-07-13 07:49:00173 test_->GetVideoSendConfig()->rtp.ssrcs[0]++;
pbos@webrtc.org6ae48c62014-06-06 10:49:19174 send_stream_ = test_->sender_call_->CreateVideoSendStream(
Sebastian Janssonf33905d2018-07-13 07:49:00175 test_->GetVideoSendConfig()->Copy(),
176 test_->GetVideoEncoderConfig()->Copy());
177 RTC_DCHECK_EQ(1, test_->GetVideoEncoderConfig()->number_of_streams);
Danil Chapovalov81687b32019-04-18 13:39:53178 frame_generator_capturer_ =
Mirko Bonadei317a1f02019-09-17 15:06:18179 std::make_unique<test::FrameGeneratorCapturer>(
Danil Chapovalovc03d8b62023-11-29 14:54:32180 &test->env().clock(),
Artem Titov8a9f3a82023-04-25 07:56:49181 test::CreateSquareFrameGenerator(
182 test::VideoTestConstants::kDefaultWidth,
183 test::VideoTestConstants::kDefaultHeight, absl::nullopt,
184 absl::nullopt),
185 test::VideoTestConstants::kDefaultFramerate,
Danil Chapovalovc03d8b62023-11-29 14:54:32186 test->env().task_queue_factory());
Danil Chapovalov81687b32019-04-18 13:39:53187 frame_generator_capturer_->Init();
Artem Titovf92cc6d2023-06-29 12:56:59188 frame_generator_capturer_->Start();
Taylor Brandstetter49fcc102018-05-16 21:20:41189 send_stream_->SetSource(frame_generator_capturer_.get(),
190 DegradationPreference::MAINTAIN_FRAMERATE);
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21191 send_stream_->Start();
pbos@webrtc.org5ab75672013-12-16 12:24:44192
Tommif6f45432022-05-20 13:21:20193 VideoReceiveStreamInterface::Decoder decoder;
Philip Eliasson2b068ce2020-08-03 15:55:10194 test_->receive_config_.decoder_factory = &decoder_factory_;
Sebastian Janssonf33905d2018-07-13 07:49:00195 decoder.payload_type = test_->GetVideoSendConfig()->rtp.payload_type;
Niels Möllercb7e1d22018-09-11 13:56:04196 decoder.video_format =
197 SdpVideoFormat(test_->GetVideoSendConfig()->rtp.payload_name);
aleloi5d78e8d2016-11-08 11:44:54198 test_->receive_config_.decoders.clear();
199 test_->receive_config_.decoders.push_back(decoder);
200 test_->receive_config_.rtp.remote_ssrc =
Sebastian Janssonf33905d2018-07-13 07:49:00201 test_->GetVideoSendConfig()->rtp.ssrcs[0];
aleloi5d78e8d2016-11-08 11:44:54202 test_->receive_config_.rtp.local_ssrc++;
203 test_->receive_config_.renderer = &test->fake_renderer_;
204 video_receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream(
205 test_->receive_config_.Copy());
206 video_receive_stream_->Start();
pbos@webrtc.org5ab75672013-12-16 12:24:44207 is_sending_receiving_ = true;
208 }
209
210 ~Stream() {
Fredrik Solenberg23fba1f2015-04-29 13:24:01211 EXPECT_FALSE(is_sending_receiving_);
perkj9fdbda62016-09-15 16:19:20212 test_->sender_call_->DestroyVideoSendStream(send_stream_);
perkja49cbd32016-09-16 14:53:41213 frame_generator_capturer_.reset(nullptr);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24214 send_stream_ = nullptr;
Fredrik Solenberg23fba1f2015-04-29 13:24:01215 if (video_receive_stream_) {
216 test_->receiver_call_->DestroyVideoReceiveStream(video_receive_stream_);
217 video_receive_stream_ = nullptr;
218 }
pbos@webrtc.org5ab75672013-12-16 12:24:44219 }
220
221 void StopSending() {
222 if (is_sending_receiving_) {
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21223 send_stream_->Stop();
Fredrik Solenberg23fba1f2015-04-29 13:24:01224 if (video_receive_stream_) {
225 video_receive_stream_->Stop();
226 }
pbos@webrtc.org5ab75672013-12-16 12:24:44227 is_sending_receiving_ = false;
228 }
229 }
230
231 private:
232 BitrateEstimatorTest* test_;
233 bool is_sending_receiving_;
234 VideoSendStream* send_stream_;
Tommif6f45432022-05-20 13:21:20235 VideoReceiveStreamInterface* video_receive_stream_;
kwibergb25345e2016-03-12 14:10:44236 std::unique_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
Niels Möllercbcbc222018-09-28 07:07:24237
238 test::FunctionVideoDecoderFactory decoder_factory_;
pbos@webrtc.org5ab75672013-12-16 12:24:44239 };
240
Peter Boström7c704b82015-12-04 15:13:05241 LogObserver receiver_log_;
Tommif6f45432022-05-20 13:21:20242 VideoReceiveStreamInterface::Config receive_config_;
pbos@webrtc.org5ab75672013-12-16 12:24:44243 std::vector<Stream*> streams_;
244};
245
Erik Språng468e62a2015-07-06 08:50:47246static const char* kAbsSendTimeLog =
247 "RemoteBitrateEstimatorAbsSendTime: Instantiating.";
248static const char* kSingleStreamLog =
249 "RemoteBitrateEstimatorSingleStream: Instantiating.";
250
Fredrik Solenberg23fba1f2015-04-29 13:24:01251TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) {
Danil Chapovalove519f382022-08-11 10:26:09252 SendTask(task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 07:49:00253 GetVideoSendConfig()->rtp.extensions.push_back(
eladalon413ee9a2017-08-22 11:02:52254 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
255 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
256 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
257 streams_.push_back(new Stream(this));
258 });
Peter Boström5811a392015-12-10 12:02:50259 EXPECT_TRUE(receiver_log_.Wait());
pbos@webrtc.org5ab75672013-12-16 12:24:44260}
261
Fredrik Solenberg23fba1f2015-04-29 13:24:01262TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForVideo) {
Danil Chapovalove519f382022-08-11 10:26:09263 SendTask(task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 07:49:00264 GetVideoSendConfig()->rtp.extensions.push_back(
eladalon413ee9a2017-08-22 11:02:52265 RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId));
266 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
267 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
268 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
269 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
270 streams_.push_back(new Stream(this));
271 });
Peter Boström5811a392015-12-10 12:02:50272 EXPECT_TRUE(receiver_log_.Wait());
Fredrik Solenberg23fba1f2015-04-29 13:24:01273}
274
Fredrik Solenberg23fba1f2015-04-29 13:24:01275TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) {
Danil Chapovalove519f382022-08-11 10:26:09276 SendTask(task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 07:49:00277 GetVideoSendConfig()->rtp.extensions.push_back(
eladalon413ee9a2017-08-22 11:02:52278 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
279 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
280 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
281 streams_.push_back(new Stream(this));
282 });
Peter Boström5811a392015-12-10 12:02:50283 EXPECT_TRUE(receiver_log_.Wait());
pbos@webrtc.org5ab75672013-12-16 12:24:44284
Danil Chapovalove519f382022-08-11 10:26:09285 SendTask(task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 07:49:00286 GetVideoSendConfig()->rtp.extensions[0] =
eladalon413ee9a2017-08-22 11:02:52287 RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId);
288 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
289 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
290 streams_.push_back(new Stream(this));
291 });
Peter Boström5811a392015-12-10 12:02:50292 EXPECT_TRUE(receiver_log_.Wait());
pbos@webrtc.org5ab75672013-12-16 12:24:44293}
294
deadbeef1086ed62016-04-22 17:52:40295// This test is flaky. See webrtc:5790.
296TEST_F(BitrateEstimatorTest, DISABLED_SwitchesToASTThenBackToTOFForVideo) {
Danil Chapovalove519f382022-08-11 10:26:09297 SendTask(task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 07:49:00298 GetVideoSendConfig()->rtp.extensions.push_back(
eladalon413ee9a2017-08-22 11:02:52299 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
300 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
301 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
302 receiver_log_.PushExpectedLogLine(kSingleStreamLog);
303 streams_.push_back(new Stream(this));
304 });
Peter Boström5811a392015-12-10 12:02:50305 EXPECT_TRUE(receiver_log_.Wait());
pbos@webrtc.org5ab75672013-12-16 12:24:44306
Danil Chapovalove519f382022-08-11 10:26:09307 SendTask(task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 07:49:00308 GetVideoSendConfig()->rtp.extensions[0] =
eladalon413ee9a2017-08-22 11:02:52309 RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId);
310 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
311 receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
312 streams_.push_back(new Stream(this));
313 });
Peter Boström5811a392015-12-10 12:02:50314 EXPECT_TRUE(receiver_log_.Wait());
pbos@webrtc.org5ab75672013-12-16 12:24:44315
Danil Chapovalove519f382022-08-11 10:26:09316 SendTask(task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 07:49:00317 GetVideoSendConfig()->rtp.extensions[0] =
eladalon413ee9a2017-08-22 11:02:52318 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId);
319 receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
320 receiver_log_.PushExpectedLogLine(
321 "WrappingBitrateEstimator: Switching to transmission time offset RBE.");
322 streams_.push_back(new Stream(this));
323 streams_[0]->StopSending();
324 streams_[1]->StopSending();
325 });
Peter Boström5811a392015-12-10 12:02:50326 EXPECT_TRUE(receiver_log_.Wait());
pbos@webrtc.org5ab75672013-12-16 12:24:44327}
328} // namespace webrtc