blob: fe562d514319a8d63a4d8cd0d93c5365781c7036 [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 {
Elad Alond8d32482019-02-18 23:45:57 +010076enum : int { // The first valid value is 1.
77 kAbsSendTimeExtensionId = 1,
78 kTimestampOffsetExtensionId,
79 kTransportSequenceNumberExtensionId,
80 kVideoContentTypeExtensionId,
81 kVideoRotationExtensionId,
82 kVideoTimingExtensionId,
83};
84
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080085constexpr int64_t kRtcpIntervalMs = 1000;
86
Yves Gerey665174f2018-06-19 15:03:05 +020087enum VideoFormat {
88 kGeneric,
89 kVP8,
90};
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080091} // namespace
sprang@webrtc.org346094c2014-02-18 08:40:33 +000092
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070093VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000094
Sebastian Jansson63470292019-02-01 10:13:43 +010095class VideoSendStreamTest : public test::CallTest {
Elad Alond8d32482019-02-18 23:45:57 +010096 public:
97 VideoSendStreamTest() {
98 RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
99 kTransportSequenceNumberExtensionId));
100 }
101
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000102 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000103 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000104 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000105 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +0100106
107 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
108 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -0700109
110 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000111};
112
Sebastian Jansson63470292019-02-01 10:13:43 +0100113TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700114 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200115 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000116
eladalon413ee9a2017-08-22 04:02:52 -0700117 test::NullTransport transport;
118 CreateSendConfig(1, 0, 0, &transport);
119 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200120 GetVideoSendStream()->Start();
121 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700122 DestroyStreams();
123 DestroyCalls();
124 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000125}
126
Sebastian Jansson63470292019-02-01 10:13:43 +0100127TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700128 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200129 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000130
eladalon413ee9a2017-08-22 04:02:52 -0700131 test::NullTransport transport;
132 CreateSendConfig(1, 0, 0, &transport);
133 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200134 GetVideoSendStream()->Stop();
135 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700136 DestroyStreams();
137 DestroyCalls();
138 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000139}
140
Sebastian Jansson63470292019-02-01 10:13:43 +0100141TEST_F(VideoSendStreamTest, SupportsCName) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000142 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000143 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000144 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000145 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000146
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000147 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000148 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700149 test::RtcpPacketParser parser;
150 EXPECT_TRUE(parser.Parse(packet, length));
151 if (parser.sdes()->num_packets() > 0) {
152 EXPECT_EQ(1u, parser.sdes()->chunks().size());
153 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000154
danilchap3dc929e2016-11-02 08:21:59 -0700155 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000156 }
157
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000158 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000159 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000160
stefanff483612015-12-21 03:14:00 -0800161 void ModifyVideoConfigs(
162 VideoSendStream::Config* send_config,
163 std::vector<VideoReceiveStream::Config>* receive_configs,
164 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000165 send_config->rtp.c_name = kCName;
166 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000167
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000168 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100169 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000170 }
171 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000172
stefane74eef12016-01-08 06:47:13 -0800173 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000174}
175
Sebastian Jansson63470292019-02-01 10:13:43 +0100176TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000177 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000178 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000179 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000180 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100181 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000182 }
183
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000184 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000185 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000186 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000187
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000188 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
189 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
190 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700191 if (header.extension.absoluteSendTime != 0) {
192 // Wait for at least one packet with a non-zero send time. The send time
193 // is a 16-bit value derived from the system clock, and it is valid
194 // for a packet to have a zero send time. To tell that from an
195 // unpopulated value we'll wait for a packet with non-zero send time.
196 observation_complete_.Set();
197 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100198 RTC_LOG(LS_WARNING)
199 << "Got a packet with zero absoluteSendTime, waiting"
200 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700201 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000202
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000203 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000204 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000205
stefanff483612015-12-21 03:14:00 -0800206 void ModifyVideoConfigs(
207 VideoSendStream::Config* send_config,
208 std::vector<VideoReceiveStream::Config>* receive_configs,
209 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200210 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100211 send_config->rtp.extensions.push_back(
212 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000213 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000214
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000215 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100216 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000217 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000218 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000219
stefane74eef12016-01-08 06:47:13 -0800220 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000221}
222
Sebastian Jansson63470292019-02-01 10:13:43 +0100223TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000224 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000225 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000226 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000227 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200228 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200229 return absl::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200230 Clock::GetRealTimeClock(), kEncodeDelayMs);
231 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000232 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100233 kRtpExtensionTransmissionTimeOffset, kTimestampOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000234 }
235
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000236 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000237 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000238 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000239 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000240
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000241 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
242 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000243 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000244 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100245 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000246
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000247 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000248 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000249
stefanff483612015-12-21 03:14:00 -0800250 void ModifyVideoConfigs(
251 VideoSendStream::Config* send_config,
252 std::vector<VideoReceiveStream::Config>* receive_configs,
253 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200254 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100255 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700256 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100257 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000258 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000259
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000260 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100261 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000262 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000263
Niels Möller4db138e2018-04-19 09:04:13 +0200264 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000265 } test;
266
stefane74eef12016-01-08 06:47:13 -0800267 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000268}
269
Sebastian Jansson63470292019-02-01 10:13:43 +0100270TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
Elad Alond8d32482019-02-18 23:45:57 +0100271 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700272 class TransportWideSequenceNumberObserver : public test::SendTest {
273 public:
274 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200275 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200276 return absl::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200277 Clock::GetRealTimeClock());
278 }) {
sprang867fb522015-08-03 04:38:41 -0700279 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
280 kRtpExtensionTransportSequenceNumber, kExtensionId));
281 }
282
283 private:
284 Action OnSendRtp(const uint8_t* packet, size_t length) override {
285 RTPHeader header;
286 EXPECT_TRUE(parser_->Parse(packet, length, &header));
287
288 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
289 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
290 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
291
Peter Boström5811a392015-12-10 13:02:50 +0100292 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700293
294 return SEND_PACKET;
295 }
296
stefanff483612015-12-21 03:14:00 -0800297 void ModifyVideoConfigs(
298 VideoSendStream::Config* send_config,
299 std::vector<VideoReceiveStream::Config>* receive_configs,
300 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200301 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700302 }
303
304 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100305 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700306 }
307
Niels Möller4db138e2018-04-19 09:04:13 +0200308 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700309 } test;
310
stefane74eef12016-01-08 06:47:13 -0800311 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700312}
313
Sebastian Jansson63470292019-02-01 10:13:43 +0100314TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
perkj803d97f2016-11-01 11:45:46 -0700315 class VideoRotationObserver : public test::SendTest {
316 public:
317 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
318 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100319 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700320 }
321
322 Action OnSendRtp(const uint8_t* packet, size_t length) override {
323 RTPHeader header;
324 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700325 // Only the last packet of the frame is required to have the extension.
326 if (!header.markerBit)
327 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700328 EXPECT_TRUE(header.extension.hasVideoRotation);
329 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
330 observation_complete_.Set();
331 return SEND_PACKET;
332 }
333
334 void ModifyVideoConfigs(
335 VideoSendStream::Config* send_config,
336 std::vector<VideoReceiveStream::Config>* receive_configs,
337 VideoEncoderConfig* encoder_config) override {
338 send_config->rtp.extensions.clear();
339 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100340 RtpExtension::kVideoRotationUri, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700341 }
342
343 void OnFrameGeneratorCapturerCreated(
344 test::FrameGeneratorCapturer* frame_generator_capturer) override {
345 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
346 }
347
348 void PerformTest() override {
349 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
350 }
351 } test;
352
353 RunBaseTest(&test);
354}
355
Sebastian Jansson63470292019-02-01 10:13:43 +0100356TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700357 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700358 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100359 VideoContentTypeObserver()
360 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700361 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100362 kRtpExtensionVideoContentType, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700363 }
364
365 Action OnSendRtp(const uint8_t* packet, size_t length) override {
366 RTPHeader header;
367 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100368 // Only the last packet of the key-frame must have extension.
369 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700370 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100371 // First marker bit seen means that the first frame is sent.
372 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700373 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700374 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
375 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700376 observation_complete_.Set();
377 return SEND_PACKET;
378 }
379
380 void ModifyVideoConfigs(
381 VideoSendStream::Config* send_config,
382 std::vector<VideoReceiveStream::Config>* receive_configs,
383 VideoEncoderConfig* encoder_config) override {
384 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100385 send_config->rtp.extensions.push_back(RtpExtension(
386 RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700387 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
388 }
389
390 void PerformTest() override {
391 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
392 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100393
394 private:
395 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700396 } test;
397
398 RunBaseTest(&test);
399}
400
Sebastian Jansson63470292019-02-01 10:13:43 +0100401TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700402 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700403 public:
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100404 VideoTimingObserver()
405 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
Elad Alond8d32482019-02-18 23:45:57 +0100406 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
407 kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700408 }
409
410 Action OnSendRtp(const uint8_t* packet, size_t length) override {
411 RTPHeader header;
412 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700413 // Only the last packet of the frame must have extension.
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100414 // Also don't check packets of the second frame if they happen to get
415 // through before the test terminates.
416 if (!header.markerBit || first_frame_sent_)
ilnik10894992017-06-21 08:23:19 -0700417 return SEND_PACKET;
418 EXPECT_TRUE(header.extension.has_video_timing);
419 observation_complete_.Set();
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100420 first_frame_sent_ = true;
ilnik04f4d122017-06-19 07:18:55 -0700421 return SEND_PACKET;
422 }
423
424 void ModifyVideoConfigs(
425 VideoSendStream::Config* send_config,
426 std::vector<VideoReceiveStream::Config>* receive_configs,
427 VideoEncoderConfig* encoder_config) override {
428 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100429 send_config->rtp.extensions.push_back(
430 RtpExtension(RtpExtension::kVideoTimingUri, kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700431 }
432
433 void PerformTest() override {
434 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
435 }
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100436
437 private:
438 bool first_frame_sent_;
ilnik04f4d122017-06-19 07:18:55 -0700439 } test;
440
441 RunBaseTest(&test);
442}
443
danilchap901b2df2017-07-28 08:56:04 -0700444class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000445 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000446 FakeReceiveStatistics(uint32_t send_ssrc,
447 uint32_t last_sequence_number,
448 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700449 uint8_t fraction_lost) {
450 stat_.SetMediaSsrc(send_ssrc);
451 stat_.SetExtHighestSeqNum(last_sequence_number);
452 stat_.SetCumulativeLost(cumulative_lost);
453 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000454 }
455
danilchap901b2df2017-07-28 08:56:04 -0700456 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
457 EXPECT_GE(max_blocks, 1u);
458 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000459 }
460
461 private:
danilchap901b2df2017-07-28 08:56:04 -0700462 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000463};
464
brandtre602f0a2016-10-31 03:40:49 -0700465class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100466 public:
brandtre602f0a2016-10-31 03:40:49 -0700467 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800468 bool use_nack,
469 bool expect_red,
470 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800471 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200472 VideoEncoderFactory* encoder_factory)
brandtr20d45472017-01-02 00:34:27 -0800473 : EndToEndTest(kTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200474 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100475 payload_name_(codec),
476 use_nack_(use_nack),
477 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700478 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800479 sent_media_(false),
480 sent_ulpfec_(false),
Elad Alond8d32482019-02-18 23:45:57 +0100481 header_extensions_enabled_(header_extensions_enabled) {
482 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
483 kAbsSendTimeExtensionId);
484 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
485 kTransportSequenceNumberExtensionId);
486 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100487
brandtr20d45472017-01-02 00:34:27 -0800488 // Some of the test cases are expected to time out and thus we are using
489 // a shorter timeout window than the default here.
490 static constexpr size_t kTimeoutMs = 10000;
491
Stefan Holmer4654d202015-12-08 09:10:43 +0100492 private:
493 Action OnSendRtp(const uint8_t* packet, size_t length) override {
494 RTPHeader header;
495 EXPECT_TRUE(parser_->Parse(packet, length, &header));
496
Stefan Holmer4654d202015-12-08 09:10:43 +0100497 int encapsulated_payload_type = -1;
498 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100499 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100500 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
501 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100502 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100503 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
504 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100505 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100506 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100507 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
508 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100509 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
510 length) {
511 // Not padding-only, media received outside of RED.
512 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800513 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100514 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100515 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000516
Stefan Holmer4654d202015-12-08 09:10:43 +0100517 if (header_extensions_enabled_) {
518 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
519 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
520 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
521 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
522 // 24 bits wrap.
523 EXPECT_GT(prev_header_.extension.absoluteSendTime,
524 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000525 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100526 EXPECT_GE(header.extension.absoluteSendTime,
527 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200528 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100529 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
530 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
531 prev_header_.extension.transportSequenceNumber;
532 EXPECT_EQ(1, seq_num_diff);
533 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200534
Stefan Holmer4654d202015-12-08 09:10:43 +0100535 if (encapsulated_payload_type != -1) {
536 if (encapsulated_payload_type ==
537 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700538 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800539 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100540 } else {
brandtr65a1e772016-12-12 01:54:58 -0800541 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000542 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000543 }
544
brandtr20d45472017-01-02 00:34:27 -0800545 if (sent_media_ && sent_ulpfec_) {
546 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100547 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000548
Stefan Holmer4654d202015-12-08 09:10:43 +0100549 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000550
Stefan Holmer4654d202015-12-08 09:10:43 +0100551 return SEND_PACKET;
552 }
553
eladalon413ee9a2017-08-22 04:02:52 -0700554 test::PacketTransport* CreateSendTransport(
555 test::SingleThreadedTaskQueueForTesting* task_queue,
556 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100557 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
558 // Configure some network delay.
559 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200560 BuiltInNetworkBehaviorConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800561 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100562 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700563 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700564 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200565 VideoSendStreamTest::payload_type_map_,
566 absl::make_unique<FakeNetworkPipe>(
567 Clock::GetRealTimeClock(),
568 absl::make_unique<SimulatedNetwork>(config)));
Peter Boström39593972016-02-15 11:27:15 +0100569 }
570
stefanff483612015-12-21 03:14:00 -0800571 void ModifyVideoConfigs(
572 VideoSendStream::Config* send_config,
573 std::vector<VideoReceiveStream::Config>* receive_configs,
574 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100575 if (use_nack_) {
576 send_config->rtp.nack.rtp_history_ms =
577 (*receive_configs)[0].rtp.nack.rtp_history_ms =
578 VideoSendStreamTest::kNackRtpHistoryMs;
579 }
Niels Möller4db138e2018-04-19 09:04:13 +0200580 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200581 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700582 send_config->rtp.ulpfec.red_payload_type =
583 VideoSendStreamTest::kRedPayloadType;
584 send_config->rtp.ulpfec.ulpfec_payload_type =
585 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800586 if (!header_extensions_enabled_) {
587 send_config->rtp.extensions.clear();
588 } else {
Elad Alond8d32482019-02-18 23:45:57 +0100589 send_config->rtp.extensions.push_back(
590 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100591 }
Niels Möller259a4972018-04-05 15:36:51 +0200592 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700593 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700594 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700595 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700596 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100597 }
598
599 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800600 EXPECT_EQ(expect_ulpfec_, Wait())
601 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100602 }
603
Niels Möller4db138e2018-04-19 09:04:13 +0200604 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800605 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100606 const bool use_nack_;
607 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700608 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800609 bool sent_media_;
610 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100611 bool header_extensions_enabled_;
612 RTPHeader prev_header_;
613};
614
Sebastian Jansson63470292019-02-01 10:13:43 +0100615TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200616 test::FunctionVideoEncoderFactory encoder_factory(
617 []() { return VP8Encoder::Create(); });
618 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800619 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100620}
621
Sebastian Jansson63470292019-02-01 10:13:43 +0100622TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200623 test::FunctionVideoEncoderFactory encoder_factory(
624 []() { return VP8Encoder::Create(); });
625 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100626 RunBaseTest(&test);
627}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000628
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200629class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
stefan60e10c72017-08-23 10:40:00 -0700630 protected:
631 VideoSendStreamWithoutUlpfecTest()
632 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
633
634 test::ScopedFieldTrials field_trial_;
635};
636
637TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200638 test::FunctionVideoEncoderFactory encoder_factory(
639 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200640 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700641 RunBaseTest(&test);
642}
643
Peter Boström39593972016-02-15 11:27:15 +0100644// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
645// since we'll still have to re-request FEC packets, effectively wasting
646// bandwidth since the receiver has to wait for FEC retransmissions to determine
647// that the received state is actually decodable.
Sebastian Jansson63470292019-02-01 10:13:43 +0100648TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200649 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200650 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200651 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200652 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100653 RunBaseTest(&test);
654}
655
656// Without retransmissions FEC for H264 is fine.
Sebastian Jansson63470292019-02-01 10:13:43 +0100657TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200658 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200659 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200660 });
661 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100662 RunBaseTest(&test);
663}
664
danilchap9f5b6222017-03-02 06:22:21 -0800665// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Jansson63470292019-02-01 10:13:43 +0100666TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200667 test::FunctionVideoEncoderFactory encoder_factory(
668 []() { return VP8Encoder::Create(); });
669 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100670 RunBaseTest(&test);
671}
672
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100673#if defined(RTC_ENABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800674// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Jansson63470292019-02-01 10:13:43 +0100675TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200676 test::FunctionVideoEncoderFactory encoder_factory(
677 []() { return VP9Encoder::Create(); });
678 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800679 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000680}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100681#endif // defined(RTC_ENABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000682
Sebastian Jansson63470292019-02-01 10:13:43 +0100683TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200684 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200685 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200686 Clock::GetRealTimeClock());
687 });
688 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800689 RunBaseTest(&test);
690}
691
brandtr39f97292016-11-16 22:57:50 -0800692// TODO(brandtr): Move these FlexFEC tests when we have created
693// FlexfecSendStream.
694class FlexfecObserver : public test::EndToEndTest {
695 public:
696 FlexfecObserver(bool header_extensions_enabled,
697 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800698 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200699 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100700 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800701 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200702 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800703 payload_name_(codec),
704 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800705 sent_media_(false),
706 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100707 header_extensions_enabled_(header_extensions_enabled),
Elad Alond8d32482019-02-18 23:45:57 +0100708 num_video_streams_(num_video_streams) {
709 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
710 kAbsSendTimeExtensionId);
711 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
712 kTimestampOffsetExtensionId);
713 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
714 kTransportSequenceNumberExtensionId);
715 }
brandtr39f97292016-11-16 22:57:50 -0800716
717 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100718 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800719
720 private:
721 Action OnSendRtp(const uint8_t* packet, size_t length) override {
722 RTPHeader header;
723 EXPECT_TRUE(parser_->Parse(packet, length, &header));
724
brandtr39f97292016-11-16 22:57:50 -0800725 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
726 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
727 sent_flexfec_ = true;
728 } else {
729 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
730 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100731 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
732 num_video_streams_),
733 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800734 sent_media_ = true;
735 }
736
737 if (header_extensions_enabled_) {
738 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
739 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
740 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
741 }
742
brandtr0c5a1542016-11-23 04:42:26 -0800743 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800744 observation_complete_.Set();
745 }
746
747 return SEND_PACKET;
748 }
749
eladalon413ee9a2017-08-22 04:02:52 -0700750 test::PacketTransport* CreateSendTransport(
751 test::SingleThreadedTaskQueueForTesting* task_queue,
752 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800753 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
754 // Therefore we need some network delay.
755 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200756 BuiltInNetworkBehaviorConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800757 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800758 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700759 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700760 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200761 VideoSendStreamTest::payload_type_map_,
762 absl::make_unique<FakeNetworkPipe>(
763 Clock::GetRealTimeClock(),
764 absl::make_unique<SimulatedNetwork>(config)));
brandtr39f97292016-11-16 22:57:50 -0800765 }
766
767 void ModifyVideoConfigs(
768 VideoSendStream::Config* send_config,
769 std::vector<VideoReceiveStream::Config>* receive_configs,
770 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800771 if (use_nack_) {
772 send_config->rtp.nack.rtp_history_ms =
773 (*receive_configs)[0].rtp.nack.rtp_history_ms =
774 VideoSendStreamTest::kNackRtpHistoryMs;
775 }
Niels Möller4db138e2018-04-19 09:04:13 +0200776 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200777 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800778 if (header_extensions_enabled_) {
Elad Alond8d32482019-02-18 23:45:57 +0100779 send_config->rtp.extensions.push_back(
780 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
brandtr39f97292016-11-16 22:57:50 -0800781 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100782 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800783 } else {
784 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800785 }
Niels Möller259a4972018-04-05 15:36:51 +0200786 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800787 }
788
789 void PerformTest() override {
790 EXPECT_TRUE(Wait())
791 << "Timed out waiting for FlexFEC and/or media packets.";
792 }
793
Niels Möller4db138e2018-04-19 09:04:13 +0200794 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800795 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800796 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800797 bool sent_media_;
798 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100799 const bool header_extensions_enabled_;
800 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800801};
802
Sebastian Jansson63470292019-02-01 10:13:43 +0100803TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200804 test::FunctionVideoEncoderFactory encoder_factory(
805 []() { return VP8Encoder::Create(); });
806 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100807 RunBaseTest(&test);
808}
809
Sebastian Jansson63470292019-02-01 10:13:43 +0100810TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200811 test::FunctionVideoEncoderFactory encoder_factory(
812 []() { return VP8Encoder::Create(); });
813 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800814 RunBaseTest(&test);
815}
816
Sebastian Jansson63470292019-02-01 10:13:43 +0100817TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200818 test::FunctionVideoEncoderFactory encoder_factory(
819 []() { return VP8Encoder::Create(); });
820 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800821 RunBaseTest(&test);
822}
823
Sebastian Jansson63470292019-02-01 10:13:43 +0100824TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200825 test::FunctionVideoEncoderFactory encoder_factory(
826 []() { return VP8Encoder::Create(); });
827 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800828 RunBaseTest(&test);
829}
830
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100831#if defined(RTC_ENABLE_VP9)
Sebastian Jansson63470292019-02-01 10:13:43 +0100832TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200833 test::FunctionVideoEncoderFactory encoder_factory(
834 []() { return VP9Encoder::Create(); });
835 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800836 RunBaseTest(&test);
837}
838
Sebastian Jansson63470292019-02-01 10:13:43 +0100839TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200840 test::FunctionVideoEncoderFactory encoder_factory(
841 []() { return VP9Encoder::Create(); });
842 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800843 RunBaseTest(&test);
844}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100845#endif // defined(RTC_ENABLE_VP9)
brandtr39f97292016-11-16 22:57:50 -0800846
Sebastian Jansson63470292019-02-01 10:13:43 +0100847TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200848 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200849 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200850 });
851 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800852 RunBaseTest(&test);
853}
854
Sebastian Jansson63470292019-02-01 10:13:43 +0100855TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200856 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200857 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200858 });
859 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800860 RunBaseTest(&test);
861}
862
Sebastian Jansson63470292019-02-01 10:13:43 +0100863TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200864 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200865 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200866 Clock::GetRealTimeClock());
867 });
868
869 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800870 RunBaseTest(&test);
871}
872
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000873void VideoSendStreamTest::TestNackRetransmission(
874 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000875 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000876 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000877 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000878 explicit NackObserver(uint32_t retransmit_ssrc,
879 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000880 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000881 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100882 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000883 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100884 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000885
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000886 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000887 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000888 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000889 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000890
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200891 // NACK packets two times at some arbitrary points.
892 const int kNackedPacketsAtOnceCount = 3;
893 const int kRetransmitTarget = kNackedPacketsAtOnceCount * 2;
894
895 // Skip padding packets because they will never be retransmitted.
896 if (header.paddingLength + header.headerLength == length) {
897 return SEND_PACKET;
898 }
899
Sebastian Janssond3f38162018-02-28 16:14:44 +0100900 ++send_count_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200901
902 // NACK packets at arbitrary points.
Sebastian Janssond3f38162018-02-28 16:14:44 +0100903 if (send_count_ == 5 || send_count_ == 25) {
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200904 nacked_sequence_numbers_.insert(
905 nacked_sequence_numbers_.end(),
906 non_padding_sequence_numbers_.end() - kNackedPacketsAtOnceCount,
907 non_padding_sequence_numbers_.end());
Sebastian Janssond3f38162018-02-28 16:14:44 +0100908
danilchap8a1d2a32017-08-01 03:21:37 -0700909 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800910 nullptr, nullptr, transport_adapter_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800911 kRtcpIntervalMs);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000912
pbosda903ea2015-10-02 02:36:56 -0700913 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100914 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000915
916 RTCPSender::FeedbackState feedback_state;
917
Sebastian Janssond3f38162018-02-28 16:14:44 +0100918 EXPECT_EQ(0, rtcp_sender.SendRTCP(
919 feedback_state, kRtcpNack,
920 static_cast<int>(nacked_sequence_numbers_.size()),
921 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000922 }
923
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000924 uint16_t sequence_number = header.sequenceNumber;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000925 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100926 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
927 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000928 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000929 const uint8_t* rtx_header = packet + header.headerLength;
930 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
931 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200932
Sebastian Janssond3f38162018-02-28 16:14:44 +0100933 auto found = std::find(nacked_sequence_numbers_.begin(),
934 nacked_sequence_numbers_.end(), sequence_number);
935 if (found != nacked_sequence_numbers_.end()) {
936 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000937
Sebastian Janssond3f38162018-02-28 16:14:44 +0100938 if (++retransmit_count_ == kRetransmitTarget) {
939 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
940 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
941 observation_complete_.Set();
942 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200943 } else {
944 non_padding_sequence_numbers_.push_back(sequence_number);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000945 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000946
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000947 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000948 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000949
stefanff483612015-12-21 03:14:00 -0800950 void ModifyVideoConfigs(
951 VideoSendStream::Config* send_config,
952 std::vector<VideoReceiveStream::Config>* receive_configs,
953 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700954 transport_adapter_.reset(
955 new internal::TransportAdapter(send_config->send_transport));
956 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000957 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000958 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100959 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000960 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
961 }
962
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000963 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100964 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000965 }
966
kwiberg27f982b2016-03-01 11:52:33 -0800967 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000968 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100969 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000970 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000971 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100972 std::vector<uint16_t> nacked_sequence_numbers_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200973 std::vector<uint16_t> non_padding_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000974 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000975
stefane74eef12016-01-08 06:47:13 -0800976 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000977}
978
Sebastian Jansson63470292019-02-01 10:13:43 +0100979TEST_F(VideoSendStreamTest, RetransmitsNack) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000980 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100981 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000982}
983
Sebastian Jansson63470292019-02-01 10:13:43 +0100984TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000985 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000986 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000987}
988
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000989void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
990 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000991 // Use a fake encoder to output a frame of every size in the range [90, 290],
992 // for each size making sure that the exact number of payload bytes received
993 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000994 static const size_t kMaxPacketSize = 128;
995 static const size_t start = 90;
996 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000997
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000998 // Observer that verifies that the expected number of packets and bytes
999 // arrive for each frame size, from start_size to stop_size.
Niels Möller759f9592018-10-09 14:57:01 +02001000 class FrameFragmentationTest : public test::SendTest {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001001 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001002 FrameFragmentationTest(size_t max_packet_size,
1003 size_t start_size,
1004 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001005 bool test_generic_packetization,
1006 bool use_fec)
1007 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001008 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +02001009 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001010 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001011 stop_size_(stop_size),
1012 test_generic_packetization_(test_generic_packetization),
1013 use_fec_(use_fec),
1014 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001015 packets_lost_(0),
1016 last_packet_count_(0),
1017 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001018 accumulated_size_(0),
1019 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001020 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001021 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001022 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001023 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001024 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -07001025 RTC_DCHECK_GT(stop_size, max_packet_size);
Philip Eliassond52a1a62018-09-07 13:03:55 +00001026 if (!test_generic_packetization_)
1027 encoder_.SetCodecType(kVideoCodecVP8);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001028 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001029
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001030 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001031 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001032 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001033 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001034 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001035
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001036 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001037
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001038 if (use_fec_) {
1039 uint8_t payload_type = packet[header.headerLength];
1040 bool is_fec = header.payloadType == kRedPayloadType &&
1041 payload_type == kUlpfecPayloadType;
1042 if (is_fec) {
1043 fec_packet_received_ = true;
1044 return SEND_PACKET;
1045 }
1046 }
1047
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001048 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001049
1050 if (use_fec_)
1051 TriggerLossReport(header);
1052
1053 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +02001054 size_t overhead = header.headerLength + header.paddingLength;
1055 // Only remove payload header and RED header if the packet actually
1056 // contains payload.
1057 if (length > overhead) {
1058 overhead += (1 /* Generic header */);
1059 if (use_fec_)
1060 overhead += 1; // RED for FEC header.
1061 }
1062 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001063 accumulated_payload_ += length - overhead;
1064 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001065
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001066 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001067 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001068 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1069 // With FEC enabled, frame size is incremented asynchronously, so
1070 // "old" frames one byte too small may arrive. Accept, but don't
1071 // increase expected frame size.
1072 accumulated_size_ = 0;
1073 accumulated_payload_ = 0;
1074 return SEND_PACKET;
1075 }
1076
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001077 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001078 if (test_generic_packetization_) {
1079 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1080 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001081
1082 // Last packet of frame; reset counters.
1083 accumulated_size_ = 0;
1084 accumulated_payload_ = 0;
1085 if (current_size_rtp_ == stop_size_) {
1086 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001087 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001088 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001089 // Increase next expected frame size. If testing with FEC, make sure
1090 // a FEC packet has been received for this frame size before
1091 // proceeding, to make sure that redundancy packets don't exceed
1092 // size limit.
1093 if (!use_fec_) {
1094 ++current_size_rtp_;
1095 } else if (fec_packet_received_) {
1096 fec_packet_received_ = false;
1097 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001098
1099 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001100 ++current_size_frame_;
1101 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001102 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001103 }
1104
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001105 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001106 }
1107
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001108 void TriggerLossReport(const RTPHeader& header) {
1109 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001110 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001111 if (++packet_count_ % (100 / kLossPercent) == 0) {
1112 packets_lost_++;
1113 int loss_delta = packets_lost_ - last_packets_lost_;
1114 int packets_delta = packet_count_ - last_packet_count_;
1115 last_packet_count_ = packet_count_;
1116 last_packets_lost_ = packets_lost_;
1117 uint8_t loss_ratio =
1118 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001119 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001120 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001121 packets_lost_, // Cumulative lost.
1122 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001123 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001124 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001125 transport_adapter_.get(), kRtcpIntervalMs);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001126
pbosda903ea2015-10-02 02:36:56 -07001127 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001128 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001129
1130 RTCPSender::FeedbackState feedback_state;
1131
1132 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1133 }
1134 }
1135
Niels Möller759f9592018-10-09 14:57:01 +02001136 void UpdateConfiguration() {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001137 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001138 // Increase frame size for next encoded frame, in the context of the
1139 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001140 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001141 ++current_size_frame_;
1142 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001143 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001144 }
Niels Möllerde8e6e62018-11-13 15:10:33 +01001145 void ModifySenderBitrateConfig(
1146 BitrateConstraints* bitrate_config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001147 const int kMinBitrateBps = 30000;
Niels Möllerde8e6e62018-11-13 15:10:33 +01001148 bitrate_config->min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001149 }
1150
stefanff483612015-12-21 03:14:00 -08001151 void ModifyVideoConfigs(
1152 VideoSendStream::Config* send_config,
1153 std::vector<VideoReceiveStream::Config>* receive_configs,
1154 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001155 transport_adapter_.reset(
1156 new internal::TransportAdapter(send_config->send_transport));
1157 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001158 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001159 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1160 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001161 }
1162
1163 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001164 send_config->rtp.payload_name = "VP8";
Philip Eliassond52a1a62018-09-07 13:03:55 +00001165
Niels Möller4db138e2018-04-19 09:04:13 +02001166 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001167 send_config->rtp.max_packet_size = kMaxPacketSize;
Niels Möller759f9592018-10-09 14:57:01 +02001168 encoder_.RegisterPostEncodeCallback([this]() { UpdateConfiguration(); });
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001169
Erik Språng95261872015-04-10 11:58:49 +02001170 // Make sure there is at least one extension header, to make the RTP
1171 // header larger than the base length of 12 bytes.
1172 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001173
1174 // Setup screen content disables frame dropping which makes this easier.
Åsa Perssond34597c2018-10-22 17:34:02 +02001175 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
1176 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
sprang4847ae62017-06-27 07:06:52 -07001177 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001178 }
1179
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001180 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001181 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001182 }
1183
kwiberg27f982b2016-03-01 11:52:33 -08001184 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001185 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möllercbcbc222018-09-28 09:07:24 +02001186 test::VideoEncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001187
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001188 const size_t max_packet_size_;
1189 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001190 const bool test_generic_packetization_;
1191 const bool use_fec_;
1192
1193 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001194 uint32_t packets_lost_;
1195 uint32_t last_packet_count_;
1196 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001197 size_t accumulated_size_;
1198 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001199 bool fec_packet_received_;
1200
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001201 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001202 rtc::CriticalSection mutex_;
1203 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001204 };
1205
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001206 // Don't auto increment if FEC is used; continue sending frame size until
1207 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001208 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1209 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001210
stefane74eef12016-01-08 06:47:13 -08001211 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001212}
1213
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001214// TODO(sprang): Is there any way of speeding up these tests?
Sebastian Jansson63470292019-02-01 10:13:43 +01001215TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001216 TestPacketFragmentationSize(kGeneric, false);
1217}
1218
Sebastian Jansson63470292019-02-01 10:13:43 +01001219TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001220 TestPacketFragmentationSize(kGeneric, true);
1221}
1222
Sebastian Jansson63470292019-02-01 10:13:43 +01001223TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001224 TestPacketFragmentationSize(kVP8, false);
1225}
1226
Sebastian Jansson63470292019-02-01 10:13:43 +01001227TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001228 TestPacketFragmentationSize(kVP8, true);
1229}
1230
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001231// The test will go through a number of phases.
1232// 1. Start sending packets.
1233// 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 +00001234// suspend the stream.
1235// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001236// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001237// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001238// When the stream is detected again, and the stats show that the stream
1239// is no longer suspended, the test ends.
Sebastian Jansson63470292019-02-01 10:13:43 +01001240TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001241 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001242
Niels Möller412d1852019-01-02 09:42:54 +01001243 class RembObserver : public test::SendTest {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001244 public:
Niels Möller412d1852019-01-02 09:42:54 +01001245 class CaptureObserver : public rtc::VideoSinkInterface<VideoFrame> {
1246 public:
1247 explicit CaptureObserver(RembObserver* remb_observer)
1248 : remb_observer_(remb_observer) {}
1249
1250 void OnFrame(const VideoFrame&) {
1251 rtc::CritScope lock(&remb_observer_->crit_);
1252 if (remb_observer_->test_state_ == kDuringSuspend &&
1253 ++remb_observer_->suspended_frame_count_ > kSuspendTimeFrames) {
1254 VideoSendStream::Stats stats = remb_observer_->stream_->GetStats();
1255 EXPECT_TRUE(stats.suspended);
1256 remb_observer_->SendRtcpFeedback(remb_observer_->high_remb_bps_);
1257 remb_observer_->test_state_ = kWaitingForPacket;
1258 }
1259 }
1260
1261 private:
1262 RembObserver* const remb_observer_;
1263 };
1264
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001265 RembObserver()
1266 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001267 clock_(Clock::GetRealTimeClock()),
Niels Möller412d1852019-01-02 09:42:54 +01001268 capture_observer_(this),
Erik Språng737336d2016-07-29 12:59:36 +02001269 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001270 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001271 rtp_count_(0),
1272 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001273 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001274 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001275 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001276
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001277 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001278 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001279 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001280 ++rtp_count_;
1281 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001282 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001283 last_sequence_number_ = header.sequenceNumber;
1284
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001285 if (test_state_ == kBeforeSuspend) {
1286 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001287 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001288 test_state_ = kDuringSuspend;
1289 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001290 if (header.paddingLength == 0) {
1291 // Received non-padding packet during suspension period. Reset the
1292 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001293 suspended_frame_count_ = 0;
1294 }
stefanf116bd02015-10-27 08:29:42 -07001295 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001296 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001297 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001298 // Non-padding packet observed. Test is almost complete. Will just
1299 // have to wait for the stats to change.
1300 test_state_ = kWaitingForStats;
1301 }
stefanf116bd02015-10-27 08:29:42 -07001302 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001303 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001304 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001305 if (stats.suspended == false) {
1306 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001307 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001308 }
stefanf116bd02015-10-27 08:29:42 -07001309 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001310 }
1311
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001312 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001313 }
1314
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001315 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001316 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001317 low_remb_bps_ = value;
1318 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001319
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001320 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001321 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001322 high_remb_bps_ = value;
1323 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001324
stefanff483612015-12-21 03:14:00 -08001325 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001326 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001327 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001328 stream_ = send_stream;
1329 }
1330
Niels Möller412d1852019-01-02 09:42:54 +01001331 void OnFrameGeneratorCapturerCreated(
1332 test::FrameGeneratorCapturer* frame_generator_capturer) override {
1333 frame_generator_capturer->AddOrUpdateSink(&capture_observer_,
1334 rtc::VideoSinkWants());
1335 }
1336
stefanff483612015-12-21 03:14:00 -08001337 void ModifyVideoConfigs(
1338 VideoSendStream::Config* send_config,
1339 std::vector<VideoReceiveStream::Config>* receive_configs,
1340 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001341 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001342 transport_adapter_.reset(
1343 new internal::TransportAdapter(send_config->send_transport));
1344 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001345 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001346 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001347 int min_bitrate_bps =
1348 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001349 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001350 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001351 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001352 min_bitrate_bps + threshold_window + 5000);
1353 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1354 }
1355
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001356 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001357 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001358 }
1359
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001360 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001361 kBeforeSuspend,
1362 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001363 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001364 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001365 };
1366
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001367 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001368 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001369 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1370 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001371 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001372 transport_adapter_.get(), kRtcpIntervalMs);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001373
pbosda903ea2015-10-02 02:36:56 -07001374 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001375 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001376 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001377 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001378 }
1379 RTCPSender::FeedbackState feedback_state;
1380 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1381 }
1382
kwiberg27f982b2016-03-01 11:52:33 -08001383 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001384 Clock* const clock_;
Niels Möller412d1852019-01-02 09:42:54 +01001385 CaptureObserver capture_observer_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001386 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001387
Peter Boströmf2f82832015-05-01 13:00:41 +02001388 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001389 TestState test_state_ RTC_GUARDED_BY(crit_);
1390 int rtp_count_ RTC_GUARDED_BY(crit_);
1391 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1392 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1393 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1394 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001395 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001396
stefane74eef12016-01-08 06:47:13 -08001397 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001398}
1399
perkj71ee44c2016-06-15 00:47:53 -07001400// This test that padding stops being send after a while if the Camera stops
1401// producing video frames and that padding resumes if the camera restarts.
Sebastian Jansson63470292019-02-01 10:13:43 +01001402TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001403 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001404 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001405 NoPaddingWhenVideoIsMuted()
1406 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001407 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001408 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001409 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001410
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001411 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001412 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001413 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001414 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001415
1416 RTPHeader header;
1417 parser_->Parse(packet, length, &header);
1418 const bool only_padding =
1419 header.headerLength + header.paddingLength == length;
1420
1421 if (test_state_ == kBeforeStopCapture) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001422 // Packets are flowing, stop camera.
perkj71ee44c2016-06-15 00:47:53 -07001423 capturer_->Stop();
1424 test_state_ = kWaitingForPadding;
1425 } else if (test_state_ == kWaitingForPadding && only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001426 // We're still getting padding, after stopping camera.
perkj71ee44c2016-06-15 00:47:53 -07001427 test_state_ = kWaitingForNoPackets;
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001428 } else if (test_state_ == kWaitingForMediaAfterCameraRestart &&
1429 !only_padding) {
1430 // Media packets are flowing again, stop camera a second time.
1431 capturer_->Stop();
1432 test_state_ = kWaitingForPaddingAfterCameraStopsAgain;
1433 } else if (test_state_ == kWaitingForPaddingAfterCameraStopsAgain &&
perkj71ee44c2016-06-15 00:47:53 -07001434 only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001435 // Padding is still flowing, test ok.
perkj71ee44c2016-06-15 00:47:53 -07001436 observation_complete_.Set();
1437 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001438 return SEND_PACKET;
1439 }
1440
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001441 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001442 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001443 const int kNoPacketsThresholdMs = 2000;
1444 if (test_state_ == kWaitingForNoPackets &&
1445 (last_packet_time_ms_ > 0 &&
1446 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1447 kNoPacketsThresholdMs)) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001448 // No packets seen for |kNoPacketsThresholdMs|, restart camera.
perkj71ee44c2016-06-15 00:47:53 -07001449 capturer_->Start();
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001450 test_state_ = kWaitingForMediaAfterCameraRestart;
perkj71ee44c2016-06-15 00:47:53 -07001451 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001452 return SEND_PACKET;
1453 }
1454
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001455 void ModifyVideoConfigs(
1456 VideoSendStream::Config* send_config,
1457 std::vector<VideoReceiveStream::Config>* receive_configs,
1458 VideoEncoderConfig* encoder_config) override {
1459 // Make sure padding is sent if encoder is not producing media.
1460 encoder_config->min_transmit_bitrate_bps = 50000;
1461 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001462
nisseef8b61e2016-04-29 06:09:15 -07001463 void OnFrameGeneratorCapturerCreated(
1464 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001465 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001466 capturer_ = frame_generator_capturer;
1467 }
1468
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001469 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001470 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001471 << "Timed out while waiting for RTP packets to stop being sent.";
1472 }
1473
perkj71ee44c2016-06-15 00:47:53 -07001474 enum TestState {
1475 kBeforeStopCapture,
1476 kWaitingForPadding,
1477 kWaitingForNoPackets,
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001478 kWaitingForMediaAfterCameraRestart,
1479 kWaitingForPaddingAfterCameraStopsAgain
perkj71ee44c2016-06-15 00:47:53 -07001480 };
1481
1482 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001483 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001484 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001485 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001486 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1487 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001488 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001489
stefane74eef12016-01-08 06:47:13 -08001490 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001491}
1492
Sebastian Jansson63470292019-02-01 10:13:43 +01001493TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
isheriffcc5903e2016-10-04 08:29:38 -07001494 const int kCapacityKbps = 10000; // 10 Mbps
1495 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1496 public:
1497 PaddingIsPrimarilyRetransmissions()
1498 : EndToEndTest(kDefaultTimeoutMs),
1499 clock_(Clock::GetRealTimeClock()),
1500 padding_length_(0),
1501 total_length_(0),
1502 call_(nullptr) {}
1503
1504 private:
1505 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1506 call_ = sender_call;
1507 }
1508
1509 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1510 rtc::CritScope lock(&crit_);
1511
1512 RTPHeader header;
1513 parser_->Parse(packet, length, &header);
1514 padding_length_ += header.paddingLength;
1515 total_length_ += length;
1516 return SEND_PACKET;
1517 }
1518
eladalon413ee9a2017-08-22 04:02:52 -07001519 test::PacketTransport* CreateSendTransport(
1520 test::SingleThreadedTaskQueueForTesting* task_queue,
1521 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001522 const int kNetworkDelayMs = 50;
Artem Titov75e36472018-10-08 12:28:56 +02001523 BuiltInNetworkBehaviorConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001524 config.loss_percent = 10;
1525 config.link_capacity_kbps = kCapacityKbps;
1526 config.queue_delay_ms = kNetworkDelayMs;
Artem Titov4e199e92018-08-20 13:30:39 +02001527 return new test::PacketTransport(
1528 task_queue, sender_call, this, test::PacketTransport::kSender,
1529 payload_type_map_,
1530 absl::make_unique<FakeNetworkPipe>(
1531 Clock::GetRealTimeClock(),
1532 absl::make_unique<SimulatedNetwork>(config)));
isheriffcc5903e2016-10-04 08:29:38 -07001533 }
1534
1535 void ModifyVideoConfigs(
1536 VideoSendStream::Config* send_config,
1537 std::vector<VideoReceiveStream::Config>* receive_configs,
1538 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001539 // Turn on RTX.
1540 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1541 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001542 }
1543
1544 void PerformTest() override {
1545 // TODO(isheriff): Some platforms do not ramp up as expected to full
1546 // capacity due to packet scheduling delays. Fix that before getting
1547 // rid of this.
1548 SleepMs(5000);
1549 {
1550 rtc::CritScope lock(&crit_);
1551 // Expect padding to be a small percentage of total bytes sent.
1552 EXPECT_LT(padding_length_, .1 * total_length_);
1553 }
1554 }
1555
1556 rtc::CriticalSection crit_;
1557 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001558 size_t padding_length_ RTC_GUARDED_BY(crit_);
1559 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001560 Call* call_;
1561 } test;
1562
1563 RunBaseTest(&test);
1564}
1565
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001566// This test first observes "high" bitrate use at which point it sends a REMB to
1567// indicate that it should be lowered significantly. The test then observes that
1568// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1569// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001570//
1571// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1572// bitrate since no receiver block or remb is sent in the initial phase.
Sebastian Jansson63470292019-02-01 10:13:43 +01001573TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001574 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001575 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001576 static const int kRembBitrateBps = 80000;
1577 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001578 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001579 public:
1580 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001581 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001582 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1583 stream_(nullptr),
1584 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001585
1586 private:
nisseef8b61e2016-04-29 06:09:15 -07001587 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001588 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001589 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001590
1591 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001592 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001593 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001594 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001595 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001596 if (!stats.substreams.empty()) {
1597 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001598 int total_bitrate_bps =
1599 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001600 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1601 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1602 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001603 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001604 rtp_rtcp_->SetRemb(kRembBitrateBps,
1605 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001606 rtp_rtcp_->Process();
1607 bitrate_capped_ = true;
1608 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001609 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001610 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001611 }
1612 }
stefanf116bd02015-10-27 08:29:42 -07001613 // Packets don't have to be delivered since the test is the receiver.
1614 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001615 }
1616
stefanff483612015-12-21 03:14:00 -08001617 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001618 VideoSendStream* send_stream,
1619 const std::vector<VideoReceiveStream*>& receive_streams) override {
1620 stream_ = send_stream;
1621 RtpRtcp::Configuration config;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001622 config.clock = Clock::GetRealTimeClock();
stefanf116bd02015-10-27 08:29:42 -07001623 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001624 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001625 rtp_rtcp_ = RtpRtcp::Create(config);
stefanf116bd02015-10-27 08:29:42 -07001626 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001627 }
1628
stefanff483612015-12-21 03:14:00 -08001629 void ModifyVideoConfigs(
1630 VideoSendStream::Config* send_config,
1631 std::vector<VideoReceiveStream::Config>* receive_configs,
1632 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001633 feedback_transport_.reset(
1634 new internal::TransportAdapter(send_config->send_transport));
1635 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001636 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001637 }
1638
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001639 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001640 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001641 << "Timeout while waiting for low bitrate stats after REMB.";
1642 }
1643
kwiberg27f982b2016-03-01 11:52:33 -08001644 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1645 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001646 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001647 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001648 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001649 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001650
stefane74eef12016-01-08 06:47:13 -08001651 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001652}
1653
Sebastian Jansson63470292019-02-01 10:13:43 +01001654TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001655 static const int kStartBitrateBps = 300000;
1656 static const int kNewMaxBitrateBps = 1234567;
Elad Alond8d32482019-02-18 23:45:57 +01001657 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001658 class ChangingNetworkRouteTest : public test::EndToEndTest {
1659 public:
eladalon413ee9a2017-08-22 04:02:52 -07001660 explicit ChangingNetworkRouteTest(
1661 test::SingleThreadedTaskQueueForTesting* task_queue)
1662 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1663 task_queue_(task_queue),
1664 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001665 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1666 kRtpExtensionTransportSequenceNumber, kExtensionId));
1667 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001668
1669 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1670 call_ = sender_call;
1671 }
1672
Stefan Holmer280de9e2016-09-30 10:06:51 +02001673 void ModifyVideoConfigs(
1674 VideoSendStream::Config* send_config,
1675 std::vector<VideoReceiveStream::Config>* receive_configs,
1676 VideoEncoderConfig* encoder_config) override {
1677 send_config->rtp.extensions.clear();
1678 send_config->rtp.extensions.push_back(RtpExtension(
1679 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1680 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1681 (*receive_configs)[0].rtp.transport_cc = true;
1682 }
1683
1684 void ModifyAudioConfigs(
1685 AudioSendStream::Config* send_config,
1686 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1687 send_config->rtp.extensions.clear();
1688 send_config->rtp.extensions.push_back(RtpExtension(
1689 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1690 (*receive_configs)[0].rtp.extensions.clear();
1691 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1692 (*receive_configs)[0].rtp.transport_cc = true;
1693 }
1694
Stefan Holmerbe402962016-07-08 16:16:41 +02001695 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1696 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1697 observation_complete_.Set();
1698 }
1699
1700 return SEND_PACKET;
1701 }
1702
1703 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001704 rtc::NetworkRoute new_route;
1705 new_route.connected = true;
1706 new_route.local_network_id = 10;
1707 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001708 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001709
1710 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001711 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1712 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001713 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001714 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1715 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001716 });
1717
Stefan Holmerbe402962016-07-08 16:16:41 +02001718 EXPECT_TRUE(Wait())
1719 << "Timed out while waiting for start bitrate to be exceeded.";
1720
eladalon413ee9a2017-08-22 04:02:52 -07001721 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1722 bitrate_config.start_bitrate_bps = -1;
1723 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001724 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1725 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001726 // TODO(holmer): We should set the last sent packet id here and verify
1727 // that we correctly ignore any packet loss reported prior to that id.
1728 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001729 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1730 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001731 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1732 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001733 }
1734
1735 private:
eladalon413ee9a2017-08-22 04:02:52 -07001736 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001737 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001738 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001739
1740 RunBaseTest(&test);
1741}
1742
Sebastian Jansson63470292019-02-01 10:13:43 +01001743TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
michaelt79e05882016-11-08 02:50:09 -08001744 class ChangingTransportOverheadTest : public test::EndToEndTest {
1745 public:
eladalon413ee9a2017-08-22 04:02:52 -07001746 explicit ChangingTransportOverheadTest(
1747 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001748 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001749 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001750 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001751 packets_sent_(0),
1752 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001753
1754 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1755 call_ = sender_call;
1756 }
1757
1758 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001759 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001760 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001761 if (++packets_sent_ < 100)
1762 return SEND_PACKET;
1763 observation_complete_.Set();
1764 return SEND_PACKET;
1765 }
1766
michaelta3328772016-11-29 09:25:03 -08001767 void ModifyVideoConfigs(
1768 VideoSendStream::Config* send_config,
1769 std::vector<VideoReceiveStream::Config>* receive_configs,
1770 VideoEncoderConfig* encoder_config) override {
1771 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1772 }
1773
michaelt79e05882016-11-08 02:50:09 -08001774 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001775 task_queue_->SendTask([this]() {
1776 transport_overhead_ = 100;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001777 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1778 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001779 });
1780
michaelt79e05882016-11-08 02:50:09 -08001781 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001782
sprang21253fc2017-02-27 03:35:47 -08001783 {
1784 rtc::CritScope cs(&lock_);
1785 packets_sent_ = 0;
1786 }
eladalon413ee9a2017-08-22 04:02:52 -07001787
1788 task_queue_->SendTask([this]() {
1789 transport_overhead_ = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001790 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1791 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001792 });
1793
michaelt79e05882016-11-08 02:50:09 -08001794 EXPECT_TRUE(Wait());
1795 }
1796
1797 private:
eladalon413ee9a2017-08-22 04:02:52 -07001798 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001799 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001800 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001801 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001802 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001803 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001804 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001805
1806 RunBaseTest(&test);
1807}
1808
sprangf24a0642017-02-28 13:23:26 -08001809// Test class takes takes as argument a switch selecting if type switch should
1810// occur and a function pointer to reset the send stream. This is necessary
1811// since you cannot change the content type of a VideoSendStream, you need to
1812// recreate it. Stopping and recreating the stream can only be done on the main
1813// thread and in the context of VideoSendStreamTest (not BaseTest).
1814template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001815class MaxPaddingSetTest : public test::SendTest {
1816 public:
1817 static const uint32_t kMinTransmitBitrateBps = 400000;
1818 static const uint32_t kActualEncodeBitrateBps = 40000;
1819 static const uint32_t kMinPacketsToSend = 50;
1820
sprangf24a0642017-02-28 13:23:26 -08001821 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001822 : SendTest(test::CallTest::kDefaultTimeoutMs),
1823 call_(nullptr),
1824 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001825 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001826 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001827 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001828 stream_resetter_(stream_reset_fun) {
1829 RTC_DCHECK(stream_resetter_);
1830 }
sprang9c0b5512016-07-06 00:54:28 -07001831
1832 void OnVideoStreamsCreated(
1833 VideoSendStream* send_stream,
1834 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001835 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001836 send_stream_ = send_stream;
1837 }
1838
1839 void ModifyVideoConfigs(
1840 VideoSendStream::Config* send_config,
1841 std::vector<VideoReceiveStream::Config>* receive_configs,
1842 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001843 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001844 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001845 encoder_config->min_transmit_bitrate_bps = 0;
1846 encoder_config->content_type =
1847 VideoEncoderConfig::ContentType::kRealtimeVideo;
1848 } else {
1849 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1850 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1851 }
sprangf24a0642017-02-28 13:23:26 -08001852 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001853 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001854 }
1855
1856 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1857 call_ = sender_call;
1858 }
1859
1860 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1861 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001862 if (running_without_padding_)
1863 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1864
1865 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1866 // we have reliable data.
1867 if (++packets_sent_ < kMinPacketsToSend)
1868 return SEND_PACKET;
1869
1870 if (running_without_padding_) {
1871 // We've sent kMinPacketsToSend packets with default configuration, switch
1872 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001873 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001874 packets_sent_ = 0;
1875 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1876 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001877 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001878 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001879 return SEND_PACKET;
1880 }
1881
1882 // Make sure the pacer has been configured with a min transmit bitrate.
1883 if (call_->GetStats().max_padding_bitrate_bps > 0)
1884 observation_complete_.Set();
1885
1886 return SEND_PACKET;
1887 }
1888
1889 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001890 if (RunningWithoutPadding()) {
1891 ASSERT_TRUE(
1892 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001893 (*stream_resetter_)(send_stream_config_, encoder_config_);
1894 }
1895
sprang9c0b5512016-07-06 00:54:28 -07001896 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1897 }
1898
1899 private:
sprangf24a0642017-02-28 13:23:26 -08001900 bool RunningWithoutPadding() const {
1901 rtc::CritScope lock(&crit_);
1902 return running_without_padding_;
1903 }
1904
sprang9c0b5512016-07-06 00:54:28 -07001905 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001906 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001907 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001908 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001909 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001910 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001911 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001912 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001913 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001914};
1915
Sebastian Jansson63470292019-02-01 10:13:43 +01001916TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001917 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1918 const VideoEncoderConfig& encoder_config) {};
1919 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001920 RunBaseTest(&test);
1921}
1922
Sebastian Jansson63470292019-02-01 10:13:43 +01001923TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001924 // Function for removing and recreating the send stream with a new config.
1925 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1926 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001927 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1928 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001929 DestroyVideoSendStreams();
1930 SetVideoSendConfig(send_stream_config);
1931 SetVideoEncoderConfig(encoder_config);
1932 CreateVideoSendStreams();
1933 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
eladalon413ee9a2017-08-22 04:02:52 -07001934 Start();
1935 });
sprangf24a0642017-02-28 13:23:26 -08001936 };
1937 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001938 RunBaseTest(&test);
1939}
1940
perkjfa10b552016-10-02 23:45:26 -07001941// This test verifies that new frame sizes reconfigures encoders even though not
1942// (yet) sending. The purpose of this is to permit encoding as quickly as
1943// possible once we start sending. Likely the frames being input are from the
1944// same source that will be sent later, which just means that we're ready
1945// earlier.
Sebastian Jansson63470292019-02-01 10:13:43 +01001946TEST_F(VideoSendStreamTest,
perkjfa10b552016-10-02 23:45:26 -07001947 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1948 class EncoderObserver : public test::FakeEncoder {
1949 public:
1950 EncoderObserver()
1951 : FakeEncoder(Clock::GetRealTimeClock()),
perkjfa10b552016-10-02 23:45:26 -07001952 number_of_initializations_(0),
1953 last_initialized_frame_width_(0),
1954 last_initialized_frame_height_(0) {}
1955
1956 void WaitForResolution(int width, int height) {
1957 {
1958 rtc::CritScope lock(&crit_);
1959 if (last_initialized_frame_width_ == width &&
1960 last_initialized_frame_height_ == height) {
1961 return;
1962 }
1963 }
Erik Språng08127a92016-11-16 16:41:30 +01001964 EXPECT_TRUE(
1965 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001966 {
1967 rtc::CritScope lock(&crit_);
1968 EXPECT_EQ(width, last_initialized_frame_width_);
1969 EXPECT_EQ(height, last_initialized_frame_height_);
1970 }
1971 }
1972
1973 private:
1974 int32_t InitEncode(const VideoCodec* config,
1975 int32_t number_of_cores,
1976 size_t max_payload_size) override {
1977 rtc::CritScope lock(&crit_);
1978 last_initialized_frame_width_ = config->width;
1979 last_initialized_frame_height_ = config->height;
1980 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001981 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001982 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1983 }
1984
1985 int32_t Encode(const VideoFrame& input_image,
1986 const CodecSpecificInfo* codec_specific_info,
Niels Möller87e2d782019-03-07 10:18:23 +01001987 const std::vector<VideoFrameType>* frame_types) override {
perkjfa10b552016-10-02 23:45:26 -07001988 ADD_FAILURE()
1989 << "Unexpected Encode call since the send stream is not started";
1990 return 0;
1991 }
1992
1993 rtc::CriticalSection crit_;
1994 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001995 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1996 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1997 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001998 };
1999
perkjfa10b552016-10-02 23:45:26 -07002000 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07002001 EncoderObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002002 test::VideoEncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07002003
Niels Möller4db138e2018-04-19 09:04:13 +02002004 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002005 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002006 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002007 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002008 CreateVideoStreams();
2009 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
2010 kDefaultHeight);
2011 frame_generator_capturer_->Start();
2012 });
perkjfa10b552016-10-02 23:45:26 -07002013
2014 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07002015
2016 task_queue_.SendTask([this]() {
2017 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
2018 kDefaultHeight * 2);
2019 });
2020
perkjfa10b552016-10-02 23:45:26 -07002021 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07002022
2023 task_queue_.SendTask([this]() {
2024 DestroyStreams();
2025 DestroyCalls();
2026 });
perkjfa10b552016-10-02 23:45:26 -07002027}
2028
Sebastian Jansson63470292019-02-01 10:13:43 +01002029TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002030 class StartBitrateObserver : public test::FakeEncoder {
2031 public:
2032 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07002033 : FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002034 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002035 int32_t InitEncode(const VideoCodec* config,
2036 int32_t number_of_cores,
2037 size_t max_payload_size) override {
2038 rtc::CritScope lock(&crit_);
2039 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07002040 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002041 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2042 }
2043
2044 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
2045 rtc::CritScope lock(&crit_);
2046 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07002047 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002048 return FakeEncoder::SetRates(new_target_bitrate, framerate);
2049 }
2050
2051 int GetStartBitrateKbps() const {
2052 rtc::CritScope lock(&crit_);
2053 return start_bitrate_kbps_;
2054 }
2055
pbos14fe7082016-04-20 06:35:56 -07002056 bool WaitForStartBitrate() {
2057 return start_bitrate_changed_.Wait(
2058 VideoSendStreamTest::kDefaultTimeoutMs);
2059 }
2060
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002061 private:
pbos5ad935c2016-01-25 03:52:44 -08002062 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002063 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002064 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002065 };
2066
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002067 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002068
solenberg4fbae2b2015-08-28 04:07:10 -07002069 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002070 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002071
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002072 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002073 bitrate_config.start_bitrate_bps =
2074 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002075 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2076 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002077
2078 StartBitrateObserver encoder;
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002079 test::VideoEncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002080 // Since this test does not use a capturer, set |internal_source| = true.
2081 // Encoder configuration is otherwise updated on the next video frame.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002082 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002083 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002084
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002085 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002086
pbos14fe7082016-04-20 06:35:56 -07002087 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002088 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002089 encoder.GetStartBitrateKbps());
2090
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002091 GetVideoEncoderConfig()->max_bitrate_bps =
2092 2 * bitrate_config.start_bitrate_bps;
2093 GetVideoSendStream()->ReconfigureVideoEncoder(
2094 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002095
2096 // New bitrate should be reconfigured above the previous max. As there's no
2097 // network connection this shouldn't be flaky, as no bitrate should've been
2098 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002099 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002100 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2101 encoder.GetStartBitrateKbps());
2102
2103 DestroyStreams();
2104}
2105
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002106class StartStopBitrateObserver : public test::FakeEncoder {
2107 public:
Niels Möllerc572ff32018-11-07 08:43:50 +01002108 StartStopBitrateObserver() : FakeEncoder(Clock::GetRealTimeClock()) {}
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002109 int32_t InitEncode(const VideoCodec* config,
2110 int32_t number_of_cores,
2111 size_t max_payload_size) override {
2112 rtc::CritScope lock(&crit_);
2113 encoder_init_.Set();
2114 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2115 }
2116
Erik Språng566124a2018-04-23 12:32:22 +02002117 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002118 uint32_t framerate) override {
2119 rtc::CritScope lock(&crit_);
2120 bitrate_kbps_ = bitrate.get_sum_kbps();
2121 bitrate_changed_.Set();
2122 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2123 }
2124
2125 bool WaitForEncoderInit() {
2126 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2127 }
2128
2129 bool WaitBitrateChanged(bool non_zero) {
2130 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002131 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002132 {
2133 rtc::CritScope lock(&crit_);
2134 bitrate_kbps = bitrate_kbps_;
2135 }
2136 if (!bitrate_kbps)
2137 continue;
2138
2139 if ((non_zero && *bitrate_kbps > 0) ||
2140 (!non_zero && *bitrate_kbps == 0)) {
2141 return true;
2142 }
2143 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2144 return false;
2145 }
2146
2147 private:
2148 rtc::CriticalSection crit_;
2149 rtc::Event encoder_init_;
2150 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002151 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002152};
2153
perkj57c21f92016-06-17 07:27:16 -07002154// This test that if the encoder use an internal source, VideoEncoder::SetRates
2155// will be called with zero bitrate during initialization and that
2156// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2157// with zero bitrate.
Sebastian Jansson63470292019-02-01 10:13:43 +01002158TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002159 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002160 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002161 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002162 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002163 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002164
Niels Möller4db138e2018-04-19 09:04:13 +02002165 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002166 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002167 CreateSendConfig(1, 0, 0, &transport);
2168
2169 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002170 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002171
2172 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002173 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002174 GetVideoSendStream()->Start();
2175 GetVideoSendStream()->SetSource(&forwarder,
2176 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002177 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002178 });
perkj57c21f92016-06-17 07:27:16 -07002179
2180 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002181
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002182 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002183 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2184
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002185 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002186 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2187
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002188 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002189 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002190
eladalon413ee9a2017-08-22 04:02:52 -07002191 task_queue_.SendTask([this]() {
2192 DestroyStreams();
2193 DestroyCalls();
2194 });
perkj57c21f92016-06-17 07:27:16 -07002195}
2196
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002197// Tests that when the encoder uses an internal source, the VideoEncoder will
2198// be updated with a new bitrate when turning the VideoSendStream on/off with
2199// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2200// is reconfigured with new active layers.
Sebastian Jansson63470292019-02-01 10:13:43 +01002201TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002202 test::NullTransport transport;
2203 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002204 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002205 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002206 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002207
Niels Möller4db138e2018-04-19 09:04:13 +02002208 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002209 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002210 // Create two simulcast streams.
2211 CreateSendConfig(2, 0, 0, &transport);
2212
2213 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002214 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002215
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002216 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002217
2218 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002219 GetVideoSendStream()->Start();
2220 GetVideoSendStream()->SetSource(&forwarder,
2221 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002222 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002223 });
2224
2225 EXPECT_TRUE(encoder.WaitForEncoderInit());
2226
2227 // When we turn on the simulcast layers it will update the BitrateAllocator,
2228 // which in turn updates the VideoEncoder's bitrate.
2229 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002230 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002231 });
2232 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2233
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002234 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2235 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002236 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002237 GetVideoSendStream()->ReconfigureVideoEncoder(
2238 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002239 });
2240 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2241 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2242 // active. Once the change is made for a "soft" reconfiguration we can remove
2243 // the expecation for an encoder init. We can also test that bitrate changes
2244 // when just updating individual active layers, which should change the
2245 // bitrate set to the video encoder.
2246 EXPECT_TRUE(encoder.WaitForEncoderInit());
2247 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2248
2249 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002250 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2251 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002252 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002253 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002254 });
2255 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2256
2257 task_queue_.SendTask([this]() {
2258 DestroyStreams();
2259 DestroyCalls();
2260 });
2261}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002262
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002263VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002264 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002265 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002266 memset(buffer.get(), data, kSizeY);
Artem Titov1ebfb6a2019-01-03 23:49:37 +01002267 VideoFrame frame =
2268 webrtc::VideoFrame::Builder()
2269 .set_video_frame_buffer(I420Buffer::Create(width, height))
2270 .set_rotation(webrtc::kVideoRotation_0)
2271 .set_timestamp_us(data)
2272 .build();
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002273 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002274 // Use data as a ms timestamp.
2275 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002276 return frame;
2277}
2278
Sebastian Jansson63470292019-02-01 10:13:43 +01002279TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002280 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2281 public:
eladalon413ee9a2017-08-22 04:02:52 -07002282 explicit EncoderStateObserver(
2283 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002284 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002285 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002286 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002287 initialized_(false),
2288 callback_registered_(false),
2289 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002290 released_(false),
2291 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002292
2293 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002294 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002295 return released_;
2296 }
2297
2298 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002299 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002300 return initialized_ && callback_registered_;
2301 }
2302
2303 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002304 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002305 return num_releases_;
2306 }
2307
2308 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002309 int32_t InitEncode(const VideoCodec* codecSettings,
2310 int32_t numberOfCores,
2311 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002312 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002313 EXPECT_FALSE(initialized_);
2314 initialized_ = true;
2315 released_ = false;
2316 return 0;
2317 }
2318
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002319 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002320 const CodecSpecificInfo* codecSpecificInfo,
Niels Möller87e2d782019-03-07 10:18:23 +01002321 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002322 EXPECT_TRUE(IsReadyForEncode());
2323
Peter Boström5811a392015-12-10 13:02:50 +01002324 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002325 return 0;
2326 }
2327
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002328 int32_t RegisterEncodeCompleteCallback(
2329 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002330 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002331 EXPECT_TRUE(initialized_);
2332 callback_registered_ = true;
2333 return 0;
2334 }
2335
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002336 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002337 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002338 EXPECT_TRUE(IsReadyForEncode());
2339 EXPECT_FALSE(released_);
2340 initialized_ = false;
2341 callback_registered_ = false;
2342 released_ = true;
2343 ++num_releases_;
2344 return 0;
2345 }
2346
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002347 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002348 EXPECT_TRUE(IsReadyForEncode());
2349 return 0;
2350 }
2351
stefanff483612015-12-21 03:14:00 -08002352 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002353 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002354 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002355 stream_ = send_stream;
2356 }
2357
stefanff483612015-12-21 03:14:00 -08002358 void ModifyVideoConfigs(
2359 VideoSendStream::Config* send_config,
2360 std::vector<VideoReceiveStream::Config>* receive_configs,
2361 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002362 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002363 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002364 }
2365
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002366 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002367 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002368
2369 task_queue_->SendTask([this]() {
2370 EXPECT_EQ(0u, num_releases());
2371 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2372 EXPECT_EQ(0u, num_releases());
2373 stream_->Stop();
2374 // Encoder should not be released before destroying the VideoSendStream.
2375 EXPECT_FALSE(IsReleased());
2376 EXPECT_TRUE(IsReadyForEncode());
2377 stream_->Start();
2378 });
2379
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002380 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002381 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002382 }
2383
eladalon413ee9a2017-08-22 04:02:52 -07002384 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002385 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002386 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002387 bool initialized_ RTC_GUARDED_BY(crit_);
2388 bool callback_registered_ RTC_GUARDED_BY(crit_);
2389 size_t num_releases_ RTC_GUARDED_BY(crit_);
2390 bool released_ RTC_GUARDED_BY(crit_);
Niels Möllercbcbc222018-09-28 09:07:24 +02002391 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002392 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002393 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002394
stefane74eef12016-01-08 06:47:13 -08002395 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002396
2397 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002398 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002399}
2400
Sebastian Jansson63470292019-02-01 10:13:43 +01002401TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002402 class VideoCodecConfigObserver : public test::SendTest,
2403 public test::FakeEncoder {
2404 public:
2405 VideoCodecConfigObserver()
2406 : SendTest(kDefaultTimeoutMs),
2407 FakeEncoder(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02002408 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002409 stream_(nullptr),
2410 encoder_factory_(this) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002411
2412 private:
stefanff483612015-12-21 03:14:00 -08002413 void ModifyVideoConfigs(
2414 VideoSendStream::Config* send_config,
2415 std::vector<VideoReceiveStream::Config>* receive_configs,
2416 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002417 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprangf24a0642017-02-28 13:23:26 -08002418 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002419 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002420 }
2421
stefanff483612015-12-21 03:14:00 -08002422 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002423 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002424 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002425 stream_ = send_stream;
2426 }
2427
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002428 int32_t InitEncode(const VideoCodec* config,
2429 int32_t number_of_cores,
2430 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002431 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002432 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002433 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002434 } else {
2435 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002436 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002437 }
2438 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002439 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002440 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2441 }
2442
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002443 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002444 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002445 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002446
sprangf24a0642017-02-28 13:23:26 -08002447 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002448 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002449 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002450 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002451 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2452 "new encoder settings.";
2453 }
2454
sprangf24a0642017-02-28 13:23:26 -08002455 const uint32_t kFirstMaxBitrateBps = 1000000;
2456 const uint32_t kSecondMaxBitrateBps = 2000000;
2457
pbos14fe7082016-04-20 06:35:56 -07002458 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002459 size_t num_initializations_;
2460 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002461 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002462 VideoEncoderConfig encoder_config_;
2463 } test;
2464
stefane74eef12016-01-08 06:47:13 -08002465 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002466}
2467
Sergey Silkin571e6c92018-04-03 10:03:31 +02002468static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002469template <typename T>
2470class VideoCodecConfigObserver : public test::SendTest,
2471 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002472 public:
2473 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2474 const char* codec_name)
2475 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2476 FakeEncoder(Clock::GetRealTimeClock()),
2477 video_codec_type_(video_codec_type),
2478 codec_name_(codec_name),
Erik Språng737336d2016-07-29 12:59:36 +02002479 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002480 stream_(nullptr),
2481 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002482 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002483 }
2484
2485 private:
stefanff483612015-12-21 03:14:00 -08002486 void ModifyVideoConfigs(
2487 VideoSendStream::Config* send_config,
2488 std::vector<VideoReceiveStream::Config>* receive_configs,
2489 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002490 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002491 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002492
Niels Möller259a4972018-04-05 15:36:51 +02002493 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002494 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
Åsa Perssond34597c2018-10-22 17:34:02 +02002495 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2496 encoder_config->simulcast_layers[0].num_temporal_layers =
2497 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07002498 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002499 }
2500
stefanff483612015-12-21 03:14:00 -08002501 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002502 VideoSendStream* send_stream,
2503 const std::vector<VideoReceiveStream*>& receive_streams) override {
2504 stream_ = send_stream;
2505 }
2506
2507 int32_t InitEncode(const VideoCodec* config,
2508 int32_t number_of_cores,
2509 size_t max_payload_size) override {
2510 EXPECT_EQ(video_codec_type_, config->codecType);
2511 VerifyCodecSpecifics(*config);
2512 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002513 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002514 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2515 }
2516
Sergey Silkin86684962018-03-28 19:32:37 +02002517 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002518 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002519 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2520 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002521
2522 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002523 EXPECT_TRUE(
2524 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002525 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002526
Sergey Silkin86684962018-03-28 19:32:37 +02002527 // Change encoder settings to actually trigger reconfiguration.
2528 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002529 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002530 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002531 ASSERT_TRUE(
2532 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002533 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002534 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2535 "new encoder settings.";
2536 }
2537
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002538 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002539 const CodecSpecificInfo* codec_specific_info,
Niels Möller87e2d782019-03-07 10:18:23 +01002540 const std::vector<VideoFrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002541 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2542 return 0;
2543 }
2544
2545 T encoder_settings_;
2546 const VideoCodecType video_codec_type_;
2547 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002548 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002549 size_t num_initializations_;
2550 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002551 test::VideoEncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002552 VideoEncoderConfig encoder_config_;
2553};
2554
2555template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002556void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2557 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2558}
2559
2560template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002561void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2562 const VideoCodec& config) const {
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002563 // Check that the number of temporal layers has propagated properly to
2564 // VideoCodec.
2565 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2566 config.H264().numberOfTemporalLayers);
2567
2568 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2569 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2570 config.simulcastStream[i].numberOfTemporalLayers);
2571 }
2572
2573 // Set expected temporal layers as they should have been set when
2574 // reconfiguring the encoder and not match the set config.
2575 VideoCodecH264 encoder_settings = encoder_settings_;
2576 encoder_settings.numberOfTemporalLayers =
2577 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002578 EXPECT_EQ(
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002579 0, memcmp(&config.H264(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002580}
kthelgason29a44e32016-09-27 03:52:02 -07002581
2582template <>
2583rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2584VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2585 return new rtc::RefCountedObject<
2586 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2587}
2588
Peter Boström53eda3d2015-03-27 15:53:18 +01002589template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002590void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2591 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2592}
2593
2594template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002595void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2596 const VideoCodec& config) const {
2597 // Check that the number of temporal layers has propagated properly to
2598 // VideoCodec.
2599 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002600 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002601
2602 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2603 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2604 config.simulcastStream[i].numberOfTemporalLayers);
2605 }
2606
2607 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002608 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002609 VideoCodecVP8 encoder_settings = encoder_settings_;
2610 encoder_settings.numberOfTemporalLayers =
2611 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002612 EXPECT_EQ(
2613 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002614}
kthelgason29a44e32016-09-27 03:52:02 -07002615
2616template <>
2617rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2618VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2619 return new rtc::RefCountedObject<
2620 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2621}
2622
Peter Boström53eda3d2015-03-27 15:53:18 +01002623template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002624void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2625 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2626}
2627
2628template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002629void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2630 const VideoCodec& config) const {
2631 // Check that the number of temporal layers has propagated properly to
2632 // VideoCodec.
2633 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002634 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002635
2636 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2637 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2638 config.simulcastStream[i].numberOfTemporalLayers);
2639 }
2640
2641 // Set expected temporal layers as they should have been set when
2642 // reconfiguring the encoder and not match the set config.
2643 VideoCodecVP9 encoder_settings = encoder_settings_;
2644 encoder_settings.numberOfTemporalLayers =
2645 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002646 EXPECT_EQ(
2647 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002648}
2649
kthelgason29a44e32016-09-27 03:52:02 -07002650template <>
2651rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2652VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2653 return new rtc::RefCountedObject<
2654 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2655}
2656
Sebastian Jansson63470292019-02-01 10:13:43 +01002657TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002658 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002659 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002660}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002661
Sebastian Jansson63470292019-02-01 10:13:43 +01002662TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002663 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002664 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002665}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002666
Sebastian Jansson63470292019-02-01 10:13:43 +01002667TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002668 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002669 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002670}
2671
Sebastian Jansson63470292019-02-01 10:13:43 +01002672TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002673 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002674 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002675 RtcpSenderReportTest()
2676 : SendTest(kDefaultTimeoutMs),
2677 rtp_packets_sent_(0),
2678 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002679
2680 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002681 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002682 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002683 RTPHeader header;
2684 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002685 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002686 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2687 return SEND_PACKET;
2688 }
2689
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002690 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002691 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002692 test::RtcpPacketParser parser;
2693 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002694
danilchap3dc929e2016-11-02 08:21:59 -07002695 if (parser.sender_report()->num_packets() > 0) {
2696 // Only compare sent media bytes if SenderPacketCount matches the
2697 // number of sent rtp packets (a new rtp packet could be sent before
2698 // the rtcp packet).
2699 if (parser.sender_report()->sender_octet_count() > 0 &&
2700 parser.sender_report()->sender_packet_count() ==
2701 rtp_packets_sent_) {
2702 EXPECT_EQ(media_bytes_sent_,
2703 parser.sender_report()->sender_octet_count());
2704 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002705 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002706 }
2707
2708 return SEND_PACKET;
2709 }
2710
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002711 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002712 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002713 }
2714
stefan4b569042015-11-11 06:39:57 -08002715 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002716 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2717 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002718 } test;
2719
stefane74eef12016-01-08 06:47:13 -08002720 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002721}
2722
Sebastian Jansson63470292019-02-01 10:13:43 +01002723TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002724 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002725
2726 class VideoStreamFactory
2727 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2728 public:
2729 VideoStreamFactory() {}
2730
2731 private:
2732 std::vector<VideoStream> CreateEncoderStreams(
2733 int width,
2734 int height,
2735 const VideoEncoderConfig& encoder_config) override {
2736 std::vector<VideoStream> streams =
2737 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002738 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2739 kScreencastMaxTargetBitrateDeltaKbps);
2740 streams[0].target_bitrate_bps =
2741 streams[0].max_bitrate_bps -
2742 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002743 return streams;
2744 }
2745 };
2746
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002747 class ScreencastTargetBitrateTest : public test::SendTest,
2748 public test::FakeEncoder {
2749 public:
2750 ScreencastTargetBitrateTest()
2751 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002752 test::FakeEncoder(Clock::GetRealTimeClock()),
2753 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002754
2755 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002756 int32_t InitEncode(const VideoCodec* config,
2757 int32_t number_of_cores,
2758 size_t max_payload_size) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002759 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002760 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002761 config->simulcastStream[0].maxBitrate -
2762 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002763 observation_complete_.Set();
Yves Gerey665174f2018-06-19 15:03:05 +02002764 return test::FakeEncoder::InitEncode(config, number_of_cores,
2765 max_payload_size);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002766 }
stefanff483612015-12-21 03:14:00 -08002767 void ModifyVideoConfigs(
2768 VideoSendStream::Config* send_config,
2769 std::vector<VideoReceiveStream::Config>* receive_configs,
2770 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002771 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002772 EXPECT_EQ(1u, encoder_config->number_of_streams);
2773 encoder_config->video_stream_factory =
2774 new rtc::RefCountedObject<VideoStreamFactory>();
Åsa Perssond34597c2018-10-22 17:34:02 +02002775 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2776 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
Erik Språng143cec12015-04-28 10:01:41 +02002777 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002778 }
2779
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002780 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002781 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002782 << "Timed out while waiting for the encoder to be initialized.";
2783 }
Niels Möllercbcbc222018-09-28 09:07:24 +02002784 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002785 } test;
2786
stefane74eef12016-01-08 06:47:13 -08002787 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002788}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002789
Sebastian Jansson63470292019-02-01 10:13:43 +01002790TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002791 // These are chosen to be "kind of odd" to not be accidentally checked against
2792 // default values.
2793 static const int kMinBitrateKbps = 137;
2794 static const int kStartBitrateKbps = 345;
2795 static const int kLowerMaxBitrateKbps = 312;
2796 static const int kMaxBitrateKbps = 413;
2797 static const int kIncreasedStartBitrateKbps = 451;
2798 static const int kIncreasedMaxBitrateKbps = 597;
Erik Språng7ca375c2019-02-06 16:20:17 +01002799 // If these fields trial are on, we get lower bitrates than expected by this
2800 // test, due to the packetization overhead and encoder pushback.
Niels Möller6613f8e2019-01-10 10:30:21 +01002801 webrtc::test::ScopedFieldTrials field_trials(
2802 std::string(field_trial::GetFieldTrialString()) +
Erik Språng7ca375c2019-02-06 16:20:17 +01002803 "WebRTC-SubtractPacketizationOverhead/Disabled/"
2804 "WebRTC-VideoRateControl/bitrate_adjuster:false/");
Niels Möller6613f8e2019-01-10 10:30:21 +01002805
pbos@webrtc.org00873182014-11-25 14:03:34 +00002806 class EncoderBitrateThresholdObserver : public test::SendTest,
2807 public test::FakeEncoder {
2808 public:
eladalon413ee9a2017-08-22 04:02:52 -07002809 explicit EncoderBitrateThresholdObserver(
2810 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002811 : SendTest(kDefaultTimeoutMs),
2812 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002813 task_queue_(task_queue),
perkj26091b12016-09-01 01:17:40 -07002814 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002815 num_initializations_(0),
2816 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002817 send_stream_(nullptr),
2818 encoder_factory_(this) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002819
2820 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002821 int32_t InitEncode(const VideoCodec* codecSettings,
2822 int32_t numberOfCores,
2823 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002824 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2825 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002826 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002827 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2828 codecSettings->minBitrate);
2829 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2830 codecSettings->startBitrate);
2831 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2832 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002833 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002834 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002835 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2836 codecSettings->maxBitrate);
2837 // The start bitrate should be kept (-1) and capped to the max bitrate.
2838 // Since this is not an end-to-end call no receiver should have been
2839 // returning a REMB that could lower this estimate.
2840 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002841 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002842 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2843 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002844 // The start bitrate will be whatever the rate BitRateController
2845 // has currently configured but in the span of the set max and min
2846 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002847 }
2848 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002849 init_encode_event_.Set();
2850
pbos@webrtc.org00873182014-11-25 14:03:34 +00002851 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2852 maxPayloadSize);
2853 }
2854
Erik Språng566124a2018-04-23 12:32:22 +02002855 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Erik Språng08127a92016-11-16 16:41:30 +01002856 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002857 {
2858 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002859 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2860 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002861 }
Erik Språng08127a92016-11-16 16:41:30 +01002862 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002863 }
2864 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002865 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002866 }
2867
2868 void WaitForSetRates(uint32_t expected_bitrate) {
Niels Möller6bb5ab92019-01-11 11:11:10 +01002869 // Wait for the expected rate to be set. In some cases there can be
2870 // more than one update pending, in which case we keep waiting
2871 // until the correct value has been observed.
2872 const int64_t start_time = rtc::TimeMillis();
2873 do {
2874 rtc::CritScope lock(&crit_);
2875 if (target_bitrate_ == expected_bitrate) {
2876 return;
2877 }
2878 } while (bitrate_changed_event_.Wait(
2879 std::max(int64_t{1}, VideoSendStreamTest::kDefaultTimeoutMs -
2880 (rtc::TimeMillis() - start_time))));
Niels Möller6613f8e2019-01-10 10:30:21 +01002881 rtc::CritScope lock(&crit_);
Niels Möller6bb5ab92019-01-11 11:11:10 +01002882 EXPECT_EQ(target_bitrate_, expected_bitrate)
2883 << "Timed out while waiting encoder rate to be set.";
perkj26091b12016-09-01 01:17:40 -07002884 }
2885
Niels Möllerde8e6e62018-11-13 15:10:33 +01002886 void ModifySenderBitrateConfig(
2887 BitrateConstraints* bitrate_config) override {
2888 bitrate_config->min_bitrate_bps = kMinBitrateKbps * 1000;
2889 bitrate_config->start_bitrate_bps = kStartBitrateKbps * 1000;
2890 bitrate_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002891 }
2892
perkjfa10b552016-10-02 23:45:26 -07002893 class VideoStreamFactory
2894 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2895 public:
2896 explicit VideoStreamFactory(int min_bitrate_bps)
2897 : min_bitrate_bps_(min_bitrate_bps) {}
2898
2899 private:
2900 std::vector<VideoStream> CreateEncoderStreams(
2901 int width,
2902 int height,
2903 const VideoEncoderConfig& encoder_config) override {
2904 std::vector<VideoStream> streams =
2905 test::CreateVideoStreams(width, height, encoder_config);
2906 streams[0].min_bitrate_bps = min_bitrate_bps_;
2907 return streams;
2908 }
2909
2910 const int min_bitrate_bps_;
2911 };
2912
stefanff483612015-12-21 03:14:00 -08002913 void ModifyVideoConfigs(
2914 VideoSendStream::Config* send_config,
2915 std::vector<VideoReceiveStream::Config>* receive_configs,
2916 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002917 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002918 // Set bitrates lower/higher than min/max to make sure they are properly
2919 // capped.
perkjfa10b552016-10-02 23:45:26 -07002920 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2921 // Create a new StreamFactory to be able to set
2922 // |VideoStream.min_bitrate_bps|.
2923 encoder_config->video_stream_factory =
2924 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002925 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002926 }
2927
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002928 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002929 call_ = sender_call;
2930 }
2931
stefanff483612015-12-21 03:14:00 -08002932 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002933 VideoSendStream* send_stream,
2934 const std::vector<VideoReceiveStream*>& receive_streams) override {
2935 send_stream_ = send_stream;
2936 }
2937
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002938 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002939 ASSERT_TRUE(
2940 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002941 << "Timed out while waiting for encoder to be configured.";
2942 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002943 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002944 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2945 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002946 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002947 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2948 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002949 });
perkj26091b12016-09-01 01:17:40 -07002950 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2951 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002952 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002953 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002954 ASSERT_TRUE(
2955 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002956 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002957 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002958 WaitForSetRates(kLowerMaxBitrateKbps);
2959
2960 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2961 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2962 ASSERT_TRUE(
2963 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002964 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002965 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002966 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002967 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002968 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002969 }
2970
eladalon413ee9a2017-08-22 04:02:52 -07002971 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002972 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002973 rtc::Event bitrate_changed_event_;
2974 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002975 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002976
pbos@webrtc.org00873182014-11-25 14:03:34 +00002977 int num_initializations_;
2978 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002979 webrtc::VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002980 test::VideoEncoderProxyFactory encoder_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002981 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002982 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002983
stefane74eef12016-01-08 06:47:13 -08002984 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002985}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002986
Sebastian Jansson63470292019-02-01 10:13:43 +01002987TEST_F(VideoSendStreamTest, ReportsSentResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002988 static const size_t kNumStreams = 3;
2989 // Unusual resolutions to make sure that they are the ones being reported.
2990 static const struct {
2991 int width;
2992 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02002993 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002994 class ScreencastTargetBitrateTest : public test::SendTest,
2995 public test::FakeEncoder {
2996 public:
2997 ScreencastTargetBitrateTest()
2998 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002999 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02003000 send_stream_(nullptr),
3001 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003002
3003 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003004 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003005 const CodecSpecificInfo* codecSpecificInfo,
Niels Möller87e2d782019-03-07 10:18:23 +01003006 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003007 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003008 specifics.codecType = kVideoCodecGeneric;
3009
3010 uint8_t buffer[16] = {0};
3011 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
Niels Möller23775882018-08-16 10:24:12 +02003012 encoded.SetTimestamp(input_image.timestamp());
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003013 encoded.capture_time_ms_ = input_image.render_time_ms();
3014
3015 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003016 encoded._frameType = (*frame_types)[i];
3017 encoded._encodedWidth = kEncodedResolution[i].width;
3018 encoded._encodedHeight = kEncodedResolution[i].height;
Niels Möllerd3b8c632018-08-27 15:33:42 +02003019 encoded.SetSpatialIndex(i);
brandtre78d2662017-01-16 05:57:16 -08003020 EncodedImageCallback* callback;
3021 {
3022 rtc::CritScope cs(&crit_sect_);
3023 callback = callback_;
3024 }
3025 RTC_DCHECK(callback);
3026 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003027 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003028 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003029 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003030 }
3031
Peter Boström5811a392015-12-10 13:02:50 +01003032 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003033 return 0;
3034 }
stefanff483612015-12-21 03:14:00 -08003035 void ModifyVideoConfigs(
3036 VideoSendStream::Config* send_config,
3037 std::vector<VideoReceiveStream::Config>* receive_configs,
3038 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003039 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003040 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003041 }
3042
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003043 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003044
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003045 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003046 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003047 << "Timed out while waiting for the encoder to send one frame.";
3048 VideoSendStream::Stats stats = send_stream_->GetStats();
3049
3050 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003051 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003052 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003053 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003054 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003055 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003056 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003057 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3058 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003059 }
3060 }
3061
stefanff483612015-12-21 03:14:00 -08003062 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003063 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003064 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003065 send_stream_ = send_stream;
3066 }
3067
3068 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003069 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003070 } test;
3071
stefane74eef12016-01-08 06:47:13 -08003072 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003073}
philipel0f9af012015-09-01 07:01:51 -07003074
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003075#if defined(RTC_ENABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003076class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003077 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003078 Vp9HeaderObserver()
3079 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003080 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003081 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3082 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003083 frames_sent_(0),
3084 expected_width_(0),
3085 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003086
stefanff483612015-12-21 03:14:00 -08003087 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003088 VideoSendStream::Config* send_config,
3089 std::vector<VideoReceiveStream::Config>* receive_configs,
3090 VideoEncoderConfig* encoder_config) {}
3091
Åsa Perssonff24c042015-12-04 10:58:08 +01003092 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003093
3094 private:
minyue20c84cc2017-04-10 16:57:57 -07003095 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003096
stefanff483612015-12-21 03:14:00 -08003097 void ModifyVideoConfigs(
3098 VideoSendStream::Config* send_config,
3099 std::vector<VideoReceiveStream::Config>* receive_configs,
3100 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003101 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003102 send_config->rtp.payload_name = "VP9";
3103 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003104 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003105 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003106 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003107 EXPECT_EQ(1u, encoder_config->number_of_streams);
Åsa Perssond34597c2018-10-22 17:34:02 +02003108 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
3109 encoder_config->simulcast_layers[0].num_temporal_layers =
3110 vp9_settings_.numberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07003111 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003112 }
3113
perkjfa10b552016-10-02 23:45:26 -07003114 void ModifyVideoCaptureStartResolution(int* width,
3115 int* height,
3116 int* frame_rate) override {
3117 expected_width_ = *width;
3118 expected_height_ = *height;
3119 }
3120
philipel0f9af012015-09-01 07:01:51 -07003121 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003122 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3123 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003124 }
3125
3126 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3127 RTPHeader header;
3128 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3129
Åsa Perssonff24c042015-12-04 10:58:08 +01003130 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3131 const uint8_t* payload = packet + header.headerLength;
3132 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003133
Åsa Perssonff24c042015-12-04 10:58:08 +01003134 bool new_packet = packets_sent_ == 0 ||
3135 IsNewerSequenceNumber(header.sequenceNumber,
3136 last_header_.sequenceNumber);
3137 if (payload_length > 0 && new_packet) {
3138 RtpDepacketizer::ParsedPayload parsed;
3139 RtpDepacketizerVp9 depacketizer;
3140 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003141 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003142 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003143 const auto& vp9_header =
3144 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3145 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003146 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003147 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003148 InspectHeader(vp9_header);
philipel0f9af012015-09-01 07:01:51 -07003149
Åsa Perssonff24c042015-12-04 10:58:08 +01003150 ++packets_sent_;
3151 if (header.markerBit) {
3152 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003153 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003154 last_header_ = header;
philipel29d88462018-08-08 14:26:00 +02003155 last_vp9_ = vp9_header;
philipel0f9af012015-09-01 07:01:51 -07003156 }
philipel0f9af012015-09-01 07:01:51 -07003157 return SEND_PACKET;
3158 }
3159
philipel7fabd462015-09-03 04:42:32 -07003160 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003161 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3162 if (last_vp9_.picture_id > vp9.picture_id) {
3163 return vp9.picture_id == 0; // Wrap.
3164 } else {
3165 return vp9.picture_id == last_vp9_.picture_id + 1;
3166 }
3167 }
3168
3169 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003170 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3171 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3172 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3173 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3174 vp9.spatial_idx);
3175 }
3176
3177 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3178 uint8_t num_layers) const {
3179 switch (num_layers) {
3180 case 0:
3181 VerifyTemporalLayerStructure0(vp9);
3182 break;
3183 case 1:
3184 VerifyTemporalLayerStructure1(vp9);
3185 break;
3186 case 2:
3187 VerifyTemporalLayerStructure2(vp9);
3188 break;
3189 case 3:
3190 VerifyTemporalLayerStructure3(vp9);
3191 break;
3192 default:
3193 RTC_NOTREACHED();
3194 }
3195 }
3196
3197 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3198 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3199 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3200 EXPECT_FALSE(vp9.temporal_up_switch);
3201 }
3202
3203 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3204 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3205 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3206 EXPECT_FALSE(vp9.temporal_up_switch);
3207 }
3208
3209 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3210 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3211 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3212 EXPECT_LE(vp9.temporal_idx, 1);
3213 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3214 if (IsNewPictureId(vp9)) {
3215 uint8_t expected_tid =
3216 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3217 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3218 }
3219 }
3220
3221 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3222 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3223 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3224 EXPECT_LE(vp9.temporal_idx, 2);
3225 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3226 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3227 switch (vp9.temporal_idx) {
3228 case 0:
3229 EXPECT_EQ(2, last_vp9_.temporal_idx);
3230 EXPECT_FALSE(vp9.temporal_up_switch);
3231 break;
3232 case 1:
3233 EXPECT_EQ(2, last_vp9_.temporal_idx);
3234 EXPECT_TRUE(vp9.temporal_up_switch);
3235 break;
3236 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003237 EXPECT_LT(last_vp9_.temporal_idx, 2);
3238 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003239 break;
3240 }
3241 }
3242 }
3243
3244 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3245 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3246 return;
3247
3248 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3249 if (vp9.temporal_idx == 0)
3250 ++expected_tl0_idx;
3251 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3252 }
3253
3254 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3255 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3256 }
3257
3258 // Flexible mode (F=1): Non-flexible mode (F=0):
3259 //
3260 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3261 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3262 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3263 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3264 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3265 // M: | EXTENDED PID | M: | EXTENDED PID |
3266 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3267 // L: | T |U| S |D| L: | T |U| S |D|
3268 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3269 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3270 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3271 // X: |EXTENDED P_DIFF| V: | SS .. |
3272 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3273 // V: | SS .. |
3274 // +-+-+-+-+-+-+-+-+
3275 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3276 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3277 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3278 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003279
3280 if (vp9_settings_.numberOfSpatialLayers > 1) {
3281 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3282 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3283 EXPECT_EQ(vp9.spatial_idx, 0);
3284 } else {
3285 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3286 }
3287
3288 if (vp9_settings_.numberOfTemporalLayers > 1) {
3289 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3290 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3291 EXPECT_EQ(vp9.temporal_idx, 0);
3292 } else {
3293 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3294 }
3295
Åsa Perssonff24c042015-12-04 10:58:08 +01003296 if (vp9.ss_data_available) // V
3297 VerifySsData(vp9);
3298
3299 if (frames_sent_ == 0)
3300 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3301
3302 if (!vp9.inter_pic_predicted) {
3303 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3304 EXPECT_FALSE(vp9.temporal_up_switch);
3305 }
3306 }
3307
3308 // Scalability structure (SS).
3309 //
3310 // +-+-+-+-+-+-+-+-+
3311 // V: | N_S |Y|G|-|-|-|
3312 // +-+-+-+-+-+-+-+-+
3313 // Y: | WIDTH | N_S + 1 times
3314 // +-+-+-+-+-+-+-+-+
3315 // | HEIGHT |
3316 // +-+-+-+-+-+-+-+-+
3317 // G: | N_G |
3318 // +-+-+-+-+-+-+-+-+
3319 // N_G: | T |U| R |-|-| N_G times
3320 // +-+-+-+-+-+-+-+-+
3321 // | P_DIFF | R times
3322 // +-+-+-+-+-+-+-+-+
3323 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3324 EXPECT_TRUE(vp9.ss_data_available); // V
3325 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3326 vp9.num_spatial_layers);
3327 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003328 int expected_width = expected_width_;
3329 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003330 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003331 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3332 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3333 expected_width /= 2;
3334 expected_height /= 2;
3335 }
3336 }
3337
3338 void CompareConsecutiveFrames(const RTPHeader& header,
3339 const RTPVideoHeader& video) const {
philipel29d88462018-08-08 14:26:00 +02003340 const auto& vp9_header =
3341 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003342
3343 bool new_frame = packets_sent_ == 0 ||
3344 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003345 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003346 if (!new_frame) {
3347 EXPECT_FALSE(last_header_.markerBit);
3348 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003349 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3350 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3351 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3352 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003353 return;
3354 }
3355 // New frame.
philipel29d88462018-08-08 14:26:00 +02003356 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003357
3358 // Compare with last packet in previous frame.
3359 if (frames_sent_ == 0)
3360 return;
3361 EXPECT_TRUE(last_vp9_.end_of_frame);
3362 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003363 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3364 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003365 }
3366
Niels Möller4db138e2018-04-19 09:04:13 +02003367 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003368 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003369 webrtc::VideoEncoderConfig encoder_config_;
3370 RTPHeader last_header_;
3371 RTPVideoHeaderVP9 last_vp9_;
3372 size_t packets_sent_;
3373 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003374 int expected_width_;
3375 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003376};
3377
Sebastian Jansson63470292019-02-01 10:13:43 +01003378TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003379 const uint8_t kNumTemporalLayers = 1;
3380 const uint8_t kNumSpatialLayers = 1;
3381 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3382}
3383
Sebastian Jansson63470292019-02-01 10:13:43 +01003384TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003385 const uint8_t kNumTemporalLayers = 2;
3386 const uint8_t kNumSpatialLayers = 1;
3387 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3388}
3389
Sebastian Jansson63470292019-02-01 10:13:43 +01003390TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003391 const uint8_t kNumTemporalLayers = 3;
3392 const uint8_t kNumSpatialLayers = 1;
3393 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3394}
3395
Sebastian Jansson63470292019-02-01 10:13:43 +01003396TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003397 const uint8_t kNumTemporalLayers = 1;
3398 const uint8_t kNumSpatialLayers = 2;
3399 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3400}
3401
Sebastian Jansson63470292019-02-01 10:13:43 +01003402TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003403 const uint8_t kNumTemporalLayers = 2;
3404 const uint8_t kNumSpatialLayers = 2;
3405 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3406}
3407
Sebastian Jansson63470292019-02-01 10:13:43 +01003408TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003409 const uint8_t kNumTemporalLayers = 3;
3410 const uint8_t kNumSpatialLayers = 2;
3411 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3412}
3413
3414void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3415 uint8_t num_spatial_layers) {
3416 static const size_t kNumFramesToSend = 100;
3417 // Set to < kNumFramesToSend and coprime to length of temporal layer
3418 // structures to verify temporal id reset on key frame.
3419 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003420
3421 static const int kWidth = kMinVp9SpatialLayerWidth;
3422 static const int kHeight = kMinVp9SpatialLayerHeight;
3423 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003424 class NonFlexibleMode : public Vp9HeaderObserver {
3425 public:
3426 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3427 : num_temporal_layers_(num_temporal_layers),
3428 num_spatial_layers_(num_spatial_layers),
3429 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003430
stefanff483612015-12-21 03:14:00 -08003431 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003432 VideoSendStream::Config* send_config,
3433 std::vector<VideoReceiveStream::Config>* receive_configs,
3434 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003435 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003436 int bitrate_bps = 0;
3437 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3438 const int width = kWidth << sl_idx;
3439 const int height = kHeight << sl_idx;
3440 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3441 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3442 }
3443 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3444
Åsa Perssonff24c042015-12-04 10:58:08 +01003445 vp9_settings_.flexibleMode = false;
3446 vp9_settings_.frameDroppingOn = false;
3447 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3448 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3449 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003450 }
3451
Sergey Silkin86684962018-03-28 19:32:37 +02003452 void ModifyVideoCaptureStartResolution(int* width,
3453 int* height,
3454 int* frame_rate) override {
3455 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3456 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3457 *width = expected_width_;
3458 *height = expected_height_;
3459 }
3460
Åsa Perssonff24c042015-12-04 10:58:08 +01003461 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003462 bool ss_data_expected =
3463 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3464 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003465 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003466 if (num_spatial_layers_ > 1) {
3467 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3468 } else {
3469 EXPECT_FALSE(vp9.inter_layer_predicted);
3470 }
3471
asapersson38bb8ad2015-12-14 01:41:19 -08003472 EXPECT_EQ(!vp9.inter_pic_predicted,
3473 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003474
3475 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003476 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3477 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3478 } else {
3479 EXPECT_EQ(0, vp9.spatial_idx);
3480 }
3481 if (num_spatial_layers_ > 1)
3482 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003483 }
3484
3485 VerifyFixedTemporalLayerStructure(vp9,
3486 l_field_ ? num_temporal_layers_ : 0);
3487
3488 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003489 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003490 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003491 const uint8_t num_temporal_layers_;
3492 const uint8_t num_spatial_layers_;
3493 const bool l_field_;
3494 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003495
stefane74eef12016-01-08 06:47:13 -08003496 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003497}
3498
Sebastian Jansson63470292019-02-01 10:13:43 +01003499TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
asaperssond9f641e2016-01-21 01:11:35 -08003500 static const size_t kNumFramesToSend = 50;
3501 static const int kWidth = 4;
3502 static const int kHeight = 4;
3503 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3504 void ModifyVideoConfigsHook(
3505 VideoSendStream::Config* send_config,
3506 std::vector<VideoReceiveStream::Config>* receive_configs,
3507 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003508 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003509 vp9_settings_.flexibleMode = false;
3510 vp9_settings_.numberOfTemporalLayers = 1;
3511 vp9_settings_.numberOfSpatialLayers = 1;
3512
perkjfa10b552016-10-02 23:45:26 -07003513 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003514 }
3515
3516 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3517 if (frames_sent_ > kNumFramesToSend)
3518 observation_complete_.Set();
3519 }
perkjfa10b552016-10-02 23:45:26 -07003520
3521 void ModifyVideoCaptureStartResolution(int* width,
3522 int* height,
3523 int* frame_rate) override {
3524 expected_width_ = kWidth;
3525 expected_height_ = kHeight;
3526 *width = kWidth;
3527 *height = kHeight;
3528 }
asaperssond9f641e2016-01-21 01:11:35 -08003529 } test;
3530
3531 RunBaseTest(&test);
3532}
3533
kjellanderf9e2a362017-03-24 12:17:33 -07003534#if defined(WEBRTC_ANDROID)
3535// Crashes on Android; bugs.webrtc.org/7401
3536#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3537#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003538// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3539// the test after webrtc:9270 is implemented.
3540#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3541// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003542#endif
Sebastian Jansson63470292019-02-01 10:13:43 +01003543TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003544 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003545 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003546 VideoSendStream::Config* send_config,
3547 std::vector<VideoReceiveStream::Config>* receive_configs,
3548 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003549 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003550 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003551 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003552 vp9_settings_.numberOfTemporalLayers = 1;
3553 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003554 }
3555
Åsa Perssonff24c042015-12-04 10:58:08 +01003556 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3557 EXPECT_TRUE(vp9_header.flexible_mode);
3558 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3559 if (vp9_header.inter_pic_predicted) {
3560 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003561 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003562 }
3563 }
3564 } test;
3565
stefane74eef12016-01-08 06:47:13 -08003566 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003567}
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003568#endif // defined(RTC_ENABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003569
perkj803d97f2016-11-01 11:45:46 -07003570void VideoSendStreamTest::TestRequestSourceRotateVideo(
3571 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003572 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003573
3574 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003575 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003576 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003577 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003578 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003579 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3580 }
3581
3582 CreateVideoStreams();
3583 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003584 GetVideoSendStream()->SetSource(&forwarder,
3585 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003586
3587 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3588 support_orientation_ext);
3589
3590 DestroyStreams();
3591}
3592
Sebastian Jansson63470292019-02-01 10:13:43 +01003593TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003594 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3595 TestRequestSourceRotateVideo(false);
3596}
3597
Sebastian Jansson63470292019-02-01 10:13:43 +01003598TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003599 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3600 TestRequestSourceRotateVideo(true);
3601}
3602
Sebastian Jansson63470292019-02-01 10:13:43 +01003603TEST_F(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) {
Åsa Perssonf06bacc2018-10-12 11:07:20 +02003604 static const int kMaxFps = 22;
3605 class FpsObserver : public test::SendTest,
3606 public test::FrameGeneratorCapturer::SinkWantsObserver {
3607 public:
3608 FpsObserver() : SendTest(kDefaultTimeoutMs) {}
3609
3610 void OnFrameGeneratorCapturerCreated(
3611 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3612 frame_generator_capturer->SetSinkWantsObserver(this);
3613 }
3614
3615 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
3616 const rtc::VideoSinkWants& wants) override {
3617 if (wants.max_framerate_fps == kMaxFps)
3618 observation_complete_.Set();
3619 }
3620
3621 void ModifyVideoConfigs(
3622 VideoSendStream::Config* send_config,
3623 std::vector<VideoReceiveStream::Config>* receive_configs,
3624 VideoEncoderConfig* encoder_config) override {
3625 encoder_config->simulcast_layers[0].max_framerate = kMaxFps;
3626 }
3627
3628 void PerformTest() override {
3629 EXPECT_TRUE(Wait()) << "Timed out while waiting for fps to be reported.";
3630 }
3631 } test;
3632
3633 RunBaseTest(&test);
3634}
3635
michaelta3328772016-11-29 09:25:03 -08003636// This test verifies that overhead is removed from the bandwidth estimate by
3637// testing that the maximum possible target payload rate is smaller than the
3638// maximum bandwidth estimate by the overhead rate.
Sebastian Jansson63470292019-02-01 10:13:43 +01003639TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003640 test::ScopedFieldTrials override_field_trials(
3641 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3642 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3643 public test::FakeEncoder {
3644 public:
eladalon413ee9a2017-08-22 04:02:52 -07003645 explicit RemoveOverheadFromBandwidthTest(
3646 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003647 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3648 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003649 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003650 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003651 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003652 max_bitrate_bps_(0),
Niels Möllerc572ff32018-11-07 08:43:50 +01003653 first_packet_sent_(false) {}
michaelta3328772016-11-29 09:25:03 -08003654
Erik Språng566124a2018-04-23 12:32:22 +02003655 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
michaelta3328772016-11-29 09:25:03 -08003656 uint32_t frameRate) override {
3657 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003658 // Wait for the first sent packet so that videosendstream knows
3659 // rtp_overhead.
3660 if (first_packet_sent_) {
3661 max_bitrate_bps_ = bitrate.get_sum_bps();
3662 bitrate_changed_event_.Set();
3663 }
michaelta3328772016-11-29 09:25:03 -08003664 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3665 }
3666
3667 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3668 call_ = sender_call;
3669 }
3670
3671 void ModifyVideoConfigs(
3672 VideoSendStream::Config* send_config,
3673 std::vector<VideoReceiveStream::Config>* receive_configs,
3674 VideoEncoderConfig* encoder_config) override {
3675 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003676 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003677 EXPECT_FALSE(send_config->rtp.extensions.empty());
3678 }
3679
michaelt192132e2017-01-26 09:05:27 -08003680 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3681 rtc::CritScope lock(&crit_);
3682 first_packet_sent_ = true;
3683 return SEND_PACKET;
3684 }
3685
michaelta3328772016-11-29 09:25:03 -08003686 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003687 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003688 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003689 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003690 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003691 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3692 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003693 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003694 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003695 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3696 bitrate_config);
Stefan Holmer64be7fa2018-10-04 15:21:55 +02003697 call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
eladalon413ee9a2017-08-22 04:02:52 -07003698 });
michaelta3328772016-11-29 09:25:03 -08003699
3700 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003701 // overhead of 40B per packet video produces 2240bps overhead.
3702 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003703 EXPECT_TRUE(
3704 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003705 {
3706 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003707 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003708 }
3709 }
3710
3711 private:
eladalon413ee9a2017-08-22 04:02:52 -07003712 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003713 test::VideoEncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003714 Call* call_;
3715 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003716 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3717 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003718 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003719 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003720 RunBaseTest(&test);
3721}
3722
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003723class PacingFactorObserver : public test::SendTest {
3724 public:
3725 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003726 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003727 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3728 configure_send_side_(configure_send_side),
3729 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003730
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003731 void ModifyVideoConfigs(
3732 VideoSendStream::Config* send_config,
3733 std::vector<VideoReceiveStream::Config>* receive_configs,
3734 VideoEncoderConfig* encoder_config) override {
3735 // Check if send-side bwe extension is already present, and remove it if
3736 // it is not desired.
3737 bool has_send_side = false;
3738 for (auto it = send_config->rtp.extensions.begin();
3739 it != send_config->rtp.extensions.end(); ++it) {
3740 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3741 if (configure_send_side_) {
3742 has_send_side = true;
3743 } else {
3744 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003745 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003746 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003747 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003748 }
3749
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003750 if (configure_send_side_ && !has_send_side) {
Elad Alon157540a2019-02-08 23:37:52 +01003751 rtc::UniqueNumberGenerator<int> unique_id_generator;
3752 unique_id_generator.AddKnownId(0); // First valid RTP extension ID is 1.
3753 for (const RtpExtension& extension : send_config->rtp.extensions) {
3754 unique_id_generator.AddKnownId(extension.id);
3755 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003756 // Want send side, not present by default, so add it.
3757 send_config->rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +01003758 RtpExtension::kTransportSequenceNumberUri, unique_id_generator());
Erik Språng7c8cca32017-10-24 17:05:18 +02003759 }
3760
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003761 // ALR only enabled for screenshare.
3762 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3763 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003764
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003765 void OnVideoStreamsCreated(
3766 VideoSendStream* send_stream,
3767 const std::vector<VideoReceiveStream*>& receive_streams) override {
3768 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3769 // Video streams created, check that pacing factor is correctly configured.
3770 EXPECT_EQ(expected_pacing_factor_,
3771 internal_send_peer.GetPacingFactorOverride());
3772 observation_complete_.Set();
3773 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003774
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003775 void PerformTest() override {
3776 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3777 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003778
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003779 private:
3780 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003781 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003782};
3783
3784std::string GetAlrProbingExperimentString() {
3785 return std::string(
3786 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3787 "/1.0,2875,80,40,-60,3/";
3788}
3789const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3790
Sebastian Jansson63470292019-02-01 10:13:43 +01003791TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003792 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003793 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003794 PacingFactorObserver test_with_send_side(true,
3795 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003796 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003797}
Erik Språng7c8cca32017-10-24 17:05:18 +02003798
Sebastian Jansson63470292019-02-01 10:13:43 +01003799TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003800 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3801 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003802 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003803 RunBaseTest(&test_without_send_side);
3804}
3805
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003806// Test class takes as argument a function pointer to reset the send
3807// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3808// change the content type of a VideoSendStream, you need to recreate it.
3809// Stopping and recreating the stream can only be done on the main thread and in
3810// the context of VideoSendStreamTest (not BaseTest). The test switches from
3811// realtime to screenshare and back.
3812template <typename T>
3813class ContentSwitchTest : public test::SendTest {
3814 public:
3815 enum class StreamState {
3816 kBeforeSwitch = 0,
3817 kInScreenshare = 1,
3818 kAfterSwitchBack = 2,
3819 };
3820 static const uint32_t kMinPacketsToSend = 50;
3821
3822 explicit ContentSwitchTest(T* stream_reset_fun)
3823 : SendTest(test::CallTest::kDefaultTimeoutMs),
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003824 call_(nullptr),
3825 state_(StreamState::kBeforeSwitch),
3826 send_stream_(nullptr),
3827 send_stream_config_(nullptr),
3828 packets_sent_(0),
3829 stream_resetter_(stream_reset_fun) {
3830 RTC_DCHECK(stream_resetter_);
3831 }
3832
3833 void OnVideoStreamsCreated(
3834 VideoSendStream* send_stream,
3835 const std::vector<VideoReceiveStream*>& receive_streams) override {
3836 rtc::CritScope lock(&crit_);
3837 send_stream_ = send_stream;
3838 }
3839
3840 void ModifyVideoConfigs(
3841 VideoSendStream::Config* send_config,
3842 std::vector<VideoReceiveStream::Config>* receive_configs,
3843 VideoEncoderConfig* encoder_config) override {
3844 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3845 encoder_config->min_transmit_bitrate_bps = 0;
3846 encoder_config->content_type =
3847 VideoEncoderConfig::ContentType::kRealtimeVideo;
3848 send_stream_config_ = send_config->Copy();
3849 encoder_config_ = encoder_config->Copy();
3850 }
3851
3852 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3853 call_ = sender_call;
3854 }
3855
3856 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3857 rtc::CritScope lock(&crit_);
3858
3859 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3860 float pacing_factor =
3861 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3862 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3863 if (send_stream_->GetStats().content_type ==
3864 webrtc::VideoContentType::SCREENSHARE) {
3865 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3866 }
3867
3868 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3869
3870 // Wait until at least kMinPacketsToSend packets to be sent, so that
3871 // some frames would be encoded.
3872 if (++packets_sent_ < kMinPacketsToSend)
3873 return SEND_PACKET;
3874
3875 if (state_ != StreamState::kAfterSwitchBack) {
3876 // We've sent kMinPacketsToSend packets, switch the content type and move
3877 // move to the next state.
3878 // Note that we need to recreate the stream if changing content type.
3879 packets_sent_ = 0;
3880 if (encoder_config_.content_type ==
3881 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3882 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3883 } else {
3884 encoder_config_.content_type =
3885 VideoEncoderConfig::ContentType::kRealtimeVideo;
3886 }
3887 switch (state_) {
3888 case StreamState::kBeforeSwitch:
3889 state_ = StreamState::kInScreenshare;
3890 break;
3891 case StreamState::kInScreenshare:
3892 state_ = StreamState::kAfterSwitchBack;
3893 break;
3894 case StreamState::kAfterSwitchBack:
3895 RTC_NOTREACHED();
3896 break;
3897 }
3898 content_switch_event_.Set();
3899 return SEND_PACKET;
3900 }
3901
3902 observation_complete_.Set();
3903 return SEND_PACKET;
3904 }
3905
3906 void PerformTest() override {
3907 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3908 ASSERT_TRUE(
3909 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3910 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3911 }
3912
3913 ASSERT_TRUE(Wait())
3914 << "Timed out waiting for a frame sent after switch back";
3915 }
3916
3917 private:
3918 StreamState GetStreamState() {
3919 rtc::CritScope lock(&crit_);
3920 return state_;
3921 }
3922
3923 rtc::CriticalSection crit_;
3924 rtc::Event content_switch_event_;
3925 Call* call_;
3926 StreamState state_ RTC_GUARDED_BY(crit_);
3927 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3928 VideoSendStream::Config send_stream_config_;
3929 VideoEncoderConfig encoder_config_;
3930 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3931 T* stream_resetter_;
3932};
3933
Sebastian Jansson63470292019-02-01 10:13:43 +01003934TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003935 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3936 const VideoEncoderConfig& encoder_config,
3937 test::BaseTest* test) {
3938 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3939 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003940 DestroyVideoSendStreams();
3941 SetVideoSendConfig(send_stream_config);
3942 SetVideoEncoderConfig(encoder_config);
3943 CreateVideoSendStreams();
3944 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3945 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003946 Start();
3947 });
3948 };
3949 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3950 RunBaseTest(&test);
3951}
3952
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003953} // namespace webrtc