blob: 057fd9538e31f569d1fc177039324aa3a6747303 [file] [log] [blame]
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00001/*
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 */
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000010#include <algorithm> // max
kwiberg27f982b2016-03-01 11:52:33 -080011#include <memory>
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +000012#include <vector>
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000013
Steve Anton40d55332019-01-07 10:21:47 -080014#include "absl/memory/memory.h"
Artem Titov46c4e602018-08-17 14:26:54 +020015#include "api/test/simulated_network.h"
Niels Möller4dc66c52018-10-05 14:17:58 +020016#include "api/video/encoded_image.h"
Erik Språngf93eda12019-01-16 17:10:57 +010017#include "api/video/video_bitrate_allocation.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "call/call.h"
Artem Titov4e199e92018-08-20 13:30:39 +020019#include "call/fake_network_pipe.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "call/rtp_transport_controller_send.h"
Artem Titov4e199e92018-08-20 13:30:39 +020021#include "call/simulated_network.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "modules/rtp_rtcp/include/rtp_header_parser.h"
23#include "modules/rtp_rtcp/include/rtp_rtcp.h"
24#include "modules/rtp_rtcp/source/rtcp_sender.h"
25#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
26#include "modules/video_coding/codecs/vp8/include/vp8.h"
27#include "modules/video_coding/codecs/vp9/include/vp9.h"
28#include "rtc_base/bind.h"
29#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/critical_section.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/event.h"
Sebastian Janssoncabe3832018-01-12 10:54:18 +010032#include "rtc_base/experiments/alr_experiment.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/logging.h"
34#include "rtc_base/platform_thread.h"
35#include "rtc_base/rate_limiter.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "rtc_base/time_utils.h"
Elad Alon157540a2019-02-08 23:37:52 +010037#include "rtc_base/unique_id_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "system_wrappers/include/sleep.h"
39#include "test/call_test.h"
40#include "test/configurable_frame_size_encoder.h"
Niels Möller4db138e2018-04-19 09:04:13 +020041#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020042#include "test/fake_texture_frame.h"
43#include "test/field_trial.h"
44#include "test/frame_generator.h"
45#include "test/frame_generator_capturer.h"
46#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010047#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020048#include "test/gtest.h"
49#include "test/null_transport.h"
50#include "test/rtcp_packet_parser.h"
51#include "test/testsupport/perf_test.h"
Niels Möllercbcbc222018-09-28 09:07:24 +020052#include "test/video_encoder_proxy_factory.h"
perkjfa10b552016-10-02 23:45:26 -070053
Sebastian Janssona45c8da2018-01-16 10:55:29 +010054#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "video/send_statistics_proxy.h"
56#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010057#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000058
59namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010060namespace test {
61class VideoSendStreamPeer {
62 public:
63 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
64 : internal_stream_(
65 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020066 absl::optional<float> GetPacingFactorOverride() const {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010067 return internal_stream_->GetPacingFactorOverride();
68 }
69
70 private:
71 internal::VideoSendStream const* const internal_stream_;
72};
73} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000074
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080075namespace {
76constexpr int64_t kRtcpIntervalMs = 1000;
77
Yves Gerey665174f2018-06-19 15:03:05 +020078enum VideoFormat {
79 kGeneric,
80 kVP8,
81};
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080082} // namespace
sprang@webrtc.org346094c2014-02-18 08:40:33 +000083
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070084VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000085
Sebastian Jansson63470292019-02-01 10:13:43 +010086class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000087 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000088 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000089 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000090 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010091
92 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
93 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070094
95 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000096};
97
Sebastian Jansson63470292019-02-01 10:13:43 +010098TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070099 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200100 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000101
eladalon413ee9a2017-08-22 04:02:52 -0700102 test::NullTransport transport;
103 CreateSendConfig(1, 0, 0, &transport);
104 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200105 GetVideoSendStream()->Start();
106 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700107 DestroyStreams();
108 DestroyCalls();
109 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000110}
111
Sebastian Jansson63470292019-02-01 10:13:43 +0100112TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700113 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200114 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000115
eladalon413ee9a2017-08-22 04:02:52 -0700116 test::NullTransport transport;
117 CreateSendConfig(1, 0, 0, &transport);
118 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200119 GetVideoSendStream()->Stop();
120 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700121 DestroyStreams();
122 DestroyCalls();
123 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000124}
125
Sebastian Jansson63470292019-02-01 10:13:43 +0100126TEST_F(VideoSendStreamTest, SupportsCName) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000127 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000128 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000129 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000130 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000131
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000132 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000133 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700134 test::RtcpPacketParser parser;
135 EXPECT_TRUE(parser.Parse(packet, length));
136 if (parser.sdes()->num_packets() > 0) {
137 EXPECT_EQ(1u, parser.sdes()->chunks().size());
138 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000139
danilchap3dc929e2016-11-02 08:21:59 -0700140 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000141 }
142
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000143 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000144 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000145
stefanff483612015-12-21 03:14:00 -0800146 void ModifyVideoConfigs(
147 VideoSendStream::Config* send_config,
148 std::vector<VideoReceiveStream::Config>* receive_configs,
149 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000150 send_config->rtp.c_name = kCName;
151 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000152
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000153 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100154 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000155 }
156 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000157
stefane74eef12016-01-08 06:47:13 -0800158 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000159}
160
Sebastian Jansson63470292019-02-01 10:13:43 +0100161TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000162 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000163 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000164 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000165 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100166 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000167 }
168
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000169 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000170 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000171 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000172
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000173 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
174 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
175 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700176 if (header.extension.absoluteSendTime != 0) {
177 // Wait for at least one packet with a non-zero send time. The send time
178 // is a 16-bit value derived from the system clock, and it is valid
179 // for a packet to have a zero send time. To tell that from an
180 // unpopulated value we'll wait for a packet with non-zero send time.
181 observation_complete_.Set();
182 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100183 RTC_LOG(LS_WARNING)
184 << "Got a packet with zero absoluteSendTime, waiting"
185 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700186 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000187
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000188 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000189 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000190
stefanff483612015-12-21 03:14:00 -0800191 void ModifyVideoConfigs(
192 VideoSendStream::Config* send_config,
193 std::vector<VideoReceiveStream::Config>* receive_configs,
194 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200195 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100196 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700197 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000198 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000199
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000200 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100201 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000202 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000203 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000204
stefane74eef12016-01-08 06:47:13 -0800205 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000206}
207
Sebastian Jansson63470292019-02-01 10:13:43 +0100208TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000209 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000210 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000211 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000212 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200213 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200214 return absl::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200215 Clock::GetRealTimeClock(), kEncodeDelayMs);
216 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000217 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100218 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000219 }
220
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000221 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000222 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000223 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000224 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000225
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000226 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
227 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000228 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000229 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100230 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000231
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000232 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000233 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000234
stefanff483612015-12-21 03:14:00 -0800235 void ModifyVideoConfigs(
236 VideoSendStream::Config* send_config,
237 std::vector<VideoReceiveStream::Config>* receive_configs,
238 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200239 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100240 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700241 send_config->rtp.extensions.push_back(RtpExtension(
242 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000243 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000244
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000245 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100246 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000247 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000248
Niels Möller4db138e2018-04-19 09:04:13 +0200249 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000250 } test;
251
stefane74eef12016-01-08 06:47:13 -0800252 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000253}
254
Sebastian Jansson63470292019-02-01 10:13:43 +0100255TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700256 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700257 class TransportWideSequenceNumberObserver : public test::SendTest {
258 public:
259 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200260 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200261 return absl::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200262 Clock::GetRealTimeClock());
263 }) {
sprang867fb522015-08-03 04:38:41 -0700264 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
265 kRtpExtensionTransportSequenceNumber, kExtensionId));
266 }
267
268 private:
269 Action OnSendRtp(const uint8_t* packet, size_t length) override {
270 RTPHeader header;
271 EXPECT_TRUE(parser_->Parse(packet, length, &header));
272
273 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
274 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
275 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
276
Peter Boström5811a392015-12-10 13:02:50 +0100277 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700278
279 return SEND_PACKET;
280 }
281
stefanff483612015-12-21 03:14:00 -0800282 void ModifyVideoConfigs(
283 VideoSendStream::Config* send_config,
284 std::vector<VideoReceiveStream::Config>* receive_configs,
285 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200286 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700287 }
288
289 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100290 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700291 }
292
Niels Möller4db138e2018-04-19 09:04:13 +0200293 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700294 } test;
295
stefane74eef12016-01-08 06:47:13 -0800296 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700297}
298
Sebastian Jansson63470292019-02-01 10:13:43 +0100299TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
perkj803d97f2016-11-01 11:45:46 -0700300 class VideoRotationObserver : public test::SendTest {
301 public:
302 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
303 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
304 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
305 }
306
307 Action OnSendRtp(const uint8_t* packet, size_t length) override {
308 RTPHeader header;
309 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700310 // Only the last packet of the frame is required to have the extension.
311 if (!header.markerBit)
312 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700313 EXPECT_TRUE(header.extension.hasVideoRotation);
314 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
315 observation_complete_.Set();
316 return SEND_PACKET;
317 }
318
319 void ModifyVideoConfigs(
320 VideoSendStream::Config* send_config,
321 std::vector<VideoReceiveStream::Config>* receive_configs,
322 VideoEncoderConfig* encoder_config) override {
323 send_config->rtp.extensions.clear();
324 send_config->rtp.extensions.push_back(RtpExtension(
325 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
326 }
327
328 void OnFrameGeneratorCapturerCreated(
329 test::FrameGeneratorCapturer* frame_generator_capturer) override {
330 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
331 }
332
333 void PerformTest() override {
334 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
335 }
336 } test;
337
338 RunBaseTest(&test);
339}
340
Sebastian Jansson63470292019-02-01 10:13:43 +0100341TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700342 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700343 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100344 VideoContentTypeObserver()
345 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700346 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
347 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
348 }
349
350 Action OnSendRtp(const uint8_t* packet, size_t length) override {
351 RTPHeader header;
352 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100353 // Only the last packet of the key-frame must have extension.
354 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700355 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100356 // First marker bit seen means that the first frame is sent.
357 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700358 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700359 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
360 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700361 observation_complete_.Set();
362 return SEND_PACKET;
363 }
364
365 void ModifyVideoConfigs(
366 VideoSendStream::Config* send_config,
367 std::vector<VideoReceiveStream::Config>* receive_configs,
368 VideoEncoderConfig* encoder_config) override {
369 send_config->rtp.extensions.clear();
370 send_config->rtp.extensions.push_back(
371 RtpExtension(RtpExtension::kVideoContentTypeUri,
372 test::kVideoContentTypeExtensionId));
373 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
374 }
375
376 void PerformTest() override {
377 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
378 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100379
380 private:
381 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700382 } test;
383
384 RunBaseTest(&test);
385}
386
Sebastian Jansson63470292019-02-01 10:13:43 +0100387TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700388 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700389 public:
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100390 VideoTimingObserver()
391 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik04f4d122017-06-19 07:18:55 -0700392 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
393 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
394 }
395
396 Action OnSendRtp(const uint8_t* packet, size_t length) override {
397 RTPHeader header;
398 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700399 // Only the last packet of the frame must have extension.
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100400 // Also don't check packets of the second frame if they happen to get
401 // through before the test terminates.
402 if (!header.markerBit || first_frame_sent_)
ilnik10894992017-06-21 08:23:19 -0700403 return SEND_PACKET;
404 EXPECT_TRUE(header.extension.has_video_timing);
405 observation_complete_.Set();
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100406 first_frame_sent_ = true;
ilnik04f4d122017-06-19 07:18:55 -0700407 return SEND_PACKET;
408 }
409
410 void ModifyVideoConfigs(
411 VideoSendStream::Config* send_config,
412 std::vector<VideoReceiveStream::Config>* receive_configs,
413 VideoEncoderConfig* encoder_config) override {
414 send_config->rtp.extensions.clear();
415 send_config->rtp.extensions.push_back(RtpExtension(
416 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
417 }
418
419 void PerformTest() override {
420 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
421 }
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100422
423 private:
424 bool first_frame_sent_;
ilnik04f4d122017-06-19 07:18:55 -0700425 } test;
426
427 RunBaseTest(&test);
428}
429
danilchap901b2df2017-07-28 08:56:04 -0700430class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000431 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000432 FakeReceiveStatistics(uint32_t send_ssrc,
433 uint32_t last_sequence_number,
434 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700435 uint8_t fraction_lost) {
436 stat_.SetMediaSsrc(send_ssrc);
437 stat_.SetExtHighestSeqNum(last_sequence_number);
438 stat_.SetCumulativeLost(cumulative_lost);
439 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000440 }
441
danilchap901b2df2017-07-28 08:56:04 -0700442 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
443 EXPECT_GE(max_blocks, 1u);
444 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000445 }
446
447 private:
danilchap901b2df2017-07-28 08:56:04 -0700448 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000449};
450
brandtre602f0a2016-10-31 03:40:49 -0700451class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100452 public:
brandtre602f0a2016-10-31 03:40:49 -0700453 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800454 bool use_nack,
455 bool expect_red,
456 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800457 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200458 VideoEncoderFactory* encoder_factory)
brandtr20d45472017-01-02 00:34:27 -0800459 : EndToEndTest(kTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200460 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100461 payload_name_(codec),
462 use_nack_(use_nack),
463 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700464 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800465 sent_media_(false),
466 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800467 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100468
brandtr20d45472017-01-02 00:34:27 -0800469 // Some of the test cases are expected to time out and thus we are using
470 // a shorter timeout window than the default here.
471 static constexpr size_t kTimeoutMs = 10000;
472
Stefan Holmer4654d202015-12-08 09:10:43 +0100473 private:
474 Action OnSendRtp(const uint8_t* packet, size_t length) override {
475 RTPHeader header;
476 EXPECT_TRUE(parser_->Parse(packet, length, &header));
477
Stefan Holmer4654d202015-12-08 09:10:43 +0100478 int encapsulated_payload_type = -1;
479 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100480 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100481 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
482 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100483 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100484 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
485 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100486 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100487 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100488 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
489 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100490 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
491 length) {
492 // Not padding-only, media received outside of RED.
493 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800494 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100495 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100496 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000497
Stefan Holmer4654d202015-12-08 09:10:43 +0100498 if (header_extensions_enabled_) {
499 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
500 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
501 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
502 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
503 // 24 bits wrap.
504 EXPECT_GT(prev_header_.extension.absoluteSendTime,
505 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000506 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100507 EXPECT_GE(header.extension.absoluteSendTime,
508 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200509 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100510 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
511 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
512 prev_header_.extension.transportSequenceNumber;
513 EXPECT_EQ(1, seq_num_diff);
514 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200515
Stefan Holmer4654d202015-12-08 09:10:43 +0100516 if (encapsulated_payload_type != -1) {
517 if (encapsulated_payload_type ==
518 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700519 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800520 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100521 } else {
brandtr65a1e772016-12-12 01:54:58 -0800522 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000523 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000524 }
525
brandtr20d45472017-01-02 00:34:27 -0800526 if (sent_media_ && sent_ulpfec_) {
527 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100528 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000529
Stefan Holmer4654d202015-12-08 09:10:43 +0100530 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000531
Stefan Holmer4654d202015-12-08 09:10:43 +0100532 return SEND_PACKET;
533 }
534
eladalon413ee9a2017-08-22 04:02:52 -0700535 test::PacketTransport* CreateSendTransport(
536 test::SingleThreadedTaskQueueForTesting* task_queue,
537 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100538 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
539 // Configure some network delay.
540 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200541 BuiltInNetworkBehaviorConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800542 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100543 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700544 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700545 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200546 VideoSendStreamTest::payload_type_map_,
547 absl::make_unique<FakeNetworkPipe>(
548 Clock::GetRealTimeClock(),
549 absl::make_unique<SimulatedNetwork>(config)));
Peter Boström39593972016-02-15 11:27:15 +0100550 }
551
stefanff483612015-12-21 03:14:00 -0800552 void ModifyVideoConfigs(
553 VideoSendStream::Config* send_config,
554 std::vector<VideoReceiveStream::Config>* receive_configs,
555 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100556 if (use_nack_) {
557 send_config->rtp.nack.rtp_history_ms =
558 (*receive_configs)[0].rtp.nack.rtp_history_ms =
559 VideoSendStreamTest::kNackRtpHistoryMs;
560 }
Niels Möller4db138e2018-04-19 09:04:13 +0200561 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200562 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700563 send_config->rtp.ulpfec.red_payload_type =
564 VideoSendStreamTest::kRedPayloadType;
565 send_config->rtp.ulpfec.ulpfec_payload_type =
566 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800567 EXPECT_FALSE(send_config->rtp.extensions.empty());
568 if (!header_extensions_enabled_) {
569 send_config->rtp.extensions.clear();
570 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100571 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700572 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100573 }
Niels Möller259a4972018-04-05 15:36:51 +0200574 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700575 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700576 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700577 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700578 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100579 }
580
581 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800582 EXPECT_EQ(expect_ulpfec_, Wait())
583 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100584 }
585
Niels Möller4db138e2018-04-19 09:04:13 +0200586 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800587 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100588 const bool use_nack_;
589 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700590 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800591 bool sent_media_;
592 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100593 bool header_extensions_enabled_;
594 RTPHeader prev_header_;
595};
596
Sebastian Jansson63470292019-02-01 10:13:43 +0100597TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200598 test::FunctionVideoEncoderFactory encoder_factory(
599 []() { return VP8Encoder::Create(); });
600 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800601 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100602}
603
Sebastian Jansson63470292019-02-01 10:13:43 +0100604TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200605 test::FunctionVideoEncoderFactory encoder_factory(
606 []() { return VP8Encoder::Create(); });
607 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100608 RunBaseTest(&test);
609}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000610
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200611class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
stefan60e10c72017-08-23 10:40:00 -0700612 protected:
613 VideoSendStreamWithoutUlpfecTest()
614 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
615
616 test::ScopedFieldTrials field_trial_;
617};
618
619TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200620 test::FunctionVideoEncoderFactory encoder_factory(
621 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200622 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700623 RunBaseTest(&test);
624}
625
Peter Boström39593972016-02-15 11:27:15 +0100626// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
627// since we'll still have to re-request FEC packets, effectively wasting
628// bandwidth since the receiver has to wait for FEC retransmissions to determine
629// that the received state is actually decodable.
Sebastian Jansson63470292019-02-01 10:13:43 +0100630TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200631 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200632 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200633 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200634 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100635 RunBaseTest(&test);
636}
637
638// Without retransmissions FEC for H264 is fine.
Sebastian Jansson63470292019-02-01 10:13:43 +0100639TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200640 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200641 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200642 });
643 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100644 RunBaseTest(&test);
645}
646
danilchap9f5b6222017-03-02 06:22:21 -0800647// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Jansson63470292019-02-01 10:13:43 +0100648TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200649 test::FunctionVideoEncoderFactory encoder_factory(
650 []() { return VP8Encoder::Create(); });
651 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100652 RunBaseTest(&test);
653}
654
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100655#if defined(RTC_ENABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800656// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Jansson63470292019-02-01 10:13:43 +0100657TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200658 test::FunctionVideoEncoderFactory encoder_factory(
659 []() { return VP9Encoder::Create(); });
660 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800661 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000662}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100663#endif // defined(RTC_ENABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000664
Sebastian Jansson63470292019-02-01 10:13:43 +0100665TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200666 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200667 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200668 Clock::GetRealTimeClock());
669 });
670 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800671 RunBaseTest(&test);
672}
673
brandtr39f97292016-11-16 22:57:50 -0800674// TODO(brandtr): Move these FlexFEC tests when we have created
675// FlexfecSendStream.
676class FlexfecObserver : public test::EndToEndTest {
677 public:
678 FlexfecObserver(bool header_extensions_enabled,
679 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800680 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200681 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100682 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800683 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200684 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800685 payload_name_(codec),
686 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800687 sent_media_(false),
688 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100689 header_extensions_enabled_(header_extensions_enabled),
690 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800691
692 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100693 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800694
695 private:
696 Action OnSendRtp(const uint8_t* packet, size_t length) override {
697 RTPHeader header;
698 EXPECT_TRUE(parser_->Parse(packet, length, &header));
699
brandtr39f97292016-11-16 22:57:50 -0800700 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
701 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
702 sent_flexfec_ = true;
703 } else {
704 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
705 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100706 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
707 num_video_streams_),
708 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800709 sent_media_ = true;
710 }
711
712 if (header_extensions_enabled_) {
713 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
714 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
715 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
716 }
717
brandtr0c5a1542016-11-23 04:42:26 -0800718 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800719 observation_complete_.Set();
720 }
721
722 return SEND_PACKET;
723 }
724
eladalon413ee9a2017-08-22 04:02:52 -0700725 test::PacketTransport* CreateSendTransport(
726 test::SingleThreadedTaskQueueForTesting* task_queue,
727 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800728 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
729 // Therefore we need some network delay.
730 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200731 BuiltInNetworkBehaviorConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800732 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800733 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700734 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700735 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200736 VideoSendStreamTest::payload_type_map_,
737 absl::make_unique<FakeNetworkPipe>(
738 Clock::GetRealTimeClock(),
739 absl::make_unique<SimulatedNetwork>(config)));
brandtr39f97292016-11-16 22:57:50 -0800740 }
741
742 void ModifyVideoConfigs(
743 VideoSendStream::Config* send_config,
744 std::vector<VideoReceiveStream::Config>* receive_configs,
745 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800746 if (use_nack_) {
747 send_config->rtp.nack.rtp_history_ms =
748 (*receive_configs)[0].rtp.nack.rtp_history_ms =
749 VideoSendStreamTest::kNackRtpHistoryMs;
750 }
Niels Möller4db138e2018-04-19 09:04:13 +0200751 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200752 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800753 if (header_extensions_enabled_) {
754 send_config->rtp.extensions.push_back(RtpExtension(
755 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
756 send_config->rtp.extensions.push_back(RtpExtension(
757 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800758 } else {
759 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800760 }
Niels Möller259a4972018-04-05 15:36:51 +0200761 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800762 }
763
764 void PerformTest() override {
765 EXPECT_TRUE(Wait())
766 << "Timed out waiting for FlexFEC and/or media packets.";
767 }
768
Niels Möller4db138e2018-04-19 09:04:13 +0200769 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800770 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800771 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800772 bool sent_media_;
773 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100774 const bool header_extensions_enabled_;
775 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800776};
777
Sebastian Jansson63470292019-02-01 10:13:43 +0100778TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200779 test::FunctionVideoEncoderFactory encoder_factory(
780 []() { return VP8Encoder::Create(); });
781 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100782 RunBaseTest(&test);
783}
784
Sebastian Jansson63470292019-02-01 10:13:43 +0100785TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200786 test::FunctionVideoEncoderFactory encoder_factory(
787 []() { return VP8Encoder::Create(); });
788 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800789 RunBaseTest(&test);
790}
791
Sebastian Jansson63470292019-02-01 10:13:43 +0100792TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200793 test::FunctionVideoEncoderFactory encoder_factory(
794 []() { return VP8Encoder::Create(); });
795 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800796 RunBaseTest(&test);
797}
798
Sebastian Jansson63470292019-02-01 10:13:43 +0100799TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200800 test::FunctionVideoEncoderFactory encoder_factory(
801 []() { return VP8Encoder::Create(); });
802 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800803 RunBaseTest(&test);
804}
805
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100806#if defined(RTC_ENABLE_VP9)
Sebastian Jansson63470292019-02-01 10:13:43 +0100807TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200808 test::FunctionVideoEncoderFactory encoder_factory(
809 []() { return VP9Encoder::Create(); });
810 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800811 RunBaseTest(&test);
812}
813
Sebastian Jansson63470292019-02-01 10:13:43 +0100814TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200815 test::FunctionVideoEncoderFactory encoder_factory(
816 []() { return VP9Encoder::Create(); });
817 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800818 RunBaseTest(&test);
819}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100820#endif // defined(RTC_ENABLE_VP9)
brandtr39f97292016-11-16 22:57:50 -0800821
Sebastian Jansson63470292019-02-01 10:13:43 +0100822TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200823 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200824 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200825 });
826 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800827 RunBaseTest(&test);
828}
829
Sebastian Jansson63470292019-02-01 10:13:43 +0100830TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200831 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200832 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200833 });
834 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800835 RunBaseTest(&test);
836}
837
Sebastian Jansson63470292019-02-01 10:13:43 +0100838TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200839 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200840 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200841 Clock::GetRealTimeClock());
842 });
843
844 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800845 RunBaseTest(&test);
846}
847
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000848void VideoSendStreamTest::TestNackRetransmission(
849 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000850 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000851 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000852 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000853 explicit NackObserver(uint32_t retransmit_ssrc,
854 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000855 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000856 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100857 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000858 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100859 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000860
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000861 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000862 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000863 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000864 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000865
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200866 // NACK packets two times at some arbitrary points.
867 const int kNackedPacketsAtOnceCount = 3;
868 const int kRetransmitTarget = kNackedPacketsAtOnceCount * 2;
869
870 // Skip padding packets because they will never be retransmitted.
871 if (header.paddingLength + header.headerLength == length) {
872 return SEND_PACKET;
873 }
874
Sebastian Janssond3f38162018-02-28 16:14:44 +0100875 ++send_count_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200876
877 // NACK packets at arbitrary points.
Sebastian Janssond3f38162018-02-28 16:14:44 +0100878 if (send_count_ == 5 || send_count_ == 25) {
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200879 nacked_sequence_numbers_.insert(
880 nacked_sequence_numbers_.end(),
881 non_padding_sequence_numbers_.end() - kNackedPacketsAtOnceCount,
882 non_padding_sequence_numbers_.end());
Sebastian Janssond3f38162018-02-28 16:14:44 +0100883
danilchap8a1d2a32017-08-01 03:21:37 -0700884 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800885 nullptr, nullptr, transport_adapter_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800886 kRtcpIntervalMs);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000887
pbosda903ea2015-10-02 02:36:56 -0700888 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100889 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000890
891 RTCPSender::FeedbackState feedback_state;
892
Sebastian Janssond3f38162018-02-28 16:14:44 +0100893 EXPECT_EQ(0, rtcp_sender.SendRTCP(
894 feedback_state, kRtcpNack,
895 static_cast<int>(nacked_sequence_numbers_.size()),
896 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000897 }
898
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000899 uint16_t sequence_number = header.sequenceNumber;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000900 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100901 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
902 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000903 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000904 const uint8_t* rtx_header = packet + header.headerLength;
905 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
906 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200907
Sebastian Janssond3f38162018-02-28 16:14:44 +0100908 auto found = std::find(nacked_sequence_numbers_.begin(),
909 nacked_sequence_numbers_.end(), sequence_number);
910 if (found != nacked_sequence_numbers_.end()) {
911 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000912
Sebastian Janssond3f38162018-02-28 16:14:44 +0100913 if (++retransmit_count_ == kRetransmitTarget) {
914 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
915 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
916 observation_complete_.Set();
917 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200918 } else {
919 non_padding_sequence_numbers_.push_back(sequence_number);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000920 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000921
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000922 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000923 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000924
stefanff483612015-12-21 03:14:00 -0800925 void ModifyVideoConfigs(
926 VideoSendStream::Config* send_config,
927 std::vector<VideoReceiveStream::Config>* receive_configs,
928 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700929 transport_adapter_.reset(
930 new internal::TransportAdapter(send_config->send_transport));
931 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000932 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000933 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100934 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000935 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
936 }
937
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000938 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100939 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000940 }
941
kwiberg27f982b2016-03-01 11:52:33 -0800942 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000943 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100944 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000945 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000946 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100947 std::vector<uint16_t> nacked_sequence_numbers_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200948 std::vector<uint16_t> non_padding_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000949 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000950
stefane74eef12016-01-08 06:47:13 -0800951 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000952}
953
Sebastian Jansson63470292019-02-01 10:13:43 +0100954TEST_F(VideoSendStreamTest, RetransmitsNack) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000955 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100956 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000957}
958
Sebastian Jansson63470292019-02-01 10:13:43 +0100959TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000960 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000961 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000962}
963
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000964void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
965 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000966 // Use a fake encoder to output a frame of every size in the range [90, 290],
967 // for each size making sure that the exact number of payload bytes received
968 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000969 static const size_t kMaxPacketSize = 128;
970 static const size_t start = 90;
971 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000972
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000973 // Observer that verifies that the expected number of packets and bytes
974 // arrive for each frame size, from start_size to stop_size.
Niels Möller759f9592018-10-09 14:57:01 +0200975 class FrameFragmentationTest : public test::SendTest {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000976 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000977 FrameFragmentationTest(size_t max_packet_size,
978 size_t start_size,
979 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000980 bool test_generic_packetization,
981 bool use_fec)
982 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000983 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +0200984 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000985 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000986 stop_size_(stop_size),
987 test_generic_packetization_(test_generic_packetization),
988 use_fec_(use_fec),
989 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100990 packets_lost_(0),
991 last_packet_count_(0),
992 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000993 accumulated_size_(0),
994 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000995 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000996 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700997 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000998 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000999 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -07001000 RTC_DCHECK_GT(stop_size, max_packet_size);
Philip Eliassond52a1a62018-09-07 13:03:55 +00001001 if (!test_generic_packetization_)
1002 encoder_.SetCodecType(kVideoCodecVP8);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001003 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001004
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001005 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001006 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001007 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001008 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001009 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001010
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001011 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001012
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001013 if (use_fec_) {
1014 uint8_t payload_type = packet[header.headerLength];
1015 bool is_fec = header.payloadType == kRedPayloadType &&
1016 payload_type == kUlpfecPayloadType;
1017 if (is_fec) {
1018 fec_packet_received_ = true;
1019 return SEND_PACKET;
1020 }
1021 }
1022
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001023 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001024
1025 if (use_fec_)
1026 TriggerLossReport(header);
1027
1028 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +02001029 size_t overhead = header.headerLength + header.paddingLength;
1030 // Only remove payload header and RED header if the packet actually
1031 // contains payload.
1032 if (length > overhead) {
1033 overhead += (1 /* Generic header */);
1034 if (use_fec_)
1035 overhead += 1; // RED for FEC header.
1036 }
1037 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001038 accumulated_payload_ += length - overhead;
1039 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001040
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001041 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001042 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001043 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1044 // With FEC enabled, frame size is incremented asynchronously, so
1045 // "old" frames one byte too small may arrive. Accept, but don't
1046 // increase expected frame size.
1047 accumulated_size_ = 0;
1048 accumulated_payload_ = 0;
1049 return SEND_PACKET;
1050 }
1051
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001052 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001053 if (test_generic_packetization_) {
1054 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1055 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001056
1057 // Last packet of frame; reset counters.
1058 accumulated_size_ = 0;
1059 accumulated_payload_ = 0;
1060 if (current_size_rtp_ == stop_size_) {
1061 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001062 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001063 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001064 // Increase next expected frame size. If testing with FEC, make sure
1065 // a FEC packet has been received for this frame size before
1066 // proceeding, to make sure that redundancy packets don't exceed
1067 // size limit.
1068 if (!use_fec_) {
1069 ++current_size_rtp_;
1070 } else if (fec_packet_received_) {
1071 fec_packet_received_ = false;
1072 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001073
1074 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001075 ++current_size_frame_;
1076 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001077 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001078 }
1079
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001080 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001081 }
1082
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001083 void TriggerLossReport(const RTPHeader& header) {
1084 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001085 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001086 if (++packet_count_ % (100 / kLossPercent) == 0) {
1087 packets_lost_++;
1088 int loss_delta = packets_lost_ - last_packets_lost_;
1089 int packets_delta = packet_count_ - last_packet_count_;
1090 last_packet_count_ = packet_count_;
1091 last_packets_lost_ = packets_lost_;
1092 uint8_t loss_ratio =
1093 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001094 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001095 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001096 packets_lost_, // Cumulative lost.
1097 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001098 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001099 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001100 transport_adapter_.get(), kRtcpIntervalMs);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001101
pbosda903ea2015-10-02 02:36:56 -07001102 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001103 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001104
1105 RTCPSender::FeedbackState feedback_state;
1106
1107 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1108 }
1109 }
1110
Niels Möller759f9592018-10-09 14:57:01 +02001111 void UpdateConfiguration() {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001112 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001113 // Increase frame size for next encoded frame, in the context of the
1114 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001115 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001116 ++current_size_frame_;
1117 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001118 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001119 }
Niels Möllerde8e6e62018-11-13 15:10:33 +01001120 void ModifySenderBitrateConfig(
1121 BitrateConstraints* bitrate_config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001122 const int kMinBitrateBps = 30000;
Niels Möllerde8e6e62018-11-13 15:10:33 +01001123 bitrate_config->min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001124 }
1125
stefanff483612015-12-21 03:14:00 -08001126 void ModifyVideoConfigs(
1127 VideoSendStream::Config* send_config,
1128 std::vector<VideoReceiveStream::Config>* receive_configs,
1129 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001130 transport_adapter_.reset(
1131 new internal::TransportAdapter(send_config->send_transport));
1132 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001133 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001134 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1135 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001136 }
1137
1138 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001139 send_config->rtp.payload_name = "VP8";
Philip Eliassond52a1a62018-09-07 13:03:55 +00001140
Niels Möller4db138e2018-04-19 09:04:13 +02001141 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001142 send_config->rtp.max_packet_size = kMaxPacketSize;
Niels Möller759f9592018-10-09 14:57:01 +02001143 encoder_.RegisterPostEncodeCallback([this]() { UpdateConfiguration(); });
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001144
Erik Språng95261872015-04-10 11:58:49 +02001145 // Make sure there is at least one extension header, to make the RTP
1146 // header larger than the base length of 12 bytes.
1147 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001148
1149 // Setup screen content disables frame dropping which makes this easier.
Åsa Perssond34597c2018-10-22 17:34:02 +02001150 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
1151 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
sprang4847ae62017-06-27 07:06:52 -07001152 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001153 }
1154
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001155 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001156 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001157 }
1158
kwiberg27f982b2016-03-01 11:52:33 -08001159 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001160 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möllercbcbc222018-09-28 09:07:24 +02001161 test::VideoEncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001162
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001163 const size_t max_packet_size_;
1164 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001165 const bool test_generic_packetization_;
1166 const bool use_fec_;
1167
1168 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001169 uint32_t packets_lost_;
1170 uint32_t last_packet_count_;
1171 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001172 size_t accumulated_size_;
1173 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001174 bool fec_packet_received_;
1175
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001176 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001177 rtc::CriticalSection mutex_;
1178 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001179 };
1180
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001181 // Don't auto increment if FEC is used; continue sending frame size until
1182 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001183 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1184 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001185
stefane74eef12016-01-08 06:47:13 -08001186 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001187}
1188
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001189// TODO(sprang): Is there any way of speeding up these tests?
Sebastian Jansson63470292019-02-01 10:13:43 +01001190TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001191 TestPacketFragmentationSize(kGeneric, false);
1192}
1193
Sebastian Jansson63470292019-02-01 10:13:43 +01001194TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001195 TestPacketFragmentationSize(kGeneric, true);
1196}
1197
Sebastian Jansson63470292019-02-01 10:13:43 +01001198TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001199 TestPacketFragmentationSize(kVP8, false);
1200}
1201
Sebastian Jansson63470292019-02-01 10:13:43 +01001202TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001203 TestPacketFragmentationSize(kVP8, true);
1204}
1205
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001206// The test will go through a number of phases.
1207// 1. Start sending packets.
1208// 2. As soon as the RTP stream has been detected, signal a low REMB value to
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001209// suspend the stream.
1210// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001211// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001212// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001213// When the stream is detected again, and the stats show that the stream
1214// is no longer suspended, the test ends.
Sebastian Jansson63470292019-02-01 10:13:43 +01001215TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001216 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001217
Niels Möller412d1852019-01-02 09:42:54 +01001218 class RembObserver : public test::SendTest {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001219 public:
Niels Möller412d1852019-01-02 09:42:54 +01001220 class CaptureObserver : public rtc::VideoSinkInterface<VideoFrame> {
1221 public:
1222 explicit CaptureObserver(RembObserver* remb_observer)
1223 : remb_observer_(remb_observer) {}
1224
1225 void OnFrame(const VideoFrame&) {
1226 rtc::CritScope lock(&remb_observer_->crit_);
1227 if (remb_observer_->test_state_ == kDuringSuspend &&
1228 ++remb_observer_->suspended_frame_count_ > kSuspendTimeFrames) {
1229 VideoSendStream::Stats stats = remb_observer_->stream_->GetStats();
1230 EXPECT_TRUE(stats.suspended);
1231 remb_observer_->SendRtcpFeedback(remb_observer_->high_remb_bps_);
1232 remb_observer_->test_state_ = kWaitingForPacket;
1233 }
1234 }
1235
1236 private:
1237 RembObserver* const remb_observer_;
1238 };
1239
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001240 RembObserver()
1241 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001242 clock_(Clock::GetRealTimeClock()),
Niels Möller412d1852019-01-02 09:42:54 +01001243 capture_observer_(this),
Erik Språng737336d2016-07-29 12:59:36 +02001244 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001245 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001246 rtp_count_(0),
1247 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001248 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001249 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001250 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001251
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001252 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001253 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001254 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001255 ++rtp_count_;
1256 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001257 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001258 last_sequence_number_ = header.sequenceNumber;
1259
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001260 if (test_state_ == kBeforeSuspend) {
1261 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001262 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001263 test_state_ = kDuringSuspend;
1264 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001265 if (header.paddingLength == 0) {
1266 // Received non-padding packet during suspension period. Reset the
1267 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001268 suspended_frame_count_ = 0;
1269 }
stefanf116bd02015-10-27 08:29:42 -07001270 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001271 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001272 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001273 // Non-padding packet observed. Test is almost complete. Will just
1274 // have to wait for the stats to change.
1275 test_state_ = kWaitingForStats;
1276 }
stefanf116bd02015-10-27 08:29:42 -07001277 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001278 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001279 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001280 if (stats.suspended == false) {
1281 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001282 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001283 }
stefanf116bd02015-10-27 08:29:42 -07001284 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001285 }
1286
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001287 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001288 }
1289
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001290 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001291 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001292 low_remb_bps_ = value;
1293 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001294
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001295 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001296 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001297 high_remb_bps_ = value;
1298 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001299
stefanff483612015-12-21 03:14:00 -08001300 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001301 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001302 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001303 stream_ = send_stream;
1304 }
1305
Niels Möller412d1852019-01-02 09:42:54 +01001306 void OnFrameGeneratorCapturerCreated(
1307 test::FrameGeneratorCapturer* frame_generator_capturer) override {
1308 frame_generator_capturer->AddOrUpdateSink(&capture_observer_,
1309 rtc::VideoSinkWants());
1310 }
1311
stefanff483612015-12-21 03:14:00 -08001312 void ModifyVideoConfigs(
1313 VideoSendStream::Config* send_config,
1314 std::vector<VideoReceiveStream::Config>* receive_configs,
1315 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001316 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001317 transport_adapter_.reset(
1318 new internal::TransportAdapter(send_config->send_transport));
1319 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001320 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001321 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001322 int min_bitrate_bps =
1323 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001324 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001325 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001326 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001327 min_bitrate_bps + threshold_window + 5000);
1328 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1329 }
1330
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001331 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001332 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001333 }
1334
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001335 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001336 kBeforeSuspend,
1337 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001338 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001339 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001340 };
1341
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001342 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001343 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001344 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1345 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001346 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001347 transport_adapter_.get(), kRtcpIntervalMs);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001348
pbosda903ea2015-10-02 02:36:56 -07001349 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001350 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001351 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001352 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001353 }
1354 RTCPSender::FeedbackState feedback_state;
1355 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1356 }
1357
kwiberg27f982b2016-03-01 11:52:33 -08001358 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001359 Clock* const clock_;
Niels Möller412d1852019-01-02 09:42:54 +01001360 CaptureObserver capture_observer_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001361 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001362
Peter Boströmf2f82832015-05-01 13:00:41 +02001363 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001364 TestState test_state_ RTC_GUARDED_BY(crit_);
1365 int rtp_count_ RTC_GUARDED_BY(crit_);
1366 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1367 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1368 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1369 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001370 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001371
stefane74eef12016-01-08 06:47:13 -08001372 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001373}
1374
perkj71ee44c2016-06-15 00:47:53 -07001375// This test that padding stops being send after a while if the Camera stops
1376// producing video frames and that padding resumes if the camera restarts.
Sebastian Jansson63470292019-02-01 10:13:43 +01001377TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001378 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001379 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001380 NoPaddingWhenVideoIsMuted()
1381 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001382 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001383 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001384 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001385
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001386 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001387 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001388 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001389 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001390
1391 RTPHeader header;
1392 parser_->Parse(packet, length, &header);
1393 const bool only_padding =
1394 header.headerLength + header.paddingLength == length;
1395
1396 if (test_state_ == kBeforeStopCapture) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001397 // Packets are flowing, stop camera.
perkj71ee44c2016-06-15 00:47:53 -07001398 capturer_->Stop();
1399 test_state_ = kWaitingForPadding;
1400 } else if (test_state_ == kWaitingForPadding && only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001401 // We're still getting padding, after stopping camera.
perkj71ee44c2016-06-15 00:47:53 -07001402 test_state_ = kWaitingForNoPackets;
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001403 } else if (test_state_ == kWaitingForMediaAfterCameraRestart &&
1404 !only_padding) {
1405 // Media packets are flowing again, stop camera a second time.
1406 capturer_->Stop();
1407 test_state_ = kWaitingForPaddingAfterCameraStopsAgain;
1408 } else if (test_state_ == kWaitingForPaddingAfterCameraStopsAgain &&
perkj71ee44c2016-06-15 00:47:53 -07001409 only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001410 // Padding is still flowing, test ok.
perkj71ee44c2016-06-15 00:47:53 -07001411 observation_complete_.Set();
1412 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001413 return SEND_PACKET;
1414 }
1415
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001416 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001417 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001418 const int kNoPacketsThresholdMs = 2000;
1419 if (test_state_ == kWaitingForNoPackets &&
1420 (last_packet_time_ms_ > 0 &&
1421 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1422 kNoPacketsThresholdMs)) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001423 // No packets seen for |kNoPacketsThresholdMs|, restart camera.
perkj71ee44c2016-06-15 00:47:53 -07001424 capturer_->Start();
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001425 test_state_ = kWaitingForMediaAfterCameraRestart;
perkj71ee44c2016-06-15 00:47:53 -07001426 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001427 return SEND_PACKET;
1428 }
1429
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001430 void ModifyVideoConfigs(
1431 VideoSendStream::Config* send_config,
1432 std::vector<VideoReceiveStream::Config>* receive_configs,
1433 VideoEncoderConfig* encoder_config) override {
1434 // Make sure padding is sent if encoder is not producing media.
1435 encoder_config->min_transmit_bitrate_bps = 50000;
1436 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001437
nisseef8b61e2016-04-29 06:09:15 -07001438 void OnFrameGeneratorCapturerCreated(
1439 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001440 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001441 capturer_ = frame_generator_capturer;
1442 }
1443
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001444 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001445 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001446 << "Timed out while waiting for RTP packets to stop being sent.";
1447 }
1448
perkj71ee44c2016-06-15 00:47:53 -07001449 enum TestState {
1450 kBeforeStopCapture,
1451 kWaitingForPadding,
1452 kWaitingForNoPackets,
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001453 kWaitingForMediaAfterCameraRestart,
1454 kWaitingForPaddingAfterCameraStopsAgain
perkj71ee44c2016-06-15 00:47:53 -07001455 };
1456
1457 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001458 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001459 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001460 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001461 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1462 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001463 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001464
stefane74eef12016-01-08 06:47:13 -08001465 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001466}
1467
Sebastian Jansson63470292019-02-01 10:13:43 +01001468TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
isheriffcc5903e2016-10-04 08:29:38 -07001469 const int kCapacityKbps = 10000; // 10 Mbps
1470 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1471 public:
1472 PaddingIsPrimarilyRetransmissions()
1473 : EndToEndTest(kDefaultTimeoutMs),
1474 clock_(Clock::GetRealTimeClock()),
1475 padding_length_(0),
1476 total_length_(0),
1477 call_(nullptr) {}
1478
1479 private:
1480 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1481 call_ = sender_call;
1482 }
1483
1484 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1485 rtc::CritScope lock(&crit_);
1486
1487 RTPHeader header;
1488 parser_->Parse(packet, length, &header);
1489 padding_length_ += header.paddingLength;
1490 total_length_ += length;
1491 return SEND_PACKET;
1492 }
1493
eladalon413ee9a2017-08-22 04:02:52 -07001494 test::PacketTransport* CreateSendTransport(
1495 test::SingleThreadedTaskQueueForTesting* task_queue,
1496 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001497 const int kNetworkDelayMs = 50;
Artem Titov75e36472018-10-08 12:28:56 +02001498 BuiltInNetworkBehaviorConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001499 config.loss_percent = 10;
1500 config.link_capacity_kbps = kCapacityKbps;
1501 config.queue_delay_ms = kNetworkDelayMs;
Artem Titov4e199e92018-08-20 13:30:39 +02001502 return new test::PacketTransport(
1503 task_queue, sender_call, this, test::PacketTransport::kSender,
1504 payload_type_map_,
1505 absl::make_unique<FakeNetworkPipe>(
1506 Clock::GetRealTimeClock(),
1507 absl::make_unique<SimulatedNetwork>(config)));
isheriffcc5903e2016-10-04 08:29:38 -07001508 }
1509
1510 void ModifyVideoConfigs(
1511 VideoSendStream::Config* send_config,
1512 std::vector<VideoReceiveStream::Config>* receive_configs,
1513 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001514 // Turn on RTX.
1515 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1516 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001517 }
1518
1519 void PerformTest() override {
1520 // TODO(isheriff): Some platforms do not ramp up as expected to full
1521 // capacity due to packet scheduling delays. Fix that before getting
1522 // rid of this.
1523 SleepMs(5000);
1524 {
1525 rtc::CritScope lock(&crit_);
1526 // Expect padding to be a small percentage of total bytes sent.
1527 EXPECT_LT(padding_length_, .1 * total_length_);
1528 }
1529 }
1530
1531 rtc::CriticalSection crit_;
1532 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001533 size_t padding_length_ RTC_GUARDED_BY(crit_);
1534 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001535 Call* call_;
1536 } test;
1537
1538 RunBaseTest(&test);
1539}
1540
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001541// This test first observes "high" bitrate use at which point it sends a REMB to
1542// indicate that it should be lowered significantly. The test then observes that
1543// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1544// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001545//
1546// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1547// bitrate since no receiver block or remb is sent in the initial phase.
Sebastian Jansson63470292019-02-01 10:13:43 +01001548TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001549 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001550 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001551 static const int kRembBitrateBps = 80000;
1552 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001553 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001554 public:
1555 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001556 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001557 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1558 stream_(nullptr),
1559 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001560
1561 private:
nisseef8b61e2016-04-29 06:09:15 -07001562 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001563 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001564 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001565
1566 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001567 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001568 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001569 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001570 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001571 if (!stats.substreams.empty()) {
1572 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001573 int total_bitrate_bps =
1574 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001575 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1576 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1577 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001578 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001579 rtp_rtcp_->SetRemb(kRembBitrateBps,
1580 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001581 rtp_rtcp_->Process();
1582 bitrate_capped_ = true;
1583 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001584 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001585 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001586 }
1587 }
stefanf116bd02015-10-27 08:29:42 -07001588 // Packets don't have to be delivered since the test is the receiver.
1589 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001590 }
1591
stefanff483612015-12-21 03:14:00 -08001592 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001593 VideoSendStream* send_stream,
1594 const std::vector<VideoReceiveStream*>& receive_streams) override {
1595 stream_ = send_stream;
1596 RtpRtcp::Configuration config;
1597 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001598 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001599 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001600 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001601 }
1602
stefanff483612015-12-21 03:14:00 -08001603 void ModifyVideoConfigs(
1604 VideoSendStream::Config* send_config,
1605 std::vector<VideoReceiveStream::Config>* receive_configs,
1606 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001607 feedback_transport_.reset(
1608 new internal::TransportAdapter(send_config->send_transport));
1609 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001610 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001611 }
1612
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001613 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001614 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001615 << "Timeout while waiting for low bitrate stats after REMB.";
1616 }
1617
kwiberg27f982b2016-03-01 11:52:33 -08001618 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1619 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001620 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001621 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001622 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001623 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001624
stefane74eef12016-01-08 06:47:13 -08001625 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001626}
1627
Sebastian Jansson63470292019-02-01 10:13:43 +01001628TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001629 static const int kStartBitrateBps = 300000;
1630 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001631 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001632 class ChangingNetworkRouteTest : public test::EndToEndTest {
1633 public:
eladalon413ee9a2017-08-22 04:02:52 -07001634 explicit ChangingNetworkRouteTest(
1635 test::SingleThreadedTaskQueueForTesting* task_queue)
1636 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1637 task_queue_(task_queue),
1638 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001639 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1640 kRtpExtensionTransportSequenceNumber, kExtensionId));
1641 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001642
1643 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1644 call_ = sender_call;
1645 }
1646
Stefan Holmer280de9e2016-09-30 10:06:51 +02001647 void ModifyVideoConfigs(
1648 VideoSendStream::Config* send_config,
1649 std::vector<VideoReceiveStream::Config>* receive_configs,
1650 VideoEncoderConfig* encoder_config) override {
1651 send_config->rtp.extensions.clear();
1652 send_config->rtp.extensions.push_back(RtpExtension(
1653 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1654 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1655 (*receive_configs)[0].rtp.transport_cc = true;
1656 }
1657
1658 void ModifyAudioConfigs(
1659 AudioSendStream::Config* send_config,
1660 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1661 send_config->rtp.extensions.clear();
1662 send_config->rtp.extensions.push_back(RtpExtension(
1663 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1664 (*receive_configs)[0].rtp.extensions.clear();
1665 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1666 (*receive_configs)[0].rtp.transport_cc = true;
1667 }
1668
Stefan Holmerbe402962016-07-08 16:16:41 +02001669 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1670 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1671 observation_complete_.Set();
1672 }
1673
1674 return SEND_PACKET;
1675 }
1676
1677 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001678 rtc::NetworkRoute new_route;
1679 new_route.connected = true;
1680 new_route.local_network_id = 10;
1681 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001682 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001683
1684 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001685 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1686 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001687 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001688 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1689 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001690 });
1691
Stefan Holmerbe402962016-07-08 16:16:41 +02001692 EXPECT_TRUE(Wait())
1693 << "Timed out while waiting for start bitrate to be exceeded.";
1694
eladalon413ee9a2017-08-22 04:02:52 -07001695 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1696 bitrate_config.start_bitrate_bps = -1;
1697 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001698 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1699 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001700 // TODO(holmer): We should set the last sent packet id here and verify
1701 // that we correctly ignore any packet loss reported prior to that id.
1702 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001703 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1704 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001705 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1706 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001707 }
1708
1709 private:
eladalon413ee9a2017-08-22 04:02:52 -07001710 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001711 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001712 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001713
1714 RunBaseTest(&test);
1715}
1716
Sebastian Jansson63470292019-02-01 10:13:43 +01001717TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
michaelt79e05882016-11-08 02:50:09 -08001718 class ChangingTransportOverheadTest : public test::EndToEndTest {
1719 public:
eladalon413ee9a2017-08-22 04:02:52 -07001720 explicit ChangingTransportOverheadTest(
1721 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001722 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001723 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001724 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001725 packets_sent_(0),
1726 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001727
1728 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1729 call_ = sender_call;
1730 }
1731
1732 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001733 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001734 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001735 if (++packets_sent_ < 100)
1736 return SEND_PACKET;
1737 observation_complete_.Set();
1738 return SEND_PACKET;
1739 }
1740
michaelta3328772016-11-29 09:25:03 -08001741 void ModifyVideoConfigs(
1742 VideoSendStream::Config* send_config,
1743 std::vector<VideoReceiveStream::Config>* receive_configs,
1744 VideoEncoderConfig* encoder_config) override {
1745 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1746 }
1747
michaelt79e05882016-11-08 02:50:09 -08001748 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001749 task_queue_->SendTask([this]() {
1750 transport_overhead_ = 100;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001751 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1752 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001753 });
1754
michaelt79e05882016-11-08 02:50:09 -08001755 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001756
sprang21253fc2017-02-27 03:35:47 -08001757 {
1758 rtc::CritScope cs(&lock_);
1759 packets_sent_ = 0;
1760 }
eladalon413ee9a2017-08-22 04:02:52 -07001761
1762 task_queue_->SendTask([this]() {
1763 transport_overhead_ = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001764 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1765 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001766 });
1767
michaelt79e05882016-11-08 02:50:09 -08001768 EXPECT_TRUE(Wait());
1769 }
1770
1771 private:
eladalon413ee9a2017-08-22 04:02:52 -07001772 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001773 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001774 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001775 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001776 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001777 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001778 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001779
1780 RunBaseTest(&test);
1781}
1782
sprangf24a0642017-02-28 13:23:26 -08001783// Test class takes takes as argument a switch selecting if type switch should
1784// occur and a function pointer to reset the send stream. This is necessary
1785// since you cannot change the content type of a VideoSendStream, you need to
1786// recreate it. Stopping and recreating the stream can only be done on the main
1787// thread and in the context of VideoSendStreamTest (not BaseTest).
1788template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001789class MaxPaddingSetTest : public test::SendTest {
1790 public:
1791 static const uint32_t kMinTransmitBitrateBps = 400000;
1792 static const uint32_t kActualEncodeBitrateBps = 40000;
1793 static const uint32_t kMinPacketsToSend = 50;
1794
sprangf24a0642017-02-28 13:23:26 -08001795 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001796 : SendTest(test::CallTest::kDefaultTimeoutMs),
1797 call_(nullptr),
1798 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001799 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001800 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001801 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001802 stream_resetter_(stream_reset_fun) {
1803 RTC_DCHECK(stream_resetter_);
1804 }
sprang9c0b5512016-07-06 00:54:28 -07001805
1806 void OnVideoStreamsCreated(
1807 VideoSendStream* send_stream,
1808 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001809 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001810 send_stream_ = send_stream;
1811 }
1812
1813 void ModifyVideoConfigs(
1814 VideoSendStream::Config* send_config,
1815 std::vector<VideoReceiveStream::Config>* receive_configs,
1816 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001817 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001818 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001819 encoder_config->min_transmit_bitrate_bps = 0;
1820 encoder_config->content_type =
1821 VideoEncoderConfig::ContentType::kRealtimeVideo;
1822 } else {
1823 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1824 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1825 }
sprangf24a0642017-02-28 13:23:26 -08001826 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001827 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001828 }
1829
1830 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1831 call_ = sender_call;
1832 }
1833
1834 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1835 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001836 if (running_without_padding_)
1837 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1838
1839 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1840 // we have reliable data.
1841 if (++packets_sent_ < kMinPacketsToSend)
1842 return SEND_PACKET;
1843
1844 if (running_without_padding_) {
1845 // We've sent kMinPacketsToSend packets with default configuration, switch
1846 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001847 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001848 packets_sent_ = 0;
1849 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1850 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001851 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001852 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001853 return SEND_PACKET;
1854 }
1855
1856 // Make sure the pacer has been configured with a min transmit bitrate.
1857 if (call_->GetStats().max_padding_bitrate_bps > 0)
1858 observation_complete_.Set();
1859
1860 return SEND_PACKET;
1861 }
1862
1863 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001864 if (RunningWithoutPadding()) {
1865 ASSERT_TRUE(
1866 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001867 (*stream_resetter_)(send_stream_config_, encoder_config_);
1868 }
1869
sprang9c0b5512016-07-06 00:54:28 -07001870 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1871 }
1872
1873 private:
sprangf24a0642017-02-28 13:23:26 -08001874 bool RunningWithoutPadding() const {
1875 rtc::CritScope lock(&crit_);
1876 return running_without_padding_;
1877 }
1878
sprang9c0b5512016-07-06 00:54:28 -07001879 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001880 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001881 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001882 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001883 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001884 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001885 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001886 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001887 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001888};
1889
Sebastian Jansson63470292019-02-01 10:13:43 +01001890TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001891 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1892 const VideoEncoderConfig& encoder_config) {};
1893 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001894 RunBaseTest(&test);
1895}
1896
Sebastian Jansson63470292019-02-01 10:13:43 +01001897TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001898 // Function for removing and recreating the send stream with a new config.
1899 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1900 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001901 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1902 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001903 DestroyVideoSendStreams();
1904 SetVideoSendConfig(send_stream_config);
1905 SetVideoEncoderConfig(encoder_config);
1906 CreateVideoSendStreams();
1907 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
eladalon413ee9a2017-08-22 04:02:52 -07001908 Start();
1909 });
sprangf24a0642017-02-28 13:23:26 -08001910 };
1911 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001912 RunBaseTest(&test);
1913}
1914
perkjfa10b552016-10-02 23:45:26 -07001915// This test verifies that new frame sizes reconfigures encoders even though not
1916// (yet) sending. The purpose of this is to permit encoding as quickly as
1917// possible once we start sending. Likely the frames being input are from the
1918// same source that will be sent later, which just means that we're ready
1919// earlier.
Sebastian Jansson63470292019-02-01 10:13:43 +01001920TEST_F(VideoSendStreamTest,
perkjfa10b552016-10-02 23:45:26 -07001921 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1922 class EncoderObserver : public test::FakeEncoder {
1923 public:
1924 EncoderObserver()
1925 : FakeEncoder(Clock::GetRealTimeClock()),
perkjfa10b552016-10-02 23:45:26 -07001926 number_of_initializations_(0),
1927 last_initialized_frame_width_(0),
1928 last_initialized_frame_height_(0) {}
1929
1930 void WaitForResolution(int width, int height) {
1931 {
1932 rtc::CritScope lock(&crit_);
1933 if (last_initialized_frame_width_ == width &&
1934 last_initialized_frame_height_ == height) {
1935 return;
1936 }
1937 }
Erik Språng08127a92016-11-16 16:41:30 +01001938 EXPECT_TRUE(
1939 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001940 {
1941 rtc::CritScope lock(&crit_);
1942 EXPECT_EQ(width, last_initialized_frame_width_);
1943 EXPECT_EQ(height, last_initialized_frame_height_);
1944 }
1945 }
1946
1947 private:
1948 int32_t InitEncode(const VideoCodec* config,
1949 int32_t number_of_cores,
1950 size_t max_payload_size) override {
1951 rtc::CritScope lock(&crit_);
1952 last_initialized_frame_width_ = config->width;
1953 last_initialized_frame_height_ = config->height;
1954 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001955 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001956 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1957 }
1958
1959 int32_t Encode(const VideoFrame& input_image,
1960 const CodecSpecificInfo* codec_specific_info,
1961 const std::vector<FrameType>* frame_types) override {
1962 ADD_FAILURE()
1963 << "Unexpected Encode call since the send stream is not started";
1964 return 0;
1965 }
1966
1967 rtc::CriticalSection crit_;
1968 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001969 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1970 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1971 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001972 };
1973
perkjfa10b552016-10-02 23:45:26 -07001974 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001975 EncoderObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02001976 test::VideoEncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07001977
Niels Möller4db138e2018-04-19 09:04:13 +02001978 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02001979 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07001980 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001981 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07001982 CreateVideoStreams();
1983 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1984 kDefaultHeight);
1985 frame_generator_capturer_->Start();
1986 });
perkjfa10b552016-10-02 23:45:26 -07001987
1988 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001989
1990 task_queue_.SendTask([this]() {
1991 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1992 kDefaultHeight * 2);
1993 });
1994
perkjfa10b552016-10-02 23:45:26 -07001995 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001996
1997 task_queue_.SendTask([this]() {
1998 DestroyStreams();
1999 DestroyCalls();
2000 });
perkjfa10b552016-10-02 23:45:26 -07002001}
2002
Sebastian Jansson63470292019-02-01 10:13:43 +01002003TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002004 class StartBitrateObserver : public test::FakeEncoder {
2005 public:
2006 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07002007 : FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002008 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002009 int32_t InitEncode(const VideoCodec* config,
2010 int32_t number_of_cores,
2011 size_t max_payload_size) override {
2012 rtc::CritScope lock(&crit_);
2013 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07002014 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002015 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2016 }
2017
2018 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
2019 rtc::CritScope lock(&crit_);
2020 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07002021 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002022 return FakeEncoder::SetRates(new_target_bitrate, framerate);
2023 }
2024
2025 int GetStartBitrateKbps() const {
2026 rtc::CritScope lock(&crit_);
2027 return start_bitrate_kbps_;
2028 }
2029
pbos14fe7082016-04-20 06:35:56 -07002030 bool WaitForStartBitrate() {
2031 return start_bitrate_changed_.Wait(
2032 VideoSendStreamTest::kDefaultTimeoutMs);
2033 }
2034
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002035 private:
pbos5ad935c2016-01-25 03:52:44 -08002036 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002037 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002038 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002039 };
2040
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002041 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002042
solenberg4fbae2b2015-08-28 04:07:10 -07002043 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002044 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002045
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002046 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002047 bitrate_config.start_bitrate_bps =
2048 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002049 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2050 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002051
2052 StartBitrateObserver encoder;
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002053 test::VideoEncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002054 // Since this test does not use a capturer, set |internal_source| = true.
2055 // Encoder configuration is otherwise updated on the next video frame.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002056 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002057 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002058
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002059 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002060
pbos14fe7082016-04-20 06:35:56 -07002061 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002062 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002063 encoder.GetStartBitrateKbps());
2064
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002065 GetVideoEncoderConfig()->max_bitrate_bps =
2066 2 * bitrate_config.start_bitrate_bps;
2067 GetVideoSendStream()->ReconfigureVideoEncoder(
2068 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002069
2070 // New bitrate should be reconfigured above the previous max. As there's no
2071 // network connection this shouldn't be flaky, as no bitrate should've been
2072 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002073 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002074 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2075 encoder.GetStartBitrateKbps());
2076
2077 DestroyStreams();
2078}
2079
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002080class StartStopBitrateObserver : public test::FakeEncoder {
2081 public:
Niels Möllerc572ff32018-11-07 08:43:50 +01002082 StartStopBitrateObserver() : FakeEncoder(Clock::GetRealTimeClock()) {}
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002083 int32_t InitEncode(const VideoCodec* config,
2084 int32_t number_of_cores,
2085 size_t max_payload_size) override {
2086 rtc::CritScope lock(&crit_);
2087 encoder_init_.Set();
2088 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2089 }
2090
Erik Språng566124a2018-04-23 12:32:22 +02002091 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002092 uint32_t framerate) override {
2093 rtc::CritScope lock(&crit_);
2094 bitrate_kbps_ = bitrate.get_sum_kbps();
2095 bitrate_changed_.Set();
2096 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2097 }
2098
2099 bool WaitForEncoderInit() {
2100 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2101 }
2102
2103 bool WaitBitrateChanged(bool non_zero) {
2104 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002105 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002106 {
2107 rtc::CritScope lock(&crit_);
2108 bitrate_kbps = bitrate_kbps_;
2109 }
2110 if (!bitrate_kbps)
2111 continue;
2112
2113 if ((non_zero && *bitrate_kbps > 0) ||
2114 (!non_zero && *bitrate_kbps == 0)) {
2115 return true;
2116 }
2117 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2118 return false;
2119 }
2120
2121 private:
2122 rtc::CriticalSection crit_;
2123 rtc::Event encoder_init_;
2124 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002125 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002126};
2127
perkj57c21f92016-06-17 07:27:16 -07002128// This test that if the encoder use an internal source, VideoEncoder::SetRates
2129// will be called with zero bitrate during initialization and that
2130// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2131// with zero bitrate.
Sebastian Jansson63470292019-02-01 10:13:43 +01002132TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002133 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002134 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002135 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002136 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002137 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002138
Niels Möller4db138e2018-04-19 09:04:13 +02002139 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002140 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002141 CreateSendConfig(1, 0, 0, &transport);
2142
2143 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002144 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002145
2146 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002147 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002148 GetVideoSendStream()->Start();
2149 GetVideoSendStream()->SetSource(&forwarder,
2150 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002151 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002152 });
perkj57c21f92016-06-17 07:27:16 -07002153
2154 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002155
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002156 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002157 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2158
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002159 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002160 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2161
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002162 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002163 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002164
eladalon413ee9a2017-08-22 04:02:52 -07002165 task_queue_.SendTask([this]() {
2166 DestroyStreams();
2167 DestroyCalls();
2168 });
perkj57c21f92016-06-17 07:27:16 -07002169}
2170
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002171// Tests that when the encoder uses an internal source, the VideoEncoder will
2172// be updated with a new bitrate when turning the VideoSendStream on/off with
2173// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2174// is reconfigured with new active layers.
Sebastian Jansson63470292019-02-01 10:13:43 +01002175TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002176 test::NullTransport transport;
2177 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002178 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002179 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002180 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002181
Niels Möller4db138e2018-04-19 09:04:13 +02002182 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002183 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002184 // Create two simulcast streams.
2185 CreateSendConfig(2, 0, 0, &transport);
2186
2187 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002188 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002189
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002190 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002191
2192 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002193 GetVideoSendStream()->Start();
2194 GetVideoSendStream()->SetSource(&forwarder,
2195 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002196 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002197 });
2198
2199 EXPECT_TRUE(encoder.WaitForEncoderInit());
2200
2201 // When we turn on the simulcast layers it will update the BitrateAllocator,
2202 // which in turn updates the VideoEncoder's bitrate.
2203 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002204 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002205 });
2206 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2207
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002208 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2209 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002210 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002211 GetVideoSendStream()->ReconfigureVideoEncoder(
2212 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002213 });
2214 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2215 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2216 // active. Once the change is made for a "soft" reconfiguration we can remove
2217 // the expecation for an encoder init. We can also test that bitrate changes
2218 // when just updating individual active layers, which should change the
2219 // bitrate set to the video encoder.
2220 EXPECT_TRUE(encoder.WaitForEncoderInit());
2221 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2222
2223 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002224 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2225 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002226 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002227 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002228 });
2229 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2230
2231 task_queue_.SendTask([this]() {
2232 DestroyStreams();
2233 DestroyCalls();
2234 });
2235}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002236
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002237VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002238 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002239 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002240 memset(buffer.get(), data, kSizeY);
Artem Titov1ebfb6a2019-01-03 23:49:37 +01002241 VideoFrame frame =
2242 webrtc::VideoFrame::Builder()
2243 .set_video_frame_buffer(I420Buffer::Create(width, height))
2244 .set_rotation(webrtc::kVideoRotation_0)
2245 .set_timestamp_us(data)
2246 .build();
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002247 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002248 // Use data as a ms timestamp.
2249 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002250 return frame;
2251}
2252
Sebastian Jansson63470292019-02-01 10:13:43 +01002253TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002254 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2255 public:
eladalon413ee9a2017-08-22 04:02:52 -07002256 explicit EncoderStateObserver(
2257 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002258 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002259 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002260 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002261 initialized_(false),
2262 callback_registered_(false),
2263 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002264 released_(false),
2265 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002266
2267 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002268 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002269 return released_;
2270 }
2271
2272 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002273 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002274 return initialized_ && callback_registered_;
2275 }
2276
2277 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002278 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002279 return num_releases_;
2280 }
2281
2282 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002283 int32_t InitEncode(const VideoCodec* codecSettings,
2284 int32_t numberOfCores,
2285 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002286 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002287 EXPECT_FALSE(initialized_);
2288 initialized_ = true;
2289 released_ = false;
2290 return 0;
2291 }
2292
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002293 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002294 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002295 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002296 EXPECT_TRUE(IsReadyForEncode());
2297
Peter Boström5811a392015-12-10 13:02:50 +01002298 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002299 return 0;
2300 }
2301
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002302 int32_t RegisterEncodeCompleteCallback(
2303 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002304 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002305 EXPECT_TRUE(initialized_);
2306 callback_registered_ = true;
2307 return 0;
2308 }
2309
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002310 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002311 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002312 EXPECT_TRUE(IsReadyForEncode());
2313 EXPECT_FALSE(released_);
2314 initialized_ = false;
2315 callback_registered_ = false;
2316 released_ = true;
2317 ++num_releases_;
2318 return 0;
2319 }
2320
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002321 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002322 EXPECT_TRUE(IsReadyForEncode());
2323 return 0;
2324 }
2325
stefanff483612015-12-21 03:14:00 -08002326 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002327 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002328 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002329 stream_ = send_stream;
2330 }
2331
stefanff483612015-12-21 03:14:00 -08002332 void ModifyVideoConfigs(
2333 VideoSendStream::Config* send_config,
2334 std::vector<VideoReceiveStream::Config>* receive_configs,
2335 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002336 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002337 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002338 }
2339
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002340 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002341 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002342
2343 task_queue_->SendTask([this]() {
2344 EXPECT_EQ(0u, num_releases());
2345 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2346 EXPECT_EQ(0u, num_releases());
2347 stream_->Stop();
2348 // Encoder should not be released before destroying the VideoSendStream.
2349 EXPECT_FALSE(IsReleased());
2350 EXPECT_TRUE(IsReadyForEncode());
2351 stream_->Start();
2352 });
2353
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002354 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002355 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002356 }
2357
eladalon413ee9a2017-08-22 04:02:52 -07002358 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002359 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002360 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002361 bool initialized_ RTC_GUARDED_BY(crit_);
2362 bool callback_registered_ RTC_GUARDED_BY(crit_);
2363 size_t num_releases_ RTC_GUARDED_BY(crit_);
2364 bool released_ RTC_GUARDED_BY(crit_);
Niels Möllercbcbc222018-09-28 09:07:24 +02002365 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002366 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002367 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002368
stefane74eef12016-01-08 06:47:13 -08002369 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002370
2371 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002372 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002373}
2374
Sebastian Jansson63470292019-02-01 10:13:43 +01002375TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002376 class VideoCodecConfigObserver : public test::SendTest,
2377 public test::FakeEncoder {
2378 public:
2379 VideoCodecConfigObserver()
2380 : SendTest(kDefaultTimeoutMs),
2381 FakeEncoder(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02002382 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002383 stream_(nullptr),
2384 encoder_factory_(this) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002385
2386 private:
stefanff483612015-12-21 03:14:00 -08002387 void ModifyVideoConfigs(
2388 VideoSendStream::Config* send_config,
2389 std::vector<VideoReceiveStream::Config>* receive_configs,
2390 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002391 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprangf24a0642017-02-28 13:23:26 -08002392 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002393 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002394 }
2395
stefanff483612015-12-21 03:14:00 -08002396 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002397 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002398 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002399 stream_ = send_stream;
2400 }
2401
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002402 int32_t InitEncode(const VideoCodec* config,
2403 int32_t number_of_cores,
2404 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002405 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002406 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002407 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002408 } else {
2409 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002410 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002411 }
2412 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002413 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002414 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2415 }
2416
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002417 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002418 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002419 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002420
sprangf24a0642017-02-28 13:23:26 -08002421 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002422 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002423 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002424 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002425 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2426 "new encoder settings.";
2427 }
2428
sprangf24a0642017-02-28 13:23:26 -08002429 const uint32_t kFirstMaxBitrateBps = 1000000;
2430 const uint32_t kSecondMaxBitrateBps = 2000000;
2431
pbos14fe7082016-04-20 06:35:56 -07002432 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002433 size_t num_initializations_;
2434 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002435 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002436 VideoEncoderConfig encoder_config_;
2437 } test;
2438
stefane74eef12016-01-08 06:47:13 -08002439 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002440}
2441
Sergey Silkin571e6c92018-04-03 10:03:31 +02002442static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002443template <typename T>
2444class VideoCodecConfigObserver : public test::SendTest,
2445 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002446 public:
2447 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2448 const char* codec_name)
2449 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2450 FakeEncoder(Clock::GetRealTimeClock()),
2451 video_codec_type_(video_codec_type),
2452 codec_name_(codec_name),
Erik Språng737336d2016-07-29 12:59:36 +02002453 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002454 stream_(nullptr),
2455 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002456 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002457 }
2458
2459 private:
stefanff483612015-12-21 03:14:00 -08002460 void ModifyVideoConfigs(
2461 VideoSendStream::Config* send_config,
2462 std::vector<VideoReceiveStream::Config>* receive_configs,
2463 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002464 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002465 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002466
Niels Möller259a4972018-04-05 15:36:51 +02002467 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002468 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
Åsa Perssond34597c2018-10-22 17:34:02 +02002469 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2470 encoder_config->simulcast_layers[0].num_temporal_layers =
2471 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07002472 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002473 }
2474
stefanff483612015-12-21 03:14:00 -08002475 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002476 VideoSendStream* send_stream,
2477 const std::vector<VideoReceiveStream*>& receive_streams) override {
2478 stream_ = send_stream;
2479 }
2480
2481 int32_t InitEncode(const VideoCodec* config,
2482 int32_t number_of_cores,
2483 size_t max_payload_size) override {
2484 EXPECT_EQ(video_codec_type_, config->codecType);
2485 VerifyCodecSpecifics(*config);
2486 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002487 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002488 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2489 }
2490
Sergey Silkin86684962018-03-28 19:32:37 +02002491 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002492 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002493 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2494 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002495
2496 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002497 EXPECT_TRUE(
2498 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002499 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002500
Sergey Silkin86684962018-03-28 19:32:37 +02002501 // Change encoder settings to actually trigger reconfiguration.
2502 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002503 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002504 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002505 ASSERT_TRUE(
2506 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002507 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002508 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2509 "new encoder settings.";
2510 }
2511
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002512 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002513 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002514 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002515 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2516 return 0;
2517 }
2518
2519 T encoder_settings_;
2520 const VideoCodecType video_codec_type_;
2521 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002522 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002523 size_t num_initializations_;
2524 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002525 test::VideoEncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002526 VideoEncoderConfig encoder_config_;
2527};
2528
2529template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002530void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2531 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2532}
2533
2534template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002535void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2536 const VideoCodec& config) const {
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002537 // Check that the number of temporal layers has propagated properly to
2538 // VideoCodec.
2539 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2540 config.H264().numberOfTemporalLayers);
2541
2542 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2543 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2544 config.simulcastStream[i].numberOfTemporalLayers);
2545 }
2546
2547 // Set expected temporal layers as they should have been set when
2548 // reconfiguring the encoder and not match the set config.
2549 VideoCodecH264 encoder_settings = encoder_settings_;
2550 encoder_settings.numberOfTemporalLayers =
2551 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002552 EXPECT_EQ(
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002553 0, memcmp(&config.H264(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002554}
kthelgason29a44e32016-09-27 03:52:02 -07002555
2556template <>
2557rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2558VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2559 return new rtc::RefCountedObject<
2560 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2561}
2562
Peter Boström53eda3d2015-03-27 15:53:18 +01002563template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002564void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2565 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2566}
2567
2568template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002569void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2570 const VideoCodec& config) const {
2571 // Check that the number of temporal layers has propagated properly to
2572 // VideoCodec.
2573 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002574 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002575
2576 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2577 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2578 config.simulcastStream[i].numberOfTemporalLayers);
2579 }
2580
2581 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002582 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002583 VideoCodecVP8 encoder_settings = encoder_settings_;
2584 encoder_settings.numberOfTemporalLayers =
2585 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002586 EXPECT_EQ(
2587 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002588}
kthelgason29a44e32016-09-27 03:52:02 -07002589
2590template <>
2591rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2592VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2593 return new rtc::RefCountedObject<
2594 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2595}
2596
Peter Boström53eda3d2015-03-27 15:53:18 +01002597template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002598void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2599 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2600}
2601
2602template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002603void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2604 const VideoCodec& config) const {
2605 // Check that the number of temporal layers has propagated properly to
2606 // VideoCodec.
2607 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002608 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002609
2610 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2611 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2612 config.simulcastStream[i].numberOfTemporalLayers);
2613 }
2614
2615 // Set expected temporal layers as they should have been set when
2616 // reconfiguring the encoder and not match the set config.
2617 VideoCodecVP9 encoder_settings = encoder_settings_;
2618 encoder_settings.numberOfTemporalLayers =
2619 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002620 EXPECT_EQ(
2621 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002622}
2623
kthelgason29a44e32016-09-27 03:52:02 -07002624template <>
2625rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2626VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2627 return new rtc::RefCountedObject<
2628 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2629}
2630
Sebastian Jansson63470292019-02-01 10:13:43 +01002631TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002632 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002633 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002634}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002635
Sebastian Jansson63470292019-02-01 10:13:43 +01002636TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002637 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002638 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002639}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002640
Sebastian Jansson63470292019-02-01 10:13:43 +01002641TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002642 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002643 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002644}
2645
Sebastian Jansson63470292019-02-01 10:13:43 +01002646TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002647 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002648 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002649 RtcpSenderReportTest()
2650 : SendTest(kDefaultTimeoutMs),
2651 rtp_packets_sent_(0),
2652 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002653
2654 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002655 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002656 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002657 RTPHeader header;
2658 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002659 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002660 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2661 return SEND_PACKET;
2662 }
2663
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002664 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002665 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002666 test::RtcpPacketParser parser;
2667 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002668
danilchap3dc929e2016-11-02 08:21:59 -07002669 if (parser.sender_report()->num_packets() > 0) {
2670 // Only compare sent media bytes if SenderPacketCount matches the
2671 // number of sent rtp packets (a new rtp packet could be sent before
2672 // the rtcp packet).
2673 if (parser.sender_report()->sender_octet_count() > 0 &&
2674 parser.sender_report()->sender_packet_count() ==
2675 rtp_packets_sent_) {
2676 EXPECT_EQ(media_bytes_sent_,
2677 parser.sender_report()->sender_octet_count());
2678 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002679 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002680 }
2681
2682 return SEND_PACKET;
2683 }
2684
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002685 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002686 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002687 }
2688
stefan4b569042015-11-11 06:39:57 -08002689 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002690 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2691 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002692 } test;
2693
stefane74eef12016-01-08 06:47:13 -08002694 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002695}
2696
Sebastian Jansson63470292019-02-01 10:13:43 +01002697TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002698 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002699
2700 class VideoStreamFactory
2701 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2702 public:
2703 VideoStreamFactory() {}
2704
2705 private:
2706 std::vector<VideoStream> CreateEncoderStreams(
2707 int width,
2708 int height,
2709 const VideoEncoderConfig& encoder_config) override {
2710 std::vector<VideoStream> streams =
2711 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002712 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2713 kScreencastMaxTargetBitrateDeltaKbps);
2714 streams[0].target_bitrate_bps =
2715 streams[0].max_bitrate_bps -
2716 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002717 return streams;
2718 }
2719 };
2720
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002721 class ScreencastTargetBitrateTest : public test::SendTest,
2722 public test::FakeEncoder {
2723 public:
2724 ScreencastTargetBitrateTest()
2725 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002726 test::FakeEncoder(Clock::GetRealTimeClock()),
2727 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002728
2729 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002730 int32_t InitEncode(const VideoCodec* config,
2731 int32_t number_of_cores,
2732 size_t max_payload_size) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002733 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002734 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002735 config->simulcastStream[0].maxBitrate -
2736 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002737 observation_complete_.Set();
Yves Gerey665174f2018-06-19 15:03:05 +02002738 return test::FakeEncoder::InitEncode(config, number_of_cores,
2739 max_payload_size);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002740 }
stefanff483612015-12-21 03:14:00 -08002741 void ModifyVideoConfigs(
2742 VideoSendStream::Config* send_config,
2743 std::vector<VideoReceiveStream::Config>* receive_configs,
2744 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002745 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002746 EXPECT_EQ(1u, encoder_config->number_of_streams);
2747 encoder_config->video_stream_factory =
2748 new rtc::RefCountedObject<VideoStreamFactory>();
Åsa Perssond34597c2018-10-22 17:34:02 +02002749 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2750 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
Erik Språng143cec12015-04-28 10:01:41 +02002751 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002752 }
2753
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002754 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002755 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002756 << "Timed out while waiting for the encoder to be initialized.";
2757 }
Niels Möllercbcbc222018-09-28 09:07:24 +02002758 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002759 } test;
2760
stefane74eef12016-01-08 06:47:13 -08002761 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002762}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002763
Sebastian Jansson63470292019-02-01 10:13:43 +01002764TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002765 // These are chosen to be "kind of odd" to not be accidentally checked against
2766 // default values.
2767 static const int kMinBitrateKbps = 137;
2768 static const int kStartBitrateKbps = 345;
2769 static const int kLowerMaxBitrateKbps = 312;
2770 static const int kMaxBitrateKbps = 413;
2771 static const int kIncreasedStartBitrateKbps = 451;
2772 static const int kIncreasedMaxBitrateKbps = 597;
Erik Språng7ca375c2019-02-06 16:20:17 +01002773 // If these fields trial are on, we get lower bitrates than expected by this
2774 // test, due to the packetization overhead and encoder pushback.
Niels Möller6613f8e2019-01-10 10:30:21 +01002775 webrtc::test::ScopedFieldTrials field_trials(
2776 std::string(field_trial::GetFieldTrialString()) +
Erik Språng7ca375c2019-02-06 16:20:17 +01002777 "WebRTC-SubtractPacketizationOverhead/Disabled/"
2778 "WebRTC-VideoRateControl/bitrate_adjuster:false/");
Niels Möller6613f8e2019-01-10 10:30:21 +01002779
pbos@webrtc.org00873182014-11-25 14:03:34 +00002780 class EncoderBitrateThresholdObserver : public test::SendTest,
2781 public test::FakeEncoder {
2782 public:
eladalon413ee9a2017-08-22 04:02:52 -07002783 explicit EncoderBitrateThresholdObserver(
2784 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002785 : SendTest(kDefaultTimeoutMs),
2786 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002787 task_queue_(task_queue),
perkj26091b12016-09-01 01:17:40 -07002788 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002789 num_initializations_(0),
2790 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002791 send_stream_(nullptr),
2792 encoder_factory_(this) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002793
2794 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002795 int32_t InitEncode(const VideoCodec* codecSettings,
2796 int32_t numberOfCores,
2797 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002798 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2799 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002800 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002801 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2802 codecSettings->minBitrate);
2803 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2804 codecSettings->startBitrate);
2805 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2806 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002807 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002808 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002809 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2810 codecSettings->maxBitrate);
2811 // The start bitrate should be kept (-1) and capped to the max bitrate.
2812 // Since this is not an end-to-end call no receiver should have been
2813 // returning a REMB that could lower this estimate.
2814 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002815 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002816 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2817 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002818 // The start bitrate will be whatever the rate BitRateController
2819 // has currently configured but in the span of the set max and min
2820 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002821 }
2822 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002823 init_encode_event_.Set();
2824
pbos@webrtc.org00873182014-11-25 14:03:34 +00002825 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2826 maxPayloadSize);
2827 }
2828
Erik Språng566124a2018-04-23 12:32:22 +02002829 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Erik Språng08127a92016-11-16 16:41:30 +01002830 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002831 {
2832 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002833 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2834 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002835 }
Erik Språng08127a92016-11-16 16:41:30 +01002836 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002837 }
2838 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002839 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002840 }
2841
2842 void WaitForSetRates(uint32_t expected_bitrate) {
Niels Möller6bb5ab92019-01-11 11:11:10 +01002843 // Wait for the expected rate to be set. In some cases there can be
2844 // more than one update pending, in which case we keep waiting
2845 // until the correct value has been observed.
2846 const int64_t start_time = rtc::TimeMillis();
2847 do {
2848 rtc::CritScope lock(&crit_);
2849 if (target_bitrate_ == expected_bitrate) {
2850 return;
2851 }
2852 } while (bitrate_changed_event_.Wait(
2853 std::max(int64_t{1}, VideoSendStreamTest::kDefaultTimeoutMs -
2854 (rtc::TimeMillis() - start_time))));
Niels Möller6613f8e2019-01-10 10:30:21 +01002855 rtc::CritScope lock(&crit_);
Niels Möller6bb5ab92019-01-11 11:11:10 +01002856 EXPECT_EQ(target_bitrate_, expected_bitrate)
2857 << "Timed out while waiting encoder rate to be set.";
perkj26091b12016-09-01 01:17:40 -07002858 }
2859
Niels Möllerde8e6e62018-11-13 15:10:33 +01002860 void ModifySenderBitrateConfig(
2861 BitrateConstraints* bitrate_config) override {
2862 bitrate_config->min_bitrate_bps = kMinBitrateKbps * 1000;
2863 bitrate_config->start_bitrate_bps = kStartBitrateKbps * 1000;
2864 bitrate_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002865 }
2866
perkjfa10b552016-10-02 23:45:26 -07002867 class VideoStreamFactory
2868 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2869 public:
2870 explicit VideoStreamFactory(int min_bitrate_bps)
2871 : min_bitrate_bps_(min_bitrate_bps) {}
2872
2873 private:
2874 std::vector<VideoStream> CreateEncoderStreams(
2875 int width,
2876 int height,
2877 const VideoEncoderConfig& encoder_config) override {
2878 std::vector<VideoStream> streams =
2879 test::CreateVideoStreams(width, height, encoder_config);
2880 streams[0].min_bitrate_bps = min_bitrate_bps_;
2881 return streams;
2882 }
2883
2884 const int min_bitrate_bps_;
2885 };
2886
stefanff483612015-12-21 03:14:00 -08002887 void ModifyVideoConfigs(
2888 VideoSendStream::Config* send_config,
2889 std::vector<VideoReceiveStream::Config>* receive_configs,
2890 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002891 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002892 // Set bitrates lower/higher than min/max to make sure they are properly
2893 // capped.
perkjfa10b552016-10-02 23:45:26 -07002894 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2895 // Create a new StreamFactory to be able to set
2896 // |VideoStream.min_bitrate_bps|.
2897 encoder_config->video_stream_factory =
2898 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002899 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002900 }
2901
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002902 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002903 call_ = sender_call;
2904 }
2905
stefanff483612015-12-21 03:14:00 -08002906 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002907 VideoSendStream* send_stream,
2908 const std::vector<VideoReceiveStream*>& receive_streams) override {
2909 send_stream_ = send_stream;
2910 }
2911
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002912 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002913 ASSERT_TRUE(
2914 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002915 << "Timed out while waiting for encoder to be configured.";
2916 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002917 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002918 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2919 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002920 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002921 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2922 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002923 });
perkj26091b12016-09-01 01:17:40 -07002924 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2925 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002926 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002927 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002928 ASSERT_TRUE(
2929 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002930 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002931 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002932 WaitForSetRates(kLowerMaxBitrateKbps);
2933
2934 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2935 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2936 ASSERT_TRUE(
2937 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002938 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002939 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002940 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002941 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002942 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002943 }
2944
eladalon413ee9a2017-08-22 04:02:52 -07002945 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002946 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002947 rtc::Event bitrate_changed_event_;
2948 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002949 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002950
pbos@webrtc.org00873182014-11-25 14:03:34 +00002951 int num_initializations_;
2952 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002953 webrtc::VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002954 test::VideoEncoderProxyFactory encoder_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002955 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002956 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002957
stefane74eef12016-01-08 06:47:13 -08002958 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002959}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002960
Sebastian Jansson63470292019-02-01 10:13:43 +01002961TEST_F(VideoSendStreamTest, ReportsSentResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002962 static const size_t kNumStreams = 3;
2963 // Unusual resolutions to make sure that they are the ones being reported.
2964 static const struct {
2965 int width;
2966 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02002967 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002968 class ScreencastTargetBitrateTest : public test::SendTest,
2969 public test::FakeEncoder {
2970 public:
2971 ScreencastTargetBitrateTest()
2972 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002973 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02002974 send_stream_(nullptr),
2975 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002976
2977 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002978 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002979 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002980 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002981 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002982 specifics.codecType = kVideoCodecGeneric;
2983
2984 uint8_t buffer[16] = {0};
2985 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
Niels Möller23775882018-08-16 10:24:12 +02002986 encoded.SetTimestamp(input_image.timestamp());
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002987 encoded.capture_time_ms_ = input_image.render_time_ms();
2988
2989 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002990 encoded._frameType = (*frame_types)[i];
2991 encoded._encodedWidth = kEncodedResolution[i].width;
2992 encoded._encodedHeight = kEncodedResolution[i].height;
Niels Möllerd3b8c632018-08-27 15:33:42 +02002993 encoded.SetSpatialIndex(i);
brandtre78d2662017-01-16 05:57:16 -08002994 EncodedImageCallback* callback;
2995 {
2996 rtc::CritScope cs(&crit_sect_);
2997 callback = callback_;
2998 }
2999 RTC_DCHECK(callback);
3000 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003001 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003002 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003003 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003004 }
3005
Peter Boström5811a392015-12-10 13:02:50 +01003006 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003007 return 0;
3008 }
stefanff483612015-12-21 03:14:00 -08003009 void ModifyVideoConfigs(
3010 VideoSendStream::Config* send_config,
3011 std::vector<VideoReceiveStream::Config>* receive_configs,
3012 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003013 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003014 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003015 }
3016
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003017 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003018
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003019 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003020 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003021 << "Timed out while waiting for the encoder to send one frame.";
3022 VideoSendStream::Stats stats = send_stream_->GetStats();
3023
3024 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003025 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003026 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003027 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003028 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003029 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003030 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003031 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3032 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003033 }
3034 }
3035
stefanff483612015-12-21 03:14:00 -08003036 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003037 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003038 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003039 send_stream_ = send_stream;
3040 }
3041
3042 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003043 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003044 } test;
3045
stefane74eef12016-01-08 06:47:13 -08003046 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003047}
philipel0f9af012015-09-01 07:01:51 -07003048
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003049#if defined(RTC_ENABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003050class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003051 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003052 Vp9HeaderObserver()
3053 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003054 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003055 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3056 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003057 frames_sent_(0),
3058 expected_width_(0),
3059 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003060
stefanff483612015-12-21 03:14:00 -08003061 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003062 VideoSendStream::Config* send_config,
3063 std::vector<VideoReceiveStream::Config>* receive_configs,
3064 VideoEncoderConfig* encoder_config) {}
3065
Åsa Perssonff24c042015-12-04 10:58:08 +01003066 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003067
3068 private:
minyue20c84cc2017-04-10 16:57:57 -07003069 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003070
stefanff483612015-12-21 03:14:00 -08003071 void ModifyVideoConfigs(
3072 VideoSendStream::Config* send_config,
3073 std::vector<VideoReceiveStream::Config>* receive_configs,
3074 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003075 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003076 send_config->rtp.payload_name = "VP9";
3077 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003078 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003079 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003080 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003081 EXPECT_EQ(1u, encoder_config->number_of_streams);
Åsa Perssond34597c2018-10-22 17:34:02 +02003082 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
3083 encoder_config->simulcast_layers[0].num_temporal_layers =
3084 vp9_settings_.numberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07003085 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003086 }
3087
perkjfa10b552016-10-02 23:45:26 -07003088 void ModifyVideoCaptureStartResolution(int* width,
3089 int* height,
3090 int* frame_rate) override {
3091 expected_width_ = *width;
3092 expected_height_ = *height;
3093 }
3094
philipel0f9af012015-09-01 07:01:51 -07003095 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003096 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3097 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003098 }
3099
3100 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3101 RTPHeader header;
3102 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3103
Åsa Perssonff24c042015-12-04 10:58:08 +01003104 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3105 const uint8_t* payload = packet + header.headerLength;
3106 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003107
Åsa Perssonff24c042015-12-04 10:58:08 +01003108 bool new_packet = packets_sent_ == 0 ||
3109 IsNewerSequenceNumber(header.sequenceNumber,
3110 last_header_.sequenceNumber);
3111 if (payload_length > 0 && new_packet) {
3112 RtpDepacketizer::ParsedPayload parsed;
3113 RtpDepacketizerVp9 depacketizer;
3114 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003115 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003116 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003117 const auto& vp9_header =
3118 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3119 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003120 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003121 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003122 InspectHeader(vp9_header);
philipel0f9af012015-09-01 07:01:51 -07003123
Åsa Perssonff24c042015-12-04 10:58:08 +01003124 ++packets_sent_;
3125 if (header.markerBit) {
3126 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003127 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003128 last_header_ = header;
philipel29d88462018-08-08 14:26:00 +02003129 last_vp9_ = vp9_header;
philipel0f9af012015-09-01 07:01:51 -07003130 }
philipel0f9af012015-09-01 07:01:51 -07003131 return SEND_PACKET;
3132 }
3133
philipel7fabd462015-09-03 04:42:32 -07003134 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003135 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3136 if (last_vp9_.picture_id > vp9.picture_id) {
3137 return vp9.picture_id == 0; // Wrap.
3138 } else {
3139 return vp9.picture_id == last_vp9_.picture_id + 1;
3140 }
3141 }
3142
3143 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003144 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3145 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3146 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3147 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3148 vp9.spatial_idx);
3149 }
3150
3151 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3152 uint8_t num_layers) const {
3153 switch (num_layers) {
3154 case 0:
3155 VerifyTemporalLayerStructure0(vp9);
3156 break;
3157 case 1:
3158 VerifyTemporalLayerStructure1(vp9);
3159 break;
3160 case 2:
3161 VerifyTemporalLayerStructure2(vp9);
3162 break;
3163 case 3:
3164 VerifyTemporalLayerStructure3(vp9);
3165 break;
3166 default:
3167 RTC_NOTREACHED();
3168 }
3169 }
3170
3171 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3172 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3173 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3174 EXPECT_FALSE(vp9.temporal_up_switch);
3175 }
3176
3177 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3178 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3179 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3180 EXPECT_FALSE(vp9.temporal_up_switch);
3181 }
3182
3183 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3184 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3185 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3186 EXPECT_LE(vp9.temporal_idx, 1);
3187 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3188 if (IsNewPictureId(vp9)) {
3189 uint8_t expected_tid =
3190 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3191 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3192 }
3193 }
3194
3195 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3196 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3197 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3198 EXPECT_LE(vp9.temporal_idx, 2);
3199 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3200 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3201 switch (vp9.temporal_idx) {
3202 case 0:
3203 EXPECT_EQ(2, last_vp9_.temporal_idx);
3204 EXPECT_FALSE(vp9.temporal_up_switch);
3205 break;
3206 case 1:
3207 EXPECT_EQ(2, last_vp9_.temporal_idx);
3208 EXPECT_TRUE(vp9.temporal_up_switch);
3209 break;
3210 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003211 EXPECT_LT(last_vp9_.temporal_idx, 2);
3212 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003213 break;
3214 }
3215 }
3216 }
3217
3218 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3219 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3220 return;
3221
3222 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3223 if (vp9.temporal_idx == 0)
3224 ++expected_tl0_idx;
3225 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3226 }
3227
3228 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3229 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3230 }
3231
3232 // Flexible mode (F=1): Non-flexible mode (F=0):
3233 //
3234 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3235 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3236 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3237 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3238 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3239 // M: | EXTENDED PID | M: | EXTENDED PID |
3240 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3241 // L: | T |U| S |D| L: | T |U| S |D|
3242 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3243 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3244 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3245 // X: |EXTENDED P_DIFF| V: | SS .. |
3246 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3247 // V: | SS .. |
3248 // +-+-+-+-+-+-+-+-+
3249 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3250 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3251 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3252 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003253
3254 if (vp9_settings_.numberOfSpatialLayers > 1) {
3255 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3256 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3257 EXPECT_EQ(vp9.spatial_idx, 0);
3258 } else {
3259 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3260 }
3261
3262 if (vp9_settings_.numberOfTemporalLayers > 1) {
3263 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3264 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3265 EXPECT_EQ(vp9.temporal_idx, 0);
3266 } else {
3267 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3268 }
3269
Åsa Perssonff24c042015-12-04 10:58:08 +01003270 if (vp9.ss_data_available) // V
3271 VerifySsData(vp9);
3272
3273 if (frames_sent_ == 0)
3274 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3275
3276 if (!vp9.inter_pic_predicted) {
3277 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3278 EXPECT_FALSE(vp9.temporal_up_switch);
3279 }
3280 }
3281
3282 // Scalability structure (SS).
3283 //
3284 // +-+-+-+-+-+-+-+-+
3285 // V: | N_S |Y|G|-|-|-|
3286 // +-+-+-+-+-+-+-+-+
3287 // Y: | WIDTH | N_S + 1 times
3288 // +-+-+-+-+-+-+-+-+
3289 // | HEIGHT |
3290 // +-+-+-+-+-+-+-+-+
3291 // G: | N_G |
3292 // +-+-+-+-+-+-+-+-+
3293 // N_G: | T |U| R |-|-| N_G times
3294 // +-+-+-+-+-+-+-+-+
3295 // | P_DIFF | R times
3296 // +-+-+-+-+-+-+-+-+
3297 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3298 EXPECT_TRUE(vp9.ss_data_available); // V
3299 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3300 vp9.num_spatial_layers);
3301 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003302 int expected_width = expected_width_;
3303 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003304 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003305 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3306 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3307 expected_width /= 2;
3308 expected_height /= 2;
3309 }
3310 }
3311
3312 void CompareConsecutiveFrames(const RTPHeader& header,
3313 const RTPVideoHeader& video) const {
philipel29d88462018-08-08 14:26:00 +02003314 const auto& vp9_header =
3315 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003316
3317 bool new_frame = packets_sent_ == 0 ||
3318 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003319 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003320 if (!new_frame) {
3321 EXPECT_FALSE(last_header_.markerBit);
3322 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003323 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3324 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3325 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3326 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003327 return;
3328 }
3329 // New frame.
philipel29d88462018-08-08 14:26:00 +02003330 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003331
3332 // Compare with last packet in previous frame.
3333 if (frames_sent_ == 0)
3334 return;
3335 EXPECT_TRUE(last_vp9_.end_of_frame);
3336 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003337 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3338 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003339 }
3340
Niels Möller4db138e2018-04-19 09:04:13 +02003341 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003342 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003343 webrtc::VideoEncoderConfig encoder_config_;
3344 RTPHeader last_header_;
3345 RTPVideoHeaderVP9 last_vp9_;
3346 size_t packets_sent_;
3347 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003348 int expected_width_;
3349 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003350};
3351
Sebastian Jansson63470292019-02-01 10:13:43 +01003352TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003353 const uint8_t kNumTemporalLayers = 1;
3354 const uint8_t kNumSpatialLayers = 1;
3355 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3356}
3357
Sebastian Jansson63470292019-02-01 10:13:43 +01003358TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003359 const uint8_t kNumTemporalLayers = 2;
3360 const uint8_t kNumSpatialLayers = 1;
3361 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3362}
3363
Sebastian Jansson63470292019-02-01 10:13:43 +01003364TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003365 const uint8_t kNumTemporalLayers = 3;
3366 const uint8_t kNumSpatialLayers = 1;
3367 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3368}
3369
Sebastian Jansson63470292019-02-01 10:13:43 +01003370TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003371 const uint8_t kNumTemporalLayers = 1;
3372 const uint8_t kNumSpatialLayers = 2;
3373 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3374}
3375
Sebastian Jansson63470292019-02-01 10:13:43 +01003376TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003377 const uint8_t kNumTemporalLayers = 2;
3378 const uint8_t kNumSpatialLayers = 2;
3379 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3380}
3381
Sebastian Jansson63470292019-02-01 10:13:43 +01003382TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003383 const uint8_t kNumTemporalLayers = 3;
3384 const uint8_t kNumSpatialLayers = 2;
3385 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3386}
3387
3388void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3389 uint8_t num_spatial_layers) {
3390 static const size_t kNumFramesToSend = 100;
3391 // Set to < kNumFramesToSend and coprime to length of temporal layer
3392 // structures to verify temporal id reset on key frame.
3393 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003394
3395 static const int kWidth = kMinVp9SpatialLayerWidth;
3396 static const int kHeight = kMinVp9SpatialLayerHeight;
3397 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003398 class NonFlexibleMode : public Vp9HeaderObserver {
3399 public:
3400 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3401 : num_temporal_layers_(num_temporal_layers),
3402 num_spatial_layers_(num_spatial_layers),
3403 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003404
stefanff483612015-12-21 03:14:00 -08003405 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003406 VideoSendStream::Config* send_config,
3407 std::vector<VideoReceiveStream::Config>* receive_configs,
3408 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003409 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003410 int bitrate_bps = 0;
3411 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3412 const int width = kWidth << sl_idx;
3413 const int height = kHeight << sl_idx;
3414 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3415 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3416 }
3417 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3418
Åsa Perssonff24c042015-12-04 10:58:08 +01003419 vp9_settings_.flexibleMode = false;
3420 vp9_settings_.frameDroppingOn = false;
3421 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3422 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3423 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003424 }
3425
Sergey Silkin86684962018-03-28 19:32:37 +02003426 void ModifyVideoCaptureStartResolution(int* width,
3427 int* height,
3428 int* frame_rate) override {
3429 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3430 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3431 *width = expected_width_;
3432 *height = expected_height_;
3433 }
3434
Åsa Perssonff24c042015-12-04 10:58:08 +01003435 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003436 bool ss_data_expected =
3437 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3438 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003439 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003440 if (num_spatial_layers_ > 1) {
3441 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3442 } else {
3443 EXPECT_FALSE(vp9.inter_layer_predicted);
3444 }
3445
asapersson38bb8ad2015-12-14 01:41:19 -08003446 EXPECT_EQ(!vp9.inter_pic_predicted,
3447 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003448
3449 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003450 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3451 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3452 } else {
3453 EXPECT_EQ(0, vp9.spatial_idx);
3454 }
3455 if (num_spatial_layers_ > 1)
3456 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003457 }
3458
3459 VerifyFixedTemporalLayerStructure(vp9,
3460 l_field_ ? num_temporal_layers_ : 0);
3461
3462 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003463 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003464 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003465 const uint8_t num_temporal_layers_;
3466 const uint8_t num_spatial_layers_;
3467 const bool l_field_;
3468 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003469
stefane74eef12016-01-08 06:47:13 -08003470 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003471}
3472
Sebastian Jansson63470292019-02-01 10:13:43 +01003473TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
asaperssond9f641e2016-01-21 01:11:35 -08003474 static const size_t kNumFramesToSend = 50;
3475 static const int kWidth = 4;
3476 static const int kHeight = 4;
3477 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3478 void ModifyVideoConfigsHook(
3479 VideoSendStream::Config* send_config,
3480 std::vector<VideoReceiveStream::Config>* receive_configs,
3481 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003482 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003483 vp9_settings_.flexibleMode = false;
3484 vp9_settings_.numberOfTemporalLayers = 1;
3485 vp9_settings_.numberOfSpatialLayers = 1;
3486
perkjfa10b552016-10-02 23:45:26 -07003487 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003488 }
3489
3490 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3491 if (frames_sent_ > kNumFramesToSend)
3492 observation_complete_.Set();
3493 }
perkjfa10b552016-10-02 23:45:26 -07003494
3495 void ModifyVideoCaptureStartResolution(int* width,
3496 int* height,
3497 int* frame_rate) override {
3498 expected_width_ = kWidth;
3499 expected_height_ = kHeight;
3500 *width = kWidth;
3501 *height = kHeight;
3502 }
asaperssond9f641e2016-01-21 01:11:35 -08003503 } test;
3504
3505 RunBaseTest(&test);
3506}
3507
kjellanderf9e2a362017-03-24 12:17:33 -07003508#if defined(WEBRTC_ANDROID)
3509// Crashes on Android; bugs.webrtc.org/7401
3510#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3511#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003512// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3513// the test after webrtc:9270 is implemented.
3514#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3515// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003516#endif
Sebastian Jansson63470292019-02-01 10:13:43 +01003517TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003518 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003519 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003520 VideoSendStream::Config* send_config,
3521 std::vector<VideoReceiveStream::Config>* receive_configs,
3522 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003523 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003524 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003525 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003526 vp9_settings_.numberOfTemporalLayers = 1;
3527 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003528 }
3529
Åsa Perssonff24c042015-12-04 10:58:08 +01003530 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3531 EXPECT_TRUE(vp9_header.flexible_mode);
3532 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3533 if (vp9_header.inter_pic_predicted) {
3534 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003535 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003536 }
3537 }
3538 } test;
3539
stefane74eef12016-01-08 06:47:13 -08003540 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003541}
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003542#endif // defined(RTC_ENABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003543
perkj803d97f2016-11-01 11:45:46 -07003544void VideoSendStreamTest::TestRequestSourceRotateVideo(
3545 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003546 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003547
3548 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003549 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003550 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003551 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003552 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003553 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3554 }
3555
3556 CreateVideoStreams();
3557 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003558 GetVideoSendStream()->SetSource(&forwarder,
3559 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003560
3561 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3562 support_orientation_ext);
3563
3564 DestroyStreams();
3565}
3566
Sebastian Jansson63470292019-02-01 10:13:43 +01003567TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003568 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3569 TestRequestSourceRotateVideo(false);
3570}
3571
Sebastian Jansson63470292019-02-01 10:13:43 +01003572TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003573 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3574 TestRequestSourceRotateVideo(true);
3575}
3576
Sebastian Jansson63470292019-02-01 10:13:43 +01003577TEST_F(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) {
Åsa Perssonf06bacc2018-10-12 11:07:20 +02003578 static const int kMaxFps = 22;
3579 class FpsObserver : public test::SendTest,
3580 public test::FrameGeneratorCapturer::SinkWantsObserver {
3581 public:
3582 FpsObserver() : SendTest(kDefaultTimeoutMs) {}
3583
3584 void OnFrameGeneratorCapturerCreated(
3585 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3586 frame_generator_capturer->SetSinkWantsObserver(this);
3587 }
3588
3589 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
3590 const rtc::VideoSinkWants& wants) override {
3591 if (wants.max_framerate_fps == kMaxFps)
3592 observation_complete_.Set();
3593 }
3594
3595 void ModifyVideoConfigs(
3596 VideoSendStream::Config* send_config,
3597 std::vector<VideoReceiveStream::Config>* receive_configs,
3598 VideoEncoderConfig* encoder_config) override {
3599 encoder_config->simulcast_layers[0].max_framerate = kMaxFps;
3600 }
3601
3602 void PerformTest() override {
3603 EXPECT_TRUE(Wait()) << "Timed out while waiting for fps to be reported.";
3604 }
3605 } test;
3606
3607 RunBaseTest(&test);
3608}
3609
michaelta3328772016-11-29 09:25:03 -08003610// This test verifies that overhead is removed from the bandwidth estimate by
3611// testing that the maximum possible target payload rate is smaller than the
3612// maximum bandwidth estimate by the overhead rate.
Sebastian Jansson63470292019-02-01 10:13:43 +01003613TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003614 test::ScopedFieldTrials override_field_trials(
3615 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3616 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3617 public test::FakeEncoder {
3618 public:
eladalon413ee9a2017-08-22 04:02:52 -07003619 explicit RemoveOverheadFromBandwidthTest(
3620 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003621 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3622 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003623 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003624 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003625 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003626 max_bitrate_bps_(0),
Niels Möllerc572ff32018-11-07 08:43:50 +01003627 first_packet_sent_(false) {}
michaelta3328772016-11-29 09:25:03 -08003628
Erik Språng566124a2018-04-23 12:32:22 +02003629 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
michaelta3328772016-11-29 09:25:03 -08003630 uint32_t frameRate) override {
3631 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003632 // Wait for the first sent packet so that videosendstream knows
3633 // rtp_overhead.
3634 if (first_packet_sent_) {
3635 max_bitrate_bps_ = bitrate.get_sum_bps();
3636 bitrate_changed_event_.Set();
3637 }
michaelta3328772016-11-29 09:25:03 -08003638 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3639 }
3640
3641 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3642 call_ = sender_call;
3643 }
3644
3645 void ModifyVideoConfigs(
3646 VideoSendStream::Config* send_config,
3647 std::vector<VideoReceiveStream::Config>* receive_configs,
3648 VideoEncoderConfig* encoder_config) override {
3649 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003650 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003651 EXPECT_FALSE(send_config->rtp.extensions.empty());
3652 }
3653
michaelt192132e2017-01-26 09:05:27 -08003654 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3655 rtc::CritScope lock(&crit_);
3656 first_packet_sent_ = true;
3657 return SEND_PACKET;
3658 }
3659
michaelta3328772016-11-29 09:25:03 -08003660 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003661 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003662 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003663 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003664 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003665 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3666 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003667 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003668 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003669 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3670 bitrate_config);
Stefan Holmer64be7fa2018-10-04 15:21:55 +02003671 call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
eladalon413ee9a2017-08-22 04:02:52 -07003672 });
michaelta3328772016-11-29 09:25:03 -08003673
3674 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003675 // overhead of 40B per packet video produces 2240bps overhead.
3676 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003677 EXPECT_TRUE(
3678 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003679 {
3680 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003681 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003682 }
3683 }
3684
3685 private:
eladalon413ee9a2017-08-22 04:02:52 -07003686 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003687 test::VideoEncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003688 Call* call_;
3689 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003690 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3691 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003692 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003693 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003694 RunBaseTest(&test);
3695}
3696
Sebastian Jansson63470292019-02-01 10:13:43 +01003697TEST_F(VideoSendStreamTest, SendsKeepAlive) {
sprang168794c2017-07-06 04:38:06 -07003698 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003699
3700 class KeepaliveObserver : public test::SendTest {
3701 public:
3702 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3703
sprangdb2a9fc2017-08-09 06:42:32 -07003704 void OnRtpTransportControllerSendCreated(
3705 RtpTransportControllerSend* controller) override {
3706 RtpKeepAliveConfig config;
3707 config.timeout_interval_ms = kTimeoutMs;
3708 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3709 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003710 }
3711
sprang168794c2017-07-06 04:38:06 -07003712 private:
3713 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3714 RTPHeader header;
3715 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3716
sprangd2702ef2017-07-10 08:41:10 -07003717 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003718 // The video stream has started. Stop it now.
3719 if (capturer_)
3720 capturer_->Stop();
3721 } else {
3722 observation_complete_.Set();
3723 }
3724
3725 return SEND_PACKET;
3726 }
3727
sprang168794c2017-07-06 04:38:06 -07003728 void PerformTest() override {
3729 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3730 }
3731
3732 void OnFrameGeneratorCapturerCreated(
3733 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3734 capturer_ = frame_generator_capturer;
3735 }
3736
3737 test::FrameGeneratorCapturer* capturer_ = nullptr;
3738 } test;
3739
3740 RunBaseTest(&test);
3741}
3742
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003743class PacingFactorObserver : public test::SendTest {
3744 public:
3745 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003746 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003747 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3748 configure_send_side_(configure_send_side),
3749 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003750
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003751 void ModifyVideoConfigs(
3752 VideoSendStream::Config* send_config,
3753 std::vector<VideoReceiveStream::Config>* receive_configs,
3754 VideoEncoderConfig* encoder_config) override {
3755 // Check if send-side bwe extension is already present, and remove it if
3756 // it is not desired.
3757 bool has_send_side = false;
3758 for (auto it = send_config->rtp.extensions.begin();
3759 it != send_config->rtp.extensions.end(); ++it) {
3760 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3761 if (configure_send_side_) {
3762 has_send_side = true;
3763 } else {
3764 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003765 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003766 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003767 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003768 }
3769
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003770 if (configure_send_side_ && !has_send_side) {
Elad Alon157540a2019-02-08 23:37:52 +01003771 rtc::UniqueNumberGenerator<int> unique_id_generator;
3772 unique_id_generator.AddKnownId(0); // First valid RTP extension ID is 1.
3773 for (const RtpExtension& extension : send_config->rtp.extensions) {
3774 unique_id_generator.AddKnownId(extension.id);
3775 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003776 // Want send side, not present by default, so add it.
3777 send_config->rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +01003778 RtpExtension::kTransportSequenceNumberUri, unique_id_generator());
Erik Språng7c8cca32017-10-24 17:05:18 +02003779 }
3780
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003781 // ALR only enabled for screenshare.
3782 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3783 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003784
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003785 void OnVideoStreamsCreated(
3786 VideoSendStream* send_stream,
3787 const std::vector<VideoReceiveStream*>& receive_streams) override {
3788 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3789 // Video streams created, check that pacing factor is correctly configured.
3790 EXPECT_EQ(expected_pacing_factor_,
3791 internal_send_peer.GetPacingFactorOverride());
3792 observation_complete_.Set();
3793 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003794
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003795 void PerformTest() override {
3796 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3797 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003798
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003799 private:
3800 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003801 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003802};
3803
3804std::string GetAlrProbingExperimentString() {
3805 return std::string(
3806 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3807 "/1.0,2875,80,40,-60,3/";
3808}
3809const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3810
Sebastian Jansson63470292019-02-01 10:13:43 +01003811TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003812 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003813 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003814 PacingFactorObserver test_with_send_side(true,
3815 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003816 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003817}
Erik Språng7c8cca32017-10-24 17:05:18 +02003818
Sebastian Jansson63470292019-02-01 10:13:43 +01003819TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003820 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3821 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003822 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003823 RunBaseTest(&test_without_send_side);
3824}
3825
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003826// Test class takes as argument a function pointer to reset the send
3827// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3828// change the content type of a VideoSendStream, you need to recreate it.
3829// Stopping and recreating the stream can only be done on the main thread and in
3830// the context of VideoSendStreamTest (not BaseTest). The test switches from
3831// realtime to screenshare and back.
3832template <typename T>
3833class ContentSwitchTest : public test::SendTest {
3834 public:
3835 enum class StreamState {
3836 kBeforeSwitch = 0,
3837 kInScreenshare = 1,
3838 kAfterSwitchBack = 2,
3839 };
3840 static const uint32_t kMinPacketsToSend = 50;
3841
3842 explicit ContentSwitchTest(T* stream_reset_fun)
3843 : SendTest(test::CallTest::kDefaultTimeoutMs),
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003844 call_(nullptr),
3845 state_(StreamState::kBeforeSwitch),
3846 send_stream_(nullptr),
3847 send_stream_config_(nullptr),
3848 packets_sent_(0),
3849 stream_resetter_(stream_reset_fun) {
3850 RTC_DCHECK(stream_resetter_);
3851 }
3852
3853 void OnVideoStreamsCreated(
3854 VideoSendStream* send_stream,
3855 const std::vector<VideoReceiveStream*>& receive_streams) override {
3856 rtc::CritScope lock(&crit_);
3857 send_stream_ = send_stream;
3858 }
3859
3860 void ModifyVideoConfigs(
3861 VideoSendStream::Config* send_config,
3862 std::vector<VideoReceiveStream::Config>* receive_configs,
3863 VideoEncoderConfig* encoder_config) override {
3864 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3865 encoder_config->min_transmit_bitrate_bps = 0;
3866 encoder_config->content_type =
3867 VideoEncoderConfig::ContentType::kRealtimeVideo;
3868 send_stream_config_ = send_config->Copy();
3869 encoder_config_ = encoder_config->Copy();
3870 }
3871
3872 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3873 call_ = sender_call;
3874 }
3875
3876 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3877 rtc::CritScope lock(&crit_);
3878
3879 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3880 float pacing_factor =
3881 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3882 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3883 if (send_stream_->GetStats().content_type ==
3884 webrtc::VideoContentType::SCREENSHARE) {
3885 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3886 }
3887
3888 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3889
3890 // Wait until at least kMinPacketsToSend packets to be sent, so that
3891 // some frames would be encoded.
3892 if (++packets_sent_ < kMinPacketsToSend)
3893 return SEND_PACKET;
3894
3895 if (state_ != StreamState::kAfterSwitchBack) {
3896 // We've sent kMinPacketsToSend packets, switch the content type and move
3897 // move to the next state.
3898 // Note that we need to recreate the stream if changing content type.
3899 packets_sent_ = 0;
3900 if (encoder_config_.content_type ==
3901 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3902 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3903 } else {
3904 encoder_config_.content_type =
3905 VideoEncoderConfig::ContentType::kRealtimeVideo;
3906 }
3907 switch (state_) {
3908 case StreamState::kBeforeSwitch:
3909 state_ = StreamState::kInScreenshare;
3910 break;
3911 case StreamState::kInScreenshare:
3912 state_ = StreamState::kAfterSwitchBack;
3913 break;
3914 case StreamState::kAfterSwitchBack:
3915 RTC_NOTREACHED();
3916 break;
3917 }
3918 content_switch_event_.Set();
3919 return SEND_PACKET;
3920 }
3921
3922 observation_complete_.Set();
3923 return SEND_PACKET;
3924 }
3925
3926 void PerformTest() override {
3927 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3928 ASSERT_TRUE(
3929 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3930 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3931 }
3932
3933 ASSERT_TRUE(Wait())
3934 << "Timed out waiting for a frame sent after switch back";
3935 }
3936
3937 private:
3938 StreamState GetStreamState() {
3939 rtc::CritScope lock(&crit_);
3940 return state_;
3941 }
3942
3943 rtc::CriticalSection crit_;
3944 rtc::Event content_switch_event_;
3945 Call* call_;
3946 StreamState state_ RTC_GUARDED_BY(crit_);
3947 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3948 VideoSendStream::Config send_stream_config_;
3949 VideoEncoderConfig encoder_config_;
3950 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3951 T* stream_resetter_;
3952};
3953
Sebastian Jansson63470292019-02-01 10:13:43 +01003954TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003955 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3956 const VideoEncoderConfig& encoder_config,
3957 test::BaseTest* test) {
3958 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3959 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003960 DestroyVideoSendStreams();
3961 SetVideoSendConfig(send_stream_config);
3962 SetVideoEncoderConfig(encoder_config);
3963 CreateVideoSendStreams();
3964 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3965 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003966 Start();
3967 });
3968 };
3969 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3970 RunBaseTest(&test);
3971}
3972
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003973} // namespace webrtc