blob: c306e84275c82e4c5d7c92e0efe95281171c70a0 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/call.h"
Artem Titov4e199e92018-08-20 13:30:39 +020018#include "call/fake_network_pipe.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "call/rtp_transport_controller_send.h"
Artem Titov4e199e92018-08-20 13:30:39 +020020#include "call/simulated_network.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/rtp_rtcp/include/rtp_header_parser.h"
22#include "modules/rtp_rtcp/include/rtp_rtcp.h"
23#include "modules/rtp_rtcp/source/rtcp_sender.h"
24#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
25#include "modules/video_coding/codecs/vp8/include/vp8.h"
26#include "modules/video_coding/codecs/vp9/include/vp9.h"
27#include "rtc_base/bind.h"
28#include "rtc_base/checks.h"
29#include "rtc_base/criticalsection.h"
30#include "rtc_base/event.h"
Sebastian Janssoncabe3832018-01-12 10:54:18 +010031#include "rtc_base/experiments/alr_experiment.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/logging.h"
33#include "rtc_base/platform_thread.h"
34#include "rtc_base/rate_limiter.h"
35#include "rtc_base/timeutils.h"
36#include "system_wrappers/include/sleep.h"
37#include "test/call_test.h"
38#include "test/configurable_frame_size_encoder.h"
Niels Möller4db138e2018-04-19 09:04:13 +020039#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020040#include "test/fake_texture_frame.h"
41#include "test/field_trial.h"
42#include "test/frame_generator.h"
43#include "test/frame_generator_capturer.h"
44#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010045#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020046#include "test/gtest.h"
47#include "test/null_transport.h"
48#include "test/rtcp_packet_parser.h"
49#include "test/testsupport/perf_test.h"
Niels Möllercbcbc222018-09-28 09:07:24 +020050#include "test/video_encoder_proxy_factory.h"
perkjfa10b552016-10-02 23:45:26 -070051
Sebastian Janssona45c8da2018-01-16 10:55:29 +010052#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020053#include "video/send_statistics_proxy.h"
54#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010055#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000056
57namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010058namespace test {
59class VideoSendStreamPeer {
60 public:
61 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
62 : internal_stream_(
63 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020064 absl::optional<float> GetPacingFactorOverride() const {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010065 return internal_stream_->GetPacingFactorOverride();
66 }
67
68 private:
69 internal::VideoSendStream const* const internal_stream_;
70};
71} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000072
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080073namespace {
74constexpr int64_t kRtcpIntervalMs = 1000;
75
Yves Gerey665174f2018-06-19 15:03:05 +020076enum VideoFormat {
77 kGeneric,
78 kVP8,
79};
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080080} // namespace
sprang@webrtc.org346094c2014-02-18 08:40:33 +000081
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070082VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000083
Sebastian Janssonc714b6e2018-08-30 15:45:41 +020084class VideoSendStreamTest : public test::CallTest,
85 public testing::WithParamInterface<std::string> {
86 public:
87 VideoSendStreamTest() : field_trial_(GetParam()) {}
88
pbos@webrtc.org013d9942013-08-22 09:42:17 +000089 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000090 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000091 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000092 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010093
94 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
95 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070096
97 void TestRequestSourceRotateVideo(bool support_orientation_ext);
Sebastian Janssonc714b6e2018-08-30 15:45:41 +020098
99 private:
100 test::ScopedFieldTrials field_trial_;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000101};
102
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200103INSTANTIATE_TEST_CASE_P(Default, VideoSendStreamTest, ::testing::Values(""));
104
105INSTANTIATE_TEST_CASE_P(
106 TaskQueueTrial,
107 VideoSendStreamTest,
108 ::testing::Values("WebRTC-TaskQueueCongestionControl/Enabled/"));
109
110TEST_P(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700111 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200112 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000113
eladalon413ee9a2017-08-22 04:02:52 -0700114 test::NullTransport transport;
115 CreateSendConfig(1, 0, 0, &transport);
116 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200117 GetVideoSendStream()->Start();
118 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700119 DestroyStreams();
120 DestroyCalls();
121 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000122}
123
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200124TEST_P(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700125 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200126 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000127
eladalon413ee9a2017-08-22 04:02:52 -0700128 test::NullTransport transport;
129 CreateSendConfig(1, 0, 0, &transport);
130 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200131 GetVideoSendStream()->Stop();
132 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700133 DestroyStreams();
134 DestroyCalls();
135 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000136}
137
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200138TEST_P(VideoSendStreamTest, SupportsCName) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000139 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000140 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000141 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000142 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000143
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000144 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000145 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700146 test::RtcpPacketParser parser;
147 EXPECT_TRUE(parser.Parse(packet, length));
148 if (parser.sdes()->num_packets() > 0) {
149 EXPECT_EQ(1u, parser.sdes()->chunks().size());
150 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000151
danilchap3dc929e2016-11-02 08:21:59 -0700152 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000153 }
154
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000155 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000156 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000157
stefanff483612015-12-21 03:14:00 -0800158 void ModifyVideoConfigs(
159 VideoSendStream::Config* send_config,
160 std::vector<VideoReceiveStream::Config>* receive_configs,
161 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000162 send_config->rtp.c_name = kCName;
163 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000164
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000165 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100166 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000167 }
168 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000169
stefane74eef12016-01-08 06:47:13 -0800170 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000171}
172
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200173TEST_P(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000174 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000175 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000176 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000177 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100178 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000179 }
180
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000181 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000182 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000183 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000184
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000185 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
186 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
187 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700188 if (header.extension.absoluteSendTime != 0) {
189 // Wait for at least one packet with a non-zero send time. The send time
190 // is a 16-bit value derived from the system clock, and it is valid
191 // for a packet to have a zero send time. To tell that from an
192 // unpopulated value we'll wait for a packet with non-zero send time.
193 observation_complete_.Set();
194 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100195 RTC_LOG(LS_WARNING)
196 << "Got a packet with zero absoluteSendTime, waiting"
197 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700198 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000199
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000200 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000201 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000202
stefanff483612015-12-21 03:14:00 -0800203 void ModifyVideoConfigs(
204 VideoSendStream::Config* send_config,
205 std::vector<VideoReceiveStream::Config>* receive_configs,
206 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200207 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100208 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700209 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000210 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000211
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000212 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100213 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000214 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000215 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000216
stefane74eef12016-01-08 06:47:13 -0800217 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000218}
219
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200220TEST_P(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000221 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000222 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000223 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000224 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200225 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200226 return absl::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200227 Clock::GetRealTimeClock(), kEncodeDelayMs);
228 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000229 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100230 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000231 }
232
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000233 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000234 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000235 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000236 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000237
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000238 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
239 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000240 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000241 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100242 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000243
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000244 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000245 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000246
stefanff483612015-12-21 03:14:00 -0800247 void ModifyVideoConfigs(
248 VideoSendStream::Config* send_config,
249 std::vector<VideoReceiveStream::Config>* receive_configs,
250 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200251 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100252 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700253 send_config->rtp.extensions.push_back(RtpExtension(
254 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000255 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000256
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000257 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100258 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000259 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000260
Niels Möller4db138e2018-04-19 09:04:13 +0200261 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000262 } test;
263
stefane74eef12016-01-08 06:47:13 -0800264 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000265}
266
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200267TEST_P(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700268 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700269 class TransportWideSequenceNumberObserver : public test::SendTest {
270 public:
271 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200272 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200273 return absl::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200274 Clock::GetRealTimeClock());
275 }) {
sprang867fb522015-08-03 04:38:41 -0700276 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
277 kRtpExtensionTransportSequenceNumber, kExtensionId));
278 }
279
280 private:
281 Action OnSendRtp(const uint8_t* packet, size_t length) override {
282 RTPHeader header;
283 EXPECT_TRUE(parser_->Parse(packet, length, &header));
284
285 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
286 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
287 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
288
Peter Boström5811a392015-12-10 13:02:50 +0100289 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700290
291 return SEND_PACKET;
292 }
293
stefanff483612015-12-21 03:14:00 -0800294 void ModifyVideoConfigs(
295 VideoSendStream::Config* send_config,
296 std::vector<VideoReceiveStream::Config>* receive_configs,
297 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200298 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700299 }
300
301 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100302 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700303 }
304
Niels Möller4db138e2018-04-19 09:04:13 +0200305 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700306 } test;
307
stefane74eef12016-01-08 06:47:13 -0800308 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700309}
310
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200311TEST_P(VideoSendStreamTest, SupportsVideoRotation) {
perkj803d97f2016-11-01 11:45:46 -0700312 class VideoRotationObserver : public test::SendTest {
313 public:
314 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
315 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
316 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
317 }
318
319 Action OnSendRtp(const uint8_t* packet, size_t length) override {
320 RTPHeader header;
321 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700322 // Only the last packet of the frame is required to have the extension.
323 if (!header.markerBit)
324 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700325 EXPECT_TRUE(header.extension.hasVideoRotation);
326 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
327 observation_complete_.Set();
328 return SEND_PACKET;
329 }
330
331 void ModifyVideoConfigs(
332 VideoSendStream::Config* send_config,
333 std::vector<VideoReceiveStream::Config>* receive_configs,
334 VideoEncoderConfig* encoder_config) override {
335 send_config->rtp.extensions.clear();
336 send_config->rtp.extensions.push_back(RtpExtension(
337 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
338 }
339
340 void OnFrameGeneratorCapturerCreated(
341 test::FrameGeneratorCapturer* frame_generator_capturer) override {
342 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
343 }
344
345 void PerformTest() override {
346 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
347 }
348 } test;
349
350 RunBaseTest(&test);
351}
352
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200353TEST_P(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700354 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700355 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100356 VideoContentTypeObserver()
357 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700358 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
359 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
360 }
361
362 Action OnSendRtp(const uint8_t* packet, size_t length) override {
363 RTPHeader header;
364 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100365 // Only the last packet of the key-frame must have extension.
366 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700367 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100368 // First marker bit seen means that the first frame is sent.
369 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700370 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700371 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
372 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700373 observation_complete_.Set();
374 return SEND_PACKET;
375 }
376
377 void ModifyVideoConfigs(
378 VideoSendStream::Config* send_config,
379 std::vector<VideoReceiveStream::Config>* receive_configs,
380 VideoEncoderConfig* encoder_config) override {
381 send_config->rtp.extensions.clear();
382 send_config->rtp.extensions.push_back(
383 RtpExtension(RtpExtension::kVideoContentTypeUri,
384 test::kVideoContentTypeExtensionId));
385 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
386 }
387
388 void PerformTest() override {
389 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
390 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100391
392 private:
393 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700394 } test;
395
396 RunBaseTest(&test);
397}
398
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200399TEST_P(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700400 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700401 public:
ilnik10894992017-06-21 08:23:19 -0700402 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700403 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
404 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
405 }
406
407 Action OnSendRtp(const uint8_t* packet, size_t length) override {
408 RTPHeader header;
409 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700410 // Only the last packet of the frame must have extension.
411 if (!header.markerBit)
412 return SEND_PACKET;
413 EXPECT_TRUE(header.extension.has_video_timing);
414 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700415 return SEND_PACKET;
416 }
417
418 void ModifyVideoConfigs(
419 VideoSendStream::Config* send_config,
420 std::vector<VideoReceiveStream::Config>* receive_configs,
421 VideoEncoderConfig* encoder_config) override {
422 send_config->rtp.extensions.clear();
423 send_config->rtp.extensions.push_back(RtpExtension(
424 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
425 }
426
427 void PerformTest() override {
428 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
429 }
430 } test;
431
432 RunBaseTest(&test);
433}
434
danilchap901b2df2017-07-28 08:56:04 -0700435class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000436 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000437 FakeReceiveStatistics(uint32_t send_ssrc,
438 uint32_t last_sequence_number,
439 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700440 uint8_t fraction_lost) {
441 stat_.SetMediaSsrc(send_ssrc);
442 stat_.SetExtHighestSeqNum(last_sequence_number);
443 stat_.SetCumulativeLost(cumulative_lost);
444 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000445 }
446
danilchap901b2df2017-07-28 08:56:04 -0700447 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
448 EXPECT_GE(max_blocks, 1u);
449 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000450 }
451
452 private:
danilchap901b2df2017-07-28 08:56:04 -0700453 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000454};
455
brandtre602f0a2016-10-31 03:40:49 -0700456class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100457 public:
brandtre602f0a2016-10-31 03:40:49 -0700458 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800459 bool use_nack,
460 bool expect_red,
461 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800462 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200463 VideoEncoderFactory* encoder_factory)
brandtr20d45472017-01-02 00:34:27 -0800464 : EndToEndTest(kTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200465 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100466 payload_name_(codec),
467 use_nack_(use_nack),
468 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700469 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800470 sent_media_(false),
471 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800472 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100473
brandtr20d45472017-01-02 00:34:27 -0800474 // Some of the test cases are expected to time out and thus we are using
475 // a shorter timeout window than the default here.
476 static constexpr size_t kTimeoutMs = 10000;
477
Stefan Holmer4654d202015-12-08 09:10:43 +0100478 private:
479 Action OnSendRtp(const uint8_t* packet, size_t length) override {
480 RTPHeader header;
481 EXPECT_TRUE(parser_->Parse(packet, length, &header));
482
Stefan Holmer4654d202015-12-08 09:10:43 +0100483 int encapsulated_payload_type = -1;
484 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100485 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100486 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
487 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100488 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100489 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
490 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100491 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100492 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100493 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
494 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100495 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
496 length) {
497 // Not padding-only, media received outside of RED.
498 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800499 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100500 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100501 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000502
Stefan Holmer4654d202015-12-08 09:10:43 +0100503 if (header_extensions_enabled_) {
504 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
505 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
506 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
507 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
508 // 24 bits wrap.
509 EXPECT_GT(prev_header_.extension.absoluteSendTime,
510 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000511 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100512 EXPECT_GE(header.extension.absoluteSendTime,
513 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200514 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100515 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
516 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
517 prev_header_.extension.transportSequenceNumber;
518 EXPECT_EQ(1, seq_num_diff);
519 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200520
Stefan Holmer4654d202015-12-08 09:10:43 +0100521 if (encapsulated_payload_type != -1) {
522 if (encapsulated_payload_type ==
523 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700524 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800525 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100526 } else {
brandtr65a1e772016-12-12 01:54:58 -0800527 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000528 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000529 }
530
brandtr20d45472017-01-02 00:34:27 -0800531 if (sent_media_ && sent_ulpfec_) {
532 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100533 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000534
Stefan Holmer4654d202015-12-08 09:10:43 +0100535 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000536
Stefan Holmer4654d202015-12-08 09:10:43 +0100537 return SEND_PACKET;
538 }
539
eladalon413ee9a2017-08-22 04:02:52 -0700540 test::PacketTransport* CreateSendTransport(
541 test::SingleThreadedTaskQueueForTesting* task_queue,
542 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100543 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
544 // Configure some network delay.
545 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200546 BuiltInNetworkBehaviorConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800547 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100548 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700549 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700550 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200551 VideoSendStreamTest::payload_type_map_,
552 absl::make_unique<FakeNetworkPipe>(
553 Clock::GetRealTimeClock(),
554 absl::make_unique<SimulatedNetwork>(config)));
Peter Boström39593972016-02-15 11:27:15 +0100555 }
556
stefanff483612015-12-21 03:14:00 -0800557 void ModifyVideoConfigs(
558 VideoSendStream::Config* send_config,
559 std::vector<VideoReceiveStream::Config>* receive_configs,
560 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100561 if (use_nack_) {
562 send_config->rtp.nack.rtp_history_ms =
563 (*receive_configs)[0].rtp.nack.rtp_history_ms =
564 VideoSendStreamTest::kNackRtpHistoryMs;
565 }
Niels Möller4db138e2018-04-19 09:04:13 +0200566 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200567 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700568 send_config->rtp.ulpfec.red_payload_type =
569 VideoSendStreamTest::kRedPayloadType;
570 send_config->rtp.ulpfec.ulpfec_payload_type =
571 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800572 EXPECT_FALSE(send_config->rtp.extensions.empty());
573 if (!header_extensions_enabled_) {
574 send_config->rtp.extensions.clear();
575 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100576 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700577 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100578 }
Niels Möller259a4972018-04-05 15:36:51 +0200579 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700580 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700581 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700582 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700583 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100584 }
585
586 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800587 EXPECT_EQ(expect_ulpfec_, Wait())
588 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100589 }
590
Niels Möller4db138e2018-04-19 09:04:13 +0200591 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800592 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100593 const bool use_nack_;
594 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700595 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800596 bool sent_media_;
597 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100598 bool header_extensions_enabled_;
599 RTPHeader prev_header_;
600};
601
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200602TEST_P(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200603 test::FunctionVideoEncoderFactory encoder_factory(
604 []() { return VP8Encoder::Create(); });
605 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800606 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100607}
608
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200609TEST_P(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200610 test::FunctionVideoEncoderFactory encoder_factory(
611 []() { return VP8Encoder::Create(); });
612 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100613 RunBaseTest(&test);
614}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000615
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200616class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
stefan60e10c72017-08-23 10:40:00 -0700617 protected:
618 VideoSendStreamWithoutUlpfecTest()
619 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
620
621 test::ScopedFieldTrials field_trial_;
622};
623
624TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200625 test::FunctionVideoEncoderFactory encoder_factory(
626 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200627 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700628 RunBaseTest(&test);
629}
630
Peter Boström39593972016-02-15 11:27:15 +0100631// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
632// since we'll still have to re-request FEC packets, effectively wasting
633// bandwidth since the receiver has to wait for FEC retransmissions to determine
634// that the received state is actually decodable.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200635TEST_P(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200636 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200637 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200638 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200639 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100640 RunBaseTest(&test);
641}
642
643// Without retransmissions FEC for H264 is fine.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200644TEST_P(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200645 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200646 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200647 });
648 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100649 RunBaseTest(&test);
650}
651
danilchap9f5b6222017-03-02 06:22:21 -0800652// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200653TEST_P(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200654 test::FunctionVideoEncoderFactory encoder_factory(
655 []() { return VP8Encoder::Create(); });
656 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100657 RunBaseTest(&test);
658}
659
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100660#if defined(RTC_ENABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800661// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200662TEST_P(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200663 test::FunctionVideoEncoderFactory encoder_factory(
664 []() { return VP9Encoder::Create(); });
665 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800666 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000667}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100668#endif // defined(RTC_ENABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000669
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200670TEST_P(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200671 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200672 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200673 Clock::GetRealTimeClock());
674 });
675 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800676 RunBaseTest(&test);
677}
678
brandtr39f97292016-11-16 22:57:50 -0800679// TODO(brandtr): Move these FlexFEC tests when we have created
680// FlexfecSendStream.
681class FlexfecObserver : public test::EndToEndTest {
682 public:
683 FlexfecObserver(bool header_extensions_enabled,
684 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800685 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200686 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100687 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800688 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200689 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800690 payload_name_(codec),
691 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800692 sent_media_(false),
693 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100694 header_extensions_enabled_(header_extensions_enabled),
695 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800696
697 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100698 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800699
700 private:
701 Action OnSendRtp(const uint8_t* packet, size_t length) override {
702 RTPHeader header;
703 EXPECT_TRUE(parser_->Parse(packet, length, &header));
704
brandtr39f97292016-11-16 22:57:50 -0800705 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
706 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
707 sent_flexfec_ = true;
708 } else {
709 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
710 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100711 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
712 num_video_streams_),
713 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800714 sent_media_ = true;
715 }
716
717 if (header_extensions_enabled_) {
718 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
719 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
720 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
721 }
722
brandtr0c5a1542016-11-23 04:42:26 -0800723 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800724 observation_complete_.Set();
725 }
726
727 return SEND_PACKET;
728 }
729
eladalon413ee9a2017-08-22 04:02:52 -0700730 test::PacketTransport* CreateSendTransport(
731 test::SingleThreadedTaskQueueForTesting* task_queue,
732 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800733 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
734 // Therefore we need some network delay.
735 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200736 BuiltInNetworkBehaviorConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800737 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800738 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700739 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700740 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200741 VideoSendStreamTest::payload_type_map_,
742 absl::make_unique<FakeNetworkPipe>(
743 Clock::GetRealTimeClock(),
744 absl::make_unique<SimulatedNetwork>(config)));
brandtr39f97292016-11-16 22:57:50 -0800745 }
746
747 void ModifyVideoConfigs(
748 VideoSendStream::Config* send_config,
749 std::vector<VideoReceiveStream::Config>* receive_configs,
750 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800751 if (use_nack_) {
752 send_config->rtp.nack.rtp_history_ms =
753 (*receive_configs)[0].rtp.nack.rtp_history_ms =
754 VideoSendStreamTest::kNackRtpHistoryMs;
755 }
Niels Möller4db138e2018-04-19 09:04:13 +0200756 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200757 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800758 if (header_extensions_enabled_) {
759 send_config->rtp.extensions.push_back(RtpExtension(
760 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
761 send_config->rtp.extensions.push_back(RtpExtension(
762 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800763 } else {
764 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800765 }
Niels Möller259a4972018-04-05 15:36:51 +0200766 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800767 }
768
769 void PerformTest() override {
770 EXPECT_TRUE(Wait())
771 << "Timed out waiting for FlexFEC and/or media packets.";
772 }
773
Niels Möller4db138e2018-04-19 09:04:13 +0200774 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800775 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800776 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800777 bool sent_media_;
778 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100779 const bool header_extensions_enabled_;
780 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800781};
782
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200783TEST_P(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200784 test::FunctionVideoEncoderFactory encoder_factory(
785 []() { return VP8Encoder::Create(); });
786 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100787 RunBaseTest(&test);
788}
789
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200790TEST_P(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200791 test::FunctionVideoEncoderFactory encoder_factory(
792 []() { return VP8Encoder::Create(); });
793 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800794 RunBaseTest(&test);
795}
796
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200797TEST_P(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200798 test::FunctionVideoEncoderFactory encoder_factory(
799 []() { return VP8Encoder::Create(); });
800 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800801 RunBaseTest(&test);
802}
803
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200804TEST_P(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200805 test::FunctionVideoEncoderFactory encoder_factory(
806 []() { return VP8Encoder::Create(); });
807 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800808 RunBaseTest(&test);
809}
810
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100811#if defined(RTC_ENABLE_VP9)
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200812TEST_P(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200813 test::FunctionVideoEncoderFactory encoder_factory(
814 []() { return VP9Encoder::Create(); });
815 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800816 RunBaseTest(&test);
817}
818
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200819TEST_P(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200820 test::FunctionVideoEncoderFactory encoder_factory(
821 []() { return VP9Encoder::Create(); });
822 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800823 RunBaseTest(&test);
824}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100825#endif // defined(RTC_ENABLE_VP9)
brandtr39f97292016-11-16 22:57:50 -0800826
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200827TEST_P(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200828 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200829 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200830 });
831 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800832 RunBaseTest(&test);
833}
834
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200835TEST_P(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200836 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200837 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200838 });
839 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800840 RunBaseTest(&test);
841}
842
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200843TEST_P(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200844 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200845 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200846 Clock::GetRealTimeClock());
847 });
848
849 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800850 RunBaseTest(&test);
851}
852
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000853void VideoSendStreamTest::TestNackRetransmission(
854 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000855 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000856 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000857 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000858 explicit NackObserver(uint32_t retransmit_ssrc,
859 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000860 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000861 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100862 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000863 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100864 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000865
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000866 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000867 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000868 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000869 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000870
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200871 // NACK packets two times at some arbitrary points.
872 const int kNackedPacketsAtOnceCount = 3;
873 const int kRetransmitTarget = kNackedPacketsAtOnceCount * 2;
874
875 // Skip padding packets because they will never be retransmitted.
876 if (header.paddingLength + header.headerLength == length) {
877 return SEND_PACKET;
878 }
879
Sebastian Janssond3f38162018-02-28 16:14:44 +0100880 ++send_count_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200881
882 // NACK packets at arbitrary points.
Sebastian Janssond3f38162018-02-28 16:14:44 +0100883 if (send_count_ == 5 || send_count_ == 25) {
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200884 nacked_sequence_numbers_.insert(
885 nacked_sequence_numbers_.end(),
886 non_padding_sequence_numbers_.end() - kNackedPacketsAtOnceCount,
887 non_padding_sequence_numbers_.end());
Sebastian Janssond3f38162018-02-28 16:14:44 +0100888
danilchap8a1d2a32017-08-01 03:21:37 -0700889 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800890 nullptr, nullptr, transport_adapter_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800891 kRtcpIntervalMs);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000892
pbosda903ea2015-10-02 02:36:56 -0700893 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100894 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000895
896 RTCPSender::FeedbackState feedback_state;
897
Sebastian Janssond3f38162018-02-28 16:14:44 +0100898 EXPECT_EQ(0, rtcp_sender.SendRTCP(
899 feedback_state, kRtcpNack,
900 static_cast<int>(nacked_sequence_numbers_.size()),
901 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000902 }
903
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000904 uint16_t sequence_number = header.sequenceNumber;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000905 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100906 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
907 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000908 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000909 const uint8_t* rtx_header = packet + header.headerLength;
910 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
911 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200912
Sebastian Janssond3f38162018-02-28 16:14:44 +0100913 auto found = std::find(nacked_sequence_numbers_.begin(),
914 nacked_sequence_numbers_.end(), sequence_number);
915 if (found != nacked_sequence_numbers_.end()) {
916 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000917
Sebastian Janssond3f38162018-02-28 16:14:44 +0100918 if (++retransmit_count_ == kRetransmitTarget) {
919 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
920 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
921 observation_complete_.Set();
922 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200923 } else {
924 non_padding_sequence_numbers_.push_back(sequence_number);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000925 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000926
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000927 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000928 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000929
stefanff483612015-12-21 03:14:00 -0800930 void ModifyVideoConfigs(
931 VideoSendStream::Config* send_config,
932 std::vector<VideoReceiveStream::Config>* receive_configs,
933 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700934 transport_adapter_.reset(
935 new internal::TransportAdapter(send_config->send_transport));
936 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000937 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000938 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100939 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000940 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
941 }
942
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000943 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100944 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000945 }
946
kwiberg27f982b2016-03-01 11:52:33 -0800947 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000948 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100949 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000950 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000951 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100952 std::vector<uint16_t> nacked_sequence_numbers_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200953 std::vector<uint16_t> non_padding_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000954 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000955
stefane74eef12016-01-08 06:47:13 -0800956 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000957}
958
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200959TEST_P(VideoSendStreamTest, RetransmitsNack) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000960 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100961 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000962}
963
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200964TEST_P(VideoSendStreamTest, RetransmitsNackOverRtx) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000965 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000966 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000967}
968
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000969void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
970 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000971 // Use a fake encoder to output a frame of every size in the range [90, 290],
972 // for each size making sure that the exact number of payload bytes received
973 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000974 static const size_t kMaxPacketSize = 128;
975 static const size_t start = 90;
976 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000977
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000978 // Observer that verifies that the expected number of packets and bytes
979 // arrive for each frame size, from start_size to stop_size.
Niels Möller759f9592018-10-09 14:57:01 +0200980 class FrameFragmentationTest : public test::SendTest {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000981 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000982 FrameFragmentationTest(size_t max_packet_size,
983 size_t start_size,
984 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000985 bool test_generic_packetization,
986 bool use_fec)
987 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000988 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +0200989 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000990 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000991 stop_size_(stop_size),
992 test_generic_packetization_(test_generic_packetization),
993 use_fec_(use_fec),
994 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100995 packets_lost_(0),
996 last_packet_count_(0),
997 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000998 accumulated_size_(0),
999 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001000 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001001 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001002 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001003 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001004 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -07001005 RTC_DCHECK_GT(stop_size, max_packet_size);
Philip Eliassond52a1a62018-09-07 13:03:55 +00001006 if (!test_generic_packetization_)
1007 encoder_.SetCodecType(kVideoCodecVP8);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001008 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001009
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001010 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001011 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001012 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001013 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001014 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001015
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001016 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001017
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001018 if (use_fec_) {
1019 uint8_t payload_type = packet[header.headerLength];
1020 bool is_fec = header.payloadType == kRedPayloadType &&
1021 payload_type == kUlpfecPayloadType;
1022 if (is_fec) {
1023 fec_packet_received_ = true;
1024 return SEND_PACKET;
1025 }
1026 }
1027
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001028 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001029
1030 if (use_fec_)
1031 TriggerLossReport(header);
1032
1033 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +02001034 size_t overhead = header.headerLength + header.paddingLength;
1035 // Only remove payload header and RED header if the packet actually
1036 // contains payload.
1037 if (length > overhead) {
1038 overhead += (1 /* Generic header */);
1039 if (use_fec_)
1040 overhead += 1; // RED for FEC header.
1041 }
1042 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001043 accumulated_payload_ += length - overhead;
1044 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001045
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001046 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001047 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001048 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1049 // With FEC enabled, frame size is incremented asynchronously, so
1050 // "old" frames one byte too small may arrive. Accept, but don't
1051 // increase expected frame size.
1052 accumulated_size_ = 0;
1053 accumulated_payload_ = 0;
1054 return SEND_PACKET;
1055 }
1056
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001057 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001058 if (test_generic_packetization_) {
1059 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1060 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001061
1062 // Last packet of frame; reset counters.
1063 accumulated_size_ = 0;
1064 accumulated_payload_ = 0;
1065 if (current_size_rtp_ == stop_size_) {
1066 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001067 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001068 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001069 // Increase next expected frame size. If testing with FEC, make sure
1070 // a FEC packet has been received for this frame size before
1071 // proceeding, to make sure that redundancy packets don't exceed
1072 // size limit.
1073 if (!use_fec_) {
1074 ++current_size_rtp_;
1075 } else if (fec_packet_received_) {
1076 fec_packet_received_ = false;
1077 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001078
1079 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001080 ++current_size_frame_;
1081 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001082 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001083 }
1084
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001085 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001086 }
1087
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001088 void TriggerLossReport(const RTPHeader& header) {
1089 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001090 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001091 if (++packet_count_ % (100 / kLossPercent) == 0) {
1092 packets_lost_++;
1093 int loss_delta = packets_lost_ - last_packets_lost_;
1094 int packets_delta = packet_count_ - last_packet_count_;
1095 last_packet_count_ = packet_count_;
1096 last_packets_lost_ = packets_lost_;
1097 uint8_t loss_ratio =
1098 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001099 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001100 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001101 packets_lost_, // Cumulative lost.
1102 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001103 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001104 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001105 transport_adapter_.get(), kRtcpIntervalMs);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001106
pbosda903ea2015-10-02 02:36:56 -07001107 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001108 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001109
1110 RTCPSender::FeedbackState feedback_state;
1111
1112 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1113 }
1114 }
1115
Niels Möller759f9592018-10-09 14:57:01 +02001116 void UpdateConfiguration() {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001117 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001118 // Increase frame size for next encoded frame, in the context of the
1119 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001120 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001121 ++current_size_frame_;
1122 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001123 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001124 }
Niels Möllerde8e6e62018-11-13 15:10:33 +01001125 void ModifySenderBitrateConfig(
1126 BitrateConstraints* bitrate_config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001127 const int kMinBitrateBps = 30000;
Niels Möllerde8e6e62018-11-13 15:10:33 +01001128 bitrate_config->min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001129 }
1130
stefanff483612015-12-21 03:14:00 -08001131 void ModifyVideoConfigs(
1132 VideoSendStream::Config* send_config,
1133 std::vector<VideoReceiveStream::Config>* receive_configs,
1134 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001135 transport_adapter_.reset(
1136 new internal::TransportAdapter(send_config->send_transport));
1137 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001138 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001139 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1140 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001141 }
1142
1143 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001144 send_config->rtp.payload_name = "VP8";
Philip Eliassond52a1a62018-09-07 13:03:55 +00001145
Niels Möller4db138e2018-04-19 09:04:13 +02001146 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001147 send_config->rtp.max_packet_size = kMaxPacketSize;
Niels Möller759f9592018-10-09 14:57:01 +02001148 encoder_.RegisterPostEncodeCallback([this]() { UpdateConfiguration(); });
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001149
Erik Språng95261872015-04-10 11:58:49 +02001150 // Make sure there is at least one extension header, to make the RTP
1151 // header larger than the base length of 12 bytes.
1152 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001153
1154 // Setup screen content disables frame dropping which makes this easier.
Åsa Perssond34597c2018-10-22 17:34:02 +02001155 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
1156 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
sprang4847ae62017-06-27 07:06:52 -07001157 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001158 }
1159
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001160 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001161 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001162 }
1163
kwiberg27f982b2016-03-01 11:52:33 -08001164 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001165 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möllercbcbc222018-09-28 09:07:24 +02001166 test::VideoEncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001167
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001168 const size_t max_packet_size_;
1169 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001170 const bool test_generic_packetization_;
1171 const bool use_fec_;
1172
1173 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001174 uint32_t packets_lost_;
1175 uint32_t last_packet_count_;
1176 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001177 size_t accumulated_size_;
1178 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001179 bool fec_packet_received_;
1180
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001181 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001182 rtc::CriticalSection mutex_;
1183 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001184 };
1185
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001186 // Don't auto increment if FEC is used; continue sending frame size until
1187 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001188 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1189 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001190
stefane74eef12016-01-08 06:47:13 -08001191 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001192}
1193
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001194// TODO(sprang): Is there any way of speeding up these tests?
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001195TEST_P(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001196 TestPacketFragmentationSize(kGeneric, false);
1197}
1198
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001199TEST_P(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001200 TestPacketFragmentationSize(kGeneric, true);
1201}
1202
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001203TEST_P(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001204 TestPacketFragmentationSize(kVP8, false);
1205}
1206
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001207TEST_P(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001208 TestPacketFragmentationSize(kVP8, true);
1209}
1210
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001211// The test will go through a number of phases.
1212// 1. Start sending packets.
1213// 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 +00001214// suspend the stream.
1215// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001216// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001217// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001218// When the stream is detected again, and the stats show that the stream
1219// is no longer suspended, the test ends.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001220TEST_P(VideoSendStreamTest, SuspendBelowMinBitrate) {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001221 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001222
Niels Möller412d1852019-01-02 09:42:54 +01001223 class RembObserver : public test::SendTest {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001224 public:
Niels Möller412d1852019-01-02 09:42:54 +01001225 class CaptureObserver : public rtc::VideoSinkInterface<VideoFrame> {
1226 public:
1227 explicit CaptureObserver(RembObserver* remb_observer)
1228 : remb_observer_(remb_observer) {}
1229
1230 void OnFrame(const VideoFrame&) {
1231 rtc::CritScope lock(&remb_observer_->crit_);
1232 if (remb_observer_->test_state_ == kDuringSuspend &&
1233 ++remb_observer_->suspended_frame_count_ > kSuspendTimeFrames) {
1234 VideoSendStream::Stats stats = remb_observer_->stream_->GetStats();
1235 EXPECT_TRUE(stats.suspended);
1236 remb_observer_->SendRtcpFeedback(remb_observer_->high_remb_bps_);
1237 remb_observer_->test_state_ = kWaitingForPacket;
1238 }
1239 }
1240
1241 private:
1242 RembObserver* const remb_observer_;
1243 };
1244
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001245 RembObserver()
1246 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001247 clock_(Clock::GetRealTimeClock()),
Niels Möller412d1852019-01-02 09:42:54 +01001248 capture_observer_(this),
Erik Språng737336d2016-07-29 12:59:36 +02001249 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001250 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001251 rtp_count_(0),
1252 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001253 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001254 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001255 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001256
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001257 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001258 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001259 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001260 ++rtp_count_;
1261 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001262 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001263 last_sequence_number_ = header.sequenceNumber;
1264
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001265 if (test_state_ == kBeforeSuspend) {
1266 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001267 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001268 test_state_ = kDuringSuspend;
1269 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001270 if (header.paddingLength == 0) {
1271 // Received non-padding packet during suspension period. Reset the
1272 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001273 suspended_frame_count_ = 0;
1274 }
stefanf116bd02015-10-27 08:29:42 -07001275 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001276 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001277 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001278 // Non-padding packet observed. Test is almost complete. Will just
1279 // have to wait for the stats to change.
1280 test_state_ = kWaitingForStats;
1281 }
stefanf116bd02015-10-27 08:29:42 -07001282 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001283 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001284 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001285 if (stats.suspended == false) {
1286 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001287 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001288 }
stefanf116bd02015-10-27 08:29:42 -07001289 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001290 }
1291
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001292 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001293 }
1294
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001295 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001296 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001297 low_remb_bps_ = value;
1298 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001299
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001300 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001301 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001302 high_remb_bps_ = value;
1303 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001304
stefanff483612015-12-21 03:14:00 -08001305 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001306 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001307 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001308 stream_ = send_stream;
1309 }
1310
Niels Möller412d1852019-01-02 09:42:54 +01001311 void OnFrameGeneratorCapturerCreated(
1312 test::FrameGeneratorCapturer* frame_generator_capturer) override {
1313 frame_generator_capturer->AddOrUpdateSink(&capture_observer_,
1314 rtc::VideoSinkWants());
1315 }
1316
stefanff483612015-12-21 03:14:00 -08001317 void ModifyVideoConfigs(
1318 VideoSendStream::Config* send_config,
1319 std::vector<VideoReceiveStream::Config>* receive_configs,
1320 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001321 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001322 transport_adapter_.reset(
1323 new internal::TransportAdapter(send_config->send_transport));
1324 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001325 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001326 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001327 int min_bitrate_bps =
1328 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001329 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001330 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001331 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001332 min_bitrate_bps + threshold_window + 5000);
1333 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1334 }
1335
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001336 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001337 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001338 }
1339
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001340 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001341 kBeforeSuspend,
1342 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001343 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001344 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001345 };
1346
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001347 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001348 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001349 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1350 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001351 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001352 transport_adapter_.get(), kRtcpIntervalMs);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001353
pbosda903ea2015-10-02 02:36:56 -07001354 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001355 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001356 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001357 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001358 }
1359 RTCPSender::FeedbackState feedback_state;
1360 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1361 }
1362
kwiberg27f982b2016-03-01 11:52:33 -08001363 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001364 Clock* const clock_;
Niels Möller412d1852019-01-02 09:42:54 +01001365 CaptureObserver capture_observer_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001366 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001367
Peter Boströmf2f82832015-05-01 13:00:41 +02001368 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001369 TestState test_state_ RTC_GUARDED_BY(crit_);
1370 int rtp_count_ RTC_GUARDED_BY(crit_);
1371 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1372 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1373 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1374 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001375 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001376
stefane74eef12016-01-08 06:47:13 -08001377 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001378}
1379
perkj71ee44c2016-06-15 00:47:53 -07001380// This test that padding stops being send after a while if the Camera stops
1381// producing video frames and that padding resumes if the camera restarts.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001382TEST_P(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001383 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001384 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001385 NoPaddingWhenVideoIsMuted()
1386 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001387 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001388 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001389 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001390
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001391 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001392 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001393 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001394 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001395
1396 RTPHeader header;
1397 parser_->Parse(packet, length, &header);
1398 const bool only_padding =
1399 header.headerLength + header.paddingLength == length;
1400
1401 if (test_state_ == kBeforeStopCapture) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001402 // Packets are flowing, stop camera.
perkj71ee44c2016-06-15 00:47:53 -07001403 capturer_->Stop();
1404 test_state_ = kWaitingForPadding;
1405 } else if (test_state_ == kWaitingForPadding && only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001406 // We're still getting padding, after stopping camera.
perkj71ee44c2016-06-15 00:47:53 -07001407 test_state_ = kWaitingForNoPackets;
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001408 } else if (test_state_ == kWaitingForMediaAfterCameraRestart &&
1409 !only_padding) {
1410 // Media packets are flowing again, stop camera a second time.
1411 capturer_->Stop();
1412 test_state_ = kWaitingForPaddingAfterCameraStopsAgain;
1413 } else if (test_state_ == kWaitingForPaddingAfterCameraStopsAgain &&
perkj71ee44c2016-06-15 00:47:53 -07001414 only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001415 // Padding is still flowing, test ok.
perkj71ee44c2016-06-15 00:47:53 -07001416 observation_complete_.Set();
1417 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001418 return SEND_PACKET;
1419 }
1420
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001421 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001422 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001423 const int kNoPacketsThresholdMs = 2000;
1424 if (test_state_ == kWaitingForNoPackets &&
1425 (last_packet_time_ms_ > 0 &&
1426 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1427 kNoPacketsThresholdMs)) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001428 // No packets seen for |kNoPacketsThresholdMs|, restart camera.
perkj71ee44c2016-06-15 00:47:53 -07001429 capturer_->Start();
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001430 test_state_ = kWaitingForMediaAfterCameraRestart;
perkj71ee44c2016-06-15 00:47:53 -07001431 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001432 return SEND_PACKET;
1433 }
1434
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001435 void ModifyVideoConfigs(
1436 VideoSendStream::Config* send_config,
1437 std::vector<VideoReceiveStream::Config>* receive_configs,
1438 VideoEncoderConfig* encoder_config) override {
1439 // Make sure padding is sent if encoder is not producing media.
1440 encoder_config->min_transmit_bitrate_bps = 50000;
1441 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001442
nisseef8b61e2016-04-29 06:09:15 -07001443 void OnFrameGeneratorCapturerCreated(
1444 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001445 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001446 capturer_ = frame_generator_capturer;
1447 }
1448
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001449 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001450 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001451 << "Timed out while waiting for RTP packets to stop being sent.";
1452 }
1453
perkj71ee44c2016-06-15 00:47:53 -07001454 enum TestState {
1455 kBeforeStopCapture,
1456 kWaitingForPadding,
1457 kWaitingForNoPackets,
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001458 kWaitingForMediaAfterCameraRestart,
1459 kWaitingForPaddingAfterCameraStopsAgain
perkj71ee44c2016-06-15 00:47:53 -07001460 };
1461
1462 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001463 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001464 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001465 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001466 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1467 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001468 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001469
stefane74eef12016-01-08 06:47:13 -08001470 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001471}
1472
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001473TEST_P(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
isheriffcc5903e2016-10-04 08:29:38 -07001474 const int kCapacityKbps = 10000; // 10 Mbps
1475 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1476 public:
1477 PaddingIsPrimarilyRetransmissions()
1478 : EndToEndTest(kDefaultTimeoutMs),
1479 clock_(Clock::GetRealTimeClock()),
1480 padding_length_(0),
1481 total_length_(0),
1482 call_(nullptr) {}
1483
1484 private:
1485 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1486 call_ = sender_call;
1487 }
1488
1489 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1490 rtc::CritScope lock(&crit_);
1491
1492 RTPHeader header;
1493 parser_->Parse(packet, length, &header);
1494 padding_length_ += header.paddingLength;
1495 total_length_ += length;
1496 return SEND_PACKET;
1497 }
1498
eladalon413ee9a2017-08-22 04:02:52 -07001499 test::PacketTransport* CreateSendTransport(
1500 test::SingleThreadedTaskQueueForTesting* task_queue,
1501 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001502 const int kNetworkDelayMs = 50;
Artem Titov75e36472018-10-08 12:28:56 +02001503 BuiltInNetworkBehaviorConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001504 config.loss_percent = 10;
1505 config.link_capacity_kbps = kCapacityKbps;
1506 config.queue_delay_ms = kNetworkDelayMs;
Artem Titov4e199e92018-08-20 13:30:39 +02001507 return new test::PacketTransport(
1508 task_queue, sender_call, this, test::PacketTransport::kSender,
1509 payload_type_map_,
1510 absl::make_unique<FakeNetworkPipe>(
1511 Clock::GetRealTimeClock(),
1512 absl::make_unique<SimulatedNetwork>(config)));
isheriffcc5903e2016-10-04 08:29:38 -07001513 }
1514
1515 void ModifyVideoConfigs(
1516 VideoSendStream::Config* send_config,
1517 std::vector<VideoReceiveStream::Config>* receive_configs,
1518 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001519 // Turn on RTX.
1520 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1521 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001522 }
1523
1524 void PerformTest() override {
1525 // TODO(isheriff): Some platforms do not ramp up as expected to full
1526 // capacity due to packet scheduling delays. Fix that before getting
1527 // rid of this.
1528 SleepMs(5000);
1529 {
1530 rtc::CritScope lock(&crit_);
1531 // Expect padding to be a small percentage of total bytes sent.
1532 EXPECT_LT(padding_length_, .1 * total_length_);
1533 }
1534 }
1535
1536 rtc::CriticalSection crit_;
1537 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001538 size_t padding_length_ RTC_GUARDED_BY(crit_);
1539 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001540 Call* call_;
1541 } test;
1542
1543 RunBaseTest(&test);
1544}
1545
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001546// This test first observes "high" bitrate use at which point it sends a REMB to
1547// indicate that it should be lowered significantly. The test then observes that
1548// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1549// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001550//
1551// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1552// bitrate since no receiver block or remb is sent in the initial phase.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001553TEST_P(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001554 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001555 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001556 static const int kRembBitrateBps = 80000;
1557 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001558 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001559 public:
1560 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001561 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001562 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1563 stream_(nullptr),
1564 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001565
1566 private:
nisseef8b61e2016-04-29 06:09:15 -07001567 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001568 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001569 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001570
1571 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001572 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001573 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001574 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001575 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001576 if (!stats.substreams.empty()) {
1577 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001578 int total_bitrate_bps =
1579 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001580 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1581 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1582 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001583 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001584 rtp_rtcp_->SetRemb(kRembBitrateBps,
1585 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001586 rtp_rtcp_->Process();
1587 bitrate_capped_ = true;
1588 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001589 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001590 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001591 }
1592 }
stefanf116bd02015-10-27 08:29:42 -07001593 // Packets don't have to be delivered since the test is the receiver.
1594 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001595 }
1596
stefanff483612015-12-21 03:14:00 -08001597 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001598 VideoSendStream* send_stream,
1599 const std::vector<VideoReceiveStream*>& receive_streams) override {
1600 stream_ = send_stream;
1601 RtpRtcp::Configuration config;
1602 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001603 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001604 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001605 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001606 }
1607
stefanff483612015-12-21 03:14:00 -08001608 void ModifyVideoConfigs(
1609 VideoSendStream::Config* send_config,
1610 std::vector<VideoReceiveStream::Config>* receive_configs,
1611 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001612 feedback_transport_.reset(
1613 new internal::TransportAdapter(send_config->send_transport));
1614 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001615 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001616 }
1617
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001618 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001619 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001620 << "Timeout while waiting for low bitrate stats after REMB.";
1621 }
1622
kwiberg27f982b2016-03-01 11:52:33 -08001623 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1624 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001625 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001626 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001627 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001628 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001629
stefane74eef12016-01-08 06:47:13 -08001630 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001631}
1632
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001633TEST_P(VideoSendStreamTest, ChangingNetworkRoute) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001634 static const int kStartBitrateBps = 300000;
1635 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001636 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001637 class ChangingNetworkRouteTest : public test::EndToEndTest {
1638 public:
eladalon413ee9a2017-08-22 04:02:52 -07001639 explicit ChangingNetworkRouteTest(
1640 test::SingleThreadedTaskQueueForTesting* task_queue)
1641 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1642 task_queue_(task_queue),
1643 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001644 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1645 kRtpExtensionTransportSequenceNumber, kExtensionId));
1646 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001647
1648 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1649 call_ = sender_call;
1650 }
1651
Stefan Holmer280de9e2016-09-30 10:06:51 +02001652 void ModifyVideoConfigs(
1653 VideoSendStream::Config* send_config,
1654 std::vector<VideoReceiveStream::Config>* receive_configs,
1655 VideoEncoderConfig* encoder_config) override {
1656 send_config->rtp.extensions.clear();
1657 send_config->rtp.extensions.push_back(RtpExtension(
1658 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1659 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1660 (*receive_configs)[0].rtp.transport_cc = true;
1661 }
1662
1663 void ModifyAudioConfigs(
1664 AudioSendStream::Config* send_config,
1665 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1666 send_config->rtp.extensions.clear();
1667 send_config->rtp.extensions.push_back(RtpExtension(
1668 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1669 (*receive_configs)[0].rtp.extensions.clear();
1670 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1671 (*receive_configs)[0].rtp.transport_cc = true;
1672 }
1673
Stefan Holmerbe402962016-07-08 16:16:41 +02001674 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1675 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1676 observation_complete_.Set();
1677 }
1678
1679 return SEND_PACKET;
1680 }
1681
1682 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001683 rtc::NetworkRoute new_route;
1684 new_route.connected = true;
1685 new_route.local_network_id = 10;
1686 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001687 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001688
1689 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001690 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1691 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001692 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001693 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1694 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001695 });
1696
Stefan Holmerbe402962016-07-08 16:16:41 +02001697 EXPECT_TRUE(Wait())
1698 << "Timed out while waiting for start bitrate to be exceeded.";
1699
eladalon413ee9a2017-08-22 04:02:52 -07001700 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1701 bitrate_config.start_bitrate_bps = -1;
1702 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001703 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1704 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001705 // TODO(holmer): We should set the last sent packet id here and verify
1706 // that we correctly ignore any packet loss reported prior to that id.
1707 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001708 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1709 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001710 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1711 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001712 }
1713
1714 private:
eladalon413ee9a2017-08-22 04:02:52 -07001715 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001716 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001717 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001718
1719 RunBaseTest(&test);
1720}
1721
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001722TEST_P(VideoSendStreamTest, ChangingTransportOverhead) {
michaelt79e05882016-11-08 02:50:09 -08001723 class ChangingTransportOverheadTest : public test::EndToEndTest {
1724 public:
eladalon413ee9a2017-08-22 04:02:52 -07001725 explicit ChangingTransportOverheadTest(
1726 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001727 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001728 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001729 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001730 packets_sent_(0),
1731 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001732
1733 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1734 call_ = sender_call;
1735 }
1736
1737 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001738 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001739 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001740 if (++packets_sent_ < 100)
1741 return SEND_PACKET;
1742 observation_complete_.Set();
1743 return SEND_PACKET;
1744 }
1745
michaelta3328772016-11-29 09:25:03 -08001746 void ModifyVideoConfigs(
1747 VideoSendStream::Config* send_config,
1748 std::vector<VideoReceiveStream::Config>* receive_configs,
1749 VideoEncoderConfig* encoder_config) override {
1750 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1751 }
1752
michaelt79e05882016-11-08 02:50:09 -08001753 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001754 task_queue_->SendTask([this]() {
1755 transport_overhead_ = 100;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001756 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1757 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001758 });
1759
michaelt79e05882016-11-08 02:50:09 -08001760 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001761
sprang21253fc2017-02-27 03:35:47 -08001762 {
1763 rtc::CritScope cs(&lock_);
1764 packets_sent_ = 0;
1765 }
eladalon413ee9a2017-08-22 04:02:52 -07001766
1767 task_queue_->SendTask([this]() {
1768 transport_overhead_ = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001769 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1770 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001771 });
1772
michaelt79e05882016-11-08 02:50:09 -08001773 EXPECT_TRUE(Wait());
1774 }
1775
1776 private:
eladalon413ee9a2017-08-22 04:02:52 -07001777 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001778 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001779 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001780 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001781 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001782 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001783 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001784
1785 RunBaseTest(&test);
1786}
1787
sprangf24a0642017-02-28 13:23:26 -08001788// Test class takes takes as argument a switch selecting if type switch should
1789// occur and a function pointer to reset the send stream. This is necessary
1790// since you cannot change the content type of a VideoSendStream, you need to
1791// recreate it. Stopping and recreating the stream can only be done on the main
1792// thread and in the context of VideoSendStreamTest (not BaseTest).
1793template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001794class MaxPaddingSetTest : public test::SendTest {
1795 public:
1796 static const uint32_t kMinTransmitBitrateBps = 400000;
1797 static const uint32_t kActualEncodeBitrateBps = 40000;
1798 static const uint32_t kMinPacketsToSend = 50;
1799
sprangf24a0642017-02-28 13:23:26 -08001800 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001801 : SendTest(test::CallTest::kDefaultTimeoutMs),
1802 call_(nullptr),
1803 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001804 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001805 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001806 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001807 stream_resetter_(stream_reset_fun) {
1808 RTC_DCHECK(stream_resetter_);
1809 }
sprang9c0b5512016-07-06 00:54:28 -07001810
1811 void OnVideoStreamsCreated(
1812 VideoSendStream* send_stream,
1813 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001814 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001815 send_stream_ = send_stream;
1816 }
1817
1818 void ModifyVideoConfigs(
1819 VideoSendStream::Config* send_config,
1820 std::vector<VideoReceiveStream::Config>* receive_configs,
1821 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001822 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001823 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001824 encoder_config->min_transmit_bitrate_bps = 0;
1825 encoder_config->content_type =
1826 VideoEncoderConfig::ContentType::kRealtimeVideo;
1827 } else {
1828 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1829 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1830 }
sprangf24a0642017-02-28 13:23:26 -08001831 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001832 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001833 }
1834
1835 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1836 call_ = sender_call;
1837 }
1838
1839 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1840 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001841 if (running_without_padding_)
1842 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1843
1844 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1845 // we have reliable data.
1846 if (++packets_sent_ < kMinPacketsToSend)
1847 return SEND_PACKET;
1848
1849 if (running_without_padding_) {
1850 // We've sent kMinPacketsToSend packets with default configuration, switch
1851 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001852 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001853 packets_sent_ = 0;
1854 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1855 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001856 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001857 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001858 return SEND_PACKET;
1859 }
1860
1861 // Make sure the pacer has been configured with a min transmit bitrate.
1862 if (call_->GetStats().max_padding_bitrate_bps > 0)
1863 observation_complete_.Set();
1864
1865 return SEND_PACKET;
1866 }
1867
1868 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001869 if (RunningWithoutPadding()) {
1870 ASSERT_TRUE(
1871 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001872 (*stream_resetter_)(send_stream_config_, encoder_config_);
1873 }
1874
sprang9c0b5512016-07-06 00:54:28 -07001875 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1876 }
1877
1878 private:
sprangf24a0642017-02-28 13:23:26 -08001879 bool RunningWithoutPadding() const {
1880 rtc::CritScope lock(&crit_);
1881 return running_without_padding_;
1882 }
1883
sprang9c0b5512016-07-06 00:54:28 -07001884 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001885 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001886 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001887 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001888 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001889 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001890 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001891 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001892 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001893};
1894
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001895TEST_P(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001896 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1897 const VideoEncoderConfig& encoder_config) {};
1898 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001899 RunBaseTest(&test);
1900}
1901
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001902TEST_P(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001903 // Function for removing and recreating the send stream with a new config.
1904 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1905 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001906 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1907 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001908 DestroyVideoSendStreams();
1909 SetVideoSendConfig(send_stream_config);
1910 SetVideoEncoderConfig(encoder_config);
1911 CreateVideoSendStreams();
1912 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
eladalon413ee9a2017-08-22 04:02:52 -07001913 Start();
1914 });
sprangf24a0642017-02-28 13:23:26 -08001915 };
1916 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001917 RunBaseTest(&test);
1918}
1919
perkjfa10b552016-10-02 23:45:26 -07001920// This test verifies that new frame sizes reconfigures encoders even though not
1921// (yet) sending. The purpose of this is to permit encoding as quickly as
1922// possible once we start sending. Likely the frames being input are from the
1923// same source that will be sent later, which just means that we're ready
1924// earlier.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001925TEST_P(VideoSendStreamTest,
perkjfa10b552016-10-02 23:45:26 -07001926 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1927 class EncoderObserver : public test::FakeEncoder {
1928 public:
1929 EncoderObserver()
1930 : FakeEncoder(Clock::GetRealTimeClock()),
perkjfa10b552016-10-02 23:45:26 -07001931 number_of_initializations_(0),
1932 last_initialized_frame_width_(0),
1933 last_initialized_frame_height_(0) {}
1934
1935 void WaitForResolution(int width, int height) {
1936 {
1937 rtc::CritScope lock(&crit_);
1938 if (last_initialized_frame_width_ == width &&
1939 last_initialized_frame_height_ == height) {
1940 return;
1941 }
1942 }
Erik Språng08127a92016-11-16 16:41:30 +01001943 EXPECT_TRUE(
1944 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001945 {
1946 rtc::CritScope lock(&crit_);
1947 EXPECT_EQ(width, last_initialized_frame_width_);
1948 EXPECT_EQ(height, last_initialized_frame_height_);
1949 }
1950 }
1951
1952 private:
1953 int32_t InitEncode(const VideoCodec* config,
1954 int32_t number_of_cores,
1955 size_t max_payload_size) override {
1956 rtc::CritScope lock(&crit_);
1957 last_initialized_frame_width_ = config->width;
1958 last_initialized_frame_height_ = config->height;
1959 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001960 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001961 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1962 }
1963
1964 int32_t Encode(const VideoFrame& input_image,
1965 const CodecSpecificInfo* codec_specific_info,
1966 const std::vector<FrameType>* frame_types) override {
1967 ADD_FAILURE()
1968 << "Unexpected Encode call since the send stream is not started";
1969 return 0;
1970 }
1971
1972 rtc::CriticalSection crit_;
1973 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001974 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1975 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1976 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001977 };
1978
perkjfa10b552016-10-02 23:45:26 -07001979 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001980 EncoderObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02001981 test::VideoEncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07001982
Niels Möller4db138e2018-04-19 09:04:13 +02001983 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02001984 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07001985 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001986 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07001987 CreateVideoStreams();
1988 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1989 kDefaultHeight);
1990 frame_generator_capturer_->Start();
1991 });
perkjfa10b552016-10-02 23:45:26 -07001992
1993 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001994
1995 task_queue_.SendTask([this]() {
1996 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1997 kDefaultHeight * 2);
1998 });
1999
perkjfa10b552016-10-02 23:45:26 -07002000 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07002001
2002 task_queue_.SendTask([this]() {
2003 DestroyStreams();
2004 DestroyCalls();
2005 });
perkjfa10b552016-10-02 23:45:26 -07002006}
2007
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002008TEST_P(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002009 class StartBitrateObserver : public test::FakeEncoder {
2010 public:
2011 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07002012 : FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002013 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002014 int32_t InitEncode(const VideoCodec* config,
2015 int32_t number_of_cores,
2016 size_t max_payload_size) override {
2017 rtc::CritScope lock(&crit_);
2018 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07002019 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002020 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2021 }
2022
2023 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
2024 rtc::CritScope lock(&crit_);
2025 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07002026 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002027 return FakeEncoder::SetRates(new_target_bitrate, framerate);
2028 }
2029
2030 int GetStartBitrateKbps() const {
2031 rtc::CritScope lock(&crit_);
2032 return start_bitrate_kbps_;
2033 }
2034
pbos14fe7082016-04-20 06:35:56 -07002035 bool WaitForStartBitrate() {
2036 return start_bitrate_changed_.Wait(
2037 VideoSendStreamTest::kDefaultTimeoutMs);
2038 }
2039
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002040 private:
pbos5ad935c2016-01-25 03:52:44 -08002041 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002042 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002043 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002044 };
2045
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002046 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002047
solenberg4fbae2b2015-08-28 04:07:10 -07002048 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002049 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002050
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002051 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002052 bitrate_config.start_bitrate_bps =
2053 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002054 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2055 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002056
2057 StartBitrateObserver encoder;
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002058 test::VideoEncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002059 // Since this test does not use a capturer, set |internal_source| = true.
2060 // Encoder configuration is otherwise updated on the next video frame.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002061 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002062 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002063
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002064 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002065
pbos14fe7082016-04-20 06:35:56 -07002066 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002067 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002068 encoder.GetStartBitrateKbps());
2069
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002070 GetVideoEncoderConfig()->max_bitrate_bps =
2071 2 * bitrate_config.start_bitrate_bps;
2072 GetVideoSendStream()->ReconfigureVideoEncoder(
2073 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002074
2075 // New bitrate should be reconfigured above the previous max. As there's no
2076 // network connection this shouldn't be flaky, as no bitrate should've been
2077 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002078 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002079 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2080 encoder.GetStartBitrateKbps());
2081
2082 DestroyStreams();
2083}
2084
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002085class StartStopBitrateObserver : public test::FakeEncoder {
2086 public:
Niels Möllerc572ff32018-11-07 08:43:50 +01002087 StartStopBitrateObserver() : FakeEncoder(Clock::GetRealTimeClock()) {}
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002088 int32_t InitEncode(const VideoCodec* config,
2089 int32_t number_of_cores,
2090 size_t max_payload_size) override {
2091 rtc::CritScope lock(&crit_);
2092 encoder_init_.Set();
2093 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2094 }
2095
Erik Språng566124a2018-04-23 12:32:22 +02002096 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002097 uint32_t framerate) override {
2098 rtc::CritScope lock(&crit_);
2099 bitrate_kbps_ = bitrate.get_sum_kbps();
2100 bitrate_changed_.Set();
2101 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2102 }
2103
2104 bool WaitForEncoderInit() {
2105 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2106 }
2107
2108 bool WaitBitrateChanged(bool non_zero) {
2109 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002110 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002111 {
2112 rtc::CritScope lock(&crit_);
2113 bitrate_kbps = bitrate_kbps_;
2114 }
2115 if (!bitrate_kbps)
2116 continue;
2117
2118 if ((non_zero && *bitrate_kbps > 0) ||
2119 (!non_zero && *bitrate_kbps == 0)) {
2120 return true;
2121 }
2122 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2123 return false;
2124 }
2125
2126 private:
2127 rtc::CriticalSection crit_;
2128 rtc::Event encoder_init_;
2129 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002130 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002131};
2132
perkj57c21f92016-06-17 07:27:16 -07002133// This test that if the encoder use an internal source, VideoEncoder::SetRates
2134// will be called with zero bitrate during initialization and that
2135// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2136// with zero bitrate.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002137TEST_P(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002138 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002139 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002140 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002141 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002142 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002143
Niels Möller4db138e2018-04-19 09:04:13 +02002144 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002145 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002146 CreateSendConfig(1, 0, 0, &transport);
2147
2148 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002149 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002150
2151 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002152 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002153 GetVideoSendStream()->Start();
2154 GetVideoSendStream()->SetSource(&forwarder,
2155 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002156 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002157 });
perkj57c21f92016-06-17 07:27:16 -07002158
2159 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002160
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002161 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002162 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2163
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002164 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002165 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2166
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002167 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002168 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002169
eladalon413ee9a2017-08-22 04:02:52 -07002170 task_queue_.SendTask([this]() {
2171 DestroyStreams();
2172 DestroyCalls();
2173 });
perkj57c21f92016-06-17 07:27:16 -07002174}
2175
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002176// Tests that when the encoder uses an internal source, the VideoEncoder will
2177// be updated with a new bitrate when turning the VideoSendStream on/off with
2178// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2179// is reconfigured with new active layers.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002180TEST_P(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002181 test::NullTransport transport;
2182 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002183 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002184 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002185 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002186
Niels Möller4db138e2018-04-19 09:04:13 +02002187 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002188 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002189 // Create two simulcast streams.
2190 CreateSendConfig(2, 0, 0, &transport);
2191
2192 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002193 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002194
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002195 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002196
2197 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002198 GetVideoSendStream()->Start();
2199 GetVideoSendStream()->SetSource(&forwarder,
2200 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002201 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002202 });
2203
2204 EXPECT_TRUE(encoder.WaitForEncoderInit());
2205
2206 // When we turn on the simulcast layers it will update the BitrateAllocator,
2207 // which in turn updates the VideoEncoder's bitrate.
2208 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002209 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002210 });
2211 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2212
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002213 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2214 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002215 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002216 GetVideoSendStream()->ReconfigureVideoEncoder(
2217 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002218 });
2219 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2220 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2221 // active. Once the change is made for a "soft" reconfiguration we can remove
2222 // the expecation for an encoder init. We can also test that bitrate changes
2223 // when just updating individual active layers, which should change the
2224 // bitrate set to the video encoder.
2225 EXPECT_TRUE(encoder.WaitForEncoderInit());
2226 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2227
2228 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002229 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2230 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002231 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002232 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002233 });
2234 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2235
2236 task_queue_.SendTask([this]() {
2237 DestroyStreams();
2238 DestroyCalls();
2239 });
2240}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002241
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002242VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002243 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002244 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002245 memset(buffer.get(), data, kSizeY);
Artem Titov1ebfb6a2019-01-03 23:49:37 +01002246 VideoFrame frame =
2247 webrtc::VideoFrame::Builder()
2248 .set_video_frame_buffer(I420Buffer::Create(width, height))
2249 .set_rotation(webrtc::kVideoRotation_0)
2250 .set_timestamp_us(data)
2251 .build();
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002252 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002253 // Use data as a ms timestamp.
2254 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002255 return frame;
2256}
2257
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002258TEST_P(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002259 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2260 public:
eladalon413ee9a2017-08-22 04:02:52 -07002261 explicit EncoderStateObserver(
2262 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002263 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002264 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002265 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002266 initialized_(false),
2267 callback_registered_(false),
2268 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002269 released_(false),
2270 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002271
2272 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002273 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002274 return released_;
2275 }
2276
2277 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002278 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002279 return initialized_ && callback_registered_;
2280 }
2281
2282 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002283 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002284 return num_releases_;
2285 }
2286
2287 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002288 int32_t InitEncode(const VideoCodec* codecSettings,
2289 int32_t numberOfCores,
2290 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002291 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002292 EXPECT_FALSE(initialized_);
2293 initialized_ = true;
2294 released_ = false;
2295 return 0;
2296 }
2297
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002298 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002299 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002300 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002301 EXPECT_TRUE(IsReadyForEncode());
2302
Peter Boström5811a392015-12-10 13:02:50 +01002303 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002304 return 0;
2305 }
2306
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002307 int32_t RegisterEncodeCompleteCallback(
2308 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002309 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002310 EXPECT_TRUE(initialized_);
2311 callback_registered_ = true;
2312 return 0;
2313 }
2314
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002315 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002316 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002317 EXPECT_TRUE(IsReadyForEncode());
2318 EXPECT_FALSE(released_);
2319 initialized_ = false;
2320 callback_registered_ = false;
2321 released_ = true;
2322 ++num_releases_;
2323 return 0;
2324 }
2325
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002326 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002327 EXPECT_TRUE(IsReadyForEncode());
2328 return 0;
2329 }
2330
stefanff483612015-12-21 03:14:00 -08002331 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002332 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002333 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002334 stream_ = send_stream;
2335 }
2336
stefanff483612015-12-21 03:14:00 -08002337 void ModifyVideoConfigs(
2338 VideoSendStream::Config* send_config,
2339 std::vector<VideoReceiveStream::Config>* receive_configs,
2340 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002341 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002342 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002343 }
2344
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002345 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002346 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002347
2348 task_queue_->SendTask([this]() {
2349 EXPECT_EQ(0u, num_releases());
2350 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2351 EXPECT_EQ(0u, num_releases());
2352 stream_->Stop();
2353 // Encoder should not be released before destroying the VideoSendStream.
2354 EXPECT_FALSE(IsReleased());
2355 EXPECT_TRUE(IsReadyForEncode());
2356 stream_->Start();
2357 });
2358
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002359 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002360 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002361 }
2362
eladalon413ee9a2017-08-22 04:02:52 -07002363 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002364 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002365 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002366 bool initialized_ RTC_GUARDED_BY(crit_);
2367 bool callback_registered_ RTC_GUARDED_BY(crit_);
2368 size_t num_releases_ RTC_GUARDED_BY(crit_);
2369 bool released_ RTC_GUARDED_BY(crit_);
Niels Möllercbcbc222018-09-28 09:07:24 +02002370 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002371 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002372 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002373
stefane74eef12016-01-08 06:47:13 -08002374 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002375
2376 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002377 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002378}
2379
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002380TEST_P(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002381 class VideoCodecConfigObserver : public test::SendTest,
2382 public test::FakeEncoder {
2383 public:
2384 VideoCodecConfigObserver()
2385 : SendTest(kDefaultTimeoutMs),
2386 FakeEncoder(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02002387 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002388 stream_(nullptr),
2389 encoder_factory_(this) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002390
2391 private:
stefanff483612015-12-21 03:14:00 -08002392 void ModifyVideoConfigs(
2393 VideoSendStream::Config* send_config,
2394 std::vector<VideoReceiveStream::Config>* receive_configs,
2395 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002396 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprangf24a0642017-02-28 13:23:26 -08002397 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002398 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002399 }
2400
stefanff483612015-12-21 03:14:00 -08002401 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002402 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002403 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002404 stream_ = send_stream;
2405 }
2406
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002407 int32_t InitEncode(const VideoCodec* config,
2408 int32_t number_of_cores,
2409 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002410 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002411 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002412 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002413 } else {
2414 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002415 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002416 }
2417 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002418 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002419 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2420 }
2421
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002422 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002423 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002424 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002425
sprangf24a0642017-02-28 13:23:26 -08002426 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002427 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002428 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002429 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002430 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2431 "new encoder settings.";
2432 }
2433
sprangf24a0642017-02-28 13:23:26 -08002434 const uint32_t kFirstMaxBitrateBps = 1000000;
2435 const uint32_t kSecondMaxBitrateBps = 2000000;
2436
pbos14fe7082016-04-20 06:35:56 -07002437 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002438 size_t num_initializations_;
2439 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002440 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002441 VideoEncoderConfig encoder_config_;
2442 } test;
2443
stefane74eef12016-01-08 06:47:13 -08002444 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002445}
2446
Sergey Silkin571e6c92018-04-03 10:03:31 +02002447static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002448template <typename T>
2449class VideoCodecConfigObserver : public test::SendTest,
2450 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002451 public:
2452 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2453 const char* codec_name)
2454 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2455 FakeEncoder(Clock::GetRealTimeClock()),
2456 video_codec_type_(video_codec_type),
2457 codec_name_(codec_name),
Erik Språng737336d2016-07-29 12:59:36 +02002458 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002459 stream_(nullptr),
2460 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002461 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002462 }
2463
2464 private:
stefanff483612015-12-21 03:14:00 -08002465 void ModifyVideoConfigs(
2466 VideoSendStream::Config* send_config,
2467 std::vector<VideoReceiveStream::Config>* receive_configs,
2468 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002469 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002470 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002471
Niels Möller259a4972018-04-05 15:36:51 +02002472 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002473 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
Åsa Perssond34597c2018-10-22 17:34:02 +02002474 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2475 encoder_config->simulcast_layers[0].num_temporal_layers =
2476 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07002477 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002478 }
2479
stefanff483612015-12-21 03:14:00 -08002480 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002481 VideoSendStream* send_stream,
2482 const std::vector<VideoReceiveStream*>& receive_streams) override {
2483 stream_ = send_stream;
2484 }
2485
2486 int32_t InitEncode(const VideoCodec* config,
2487 int32_t number_of_cores,
2488 size_t max_payload_size) override {
2489 EXPECT_EQ(video_codec_type_, config->codecType);
2490 VerifyCodecSpecifics(*config);
2491 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002492 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002493 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2494 }
2495
Sergey Silkin86684962018-03-28 19:32:37 +02002496 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002497 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002498 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2499 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002500
2501 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002502 EXPECT_TRUE(
2503 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002504 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002505
Sergey Silkin86684962018-03-28 19:32:37 +02002506 // Change encoder settings to actually trigger reconfiguration.
2507 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002508 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002509 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002510 ASSERT_TRUE(
2511 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002512 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002513 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2514 "new encoder settings.";
2515 }
2516
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002517 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002518 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002519 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002520 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2521 return 0;
2522 }
2523
2524 T encoder_settings_;
2525 const VideoCodecType video_codec_type_;
2526 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002527 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002528 size_t num_initializations_;
2529 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002530 test::VideoEncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002531 VideoEncoderConfig encoder_config_;
2532};
2533
2534template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002535void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2536 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2537}
2538
2539template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002540void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2541 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002542 EXPECT_EQ(
2543 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002544}
kthelgason29a44e32016-09-27 03:52:02 -07002545
2546template <>
2547rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2548VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2549 return new rtc::RefCountedObject<
2550 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2551}
2552
Peter Boström53eda3d2015-03-27 15:53:18 +01002553template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002554void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2555 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2556}
2557
2558template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002559void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2560 const VideoCodec& config) const {
2561 // Check that the number of temporal layers has propagated properly to
2562 // VideoCodec.
2563 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002564 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002565
2566 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2567 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2568 config.simulcastStream[i].numberOfTemporalLayers);
2569 }
2570
2571 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002572 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002573 VideoCodecVP8 encoder_settings = encoder_settings_;
2574 encoder_settings.numberOfTemporalLayers =
2575 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002576 EXPECT_EQ(
2577 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002578}
kthelgason29a44e32016-09-27 03:52:02 -07002579
2580template <>
2581rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2582VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2583 return new rtc::RefCountedObject<
2584 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2585}
2586
Peter Boström53eda3d2015-03-27 15:53:18 +01002587template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002588void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2589 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2590}
2591
2592template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002593void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2594 const VideoCodec& config) const {
2595 // Check that the number of temporal layers has propagated properly to
2596 // VideoCodec.
2597 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002598 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002599
2600 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2601 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2602 config.simulcastStream[i].numberOfTemporalLayers);
2603 }
2604
2605 // Set expected temporal layers as they should have been set when
2606 // reconfiguring the encoder and not match the set config.
2607 VideoCodecVP9 encoder_settings = encoder_settings_;
2608 encoder_settings.numberOfTemporalLayers =
2609 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002610 EXPECT_EQ(
2611 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002612}
2613
kthelgason29a44e32016-09-27 03:52:02 -07002614template <>
2615rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2616VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2617 return new rtc::RefCountedObject<
2618 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2619}
2620
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002621TEST_P(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002622 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002623 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002624}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002625
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002626TEST_P(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002627 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002628 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002629}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002630
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002631TEST_P(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002632 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002633 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002634}
2635
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002636TEST_P(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002637 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002638 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002639 RtcpSenderReportTest()
2640 : SendTest(kDefaultTimeoutMs),
2641 rtp_packets_sent_(0),
2642 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002643
2644 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002645 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002646 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002647 RTPHeader header;
2648 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002649 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002650 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2651 return SEND_PACKET;
2652 }
2653
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002654 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002655 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002656 test::RtcpPacketParser parser;
2657 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002658
danilchap3dc929e2016-11-02 08:21:59 -07002659 if (parser.sender_report()->num_packets() > 0) {
2660 // Only compare sent media bytes if SenderPacketCount matches the
2661 // number of sent rtp packets (a new rtp packet could be sent before
2662 // the rtcp packet).
2663 if (parser.sender_report()->sender_octet_count() > 0 &&
2664 parser.sender_report()->sender_packet_count() ==
2665 rtp_packets_sent_) {
2666 EXPECT_EQ(media_bytes_sent_,
2667 parser.sender_report()->sender_octet_count());
2668 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002669 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002670 }
2671
2672 return SEND_PACKET;
2673 }
2674
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002675 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002676 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002677 }
2678
stefan4b569042015-11-11 06:39:57 -08002679 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002680 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2681 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002682 } test;
2683
stefane74eef12016-01-08 06:47:13 -08002684 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002685}
2686
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002687TEST_P(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002688 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002689
2690 class VideoStreamFactory
2691 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2692 public:
2693 VideoStreamFactory() {}
2694
2695 private:
2696 std::vector<VideoStream> CreateEncoderStreams(
2697 int width,
2698 int height,
2699 const VideoEncoderConfig& encoder_config) override {
2700 std::vector<VideoStream> streams =
2701 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002702 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2703 kScreencastMaxTargetBitrateDeltaKbps);
2704 streams[0].target_bitrate_bps =
2705 streams[0].max_bitrate_bps -
2706 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002707 return streams;
2708 }
2709 };
2710
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002711 class ScreencastTargetBitrateTest : public test::SendTest,
2712 public test::FakeEncoder {
2713 public:
2714 ScreencastTargetBitrateTest()
2715 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002716 test::FakeEncoder(Clock::GetRealTimeClock()),
2717 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002718
2719 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002720 int32_t InitEncode(const VideoCodec* config,
2721 int32_t number_of_cores,
2722 size_t max_payload_size) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002723 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002724 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002725 config->simulcastStream[0].maxBitrate -
2726 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002727 observation_complete_.Set();
Yves Gerey665174f2018-06-19 15:03:05 +02002728 return test::FakeEncoder::InitEncode(config, number_of_cores,
2729 max_payload_size);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002730 }
stefanff483612015-12-21 03:14:00 -08002731 void ModifyVideoConfigs(
2732 VideoSendStream::Config* send_config,
2733 std::vector<VideoReceiveStream::Config>* receive_configs,
2734 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002735 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002736 EXPECT_EQ(1u, encoder_config->number_of_streams);
2737 encoder_config->video_stream_factory =
2738 new rtc::RefCountedObject<VideoStreamFactory>();
Åsa Perssond34597c2018-10-22 17:34:02 +02002739 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2740 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
Erik Språng143cec12015-04-28 10:01:41 +02002741 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002742 }
2743
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002744 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002745 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002746 << "Timed out while waiting for the encoder to be initialized.";
2747 }
Niels Möllercbcbc222018-09-28 09:07:24 +02002748 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002749 } test;
2750
stefane74eef12016-01-08 06:47:13 -08002751 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002752}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002753
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002754TEST_P(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002755 // These are chosen to be "kind of odd" to not be accidentally checked against
2756 // default values.
2757 static const int kMinBitrateKbps = 137;
2758 static const int kStartBitrateKbps = 345;
2759 static const int kLowerMaxBitrateKbps = 312;
2760 static const int kMaxBitrateKbps = 413;
2761 static const int kIncreasedStartBitrateKbps = 451;
2762 static const int kIncreasedMaxBitrateKbps = 597;
Niels Möller6613f8e2019-01-10 10:30:21 +01002763 // If this field trial is on, we get lower bitrates than expected by this
2764 // test, due to the packetization overhead.
2765 webrtc::test::ScopedFieldTrials field_trials(
2766 std::string(field_trial::GetFieldTrialString()) +
2767 "WebRTC-SubtractPacketizationOverhead/Disabled/");
2768
pbos@webrtc.org00873182014-11-25 14:03:34 +00002769 class EncoderBitrateThresholdObserver : public test::SendTest,
2770 public test::FakeEncoder {
2771 public:
eladalon413ee9a2017-08-22 04:02:52 -07002772 explicit EncoderBitrateThresholdObserver(
2773 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002774 : SendTest(kDefaultTimeoutMs),
2775 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002776 task_queue_(task_queue),
perkj26091b12016-09-01 01:17:40 -07002777 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002778 num_initializations_(0),
2779 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002780 send_stream_(nullptr),
2781 encoder_factory_(this) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002782
2783 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002784 int32_t InitEncode(const VideoCodec* codecSettings,
2785 int32_t numberOfCores,
2786 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002787 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2788 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002789 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002790 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2791 codecSettings->minBitrate);
2792 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2793 codecSettings->startBitrate);
2794 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2795 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002796 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002797 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002798 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2799 codecSettings->maxBitrate);
2800 // The start bitrate should be kept (-1) and capped to the max bitrate.
2801 // Since this is not an end-to-end call no receiver should have been
2802 // returning a REMB that could lower this estimate.
2803 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002804 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002805 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2806 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002807 // The start bitrate will be whatever the rate BitRateController
2808 // has currently configured but in the span of the set max and min
2809 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002810 }
2811 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002812 init_encode_event_.Set();
2813
pbos@webrtc.org00873182014-11-25 14:03:34 +00002814 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2815 maxPayloadSize);
2816 }
2817
Erik Språng566124a2018-04-23 12:32:22 +02002818 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Erik Språng08127a92016-11-16 16:41:30 +01002819 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002820 {
2821 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002822 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2823 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002824 }
Erik Språng08127a92016-11-16 16:41:30 +01002825 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002826 }
2827 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002828 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002829 }
2830
2831 void WaitForSetRates(uint32_t expected_bitrate) {
Niels Möller6bb5ab92019-01-11 11:11:10 +01002832 // Wait for the expected rate to be set. In some cases there can be
2833 // more than one update pending, in which case we keep waiting
2834 // until the correct value has been observed.
2835 const int64_t start_time = rtc::TimeMillis();
2836 do {
2837 rtc::CritScope lock(&crit_);
2838 if (target_bitrate_ == expected_bitrate) {
2839 return;
2840 }
2841 } while (bitrate_changed_event_.Wait(
2842 std::max(int64_t{1}, VideoSendStreamTest::kDefaultTimeoutMs -
2843 (rtc::TimeMillis() - start_time))));
Niels Möller6613f8e2019-01-10 10:30:21 +01002844 rtc::CritScope lock(&crit_);
Niels Möller6bb5ab92019-01-11 11:11:10 +01002845 EXPECT_EQ(target_bitrate_, expected_bitrate)
2846 << "Timed out while waiting encoder rate to be set.";
perkj26091b12016-09-01 01:17:40 -07002847 }
2848
Niels Möllerde8e6e62018-11-13 15:10:33 +01002849 void ModifySenderBitrateConfig(
2850 BitrateConstraints* bitrate_config) override {
2851 bitrate_config->min_bitrate_bps = kMinBitrateKbps * 1000;
2852 bitrate_config->start_bitrate_bps = kStartBitrateKbps * 1000;
2853 bitrate_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002854 }
2855
perkjfa10b552016-10-02 23:45:26 -07002856 class VideoStreamFactory
2857 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2858 public:
2859 explicit VideoStreamFactory(int min_bitrate_bps)
2860 : min_bitrate_bps_(min_bitrate_bps) {}
2861
2862 private:
2863 std::vector<VideoStream> CreateEncoderStreams(
2864 int width,
2865 int height,
2866 const VideoEncoderConfig& encoder_config) override {
2867 std::vector<VideoStream> streams =
2868 test::CreateVideoStreams(width, height, encoder_config);
2869 streams[0].min_bitrate_bps = min_bitrate_bps_;
2870 return streams;
2871 }
2872
2873 const int min_bitrate_bps_;
2874 };
2875
stefanff483612015-12-21 03:14:00 -08002876 void ModifyVideoConfigs(
2877 VideoSendStream::Config* send_config,
2878 std::vector<VideoReceiveStream::Config>* receive_configs,
2879 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002880 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002881 // Set bitrates lower/higher than min/max to make sure they are properly
2882 // capped.
perkjfa10b552016-10-02 23:45:26 -07002883 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2884 // Create a new StreamFactory to be able to set
2885 // |VideoStream.min_bitrate_bps|.
2886 encoder_config->video_stream_factory =
2887 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002888 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002889 }
2890
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002891 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002892 call_ = sender_call;
2893 }
2894
stefanff483612015-12-21 03:14:00 -08002895 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002896 VideoSendStream* send_stream,
2897 const std::vector<VideoReceiveStream*>& receive_streams) override {
2898 send_stream_ = send_stream;
2899 }
2900
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002901 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002902 ASSERT_TRUE(
2903 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002904 << "Timed out while waiting for encoder to be configured.";
2905 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002906 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002907 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2908 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002909 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002910 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2911 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002912 });
perkj26091b12016-09-01 01:17:40 -07002913 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2914 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002915 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002916 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002917 ASSERT_TRUE(
2918 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002919 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002920 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002921 WaitForSetRates(kLowerMaxBitrateKbps);
2922
2923 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2924 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2925 ASSERT_TRUE(
2926 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002927 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002928 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002929 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002930 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002931 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002932 }
2933
eladalon413ee9a2017-08-22 04:02:52 -07002934 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002935 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002936 rtc::Event bitrate_changed_event_;
2937 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002938 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002939
pbos@webrtc.org00873182014-11-25 14:03:34 +00002940 int num_initializations_;
2941 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002942 webrtc::VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002943 test::VideoEncoderProxyFactory encoder_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002944 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002945 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002946
stefane74eef12016-01-08 06:47:13 -08002947 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002948}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002949
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002950TEST_P(VideoSendStreamTest, ReportsSentResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002951 static const size_t kNumStreams = 3;
2952 // Unusual resolutions to make sure that they are the ones being reported.
2953 static const struct {
2954 int width;
2955 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02002956 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002957 class ScreencastTargetBitrateTest : public test::SendTest,
2958 public test::FakeEncoder {
2959 public:
2960 ScreencastTargetBitrateTest()
2961 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002962 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02002963 send_stream_(nullptr),
2964 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002965
2966 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002967 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002968 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002969 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002970 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002971 specifics.codecType = kVideoCodecGeneric;
2972
2973 uint8_t buffer[16] = {0};
2974 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
Niels Möller23775882018-08-16 10:24:12 +02002975 encoded.SetTimestamp(input_image.timestamp());
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002976 encoded.capture_time_ms_ = input_image.render_time_ms();
2977
2978 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002979 encoded._frameType = (*frame_types)[i];
2980 encoded._encodedWidth = kEncodedResolution[i].width;
2981 encoded._encodedHeight = kEncodedResolution[i].height;
Niels Möllerd3b8c632018-08-27 15:33:42 +02002982 encoded.SetSpatialIndex(i);
brandtre78d2662017-01-16 05:57:16 -08002983 EncodedImageCallback* callback;
2984 {
2985 rtc::CritScope cs(&crit_sect_);
2986 callback = callback_;
2987 }
2988 RTC_DCHECK(callback);
2989 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002990 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002991 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002992 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002993 }
2994
Peter Boström5811a392015-12-10 13:02:50 +01002995 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002996 return 0;
2997 }
stefanff483612015-12-21 03:14:00 -08002998 void ModifyVideoConfigs(
2999 VideoSendStream::Config* send_config,
3000 std::vector<VideoReceiveStream::Config>* receive_configs,
3001 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003002 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003003 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003004 }
3005
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003006 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003007
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003008 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003009 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003010 << "Timed out while waiting for the encoder to send one frame.";
3011 VideoSendStream::Stats stats = send_stream_->GetStats();
3012
3013 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003014 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003015 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003016 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003017 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003018 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003019 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003020 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3021 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003022 }
3023 }
3024
stefanff483612015-12-21 03:14:00 -08003025 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003026 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003027 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003028 send_stream_ = send_stream;
3029 }
3030
3031 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003032 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003033 } test;
3034
stefane74eef12016-01-08 06:47:13 -08003035 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003036}
philipel0f9af012015-09-01 07:01:51 -07003037
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003038#if defined(RTC_ENABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003039class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003040 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003041 Vp9HeaderObserver()
3042 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003043 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003044 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3045 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003046 frames_sent_(0),
3047 expected_width_(0),
3048 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003049
stefanff483612015-12-21 03:14:00 -08003050 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003051 VideoSendStream::Config* send_config,
3052 std::vector<VideoReceiveStream::Config>* receive_configs,
3053 VideoEncoderConfig* encoder_config) {}
3054
Åsa Perssonff24c042015-12-04 10:58:08 +01003055 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003056
3057 private:
minyue20c84cc2017-04-10 16:57:57 -07003058 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003059
stefanff483612015-12-21 03:14:00 -08003060 void ModifyVideoConfigs(
3061 VideoSendStream::Config* send_config,
3062 std::vector<VideoReceiveStream::Config>* receive_configs,
3063 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003064 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003065 send_config->rtp.payload_name = "VP9";
3066 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003067 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003068 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003069 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003070 EXPECT_EQ(1u, encoder_config->number_of_streams);
Åsa Perssond34597c2018-10-22 17:34:02 +02003071 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
3072 encoder_config->simulcast_layers[0].num_temporal_layers =
3073 vp9_settings_.numberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07003074 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003075 }
3076
perkjfa10b552016-10-02 23:45:26 -07003077 void ModifyVideoCaptureStartResolution(int* width,
3078 int* height,
3079 int* frame_rate) override {
3080 expected_width_ = *width;
3081 expected_height_ = *height;
3082 }
3083
philipel0f9af012015-09-01 07:01:51 -07003084 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003085 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3086 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003087 }
3088
3089 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3090 RTPHeader header;
3091 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3092
Åsa Perssonff24c042015-12-04 10:58:08 +01003093 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3094 const uint8_t* payload = packet + header.headerLength;
3095 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003096
Åsa Perssonff24c042015-12-04 10:58:08 +01003097 bool new_packet = packets_sent_ == 0 ||
3098 IsNewerSequenceNumber(header.sequenceNumber,
3099 last_header_.sequenceNumber);
3100 if (payload_length > 0 && new_packet) {
3101 RtpDepacketizer::ParsedPayload parsed;
3102 RtpDepacketizerVp9 depacketizer;
3103 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003104 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003105 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003106 const auto& vp9_header =
3107 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3108 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003109 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003110 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003111 InspectHeader(vp9_header);
philipel0f9af012015-09-01 07:01:51 -07003112
Åsa Perssonff24c042015-12-04 10:58:08 +01003113 ++packets_sent_;
3114 if (header.markerBit) {
3115 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003116 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003117 last_header_ = header;
philipel29d88462018-08-08 14:26:00 +02003118 last_vp9_ = vp9_header;
philipel0f9af012015-09-01 07:01:51 -07003119 }
philipel0f9af012015-09-01 07:01:51 -07003120 return SEND_PACKET;
3121 }
3122
philipel7fabd462015-09-03 04:42:32 -07003123 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003124 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3125 if (last_vp9_.picture_id > vp9.picture_id) {
3126 return vp9.picture_id == 0; // Wrap.
3127 } else {
3128 return vp9.picture_id == last_vp9_.picture_id + 1;
3129 }
3130 }
3131
3132 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003133 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3134 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3135 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3136 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3137 vp9.spatial_idx);
3138 }
3139
3140 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3141 uint8_t num_layers) const {
3142 switch (num_layers) {
3143 case 0:
3144 VerifyTemporalLayerStructure0(vp9);
3145 break;
3146 case 1:
3147 VerifyTemporalLayerStructure1(vp9);
3148 break;
3149 case 2:
3150 VerifyTemporalLayerStructure2(vp9);
3151 break;
3152 case 3:
3153 VerifyTemporalLayerStructure3(vp9);
3154 break;
3155 default:
3156 RTC_NOTREACHED();
3157 }
3158 }
3159
3160 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3161 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3162 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3163 EXPECT_FALSE(vp9.temporal_up_switch);
3164 }
3165
3166 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3167 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3168 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3169 EXPECT_FALSE(vp9.temporal_up_switch);
3170 }
3171
3172 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3173 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3174 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3175 EXPECT_LE(vp9.temporal_idx, 1);
3176 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3177 if (IsNewPictureId(vp9)) {
3178 uint8_t expected_tid =
3179 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3180 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3181 }
3182 }
3183
3184 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3185 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3186 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3187 EXPECT_LE(vp9.temporal_idx, 2);
3188 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3189 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3190 switch (vp9.temporal_idx) {
3191 case 0:
3192 EXPECT_EQ(2, last_vp9_.temporal_idx);
3193 EXPECT_FALSE(vp9.temporal_up_switch);
3194 break;
3195 case 1:
3196 EXPECT_EQ(2, last_vp9_.temporal_idx);
3197 EXPECT_TRUE(vp9.temporal_up_switch);
3198 break;
3199 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003200 EXPECT_LT(last_vp9_.temporal_idx, 2);
3201 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003202 break;
3203 }
3204 }
3205 }
3206
3207 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3208 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3209 return;
3210
3211 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3212 if (vp9.temporal_idx == 0)
3213 ++expected_tl0_idx;
3214 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3215 }
3216
3217 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3218 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3219 }
3220
3221 // Flexible mode (F=1): Non-flexible mode (F=0):
3222 //
3223 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3224 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3225 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3226 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3227 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3228 // M: | EXTENDED PID | M: | EXTENDED PID |
3229 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3230 // L: | T |U| S |D| L: | T |U| S |D|
3231 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3232 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3233 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3234 // X: |EXTENDED P_DIFF| V: | SS .. |
3235 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3236 // V: | SS .. |
3237 // +-+-+-+-+-+-+-+-+
3238 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3239 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3240 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3241 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003242
3243 if (vp9_settings_.numberOfSpatialLayers > 1) {
3244 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3245 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3246 EXPECT_EQ(vp9.spatial_idx, 0);
3247 } else {
3248 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3249 }
3250
3251 if (vp9_settings_.numberOfTemporalLayers > 1) {
3252 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3253 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3254 EXPECT_EQ(vp9.temporal_idx, 0);
3255 } else {
3256 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3257 }
3258
Åsa Perssonff24c042015-12-04 10:58:08 +01003259 if (vp9.ss_data_available) // V
3260 VerifySsData(vp9);
3261
3262 if (frames_sent_ == 0)
3263 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3264
3265 if (!vp9.inter_pic_predicted) {
3266 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3267 EXPECT_FALSE(vp9.temporal_up_switch);
3268 }
3269 }
3270
3271 // Scalability structure (SS).
3272 //
3273 // +-+-+-+-+-+-+-+-+
3274 // V: | N_S |Y|G|-|-|-|
3275 // +-+-+-+-+-+-+-+-+
3276 // Y: | WIDTH | N_S + 1 times
3277 // +-+-+-+-+-+-+-+-+
3278 // | HEIGHT |
3279 // +-+-+-+-+-+-+-+-+
3280 // G: | N_G |
3281 // +-+-+-+-+-+-+-+-+
3282 // N_G: | T |U| R |-|-| N_G times
3283 // +-+-+-+-+-+-+-+-+
3284 // | P_DIFF | R times
3285 // +-+-+-+-+-+-+-+-+
3286 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3287 EXPECT_TRUE(vp9.ss_data_available); // V
3288 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3289 vp9.num_spatial_layers);
3290 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003291 int expected_width = expected_width_;
3292 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003293 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003294 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3295 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3296 expected_width /= 2;
3297 expected_height /= 2;
3298 }
3299 }
3300
3301 void CompareConsecutiveFrames(const RTPHeader& header,
3302 const RTPVideoHeader& video) const {
philipel29d88462018-08-08 14:26:00 +02003303 const auto& vp9_header =
3304 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003305
3306 bool new_frame = packets_sent_ == 0 ||
3307 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003308 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003309 if (!new_frame) {
3310 EXPECT_FALSE(last_header_.markerBit);
3311 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003312 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3313 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3314 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3315 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003316 return;
3317 }
3318 // New frame.
philipel29d88462018-08-08 14:26:00 +02003319 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003320
3321 // Compare with last packet in previous frame.
3322 if (frames_sent_ == 0)
3323 return;
3324 EXPECT_TRUE(last_vp9_.end_of_frame);
3325 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003326 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3327 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003328 }
3329
Niels Möller4db138e2018-04-19 09:04:13 +02003330 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003331 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003332 webrtc::VideoEncoderConfig encoder_config_;
3333 RTPHeader last_header_;
3334 RTPVideoHeaderVP9 last_vp9_;
3335 size_t packets_sent_;
3336 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003337 int expected_width_;
3338 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003339};
3340
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003341TEST_P(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003342 const uint8_t kNumTemporalLayers = 1;
3343 const uint8_t kNumSpatialLayers = 1;
3344 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3345}
3346
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003347TEST_P(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003348 const uint8_t kNumTemporalLayers = 2;
3349 const uint8_t kNumSpatialLayers = 1;
3350 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3351}
3352
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003353TEST_P(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003354 const uint8_t kNumTemporalLayers = 3;
3355 const uint8_t kNumSpatialLayers = 1;
3356 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3357}
3358
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003359TEST_P(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003360 const uint8_t kNumTemporalLayers = 1;
3361 const uint8_t kNumSpatialLayers = 2;
3362 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3363}
3364
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003365TEST_P(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003366 const uint8_t kNumTemporalLayers = 2;
3367 const uint8_t kNumSpatialLayers = 2;
3368 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3369}
3370
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003371TEST_P(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003372 const uint8_t kNumTemporalLayers = 3;
3373 const uint8_t kNumSpatialLayers = 2;
3374 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3375}
3376
3377void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3378 uint8_t num_spatial_layers) {
3379 static const size_t kNumFramesToSend = 100;
3380 // Set to < kNumFramesToSend and coprime to length of temporal layer
3381 // structures to verify temporal id reset on key frame.
3382 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003383
3384 static const int kWidth = kMinVp9SpatialLayerWidth;
3385 static const int kHeight = kMinVp9SpatialLayerHeight;
3386 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003387 class NonFlexibleMode : public Vp9HeaderObserver {
3388 public:
3389 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3390 : num_temporal_layers_(num_temporal_layers),
3391 num_spatial_layers_(num_spatial_layers),
3392 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003393
stefanff483612015-12-21 03:14:00 -08003394 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003395 VideoSendStream::Config* send_config,
3396 std::vector<VideoReceiveStream::Config>* receive_configs,
3397 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003398 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003399 int bitrate_bps = 0;
3400 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3401 const int width = kWidth << sl_idx;
3402 const int height = kHeight << sl_idx;
3403 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3404 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3405 }
3406 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3407
Åsa Perssonff24c042015-12-04 10:58:08 +01003408 vp9_settings_.flexibleMode = false;
3409 vp9_settings_.frameDroppingOn = false;
3410 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3411 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3412 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003413 }
3414
Sergey Silkin86684962018-03-28 19:32:37 +02003415 void ModifyVideoCaptureStartResolution(int* width,
3416 int* height,
3417 int* frame_rate) override {
3418 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3419 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3420 *width = expected_width_;
3421 *height = expected_height_;
3422 }
3423
Åsa Perssonff24c042015-12-04 10:58:08 +01003424 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003425 bool ss_data_expected =
3426 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3427 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003428 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003429 if (num_spatial_layers_ > 1) {
3430 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3431 } else {
3432 EXPECT_FALSE(vp9.inter_layer_predicted);
3433 }
3434
asapersson38bb8ad2015-12-14 01:41:19 -08003435 EXPECT_EQ(!vp9.inter_pic_predicted,
3436 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003437
3438 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003439 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3440 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3441 } else {
3442 EXPECT_EQ(0, vp9.spatial_idx);
3443 }
3444 if (num_spatial_layers_ > 1)
3445 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003446 }
3447
3448 VerifyFixedTemporalLayerStructure(vp9,
3449 l_field_ ? num_temporal_layers_ : 0);
3450
3451 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003452 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003453 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003454 const uint8_t num_temporal_layers_;
3455 const uint8_t num_spatial_layers_;
3456 const bool l_field_;
3457 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003458
stefane74eef12016-01-08 06:47:13 -08003459 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003460}
3461
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003462TEST_P(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
asaperssond9f641e2016-01-21 01:11:35 -08003463 static const size_t kNumFramesToSend = 50;
3464 static const int kWidth = 4;
3465 static const int kHeight = 4;
3466 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3467 void ModifyVideoConfigsHook(
3468 VideoSendStream::Config* send_config,
3469 std::vector<VideoReceiveStream::Config>* receive_configs,
3470 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003471 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003472 vp9_settings_.flexibleMode = false;
3473 vp9_settings_.numberOfTemporalLayers = 1;
3474 vp9_settings_.numberOfSpatialLayers = 1;
3475
perkjfa10b552016-10-02 23:45:26 -07003476 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003477 }
3478
3479 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3480 if (frames_sent_ > kNumFramesToSend)
3481 observation_complete_.Set();
3482 }
perkjfa10b552016-10-02 23:45:26 -07003483
3484 void ModifyVideoCaptureStartResolution(int* width,
3485 int* height,
3486 int* frame_rate) override {
3487 expected_width_ = kWidth;
3488 expected_height_ = kHeight;
3489 *width = kWidth;
3490 *height = kHeight;
3491 }
asaperssond9f641e2016-01-21 01:11:35 -08003492 } test;
3493
3494 RunBaseTest(&test);
3495}
3496
kjellanderf9e2a362017-03-24 12:17:33 -07003497#if defined(WEBRTC_ANDROID)
3498// Crashes on Android; bugs.webrtc.org/7401
3499#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3500#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003501// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3502// the test after webrtc:9270 is implemented.
3503#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3504// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003505#endif
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003506TEST_P(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003507 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003508 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003509 VideoSendStream::Config* send_config,
3510 std::vector<VideoReceiveStream::Config>* receive_configs,
3511 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003512 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003513 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003514 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003515 vp9_settings_.numberOfTemporalLayers = 1;
3516 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003517 }
3518
Åsa Perssonff24c042015-12-04 10:58:08 +01003519 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3520 EXPECT_TRUE(vp9_header.flexible_mode);
3521 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3522 if (vp9_header.inter_pic_predicted) {
3523 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003524 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003525 }
3526 }
3527 } test;
3528
stefane74eef12016-01-08 06:47:13 -08003529 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003530}
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003531#endif // defined(RTC_ENABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003532
perkj803d97f2016-11-01 11:45:46 -07003533void VideoSendStreamTest::TestRequestSourceRotateVideo(
3534 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003535 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003536
3537 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003538 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003539 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003540 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003541 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003542 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3543 }
3544
3545 CreateVideoStreams();
3546 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003547 GetVideoSendStream()->SetSource(&forwarder,
3548 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003549
3550 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3551 support_orientation_ext);
3552
3553 DestroyStreams();
3554}
3555
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003556TEST_P(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003557 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3558 TestRequestSourceRotateVideo(false);
3559}
3560
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003561TEST_P(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003562 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3563 TestRequestSourceRotateVideo(true);
3564}
3565
Åsa Perssonf06bacc2018-10-12 11:07:20 +02003566TEST_P(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) {
3567 static const int kMaxFps = 22;
3568 class FpsObserver : public test::SendTest,
3569 public test::FrameGeneratorCapturer::SinkWantsObserver {
3570 public:
3571 FpsObserver() : SendTest(kDefaultTimeoutMs) {}
3572
3573 void OnFrameGeneratorCapturerCreated(
3574 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3575 frame_generator_capturer->SetSinkWantsObserver(this);
3576 }
3577
3578 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
3579 const rtc::VideoSinkWants& wants) override {
3580 if (wants.max_framerate_fps == kMaxFps)
3581 observation_complete_.Set();
3582 }
3583
3584 void ModifyVideoConfigs(
3585 VideoSendStream::Config* send_config,
3586 std::vector<VideoReceiveStream::Config>* receive_configs,
3587 VideoEncoderConfig* encoder_config) override {
3588 encoder_config->simulcast_layers[0].max_framerate = kMaxFps;
3589 }
3590
3591 void PerformTest() override {
3592 EXPECT_TRUE(Wait()) << "Timed out while waiting for fps to be reported.";
3593 }
3594 } test;
3595
3596 RunBaseTest(&test);
3597}
3598
michaelta3328772016-11-29 09:25:03 -08003599// This test verifies that overhead is removed from the bandwidth estimate by
3600// testing that the maximum possible target payload rate is smaller than the
3601// maximum bandwidth estimate by the overhead rate.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003602TEST_P(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003603 test::ScopedFieldTrials override_field_trials(
3604 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3605 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3606 public test::FakeEncoder {
3607 public:
eladalon413ee9a2017-08-22 04:02:52 -07003608 explicit RemoveOverheadFromBandwidthTest(
3609 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003610 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3611 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003612 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003613 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003614 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003615 max_bitrate_bps_(0),
Niels Möllerc572ff32018-11-07 08:43:50 +01003616 first_packet_sent_(false) {}
michaelta3328772016-11-29 09:25:03 -08003617
Erik Språng566124a2018-04-23 12:32:22 +02003618 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
michaelta3328772016-11-29 09:25:03 -08003619 uint32_t frameRate) override {
3620 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003621 // Wait for the first sent packet so that videosendstream knows
3622 // rtp_overhead.
3623 if (first_packet_sent_) {
3624 max_bitrate_bps_ = bitrate.get_sum_bps();
3625 bitrate_changed_event_.Set();
3626 }
michaelta3328772016-11-29 09:25:03 -08003627 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3628 }
3629
3630 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3631 call_ = sender_call;
3632 }
3633
3634 void ModifyVideoConfigs(
3635 VideoSendStream::Config* send_config,
3636 std::vector<VideoReceiveStream::Config>* receive_configs,
3637 VideoEncoderConfig* encoder_config) override {
3638 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003639 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003640 EXPECT_FALSE(send_config->rtp.extensions.empty());
3641 }
3642
michaelt192132e2017-01-26 09:05:27 -08003643 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3644 rtc::CritScope lock(&crit_);
3645 first_packet_sent_ = true;
3646 return SEND_PACKET;
3647 }
3648
michaelta3328772016-11-29 09:25:03 -08003649 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003650 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003651 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003652 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003653 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003654 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3655 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003656 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003657 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003658 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3659 bitrate_config);
Stefan Holmer64be7fa2018-10-04 15:21:55 +02003660 call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
eladalon413ee9a2017-08-22 04:02:52 -07003661 });
michaelta3328772016-11-29 09:25:03 -08003662
3663 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003664 // overhead of 40B per packet video produces 2240bps overhead.
3665 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003666 EXPECT_TRUE(
3667 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003668 {
3669 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003670 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003671 }
3672 }
3673
3674 private:
eladalon413ee9a2017-08-22 04:02:52 -07003675 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003676 test::VideoEncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003677 Call* call_;
3678 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003679 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3680 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003681 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003682 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003683 RunBaseTest(&test);
3684}
3685
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003686TEST_P(VideoSendStreamTest, SendsKeepAlive) {
sprang168794c2017-07-06 04:38:06 -07003687 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003688
3689 class KeepaliveObserver : public test::SendTest {
3690 public:
3691 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3692
sprangdb2a9fc2017-08-09 06:42:32 -07003693 void OnRtpTransportControllerSendCreated(
3694 RtpTransportControllerSend* controller) override {
3695 RtpKeepAliveConfig config;
3696 config.timeout_interval_ms = kTimeoutMs;
3697 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3698 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003699 }
3700
sprang168794c2017-07-06 04:38:06 -07003701 private:
3702 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3703 RTPHeader header;
3704 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3705
sprangd2702ef2017-07-10 08:41:10 -07003706 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003707 // The video stream has started. Stop it now.
3708 if (capturer_)
3709 capturer_->Stop();
3710 } else {
3711 observation_complete_.Set();
3712 }
3713
3714 return SEND_PACKET;
3715 }
3716
sprang168794c2017-07-06 04:38:06 -07003717 void PerformTest() override {
3718 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3719 }
3720
3721 void OnFrameGeneratorCapturerCreated(
3722 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3723 capturer_ = frame_generator_capturer;
3724 }
3725
3726 test::FrameGeneratorCapturer* capturer_ = nullptr;
3727 } test;
3728
3729 RunBaseTest(&test);
3730}
3731
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003732class PacingFactorObserver : public test::SendTest {
3733 public:
3734 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003735 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003736 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3737 configure_send_side_(configure_send_side),
3738 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003739
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003740 void ModifyVideoConfigs(
3741 VideoSendStream::Config* send_config,
3742 std::vector<VideoReceiveStream::Config>* receive_configs,
3743 VideoEncoderConfig* encoder_config) override {
3744 // Check if send-side bwe extension is already present, and remove it if
3745 // it is not desired.
3746 bool has_send_side = false;
3747 for (auto it = send_config->rtp.extensions.begin();
3748 it != send_config->rtp.extensions.end(); ++it) {
3749 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3750 if (configure_send_side_) {
3751 has_send_side = true;
3752 } else {
3753 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003754 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003755 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003756 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003757 }
3758
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003759 if (configure_send_side_ && !has_send_side) {
3760 // Want send side, not present by default, so add it.
3761 send_config->rtp.extensions.emplace_back(
3762 RtpExtension::kTransportSequenceNumberUri,
3763 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003764 }
3765
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003766 // ALR only enabled for screenshare.
3767 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3768 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003769
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003770 void OnVideoStreamsCreated(
3771 VideoSendStream* send_stream,
3772 const std::vector<VideoReceiveStream*>& receive_streams) override {
3773 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3774 // Video streams created, check that pacing factor is correctly configured.
3775 EXPECT_EQ(expected_pacing_factor_,
3776 internal_send_peer.GetPacingFactorOverride());
3777 observation_complete_.Set();
3778 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003779
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003780 void PerformTest() override {
3781 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3782 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003783
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003784 private:
3785 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003786 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003787};
3788
3789std::string GetAlrProbingExperimentString() {
3790 return std::string(
3791 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3792 "/1.0,2875,80,40,-60,3/";
3793}
3794const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3795
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003796TEST_P(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003797 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003798 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003799 PacingFactorObserver test_with_send_side(true,
3800 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003801 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003802}
Erik Språng7c8cca32017-10-24 17:05:18 +02003803
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003804TEST_P(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003805 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3806 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003807 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003808 RunBaseTest(&test_without_send_side);
3809}
3810
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003811// Test class takes as argument a function pointer to reset the send
3812// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3813// change the content type of a VideoSendStream, you need to recreate it.
3814// Stopping and recreating the stream can only be done on the main thread and in
3815// the context of VideoSendStreamTest (not BaseTest). The test switches from
3816// realtime to screenshare and back.
3817template <typename T>
3818class ContentSwitchTest : public test::SendTest {
3819 public:
3820 enum class StreamState {
3821 kBeforeSwitch = 0,
3822 kInScreenshare = 1,
3823 kAfterSwitchBack = 2,
3824 };
3825 static const uint32_t kMinPacketsToSend = 50;
3826
3827 explicit ContentSwitchTest(T* stream_reset_fun)
3828 : SendTest(test::CallTest::kDefaultTimeoutMs),
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003829 call_(nullptr),
3830 state_(StreamState::kBeforeSwitch),
3831 send_stream_(nullptr),
3832 send_stream_config_(nullptr),
3833 packets_sent_(0),
3834 stream_resetter_(stream_reset_fun) {
3835 RTC_DCHECK(stream_resetter_);
3836 }
3837
3838 void OnVideoStreamsCreated(
3839 VideoSendStream* send_stream,
3840 const std::vector<VideoReceiveStream*>& receive_streams) override {
3841 rtc::CritScope lock(&crit_);
3842 send_stream_ = send_stream;
3843 }
3844
3845 void ModifyVideoConfigs(
3846 VideoSendStream::Config* send_config,
3847 std::vector<VideoReceiveStream::Config>* receive_configs,
3848 VideoEncoderConfig* encoder_config) override {
3849 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3850 encoder_config->min_transmit_bitrate_bps = 0;
3851 encoder_config->content_type =
3852 VideoEncoderConfig::ContentType::kRealtimeVideo;
3853 send_stream_config_ = send_config->Copy();
3854 encoder_config_ = encoder_config->Copy();
3855 }
3856
3857 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3858 call_ = sender_call;
3859 }
3860
3861 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3862 rtc::CritScope lock(&crit_);
3863
3864 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3865 float pacing_factor =
3866 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3867 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3868 if (send_stream_->GetStats().content_type ==
3869 webrtc::VideoContentType::SCREENSHARE) {
3870 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3871 }
3872
3873 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3874
3875 // Wait until at least kMinPacketsToSend packets to be sent, so that
3876 // some frames would be encoded.
3877 if (++packets_sent_ < kMinPacketsToSend)
3878 return SEND_PACKET;
3879
3880 if (state_ != StreamState::kAfterSwitchBack) {
3881 // We've sent kMinPacketsToSend packets, switch the content type and move
3882 // move to the next state.
3883 // Note that we need to recreate the stream if changing content type.
3884 packets_sent_ = 0;
3885 if (encoder_config_.content_type ==
3886 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3887 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3888 } else {
3889 encoder_config_.content_type =
3890 VideoEncoderConfig::ContentType::kRealtimeVideo;
3891 }
3892 switch (state_) {
3893 case StreamState::kBeforeSwitch:
3894 state_ = StreamState::kInScreenshare;
3895 break;
3896 case StreamState::kInScreenshare:
3897 state_ = StreamState::kAfterSwitchBack;
3898 break;
3899 case StreamState::kAfterSwitchBack:
3900 RTC_NOTREACHED();
3901 break;
3902 }
3903 content_switch_event_.Set();
3904 return SEND_PACKET;
3905 }
3906
3907 observation_complete_.Set();
3908 return SEND_PACKET;
3909 }
3910
3911 void PerformTest() override {
3912 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3913 ASSERT_TRUE(
3914 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3915 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3916 }
3917
3918 ASSERT_TRUE(Wait())
3919 << "Timed out waiting for a frame sent after switch back";
3920 }
3921
3922 private:
3923 StreamState GetStreamState() {
3924 rtc::CritScope lock(&crit_);
3925 return state_;
3926 }
3927
3928 rtc::CriticalSection crit_;
3929 rtc::Event content_switch_event_;
3930 Call* call_;
3931 StreamState state_ RTC_GUARDED_BY(crit_);
3932 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3933 VideoSendStream::Config send_stream_config_;
3934 VideoEncoderConfig encoder_config_;
3935 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3936 T* stream_resetter_;
3937};
3938
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003939TEST_P(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003940 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3941 const VideoEncoderConfig& encoder_config,
3942 test::BaseTest* test) {
3943 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3944 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003945 DestroyVideoSendStreams();
3946 SetVideoSendConfig(send_stream_config);
3947 SetVideoEncoderConfig(encoder_config);
3948 CreateVideoSendStreams();
3949 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3950 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003951 Start();
3952 });
3953 };
3954 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3955 RunBaseTest(&test);
3956}
3957
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003958} // namespace webrtc