blob: c015f56142c94120bbc923bee3954984ce11a760 [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
Artem Titov46c4e602018-08-17 14:26:54 +020014#include "api/test/simulated_network.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "call/call.h"
Artem Titov4e199e92018-08-20 13:30:39 +020016#include "call/fake_network_pipe.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "call/rtp_transport_controller_send.h"
Artem Titov4e199e92018-08-20 13:30:39 +020018#include "call/simulated_network.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "common_video/include/frame_callback.h"
20#include "common_video/include/video_frame.h"
21#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/encoder_proxy_factory.h"
40#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "test/fake_texture_frame.h"
42#include "test/field_trial.h"
43#include "test/frame_generator.h"
44#include "test/frame_generator_capturer.h"
45#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010046#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020047#include "test/gtest.h"
48#include "test/null_transport.h"
49#include "test/rtcp_packet_parser.h"
50#include "test/testsupport/perf_test.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
Yves Gerey665174f2018-06-19 15:03:05 +020073enum VideoFormat {
74 kGeneric,
75 kVP8,
76};
sprang@webrtc.org346094c2014-02-18 08:40:33 +000077
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070078void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
79 const std::vector<VideoFrame>& frames2);
80VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000081
Sebastian Janssonc714b6e2018-08-30 15:45:41 +020082class VideoSendStreamTest : public test::CallTest,
83 public testing::WithParamInterface<std::string> {
84 public:
85 VideoSendStreamTest() : field_trial_(GetParam()) {}
86
pbos@webrtc.org013d9942013-08-22 09:42:17 +000087 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000088 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000089 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000090 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010091
92 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
93 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070094
95 void TestRequestSourceRotateVideo(bool support_orientation_ext);
Sebastian Janssonc714b6e2018-08-30 15:45:41 +020096
97 private:
98 test::ScopedFieldTrials field_trial_;
pbos@webrtc.org013d9942013-08-22 09:42:17 +000099};
100
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200101INSTANTIATE_TEST_CASE_P(Default, VideoSendStreamTest, ::testing::Values(""));
102
103INSTANTIATE_TEST_CASE_P(
104 TaskQueueTrial,
105 VideoSendStreamTest,
106 ::testing::Values("WebRTC-TaskQueueCongestionControl/Enabled/"));
107
108TEST_P(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700109 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200110 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000111
eladalon413ee9a2017-08-22 04:02:52 -0700112 test::NullTransport transport;
113 CreateSendConfig(1, 0, 0, &transport);
114 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200115 GetVideoSendStream()->Start();
116 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700117 DestroyStreams();
118 DestroyCalls();
119 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000120}
121
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200122TEST_P(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700123 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200124 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000125
eladalon413ee9a2017-08-22 04:02:52 -0700126 test::NullTransport transport;
127 CreateSendConfig(1, 0, 0, &transport);
128 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200129 GetVideoSendStream()->Stop();
130 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700131 DestroyStreams();
132 DestroyCalls();
133 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000134}
135
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200136TEST_P(VideoSendStreamTest, SupportsCName) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000137 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000138 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000139 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000140 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000141
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000142 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000143 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700144 test::RtcpPacketParser parser;
145 EXPECT_TRUE(parser.Parse(packet, length));
146 if (parser.sdes()->num_packets() > 0) {
147 EXPECT_EQ(1u, parser.sdes()->chunks().size());
148 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000149
danilchap3dc929e2016-11-02 08:21:59 -0700150 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000151 }
152
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000153 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000154 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000155
stefanff483612015-12-21 03:14:00 -0800156 void ModifyVideoConfigs(
157 VideoSendStream::Config* send_config,
158 std::vector<VideoReceiveStream::Config>* receive_configs,
159 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000160 send_config->rtp.c_name = kCName;
161 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000162
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000163 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100164 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000165 }
166 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000167
stefane74eef12016-01-08 06:47:13 -0800168 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000169}
170
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200171TEST_P(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000172 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000173 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000174 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000175 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100176 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000177 }
178
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000179 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000180 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000181 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000182
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000183 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
184 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
185 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700186 if (header.extension.absoluteSendTime != 0) {
187 // Wait for at least one packet with a non-zero send time. The send time
188 // is a 16-bit value derived from the system clock, and it is valid
189 // for a packet to have a zero send time. To tell that from an
190 // unpopulated value we'll wait for a packet with non-zero send time.
191 observation_complete_.Set();
192 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100193 RTC_LOG(LS_WARNING)
194 << "Got a packet with zero absoluteSendTime, waiting"
195 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700196 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000197
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000198 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000199 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000200
stefanff483612015-12-21 03:14:00 -0800201 void ModifyVideoConfigs(
202 VideoSendStream::Config* send_config,
203 std::vector<VideoReceiveStream::Config>* receive_configs,
204 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200205 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100206 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700207 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000208 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000209
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000210 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100211 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000212 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000213 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000214
stefane74eef12016-01-08 06:47:13 -0800215 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000216}
217
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200218TEST_P(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000219 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000220 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000221 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000222 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200223 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200224 return absl::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200225 Clock::GetRealTimeClock(), kEncodeDelayMs);
226 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000227 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100228 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000229 }
230
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000231 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000232 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000233 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000234 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000235
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000236 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
237 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000238 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000239 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100240 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000241
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000242 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000243 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000244
stefanff483612015-12-21 03:14:00 -0800245 void ModifyVideoConfigs(
246 VideoSendStream::Config* send_config,
247 std::vector<VideoReceiveStream::Config>* receive_configs,
248 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200249 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100250 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700251 send_config->rtp.extensions.push_back(RtpExtension(
252 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000253 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000254
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000255 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100256 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000257 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000258
Niels Möller4db138e2018-04-19 09:04:13 +0200259 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000260 } test;
261
stefane74eef12016-01-08 06:47:13 -0800262 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000263}
264
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200265TEST_P(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700266 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700267 class TransportWideSequenceNumberObserver : public test::SendTest {
268 public:
269 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200270 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200271 return absl::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200272 Clock::GetRealTimeClock());
273 }) {
sprang867fb522015-08-03 04:38:41 -0700274 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
275 kRtpExtensionTransportSequenceNumber, kExtensionId));
276 }
277
278 private:
279 Action OnSendRtp(const uint8_t* packet, size_t length) override {
280 RTPHeader header;
281 EXPECT_TRUE(parser_->Parse(packet, length, &header));
282
283 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
284 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
285 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
286
Peter Boström5811a392015-12-10 13:02:50 +0100287 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700288
289 return SEND_PACKET;
290 }
291
stefanff483612015-12-21 03:14:00 -0800292 void ModifyVideoConfigs(
293 VideoSendStream::Config* send_config,
294 std::vector<VideoReceiveStream::Config>* receive_configs,
295 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200296 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700297 }
298
299 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100300 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700301 }
302
Niels Möller4db138e2018-04-19 09:04:13 +0200303 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700304 } test;
305
stefane74eef12016-01-08 06:47:13 -0800306 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700307}
308
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200309TEST_P(VideoSendStreamTest, SupportsVideoRotation) {
perkj803d97f2016-11-01 11:45:46 -0700310 class VideoRotationObserver : public test::SendTest {
311 public:
312 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
313 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
314 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
315 }
316
317 Action OnSendRtp(const uint8_t* packet, size_t length) override {
318 RTPHeader header;
319 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700320 // Only the last packet of the frame is required to have the extension.
321 if (!header.markerBit)
322 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700323 EXPECT_TRUE(header.extension.hasVideoRotation);
324 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
325 observation_complete_.Set();
326 return SEND_PACKET;
327 }
328
329 void ModifyVideoConfigs(
330 VideoSendStream::Config* send_config,
331 std::vector<VideoReceiveStream::Config>* receive_configs,
332 VideoEncoderConfig* encoder_config) override {
333 send_config->rtp.extensions.clear();
334 send_config->rtp.extensions.push_back(RtpExtension(
335 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
336 }
337
338 void OnFrameGeneratorCapturerCreated(
339 test::FrameGeneratorCapturer* frame_generator_capturer) override {
340 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
341 }
342
343 void PerformTest() override {
344 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
345 }
346 } test;
347
348 RunBaseTest(&test);
349}
350
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200351TEST_P(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700352 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700353 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100354 VideoContentTypeObserver()
355 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700356 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
357 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
358 }
359
360 Action OnSendRtp(const uint8_t* packet, size_t length) override {
361 RTPHeader header;
362 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100363 // Only the last packet of the key-frame must have extension.
364 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700365 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100366 // First marker bit seen means that the first frame is sent.
367 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700368 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700369 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
370 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700371 observation_complete_.Set();
372 return SEND_PACKET;
373 }
374
375 void ModifyVideoConfigs(
376 VideoSendStream::Config* send_config,
377 std::vector<VideoReceiveStream::Config>* receive_configs,
378 VideoEncoderConfig* encoder_config) override {
379 send_config->rtp.extensions.clear();
380 send_config->rtp.extensions.push_back(
381 RtpExtension(RtpExtension::kVideoContentTypeUri,
382 test::kVideoContentTypeExtensionId));
383 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
384 }
385
386 void PerformTest() override {
387 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
388 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100389
390 private:
391 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700392 } test;
393
394 RunBaseTest(&test);
395}
396
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200397TEST_P(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700398 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700399 public:
ilnik10894992017-06-21 08:23:19 -0700400 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700401 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
402 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
403 }
404
405 Action OnSendRtp(const uint8_t* packet, size_t length) override {
406 RTPHeader header;
407 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700408 // Only the last packet of the frame must have extension.
409 if (!header.markerBit)
410 return SEND_PACKET;
411 EXPECT_TRUE(header.extension.has_video_timing);
412 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700413 return SEND_PACKET;
414 }
415
416 void ModifyVideoConfigs(
417 VideoSendStream::Config* send_config,
418 std::vector<VideoReceiveStream::Config>* receive_configs,
419 VideoEncoderConfig* encoder_config) override {
420 send_config->rtp.extensions.clear();
421 send_config->rtp.extensions.push_back(RtpExtension(
422 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
423 }
424
425 void PerformTest() override {
426 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
427 }
428 } test;
429
430 RunBaseTest(&test);
431}
432
danilchap901b2df2017-07-28 08:56:04 -0700433class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000434 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000435 FakeReceiveStatistics(uint32_t send_ssrc,
436 uint32_t last_sequence_number,
437 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700438 uint8_t fraction_lost) {
439 stat_.SetMediaSsrc(send_ssrc);
440 stat_.SetExtHighestSeqNum(last_sequence_number);
441 stat_.SetCumulativeLost(cumulative_lost);
442 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000443 }
444
danilchap901b2df2017-07-28 08:56:04 -0700445 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
446 EXPECT_GE(max_blocks, 1u);
447 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000448 }
449
450 private:
danilchap901b2df2017-07-28 08:56:04 -0700451 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000452};
453
brandtre602f0a2016-10-31 03:40:49 -0700454class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100455 public:
brandtre602f0a2016-10-31 03:40:49 -0700456 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800457 bool use_nack,
458 bool expect_red,
459 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800460 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200461 VideoEncoderFactory* encoder_factory)
brandtr20d45472017-01-02 00:34:27 -0800462 : EndToEndTest(kTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200463 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100464 payload_name_(codec),
465 use_nack_(use_nack),
466 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700467 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800468 sent_media_(false),
469 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800470 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100471
brandtr20d45472017-01-02 00:34:27 -0800472 // Some of the test cases are expected to time out and thus we are using
473 // a shorter timeout window than the default here.
474 static constexpr size_t kTimeoutMs = 10000;
475
Stefan Holmer4654d202015-12-08 09:10:43 +0100476 private:
477 Action OnSendRtp(const uint8_t* packet, size_t length) override {
478 RTPHeader header;
479 EXPECT_TRUE(parser_->Parse(packet, length, &header));
480
Stefan Holmer4654d202015-12-08 09:10:43 +0100481 int encapsulated_payload_type = -1;
482 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100483 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100484 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
485 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100486 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100487 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
488 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100489 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100490 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100491 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
492 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100493 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
494 length) {
495 // Not padding-only, media received outside of RED.
496 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800497 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100498 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100499 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000500
Stefan Holmer4654d202015-12-08 09:10:43 +0100501 if (header_extensions_enabled_) {
502 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
503 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
504 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
505 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
506 // 24 bits wrap.
507 EXPECT_GT(prev_header_.extension.absoluteSendTime,
508 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000509 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100510 EXPECT_GE(header.extension.absoluteSendTime,
511 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200512 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100513 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
514 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
515 prev_header_.extension.transportSequenceNumber;
516 EXPECT_EQ(1, seq_num_diff);
517 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200518
Stefan Holmer4654d202015-12-08 09:10:43 +0100519 if (encapsulated_payload_type != -1) {
520 if (encapsulated_payload_type ==
521 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700522 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800523 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100524 } else {
brandtr65a1e772016-12-12 01:54:58 -0800525 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000526 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000527 }
528
brandtr20d45472017-01-02 00:34:27 -0800529 if (sent_media_ && sent_ulpfec_) {
530 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100531 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000532
Stefan Holmer4654d202015-12-08 09:10:43 +0100533 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000534
Stefan Holmer4654d202015-12-08 09:10:43 +0100535 return SEND_PACKET;
536 }
537
eladalon413ee9a2017-08-22 04:02:52 -0700538 test::PacketTransport* CreateSendTransport(
539 test::SingleThreadedTaskQueueForTesting* task_queue,
540 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100541 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
542 // Configure some network delay.
543 const int kNetworkDelayMs = 100;
Artem Titov46c4e602018-08-17 14:26:54 +0200544 DefaultNetworkSimulationConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800545 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100546 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700547 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700548 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200549 VideoSendStreamTest::payload_type_map_,
550 absl::make_unique<FakeNetworkPipe>(
551 Clock::GetRealTimeClock(),
552 absl::make_unique<SimulatedNetwork>(config)));
Peter Boström39593972016-02-15 11:27:15 +0100553 }
554
stefanff483612015-12-21 03:14:00 -0800555 void ModifyVideoConfigs(
556 VideoSendStream::Config* send_config,
557 std::vector<VideoReceiveStream::Config>* receive_configs,
558 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100559 if (use_nack_) {
560 send_config->rtp.nack.rtp_history_ms =
561 (*receive_configs)[0].rtp.nack.rtp_history_ms =
562 VideoSendStreamTest::kNackRtpHistoryMs;
563 }
Niels Möller4db138e2018-04-19 09:04:13 +0200564 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200565 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700566 send_config->rtp.ulpfec.red_payload_type =
567 VideoSendStreamTest::kRedPayloadType;
568 send_config->rtp.ulpfec.ulpfec_payload_type =
569 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800570 EXPECT_FALSE(send_config->rtp.extensions.empty());
571 if (!header_extensions_enabled_) {
572 send_config->rtp.extensions.clear();
573 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100574 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700575 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100576 }
Niels Möller259a4972018-04-05 15:36:51 +0200577 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700578 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700579 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700580 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700581 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100582 }
583
584 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800585 EXPECT_EQ(expect_ulpfec_, Wait())
586 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100587 }
588
Niels Möller4db138e2018-04-19 09:04:13 +0200589 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800590 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100591 const bool use_nack_;
592 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700593 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800594 bool sent_media_;
595 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100596 bool header_extensions_enabled_;
597 RTPHeader prev_header_;
598};
599
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200600TEST_P(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200601 test::FunctionVideoEncoderFactory encoder_factory(
602 []() { return VP8Encoder::Create(); });
603 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800604 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100605}
606
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200607TEST_P(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200608 test::FunctionVideoEncoderFactory encoder_factory(
609 []() { return VP8Encoder::Create(); });
610 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100611 RunBaseTest(&test);
612}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000613
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200614class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
stefan60e10c72017-08-23 10:40:00 -0700615 protected:
616 VideoSendStreamWithoutUlpfecTest()
617 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
618
619 test::ScopedFieldTrials field_trial_;
620};
621
622TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200623 test::FunctionVideoEncoderFactory encoder_factory(
624 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200625 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700626 RunBaseTest(&test);
627}
628
Peter Boström39593972016-02-15 11:27:15 +0100629// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
630// since we'll still have to re-request FEC packets, effectively wasting
631// bandwidth since the receiver has to wait for FEC retransmissions to determine
632// that the received state is actually decodable.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200633TEST_P(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200634 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200635 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200636 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200637 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100638 RunBaseTest(&test);
639}
640
641// Without retransmissions FEC for H264 is fine.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200642TEST_P(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200643 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200644 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200645 });
646 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100647 RunBaseTest(&test);
648}
649
danilchap9f5b6222017-03-02 06:22:21 -0800650// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200651TEST_P(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200652 test::FunctionVideoEncoderFactory encoder_factory(
653 []() { return VP8Encoder::Create(); });
654 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100655 RunBaseTest(&test);
656}
657
Peter Boström12996152016-05-14 02:03:18 +0200658#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800659// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200660TEST_P(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200661 test::FunctionVideoEncoderFactory encoder_factory(
662 []() { return VP9Encoder::Create(); });
663 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800664 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000665}
Peter Boström12996152016-05-14 02:03:18 +0200666#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000667
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200668TEST_P(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200669 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200670 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200671 Clock::GetRealTimeClock());
672 });
673 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800674 RunBaseTest(&test);
675}
676
brandtr39f97292016-11-16 22:57:50 -0800677// TODO(brandtr): Move these FlexFEC tests when we have created
678// FlexfecSendStream.
679class FlexfecObserver : public test::EndToEndTest {
680 public:
681 FlexfecObserver(bool header_extensions_enabled,
682 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800683 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200684 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100685 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800686 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200687 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800688 payload_name_(codec),
689 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800690 sent_media_(false),
691 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100692 header_extensions_enabled_(header_extensions_enabled),
693 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800694
695 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100696 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800697
698 private:
699 Action OnSendRtp(const uint8_t* packet, size_t length) override {
700 RTPHeader header;
701 EXPECT_TRUE(parser_->Parse(packet, length, &header));
702
brandtr39f97292016-11-16 22:57:50 -0800703 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
704 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
705 sent_flexfec_ = true;
706 } else {
707 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
708 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100709 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
710 num_video_streams_),
711 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800712 sent_media_ = true;
713 }
714
715 if (header_extensions_enabled_) {
716 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
717 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
718 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
719 }
720
brandtr0c5a1542016-11-23 04:42:26 -0800721 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800722 observation_complete_.Set();
723 }
724
725 return SEND_PACKET;
726 }
727
eladalon413ee9a2017-08-22 04:02:52 -0700728 test::PacketTransport* CreateSendTransport(
729 test::SingleThreadedTaskQueueForTesting* task_queue,
730 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800731 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
732 // Therefore we need some network delay.
733 const int kNetworkDelayMs = 100;
Artem Titov46c4e602018-08-17 14:26:54 +0200734 DefaultNetworkSimulationConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800735 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800736 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700737 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700738 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200739 VideoSendStreamTest::payload_type_map_,
740 absl::make_unique<FakeNetworkPipe>(
741 Clock::GetRealTimeClock(),
742 absl::make_unique<SimulatedNetwork>(config)));
brandtr39f97292016-11-16 22:57:50 -0800743 }
744
745 void ModifyVideoConfigs(
746 VideoSendStream::Config* send_config,
747 std::vector<VideoReceiveStream::Config>* receive_configs,
748 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800749 if (use_nack_) {
750 send_config->rtp.nack.rtp_history_ms =
751 (*receive_configs)[0].rtp.nack.rtp_history_ms =
752 VideoSendStreamTest::kNackRtpHistoryMs;
753 }
Niels Möller4db138e2018-04-19 09:04:13 +0200754 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200755 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800756 if (header_extensions_enabled_) {
757 send_config->rtp.extensions.push_back(RtpExtension(
758 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
759 send_config->rtp.extensions.push_back(RtpExtension(
760 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800761 } else {
762 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800763 }
Niels Möller259a4972018-04-05 15:36:51 +0200764 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800765 }
766
767 void PerformTest() override {
768 EXPECT_TRUE(Wait())
769 << "Timed out waiting for FlexFEC and/or media packets.";
770 }
771
Niels Möller4db138e2018-04-19 09:04:13 +0200772 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800773 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800774 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800775 bool sent_media_;
776 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100777 const bool header_extensions_enabled_;
778 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800779};
780
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200781TEST_P(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200782 test::FunctionVideoEncoderFactory encoder_factory(
783 []() { return VP8Encoder::Create(); });
784 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100785 RunBaseTest(&test);
786}
787
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200788TEST_P(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200789 test::FunctionVideoEncoderFactory encoder_factory(
790 []() { return VP8Encoder::Create(); });
791 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800792 RunBaseTest(&test);
793}
794
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200795TEST_P(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200796 test::FunctionVideoEncoderFactory encoder_factory(
797 []() { return VP8Encoder::Create(); });
798 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800799 RunBaseTest(&test);
800}
801
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200802TEST_P(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200803 test::FunctionVideoEncoderFactory encoder_factory(
804 []() { return VP8Encoder::Create(); });
805 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800806 RunBaseTest(&test);
807}
808
brandtr39f97292016-11-16 22:57:50 -0800809#if !defined(RTC_DISABLE_VP9)
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200810TEST_P(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200811 test::FunctionVideoEncoderFactory encoder_factory(
812 []() { return VP9Encoder::Create(); });
813 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800814 RunBaseTest(&test);
815}
816
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200817TEST_P(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200818 test::FunctionVideoEncoderFactory encoder_factory(
819 []() { return VP9Encoder::Create(); });
820 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800821 RunBaseTest(&test);
822}
823#endif // defined(RTC_DISABLE_VP9)
824
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200825TEST_P(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200826 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200827 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200828 });
829 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800830 RunBaseTest(&test);
831}
832
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200833TEST_P(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200834 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200835 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200836 });
837 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800838 RunBaseTest(&test);
839}
840
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200841TEST_P(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200842 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200843 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200844 Clock::GetRealTimeClock());
845 });
846
847 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800848 RunBaseTest(&test);
849}
850
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000851void VideoSendStreamTest::TestNackRetransmission(
852 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000853 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000854 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000855 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000856 explicit NackObserver(uint32_t retransmit_ssrc,
857 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000858 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000859 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100860 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000861 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100862 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000863
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000864 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000865 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000866 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000867 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000868
Sebastian Janssond3f38162018-02-28 16:14:44 +0100869 int kRetransmitTarget = 6;
870 ++send_count_;
871 if (send_count_ == 5 || send_count_ == 25) {
872 nacked_sequence_numbers_.push_back(
873 static_cast<uint16_t>(header.sequenceNumber - 3));
874 nacked_sequence_numbers_.push_back(
875 static_cast<uint16_t>(header.sequenceNumber - 2));
876 nacked_sequence_numbers_.push_back(
877 static_cast<uint16_t>(header.sequenceNumber - 1));
878
danilchap8a1d2a32017-08-01 03:21:37 -0700879 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800880 nullptr, nullptr, transport_adapter_.get(),
881 RtcpIntervalConfig{});
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000882
pbosda903ea2015-10-02 02:36:56 -0700883 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100884 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000885
886 RTCPSender::FeedbackState feedback_state;
887
Sebastian Janssond3f38162018-02-28 16:14:44 +0100888 EXPECT_EQ(0, rtcp_sender.SendRTCP(
889 feedback_state, kRtcpNack,
890 static_cast<int>(nacked_sequence_numbers_.size()),
891 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000892 }
893
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000894 uint16_t sequence_number = header.sequenceNumber;
895
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000896 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100897 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
898 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000899 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000900 const uint8_t* rtx_header = packet + header.headerLength;
901 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
902 }
Sebastian Janssond3f38162018-02-28 16:14:44 +0100903 auto found = std::find(nacked_sequence_numbers_.begin(),
904 nacked_sequence_numbers_.end(), sequence_number);
905 if (found != nacked_sequence_numbers_.end()) {
906 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000907
Sebastian Janssond3f38162018-02-28 16:14:44 +0100908 if (++retransmit_count_ == kRetransmitTarget) {
909 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
910 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
911 observation_complete_.Set();
912 }
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000913 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000914
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000915 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000916 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000917
stefanff483612015-12-21 03:14:00 -0800918 void ModifyVideoConfigs(
919 VideoSendStream::Config* send_config,
920 std::vector<VideoReceiveStream::Config>* receive_configs,
921 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700922 transport_adapter_.reset(
923 new internal::TransportAdapter(send_config->send_transport));
924 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000925 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000926 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100927 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000928 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
929 }
930
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000931 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100932 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000933 }
934
kwiberg27f982b2016-03-01 11:52:33 -0800935 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000936 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100937 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000938 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000939 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100940 std::vector<uint16_t> nacked_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000941 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000942
stefane74eef12016-01-08 06:47:13 -0800943 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000944}
945
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200946TEST_P(VideoSendStreamTest, RetransmitsNack) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000947 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100948 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000949}
950
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200951TEST_P(VideoSendStreamTest, RetransmitsNackOverRtx) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000952 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000953 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000954}
955
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000956void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
957 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000958 // Use a fake encoder to output a frame of every size in the range [90, 290],
959 // for each size making sure that the exact number of payload bytes received
960 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000961 static const size_t kMaxPacketSize = 128;
962 static const size_t start = 90;
963 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000964
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000965 // Observer that verifies that the expected number of packets and bytes
966 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000967 class FrameFragmentationTest : public test::SendTest,
968 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000969 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000970 FrameFragmentationTest(size_t max_packet_size,
971 size_t start_size,
972 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000973 bool test_generic_packetization,
974 bool use_fec)
975 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000976 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +0200977 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000978 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000979 stop_size_(stop_size),
980 test_generic_packetization_(test_generic_packetization),
981 use_fec_(use_fec),
982 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100983 packets_lost_(0),
984 last_packet_count_(0),
985 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000986 accumulated_size_(0),
987 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000988 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000989 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700990 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000991 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000992 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700993 RTC_DCHECK_GT(stop_size, max_packet_size);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000994 if (!test_generic_packetization_)
995 encoder_.SetCodecType(kVideoCodecVP8);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000996 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000997
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000998 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000999 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001000 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001001 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001002 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001003
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001004 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001005
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001006 if (use_fec_) {
1007 uint8_t payload_type = packet[header.headerLength];
1008 bool is_fec = header.payloadType == kRedPayloadType &&
1009 payload_type == kUlpfecPayloadType;
1010 if (is_fec) {
1011 fec_packet_received_ = true;
1012 return SEND_PACKET;
1013 }
1014 }
1015
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001016 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001017
1018 if (use_fec_)
1019 TriggerLossReport(header);
1020
1021 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +02001022 size_t overhead = header.headerLength + header.paddingLength;
1023 // Only remove payload header and RED header if the packet actually
1024 // contains payload.
1025 if (length > overhead) {
1026 overhead += (1 /* Generic header */);
1027 if (use_fec_)
1028 overhead += 1; // RED for FEC header.
1029 }
1030 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001031 accumulated_payload_ += length - overhead;
1032 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001033
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001034 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001035 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001036 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1037 // With FEC enabled, frame size is incremented asynchronously, so
1038 // "old" frames one byte too small may arrive. Accept, but don't
1039 // increase expected frame size.
1040 accumulated_size_ = 0;
1041 accumulated_payload_ = 0;
1042 return SEND_PACKET;
1043 }
1044
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001045 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001046 if (test_generic_packetization_) {
1047 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1048 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001049
1050 // Last packet of frame; reset counters.
1051 accumulated_size_ = 0;
1052 accumulated_payload_ = 0;
1053 if (current_size_rtp_ == stop_size_) {
1054 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001055 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001056 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001057 // Increase next expected frame size. If testing with FEC, make sure
1058 // a FEC packet has been received for this frame size before
1059 // proceeding, to make sure that redundancy packets don't exceed
1060 // size limit.
1061 if (!use_fec_) {
1062 ++current_size_rtp_;
1063 } else if (fec_packet_received_) {
1064 fec_packet_received_ = false;
1065 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001066
1067 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001068 ++current_size_frame_;
1069 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001070 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001071 }
1072
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001073 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001074 }
1075
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001076 void TriggerLossReport(const RTPHeader& header) {
1077 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001078 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001079 if (++packet_count_ % (100 / kLossPercent) == 0) {
1080 packets_lost_++;
1081 int loss_delta = packets_lost_ - last_packets_lost_;
1082 int packets_delta = packet_count_ - last_packet_count_;
1083 last_packet_count_ = packet_count_;
1084 last_packets_lost_ = packets_lost_;
1085 uint8_t loss_ratio =
1086 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001087 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001088 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001089 packets_lost_, // Cumulative lost.
1090 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001091 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001092 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001093 transport_adapter_.get(), RtcpIntervalConfig{});
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001094
pbosda903ea2015-10-02 02:36:56 -07001095 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001096 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001097
1098 RTCPSender::FeedbackState feedback_state;
1099
1100 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1101 }
1102 }
1103
nisseef8b61e2016-04-29 06:09:15 -07001104 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001105 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001106 // Increase frame size for next encoded frame, in the context of the
1107 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001108 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001109 ++current_size_frame_;
1110 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001111 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001112 }
Sebastian Jansson72582242018-07-13 13:19:42 +02001113 void ModifySenderCallConfig(Call::Config* config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001114 const int kMinBitrateBps = 30000;
Sebastian Jansson72582242018-07-13 13:19:42 +02001115 config->bitrate_config.min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001116 }
1117
stefanff483612015-12-21 03:14:00 -08001118 void ModifyVideoConfigs(
1119 VideoSendStream::Config* send_config,
1120 std::vector<VideoReceiveStream::Config>* receive_configs,
1121 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001122 transport_adapter_.reset(
1123 new internal::TransportAdapter(send_config->send_transport));
1124 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001125 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001126 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1127 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001128 }
1129
1130 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001131 send_config->rtp.payload_name = "VP8";
Philip Eliassond52a1a62018-09-07 13:03:55 +00001132
Niels Möller4db138e2018-04-19 09:04:13 +02001133 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001134 send_config->rtp.max_packet_size = kMaxPacketSize;
1135 send_config->post_encode_callback = this;
1136
Erik Språng95261872015-04-10 11:58:49 +02001137 // Make sure there is at least one extension header, to make the RTP
1138 // header larger than the base length of 12 bytes.
1139 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001140
1141 // Setup screen content disables frame dropping which makes this easier.
1142 class VideoStreamFactory
1143 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1144 public:
1145 explicit VideoStreamFactory(size_t num_temporal_layers)
1146 : num_temporal_layers_(num_temporal_layers) {
1147 EXPECT_GT(num_temporal_layers, 0u);
1148 }
1149
1150 private:
1151 std::vector<VideoStream> CreateEncoderStreams(
1152 int width,
1153 int height,
1154 const VideoEncoderConfig& encoder_config) override {
1155 std::vector<VideoStream> streams =
1156 test::CreateVideoStreams(width, height, encoder_config);
1157 for (VideoStream& stream : streams) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01001158 stream.num_temporal_layers = num_temporal_layers_;
sprang4847ae62017-06-27 07:06:52 -07001159 }
1160 return streams;
1161 }
1162 const size_t num_temporal_layers_;
1163 };
1164
1165 encoder_config->video_stream_factory =
1166 new rtc::RefCountedObject<VideoStreamFactory>(2);
1167 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001168 }
1169
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001170 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001171 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001172 }
1173
kwiberg27f982b2016-03-01 11:52:33 -08001174 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001175 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möller4db138e2018-04-19 09:04:13 +02001176 test::EncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001177
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001178 const size_t max_packet_size_;
1179 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001180 const bool test_generic_packetization_;
1181 const bool use_fec_;
1182
1183 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001184 uint32_t packets_lost_;
1185 uint32_t last_packet_count_;
1186 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001187 size_t accumulated_size_;
1188 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001189 bool fec_packet_received_;
1190
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001191 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001192 rtc::CriticalSection mutex_;
1193 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001194 };
1195
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001196 // Don't auto increment if FEC is used; continue sending frame size until
1197 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001198 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1199 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001200
stefane74eef12016-01-08 06:47:13 -08001201 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001202}
1203
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001204// TODO(sprang): Is there any way of speeding up these tests?
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001205TEST_P(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001206 TestPacketFragmentationSize(kGeneric, false);
1207}
1208
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001209TEST_P(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001210 TestPacketFragmentationSize(kGeneric, true);
1211}
1212
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001213TEST_P(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001214 TestPacketFragmentationSize(kVP8, false);
1215}
1216
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001217TEST_P(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001218 TestPacketFragmentationSize(kVP8, true);
1219}
1220
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001221// The test will go through a number of phases.
1222// 1. Start sending packets.
1223// 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 +00001224// suspend the stream.
1225// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001226// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001227// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001228// When the stream is detected again, and the stats show that the stream
1229// is no longer suspended, the test ends.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001230TEST_P(VideoSendStreamTest, SuspendBelowMinBitrate) {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001231 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001232
nissed30a1112016-04-18 05:15:22 -07001233 class RembObserver : public test::SendTest,
1234 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001235 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001236 RembObserver()
1237 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001238 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001239 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001240 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001241 rtp_count_(0),
1242 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001243 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001244 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001245 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001246
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001247 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001248 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001249 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001250 ++rtp_count_;
1251 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001252 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001253 last_sequence_number_ = header.sequenceNumber;
1254
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001255 if (test_state_ == kBeforeSuspend) {
1256 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001257 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001258 test_state_ = kDuringSuspend;
1259 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001260 if (header.paddingLength == 0) {
1261 // Received non-padding packet during suspension period. Reset the
1262 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001263 suspended_frame_count_ = 0;
1264 }
stefanf116bd02015-10-27 08:29:42 -07001265 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001266 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001267 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001268 // Non-padding packet observed. Test is almost complete. Will just
1269 // have to wait for the stats to change.
1270 test_state_ = kWaitingForStats;
1271 }
stefanf116bd02015-10-27 08:29:42 -07001272 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001273 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001274 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001275 if (stats.suspended == false) {
1276 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001277 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001278 }
stefanf116bd02015-10-27 08:29:42 -07001279 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001280 }
1281
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001282 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001283 }
1284
perkj26091b12016-09-01 01:17:40 -07001285 // This method implements the rtc::VideoSinkInterface. This is called when
1286 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001287 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001288 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001289 if (test_state_ == kDuringSuspend &&
1290 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001291 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001292 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001293 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001294 test_state_ = kWaitingForPacket;
1295 }
1296 }
1297
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001298 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001299 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001300 low_remb_bps_ = value;
1301 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001302
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001303 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001304 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001305 high_remb_bps_ = value;
1306 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001307
stefanff483612015-12-21 03:14:00 -08001308 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001309 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001310 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001311 stream_ = send_stream;
1312 }
1313
stefanff483612015-12-21 03:14:00 -08001314 void ModifyVideoConfigs(
1315 VideoSendStream::Config* send_config,
1316 std::vector<VideoReceiveStream::Config>* receive_configs,
1317 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001318 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001319 transport_adapter_.reset(
1320 new internal::TransportAdapter(send_config->send_transport));
1321 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001322 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001323 send_config->pre_encode_callback = this;
1324 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001325 int min_bitrate_bps =
1326 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001327 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001328 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001329 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001330 min_bitrate_bps + threshold_window + 5000);
1331 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1332 }
1333
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001334 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001335 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001336 }
1337
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001338 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001339 kBeforeSuspend,
1340 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001341 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001342 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001343 };
1344
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001345 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001346 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001347 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1348 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001349 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001350 transport_adapter_.get(), RtcpIntervalConfig{});
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001351
pbosda903ea2015-10-02 02:36:56 -07001352 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001353 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001354 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001355 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001356 }
1357 RTCPSender::FeedbackState feedback_state;
1358 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1359 }
1360
kwiberg27f982b2016-03-01 11:52:33 -08001361 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001362 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001363 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001364
Peter Boströmf2f82832015-05-01 13:00:41 +02001365 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001366 TestState test_state_ RTC_GUARDED_BY(crit_);
1367 int rtp_count_ RTC_GUARDED_BY(crit_);
1368 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1369 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1370 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1371 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001372 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001373
stefane74eef12016-01-08 06:47:13 -08001374 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001375}
1376
perkj71ee44c2016-06-15 00:47:53 -07001377// This test that padding stops being send after a while if the Camera stops
1378// producing video frames and that padding resumes if the camera restarts.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001379TEST_P(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001380 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001381 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001382 NoPaddingWhenVideoIsMuted()
1383 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001384 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001385 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001386 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001387
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001388 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001389 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001390 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001391 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001392
1393 RTPHeader header;
1394 parser_->Parse(packet, length, &header);
1395 const bool only_padding =
1396 header.headerLength + header.paddingLength == length;
1397
1398 if (test_state_ == kBeforeStopCapture) {
1399 capturer_->Stop();
1400 test_state_ = kWaitingForPadding;
1401 } else if (test_state_ == kWaitingForPadding && only_padding) {
1402 test_state_ = kWaitingForNoPackets;
1403 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1404 only_padding) {
1405 observation_complete_.Set();
1406 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001407 return SEND_PACKET;
1408 }
1409
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001410 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001411 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001412 const int kNoPacketsThresholdMs = 2000;
1413 if (test_state_ == kWaitingForNoPackets &&
1414 (last_packet_time_ms_ > 0 &&
1415 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1416 kNoPacketsThresholdMs)) {
1417 capturer_->Start();
1418 test_state_ = kWaitingForPaddingAfterCameraRestart;
1419 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001420 return SEND_PACKET;
1421 }
1422
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001423 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001424
nisseef8b61e2016-04-29 06:09:15 -07001425 void OnFrameGeneratorCapturerCreated(
1426 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001427 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001428 capturer_ = frame_generator_capturer;
1429 }
1430
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001431 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001432 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001433 << "Timed out while waiting for RTP packets to stop being sent.";
1434 }
1435
perkj71ee44c2016-06-15 00:47:53 -07001436 enum TestState {
1437 kBeforeStopCapture,
1438 kWaitingForPadding,
1439 kWaitingForNoPackets,
1440 kWaitingForPaddingAfterCameraRestart
1441 };
1442
1443 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001444 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001445 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001446 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001447 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1448 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001449 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001450
stefane74eef12016-01-08 06:47:13 -08001451 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001452}
1453
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001454TEST_P(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
isheriffcc5903e2016-10-04 08:29:38 -07001455 const int kCapacityKbps = 10000; // 10 Mbps
1456 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1457 public:
1458 PaddingIsPrimarilyRetransmissions()
1459 : EndToEndTest(kDefaultTimeoutMs),
1460 clock_(Clock::GetRealTimeClock()),
1461 padding_length_(0),
1462 total_length_(0),
1463 call_(nullptr) {}
1464
1465 private:
1466 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1467 call_ = sender_call;
1468 }
1469
1470 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1471 rtc::CritScope lock(&crit_);
1472
1473 RTPHeader header;
1474 parser_->Parse(packet, length, &header);
1475 padding_length_ += header.paddingLength;
1476 total_length_ += length;
1477 return SEND_PACKET;
1478 }
1479
eladalon413ee9a2017-08-22 04:02:52 -07001480 test::PacketTransport* CreateSendTransport(
1481 test::SingleThreadedTaskQueueForTesting* task_queue,
1482 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001483 const int kNetworkDelayMs = 50;
Artem Titov46c4e602018-08-17 14:26:54 +02001484 DefaultNetworkSimulationConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001485 config.loss_percent = 10;
1486 config.link_capacity_kbps = kCapacityKbps;
1487 config.queue_delay_ms = kNetworkDelayMs;
Artem Titov4e199e92018-08-20 13:30:39 +02001488 return new test::PacketTransport(
1489 task_queue, sender_call, this, test::PacketTransport::kSender,
1490 payload_type_map_,
1491 absl::make_unique<FakeNetworkPipe>(
1492 Clock::GetRealTimeClock(),
1493 absl::make_unique<SimulatedNetwork>(config)));
isheriffcc5903e2016-10-04 08:29:38 -07001494 }
1495
1496 void ModifyVideoConfigs(
1497 VideoSendStream::Config* send_config,
1498 std::vector<VideoReceiveStream::Config>* receive_configs,
1499 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001500 // Turn on RTX.
1501 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1502 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001503 }
1504
1505 void PerformTest() override {
1506 // TODO(isheriff): Some platforms do not ramp up as expected to full
1507 // capacity due to packet scheduling delays. Fix that before getting
1508 // rid of this.
1509 SleepMs(5000);
1510 {
1511 rtc::CritScope lock(&crit_);
1512 // Expect padding to be a small percentage of total bytes sent.
1513 EXPECT_LT(padding_length_, .1 * total_length_);
1514 }
1515 }
1516
1517 rtc::CriticalSection crit_;
1518 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001519 size_t padding_length_ RTC_GUARDED_BY(crit_);
1520 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001521 Call* call_;
1522 } test;
1523
1524 RunBaseTest(&test);
1525}
1526
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001527// This test first observes "high" bitrate use at which point it sends a REMB to
1528// indicate that it should be lowered significantly. The test then observes that
1529// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1530// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001531//
1532// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1533// bitrate since no receiver block or remb is sent in the initial phase.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001534TEST_P(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001535 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001536 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001537 static const int kRembBitrateBps = 80000;
1538 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001539 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001540 public:
1541 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001542 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001543 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1544 stream_(nullptr),
1545 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001546
1547 private:
nisseef8b61e2016-04-29 06:09:15 -07001548 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001549 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001550 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001551
1552 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001553 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001554 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001555 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001556 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001557 if (!stats.substreams.empty()) {
1558 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001559 int total_bitrate_bps =
1560 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001561 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1562 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1563 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001564 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001565 rtp_rtcp_->SetRemb(kRembBitrateBps,
1566 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001567 rtp_rtcp_->Process();
1568 bitrate_capped_ = true;
1569 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001570 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001571 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001572 }
1573 }
stefanf116bd02015-10-27 08:29:42 -07001574 // Packets don't have to be delivered since the test is the receiver.
1575 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001576 }
1577
stefanff483612015-12-21 03:14:00 -08001578 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001579 VideoSendStream* send_stream,
1580 const std::vector<VideoReceiveStream*>& receive_streams) override {
1581 stream_ = send_stream;
1582 RtpRtcp::Configuration config;
1583 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001584 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001585 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001586 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001587 }
1588
stefanff483612015-12-21 03:14:00 -08001589 void ModifyVideoConfigs(
1590 VideoSendStream::Config* send_config,
1591 std::vector<VideoReceiveStream::Config>* receive_configs,
1592 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001593 feedback_transport_.reset(
1594 new internal::TransportAdapter(send_config->send_transport));
1595 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001596 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001597 }
1598
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001599 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001600 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001601 << "Timeout while waiting for low bitrate stats after REMB.";
1602 }
1603
kwiberg27f982b2016-03-01 11:52:33 -08001604 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1605 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001606 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001607 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001608 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001609 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001610
stefane74eef12016-01-08 06:47:13 -08001611 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001612}
1613
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001614TEST_P(VideoSendStreamTest, ChangingNetworkRoute) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001615 static const int kStartBitrateBps = 300000;
1616 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001617 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001618 class ChangingNetworkRouteTest : public test::EndToEndTest {
1619 public:
eladalon413ee9a2017-08-22 04:02:52 -07001620 explicit ChangingNetworkRouteTest(
1621 test::SingleThreadedTaskQueueForTesting* task_queue)
1622 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1623 task_queue_(task_queue),
1624 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001625 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1626 kRtpExtensionTransportSequenceNumber, kExtensionId));
1627 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001628
1629 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1630 call_ = sender_call;
1631 }
1632
Stefan Holmer280de9e2016-09-30 10:06:51 +02001633 void ModifyVideoConfigs(
1634 VideoSendStream::Config* send_config,
1635 std::vector<VideoReceiveStream::Config>* receive_configs,
1636 VideoEncoderConfig* encoder_config) override {
1637 send_config->rtp.extensions.clear();
1638 send_config->rtp.extensions.push_back(RtpExtension(
1639 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1640 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1641 (*receive_configs)[0].rtp.transport_cc = true;
1642 }
1643
1644 void ModifyAudioConfigs(
1645 AudioSendStream::Config* send_config,
1646 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1647 send_config->rtp.extensions.clear();
1648 send_config->rtp.extensions.push_back(RtpExtension(
1649 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1650 (*receive_configs)[0].rtp.extensions.clear();
1651 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1652 (*receive_configs)[0].rtp.transport_cc = true;
1653 }
1654
Stefan Holmerbe402962016-07-08 16:16:41 +02001655 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1656 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1657 observation_complete_.Set();
1658 }
1659
1660 return SEND_PACKET;
1661 }
1662
1663 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001664 rtc::NetworkRoute new_route;
1665 new_route.connected = true;
1666 new_route.local_network_id = 10;
1667 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001668 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001669
1670 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001671 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1672 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001673 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001674 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1675 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001676 });
1677
Stefan Holmerbe402962016-07-08 16:16:41 +02001678 EXPECT_TRUE(Wait())
1679 << "Timed out while waiting for start bitrate to be exceeded.";
1680
eladalon413ee9a2017-08-22 04:02:52 -07001681 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1682 bitrate_config.start_bitrate_bps = -1;
1683 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001684 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1685 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001686 // TODO(holmer): We should set the last sent packet id here and verify
1687 // that we correctly ignore any packet loss reported prior to that id.
1688 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001689 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1690 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001691 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1692 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001693 }
1694
1695 private:
eladalon413ee9a2017-08-22 04:02:52 -07001696 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001697 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001698 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001699
1700 RunBaseTest(&test);
1701}
1702
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001703TEST_P(VideoSendStreamTest, ChangingTransportOverhead) {
michaelt79e05882016-11-08 02:50:09 -08001704 class ChangingTransportOverheadTest : public test::EndToEndTest {
1705 public:
eladalon413ee9a2017-08-22 04:02:52 -07001706 explicit ChangingTransportOverheadTest(
1707 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001708 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001709 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001710 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001711 packets_sent_(0),
1712 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001713
1714 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1715 call_ = sender_call;
1716 }
1717
1718 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001719 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001720 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001721 if (++packets_sent_ < 100)
1722 return SEND_PACKET;
1723 observation_complete_.Set();
1724 return SEND_PACKET;
1725 }
1726
michaelta3328772016-11-29 09:25:03 -08001727 void ModifyVideoConfigs(
1728 VideoSendStream::Config* send_config,
1729 std::vector<VideoReceiveStream::Config>* receive_configs,
1730 VideoEncoderConfig* encoder_config) override {
1731 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1732 }
1733
michaelt79e05882016-11-08 02:50:09 -08001734 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001735 task_queue_->SendTask([this]() {
1736 transport_overhead_ = 100;
1737 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1738 transport_overhead_);
1739 });
1740
michaelt79e05882016-11-08 02:50:09 -08001741 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001742
sprang21253fc2017-02-27 03:35:47 -08001743 {
1744 rtc::CritScope cs(&lock_);
1745 packets_sent_ = 0;
1746 }
eladalon413ee9a2017-08-22 04:02:52 -07001747
1748 task_queue_->SendTask([this]() {
1749 transport_overhead_ = 500;
1750 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1751 transport_overhead_);
1752 });
1753
michaelt79e05882016-11-08 02:50:09 -08001754 EXPECT_TRUE(Wait());
1755 }
1756
1757 private:
eladalon413ee9a2017-08-22 04:02:52 -07001758 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001759 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001760 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001761 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001762 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001763 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001764 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001765
1766 RunBaseTest(&test);
1767}
1768
sprangf24a0642017-02-28 13:23:26 -08001769// Test class takes takes as argument a switch selecting if type switch should
1770// occur and a function pointer to reset the send stream. This is necessary
1771// since you cannot change the content type of a VideoSendStream, you need to
1772// recreate it. Stopping and recreating the stream can only be done on the main
1773// thread and in the context of VideoSendStreamTest (not BaseTest).
1774template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001775class MaxPaddingSetTest : public test::SendTest {
1776 public:
1777 static const uint32_t kMinTransmitBitrateBps = 400000;
1778 static const uint32_t kActualEncodeBitrateBps = 40000;
1779 static const uint32_t kMinPacketsToSend = 50;
1780
sprangf24a0642017-02-28 13:23:26 -08001781 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001782 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001783 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001784 call_(nullptr),
1785 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001786 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001787 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001788 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001789 stream_resetter_(stream_reset_fun) {
1790 RTC_DCHECK(stream_resetter_);
1791 }
sprang9c0b5512016-07-06 00:54:28 -07001792
1793 void OnVideoStreamsCreated(
1794 VideoSendStream* send_stream,
1795 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001796 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001797 send_stream_ = send_stream;
1798 }
1799
1800 void ModifyVideoConfigs(
1801 VideoSendStream::Config* send_config,
1802 std::vector<VideoReceiveStream::Config>* receive_configs,
1803 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001804 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001805 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001806 encoder_config->min_transmit_bitrate_bps = 0;
1807 encoder_config->content_type =
1808 VideoEncoderConfig::ContentType::kRealtimeVideo;
1809 } else {
1810 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1811 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1812 }
sprangf24a0642017-02-28 13:23:26 -08001813 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001814 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001815 }
1816
1817 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1818 call_ = sender_call;
1819 }
1820
1821 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1822 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001823 if (running_without_padding_)
1824 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1825
1826 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1827 // we have reliable data.
1828 if (++packets_sent_ < kMinPacketsToSend)
1829 return SEND_PACKET;
1830
1831 if (running_without_padding_) {
1832 // We've sent kMinPacketsToSend packets with default configuration, switch
1833 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001834 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001835 packets_sent_ = 0;
1836 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1837 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001838 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001839 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001840 return SEND_PACKET;
1841 }
1842
1843 // Make sure the pacer has been configured with a min transmit bitrate.
1844 if (call_->GetStats().max_padding_bitrate_bps > 0)
1845 observation_complete_.Set();
1846
1847 return SEND_PACKET;
1848 }
1849
1850 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001851 if (RunningWithoutPadding()) {
1852 ASSERT_TRUE(
1853 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001854 (*stream_resetter_)(send_stream_config_, encoder_config_);
1855 }
1856
sprang9c0b5512016-07-06 00:54:28 -07001857 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1858 }
1859
1860 private:
sprangf24a0642017-02-28 13:23:26 -08001861 bool RunningWithoutPadding() const {
1862 rtc::CritScope lock(&crit_);
1863 return running_without_padding_;
1864 }
1865
sprang9c0b5512016-07-06 00:54:28 -07001866 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001867 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001868 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001869 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001870 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001871 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001872 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001873 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001874 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001875};
1876
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001877TEST_P(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001878 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1879 const VideoEncoderConfig& encoder_config) {};
1880 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001881 RunBaseTest(&test);
1882}
1883
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001884TEST_P(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001885 // Function for removing and recreating the send stream with a new config.
1886 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1887 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001888 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1889 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001890 DestroyVideoSendStreams();
1891 SetVideoSendConfig(send_stream_config);
1892 SetVideoEncoderConfig(encoder_config);
1893 CreateVideoSendStreams();
1894 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
eladalon413ee9a2017-08-22 04:02:52 -07001895 Start();
1896 });
sprangf24a0642017-02-28 13:23:26 -08001897 };
1898 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001899 RunBaseTest(&test);
1900}
1901
perkjfa10b552016-10-02 23:45:26 -07001902// This test verifies that new frame sizes reconfigures encoders even though not
1903// (yet) sending. The purpose of this is to permit encoding as quickly as
1904// possible once we start sending. Likely the frames being input are from the
1905// same source that will be sent later, which just means that we're ready
1906// earlier.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001907TEST_P(VideoSendStreamTest,
perkjfa10b552016-10-02 23:45:26 -07001908 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1909 class EncoderObserver : public test::FakeEncoder {
1910 public:
1911 EncoderObserver()
1912 : FakeEncoder(Clock::GetRealTimeClock()),
1913 init_encode_called_(false, false),
1914 number_of_initializations_(0),
1915 last_initialized_frame_width_(0),
1916 last_initialized_frame_height_(0) {}
1917
1918 void WaitForResolution(int width, int height) {
1919 {
1920 rtc::CritScope lock(&crit_);
1921 if (last_initialized_frame_width_ == width &&
1922 last_initialized_frame_height_ == height) {
1923 return;
1924 }
1925 }
Erik Språng08127a92016-11-16 16:41:30 +01001926 EXPECT_TRUE(
1927 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001928 {
1929 rtc::CritScope lock(&crit_);
1930 EXPECT_EQ(width, last_initialized_frame_width_);
1931 EXPECT_EQ(height, last_initialized_frame_height_);
1932 }
1933 }
1934
1935 private:
1936 int32_t InitEncode(const VideoCodec* config,
1937 int32_t number_of_cores,
1938 size_t max_payload_size) override {
1939 rtc::CritScope lock(&crit_);
1940 last_initialized_frame_width_ = config->width;
1941 last_initialized_frame_height_ = config->height;
1942 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001943 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001944 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1945 }
1946
1947 int32_t Encode(const VideoFrame& input_image,
1948 const CodecSpecificInfo* codec_specific_info,
1949 const std::vector<FrameType>* frame_types) override {
1950 ADD_FAILURE()
1951 << "Unexpected Encode call since the send stream is not started";
1952 return 0;
1953 }
1954
1955 rtc::CriticalSection crit_;
1956 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001957 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1958 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1959 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001960 };
1961
perkjfa10b552016-10-02 23:45:26 -07001962 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001963 EncoderObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02001964 test::EncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07001965
Niels Möller4db138e2018-04-19 09:04:13 +02001966 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02001967 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07001968 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001969 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07001970 CreateVideoStreams();
1971 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1972 kDefaultHeight);
1973 frame_generator_capturer_->Start();
1974 });
perkjfa10b552016-10-02 23:45:26 -07001975
1976 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001977
1978 task_queue_.SendTask([this]() {
1979 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1980 kDefaultHeight * 2);
1981 });
1982
perkjfa10b552016-10-02 23:45:26 -07001983 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001984
1985 task_queue_.SendTask([this]() {
1986 DestroyStreams();
1987 DestroyCalls();
1988 });
perkjfa10b552016-10-02 23:45:26 -07001989}
1990
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02001991TEST_P(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001992 class StartBitrateObserver : public test::FakeEncoder {
1993 public:
1994 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001995 : FakeEncoder(Clock::GetRealTimeClock()),
1996 start_bitrate_changed_(false, false),
1997 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001998 int32_t InitEncode(const VideoCodec* config,
1999 int32_t number_of_cores,
2000 size_t max_payload_size) override {
2001 rtc::CritScope lock(&crit_);
2002 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07002003 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002004 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2005 }
2006
2007 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
2008 rtc::CritScope lock(&crit_);
2009 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07002010 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002011 return FakeEncoder::SetRates(new_target_bitrate, framerate);
2012 }
2013
2014 int GetStartBitrateKbps() const {
2015 rtc::CritScope lock(&crit_);
2016 return start_bitrate_kbps_;
2017 }
2018
pbos14fe7082016-04-20 06:35:56 -07002019 bool WaitForStartBitrate() {
2020 return start_bitrate_changed_.Wait(
2021 VideoSendStreamTest::kDefaultTimeoutMs);
2022 }
2023
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002024 private:
pbos5ad935c2016-01-25 03:52:44 -08002025 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002026 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002027 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002028 };
2029
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002030 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002031
solenberg4fbae2b2015-08-28 04:07:10 -07002032 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002033 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002034
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002035 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002036 bitrate_config.start_bitrate_bps =
2037 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002038 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2039 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002040
2041 StartBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002042 test::EncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002043 // Since this test does not use a capturer, set |internal_source| = true.
2044 // Encoder configuration is otherwise updated on the next video frame.
Niels Möller4db138e2018-04-19 09:04:13 +02002045 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002046 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002047
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002048 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002049
pbos14fe7082016-04-20 06:35:56 -07002050 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002051 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002052 encoder.GetStartBitrateKbps());
2053
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002054 GetVideoEncoderConfig()->max_bitrate_bps =
2055 2 * bitrate_config.start_bitrate_bps;
2056 GetVideoSendStream()->ReconfigureVideoEncoder(
2057 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002058
2059 // New bitrate should be reconfigured above the previous max. As there's no
2060 // network connection this shouldn't be flaky, as no bitrate should've been
2061 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002062 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002063 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2064 encoder.GetStartBitrateKbps());
2065
2066 DestroyStreams();
2067}
2068
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002069class StartStopBitrateObserver : public test::FakeEncoder {
2070 public:
2071 StartStopBitrateObserver()
2072 : FakeEncoder(Clock::GetRealTimeClock()),
2073 encoder_init_(false, false),
2074 bitrate_changed_(false, false) {}
2075 int32_t InitEncode(const VideoCodec* config,
2076 int32_t number_of_cores,
2077 size_t max_payload_size) override {
2078 rtc::CritScope lock(&crit_);
2079 encoder_init_.Set();
2080 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2081 }
2082
Erik Språng566124a2018-04-23 12:32:22 +02002083 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002084 uint32_t framerate) override {
2085 rtc::CritScope lock(&crit_);
2086 bitrate_kbps_ = bitrate.get_sum_kbps();
2087 bitrate_changed_.Set();
2088 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2089 }
2090
2091 bool WaitForEncoderInit() {
2092 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2093 }
2094
2095 bool WaitBitrateChanged(bool non_zero) {
2096 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002097 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002098 {
2099 rtc::CritScope lock(&crit_);
2100 bitrate_kbps = bitrate_kbps_;
2101 }
2102 if (!bitrate_kbps)
2103 continue;
2104
2105 if ((non_zero && *bitrate_kbps > 0) ||
2106 (!non_zero && *bitrate_kbps == 0)) {
2107 return true;
2108 }
2109 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2110 return false;
2111 }
2112
2113 private:
2114 rtc::CriticalSection crit_;
2115 rtc::Event encoder_init_;
2116 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002117 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002118};
2119
perkj57c21f92016-06-17 07:27:16 -07002120// This test that if the encoder use an internal source, VideoEncoder::SetRates
2121// will be called with zero bitrate during initialization and that
2122// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2123// with zero bitrate.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002124TEST_P(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002125 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002126 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002127 test::EncoderProxyFactory encoder_factory(&encoder);
2128 encoder_factory.SetHasInternalSource(true);
2129 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002130
Niels Möller4db138e2018-04-19 09:04:13 +02002131 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002132 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002133 CreateSendConfig(1, 0, 0, &transport);
2134
2135 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002136 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002137
2138 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002139 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002140 GetVideoSendStream()->Start();
2141 GetVideoSendStream()->SetSource(&forwarder,
2142 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002143 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002144 });
perkj57c21f92016-06-17 07:27:16 -07002145
2146 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002147
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002148 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002149 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2150
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002151 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002152 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2153
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002154 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002155 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002156
eladalon413ee9a2017-08-22 04:02:52 -07002157 task_queue_.SendTask([this]() {
2158 DestroyStreams();
2159 DestroyCalls();
2160 });
perkj57c21f92016-06-17 07:27:16 -07002161}
2162
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002163// Tests that when the encoder uses an internal source, the VideoEncoder will
2164// be updated with a new bitrate when turning the VideoSendStream on/off with
2165// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2166// is reconfigured with new active layers.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002167TEST_P(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002168 test::NullTransport transport;
2169 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002170 test::EncoderProxyFactory encoder_factory(&encoder);
2171 encoder_factory.SetHasInternalSource(true);
2172 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002173
Niels Möller4db138e2018-04-19 09:04:13 +02002174 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002175 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002176 // Create two simulcast streams.
2177 CreateSendConfig(2, 0, 0, &transport);
2178
2179 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002180 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002181
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002182 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002183
2184 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002185 GetVideoSendStream()->Start();
2186 GetVideoSendStream()->SetSource(&forwarder,
2187 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002188 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002189 });
2190
2191 EXPECT_TRUE(encoder.WaitForEncoderInit());
2192
2193 // When we turn on the simulcast layers it will update the BitrateAllocator,
2194 // which in turn updates the VideoEncoder's bitrate.
2195 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002196 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002197 });
2198 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2199
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002200 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2201 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002202 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002203 GetVideoSendStream()->ReconfigureVideoEncoder(
2204 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002205 });
2206 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2207 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2208 // active. Once the change is made for a "soft" reconfiguration we can remove
2209 // the expecation for an encoder init. We can also test that bitrate changes
2210 // when just updating individual active layers, which should change the
2211 // bitrate set to the video encoder.
2212 EXPECT_TRUE(encoder.WaitForEncoderInit());
2213 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2214
2215 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002216 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2217 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002218 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002219 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002220 });
2221 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2222
2223 task_queue_.SendTask([this]() {
2224 DestroyStreams();
2225 DestroyCalls();
2226 });
2227}
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002228TEST_P(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002229 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002230 public:
Peter Boström5811a392015-12-10 13:02:50 +01002231 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002232
nissed30a1112016-04-18 05:15:22 -07002233 void OnFrame(const VideoFrame& video_frame) override {
2234 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002235 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002236 }
2237
2238 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002239 const int kWaitFrameTimeoutMs = 3000;
2240 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002241 << "Timeout while waiting for output frames.";
2242 }
2243
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002244 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002245 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002246 }
2247
2248 private:
2249 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002250 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002251
2252 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002253 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002254 };
2255
solenberg4fbae2b2015-08-28 04:07:10 -07002256 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002257 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002258 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002259
eladalon413ee9a2017-08-22 04:02:52 -07002260 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2261 // Initialize send stream.
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002262 CreateSenderCall();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002263
eladalon413ee9a2017-08-22 04:02:52 -07002264 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002265 GetVideoSendConfig()->pre_encode_callback = &observer;
eladalon413ee9a2017-08-22 04:02:52 -07002266 CreateVideoStreams();
2267
2268 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2269 // alternatively.
2270 int width = 168;
2271 int height = 132;
2272
2273 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2274 width, height, 1, 1, kVideoRotation_0));
2275 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2276 width, height, 2, 2, kVideoRotation_0));
2277 input_frames.push_back(CreateVideoFrame(width, height, 3));
2278 input_frames.push_back(CreateVideoFrame(width, height, 4));
2279 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2280 width, height, 5, 5, kVideoRotation_0));
2281
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002282 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -07002283 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002284 GetVideoSendStream()->SetSource(&forwarder,
2285 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002286 for (size_t i = 0; i < input_frames.size(); i++) {
2287 forwarder.IncomingCapturedFrame(input_frames[i]);
2288 // Wait until the output frame is received before sending the next input
2289 // frame. Or the previous input frame may be replaced without delivering.
2290 observer.WaitOutputFrame();
2291 }
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002292 GetVideoSendStream()->Stop();
2293 GetVideoSendStream()->SetSource(nullptr,
2294 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002295 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002296
2297 // Test if the input and output frames are the same. render_time_ms and
2298 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002299 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002300
eladalon413ee9a2017-08-22 04:02:52 -07002301 task_queue_.SendTask([this]() {
2302 DestroyStreams();
2303 DestroyCalls();
2304 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002305}
2306
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002307void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2308 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002309 EXPECT_EQ(frames1.size(), frames2.size());
2310 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002311 // Compare frame buffers, since we don't care about differing timestamps.
2312 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2313 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002314}
2315
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002316VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002317 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002318 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002319 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002320 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002321 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002322 // Use data as a ms timestamp.
2323 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002324 return frame;
2325}
2326
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002327TEST_P(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002328 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2329 public:
eladalon413ee9a2017-08-22 04:02:52 -07002330 explicit EncoderStateObserver(
2331 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002332 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002333 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002334 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002335 initialized_(false),
2336 callback_registered_(false),
2337 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002338 released_(false),
2339 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002340
2341 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002342 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002343 return released_;
2344 }
2345
2346 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002347 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002348 return initialized_ && callback_registered_;
2349 }
2350
2351 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002352 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002353 return num_releases_;
2354 }
2355
2356 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002357 int32_t InitEncode(const VideoCodec* codecSettings,
2358 int32_t numberOfCores,
2359 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002360 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002361 EXPECT_FALSE(initialized_);
2362 initialized_ = true;
2363 released_ = false;
2364 return 0;
2365 }
2366
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002367 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002368 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002369 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002370 EXPECT_TRUE(IsReadyForEncode());
2371
Peter Boström5811a392015-12-10 13:02:50 +01002372 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002373 return 0;
2374 }
2375
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002376 int32_t RegisterEncodeCompleteCallback(
2377 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002378 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002379 EXPECT_TRUE(initialized_);
2380 callback_registered_ = true;
2381 return 0;
2382 }
2383
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002384 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002385 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002386 EXPECT_TRUE(IsReadyForEncode());
2387 EXPECT_FALSE(released_);
2388 initialized_ = false;
2389 callback_registered_ = false;
2390 released_ = true;
2391 ++num_releases_;
2392 return 0;
2393 }
2394
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002395 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002396 EXPECT_TRUE(IsReadyForEncode());
2397 return 0;
2398 }
2399
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002400 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002401 EXPECT_TRUE(IsReadyForEncode());
2402 return 0;
2403 }
2404
stefanff483612015-12-21 03:14:00 -08002405 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002406 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002407 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002408 stream_ = send_stream;
2409 }
2410
stefanff483612015-12-21 03:14:00 -08002411 void ModifyVideoConfigs(
2412 VideoSendStream::Config* send_config,
2413 std::vector<VideoReceiveStream::Config>* receive_configs,
2414 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002415 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002416 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002417 }
2418
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002419 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002420 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002421
2422 task_queue_->SendTask([this]() {
2423 EXPECT_EQ(0u, num_releases());
2424 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2425 EXPECT_EQ(0u, num_releases());
2426 stream_->Stop();
2427 // Encoder should not be released before destroying the VideoSendStream.
2428 EXPECT_FALSE(IsReleased());
2429 EXPECT_TRUE(IsReadyForEncode());
2430 stream_->Start();
2431 });
2432
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002433 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002434 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002435 }
2436
eladalon413ee9a2017-08-22 04:02:52 -07002437 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002438 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002439 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002440 bool initialized_ RTC_GUARDED_BY(crit_);
2441 bool callback_registered_ RTC_GUARDED_BY(crit_);
2442 size_t num_releases_ RTC_GUARDED_BY(crit_);
2443 bool released_ RTC_GUARDED_BY(crit_);
Niels Möller4db138e2018-04-19 09:04:13 +02002444 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002445 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002446 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002447
stefane74eef12016-01-08 06:47:13 -08002448 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002449
2450 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002451 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002452}
2453
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002454TEST_P(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002455 class VideoCodecConfigObserver : public test::SendTest,
2456 public test::FakeEncoder {
2457 public:
2458 VideoCodecConfigObserver()
2459 : SendTest(kDefaultTimeoutMs),
2460 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002461 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002462 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002463 stream_(nullptr),
2464 encoder_factory_(this) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002465
2466 private:
stefanff483612015-12-21 03:14:00 -08002467 void ModifyVideoConfigs(
2468 VideoSendStream::Config* send_config,
2469 std::vector<VideoReceiveStream::Config>* receive_configs,
2470 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002471 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprangf24a0642017-02-28 13:23:26 -08002472 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002473 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002474 }
2475
stefanff483612015-12-21 03:14:00 -08002476 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002477 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002478 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002479 stream_ = send_stream;
2480 }
2481
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002482 int32_t InitEncode(const VideoCodec* config,
2483 int32_t number_of_cores,
2484 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002485 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002486 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002487 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002488 } else {
2489 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002490 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002491 }
2492 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002493 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002494 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2495 }
2496
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002497 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002498 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002499 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002500
sprangf24a0642017-02-28 13:23:26 -08002501 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002502 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002503 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002504 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002505 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2506 "new encoder settings.";
2507 }
2508
sprangf24a0642017-02-28 13:23:26 -08002509 const uint32_t kFirstMaxBitrateBps = 1000000;
2510 const uint32_t kSecondMaxBitrateBps = 2000000;
2511
pbos14fe7082016-04-20 06:35:56 -07002512 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002513 size_t num_initializations_;
2514 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002515 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002516 VideoEncoderConfig encoder_config_;
2517 } test;
2518
stefane74eef12016-01-08 06:47:13 -08002519 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002520}
2521
Sergey Silkin571e6c92018-04-03 10:03:31 +02002522static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002523template <typename T>
2524class VideoCodecConfigObserver : public test::SendTest,
2525 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002526 public:
2527 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2528 const char* codec_name)
2529 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2530 FakeEncoder(Clock::GetRealTimeClock()),
2531 video_codec_type_(video_codec_type),
2532 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002533 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002534 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002535 stream_(nullptr),
2536 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002537 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002538 }
2539
2540 private:
perkjfa10b552016-10-02 23:45:26 -07002541 class VideoStreamFactory
2542 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2543 public:
2544 VideoStreamFactory() {}
2545
2546 private:
2547 std::vector<VideoStream> CreateEncoderStreams(
2548 int width,
2549 int height,
2550 const VideoEncoderConfig& encoder_config) override {
2551 std::vector<VideoStream> streams =
2552 test::CreateVideoStreams(width, height, encoder_config);
2553 for (size_t i = 0; i < streams.size(); ++i) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002554 streams[i].num_temporal_layers =
2555 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkjfa10b552016-10-02 23:45:26 -07002556 }
2557 return streams;
2558 }
2559 };
2560
stefanff483612015-12-21 03:14:00 -08002561 void ModifyVideoConfigs(
2562 VideoSendStream::Config* send_config,
2563 std::vector<VideoReceiveStream::Config>* receive_configs,
2564 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002565 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002566 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002567
Niels Möller259a4972018-04-05 15:36:51 +02002568 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002569 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002570 encoder_config->video_stream_factory =
2571 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002572 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002573 }
2574
stefanff483612015-12-21 03:14:00 -08002575 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002576 VideoSendStream* send_stream,
2577 const std::vector<VideoReceiveStream*>& receive_streams) override {
2578 stream_ = send_stream;
2579 }
2580
2581 int32_t InitEncode(const VideoCodec* config,
2582 int32_t number_of_cores,
2583 size_t max_payload_size) override {
2584 EXPECT_EQ(video_codec_type_, config->codecType);
2585 VerifyCodecSpecifics(*config);
2586 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002587 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002588 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2589 }
2590
Sergey Silkin86684962018-03-28 19:32:37 +02002591 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002592 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002593 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2594 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002595
2596 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002597 EXPECT_TRUE(
2598 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002599 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002600
Sergey Silkin86684962018-03-28 19:32:37 +02002601 // Change encoder settings to actually trigger reconfiguration.
2602 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002603 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002604 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002605 ASSERT_TRUE(
2606 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002607 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002608 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2609 "new encoder settings.";
2610 }
2611
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002612 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002613 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002614 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002615 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2616 return 0;
2617 }
2618
2619 T encoder_settings_;
2620 const VideoCodecType video_codec_type_;
2621 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002622 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002623 size_t num_initializations_;
2624 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002625 test::EncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002626 VideoEncoderConfig encoder_config_;
2627};
2628
2629template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002630void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2631 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2632}
2633
2634template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002635void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2636 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002637 EXPECT_EQ(
2638 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002639}
kthelgason29a44e32016-09-27 03:52:02 -07002640
2641template <>
2642rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2643VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2644 return new rtc::RefCountedObject<
2645 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2646}
2647
Peter Boström53eda3d2015-03-27 15:53:18 +01002648template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002649void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2650 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2651}
2652
2653template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002654void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2655 const VideoCodec& config) const {
2656 // Check that the number of temporal layers has propagated properly to
2657 // VideoCodec.
2658 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002659 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002660
2661 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2662 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2663 config.simulcastStream[i].numberOfTemporalLayers);
2664 }
2665
2666 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002667 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002668 VideoCodecVP8 encoder_settings = encoder_settings_;
2669 encoder_settings.numberOfTemporalLayers =
2670 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002671 EXPECT_EQ(
2672 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002673}
kthelgason29a44e32016-09-27 03:52:02 -07002674
2675template <>
2676rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2677VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2678 return new rtc::RefCountedObject<
2679 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2680}
2681
Peter Boström53eda3d2015-03-27 15:53:18 +01002682template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002683void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2684 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2685}
2686
2687template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002688void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2689 const VideoCodec& config) const {
2690 // Check that the number of temporal layers has propagated properly to
2691 // VideoCodec.
2692 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002693 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002694
2695 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2696 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2697 config.simulcastStream[i].numberOfTemporalLayers);
2698 }
2699
2700 // Set expected temporal layers as they should have been set when
2701 // reconfiguring the encoder and not match the set config.
2702 VideoCodecVP9 encoder_settings = encoder_settings_;
2703 encoder_settings.numberOfTemporalLayers =
2704 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002705 EXPECT_EQ(
2706 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002707}
2708
kthelgason29a44e32016-09-27 03:52:02 -07002709template <>
2710rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2711VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2712 return new rtc::RefCountedObject<
2713 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2714}
2715
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002716TEST_P(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002717 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002718 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002719}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002720
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002721TEST_P(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002722 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002723 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002724}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002725
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002726TEST_P(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002727 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002728 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002729}
2730
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002731TEST_P(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002732 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002733 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002734 RtcpSenderReportTest()
2735 : SendTest(kDefaultTimeoutMs),
2736 rtp_packets_sent_(0),
2737 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002738
2739 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002740 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002741 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002742 RTPHeader header;
2743 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002744 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002745 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2746 return SEND_PACKET;
2747 }
2748
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002749 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002750 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002751 test::RtcpPacketParser parser;
2752 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002753
danilchap3dc929e2016-11-02 08:21:59 -07002754 if (parser.sender_report()->num_packets() > 0) {
2755 // Only compare sent media bytes if SenderPacketCount matches the
2756 // number of sent rtp packets (a new rtp packet could be sent before
2757 // the rtcp packet).
2758 if (parser.sender_report()->sender_octet_count() > 0 &&
2759 parser.sender_report()->sender_packet_count() ==
2760 rtp_packets_sent_) {
2761 EXPECT_EQ(media_bytes_sent_,
2762 parser.sender_report()->sender_octet_count());
2763 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002764 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002765 }
2766
2767 return SEND_PACKET;
2768 }
2769
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002770 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002771 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002772 }
2773
stefan4b569042015-11-11 06:39:57 -08002774 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002775 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2776 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002777 } test;
2778
stefane74eef12016-01-08 06:47:13 -08002779 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002780}
2781
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002782TEST_P(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002783 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002784
2785 class VideoStreamFactory
2786 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2787 public:
2788 VideoStreamFactory() {}
2789
2790 private:
2791 std::vector<VideoStream> CreateEncoderStreams(
2792 int width,
2793 int height,
2794 const VideoEncoderConfig& encoder_config) override {
2795 std::vector<VideoStream> streams =
2796 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002797 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
2798 streams[0].num_temporal_layers = 2;
2799 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2800 kScreencastMaxTargetBitrateDeltaKbps);
2801 streams[0].target_bitrate_bps =
2802 streams[0].max_bitrate_bps -
2803 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002804 return streams;
2805 }
2806 };
2807
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002808 class ScreencastTargetBitrateTest : public test::SendTest,
2809 public test::FakeEncoder {
2810 public:
2811 ScreencastTargetBitrateTest()
2812 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002813 test::FakeEncoder(Clock::GetRealTimeClock()),
2814 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002815
2816 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002817 int32_t InitEncode(const VideoCodec* config,
2818 int32_t number_of_cores,
2819 size_t max_payload_size) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002820 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002821 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002822 config->simulcastStream[0].maxBitrate -
2823 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002824 observation_complete_.Set();
Yves Gerey665174f2018-06-19 15:03:05 +02002825 return test::FakeEncoder::InitEncode(config, number_of_cores,
2826 max_payload_size);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002827 }
stefanff483612015-12-21 03:14:00 -08002828 void ModifyVideoConfigs(
2829 VideoSendStream::Config* send_config,
2830 std::vector<VideoReceiveStream::Config>* receive_configs,
2831 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002832 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002833 EXPECT_EQ(1u, encoder_config->number_of_streams);
2834 encoder_config->video_stream_factory =
2835 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002836 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002837 }
2838
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002839 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002840 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002841 << "Timed out while waiting for the encoder to be initialized.";
2842 }
Niels Möller4db138e2018-04-19 09:04:13 +02002843 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002844 } test;
2845
stefane74eef12016-01-08 06:47:13 -08002846 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002847}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002848
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02002849TEST_P(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002850 // These are chosen to be "kind of odd" to not be accidentally checked against
2851 // default values.
2852 static const int kMinBitrateKbps = 137;
2853 static const int kStartBitrateKbps = 345;
2854 static const int kLowerMaxBitrateKbps = 312;
2855 static const int kMaxBitrateKbps = 413;
2856 static const int kIncreasedStartBitrateKbps = 451;
2857 static const int kIncreasedMaxBitrateKbps = 597;
2858 class EncoderBitrateThresholdObserver : public test::SendTest,
2859 public test::FakeEncoder {
2860 public:
eladalon413ee9a2017-08-22 04:02:52 -07002861 explicit EncoderBitrateThresholdObserver(
2862 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002863 : SendTest(kDefaultTimeoutMs),
2864 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002865 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002866 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002867 bitrate_changed_event_(false, false),
2868 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002869 num_initializations_(0),
2870 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002871 send_stream_(nullptr),
2872 encoder_factory_(this) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002873
2874 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002875 int32_t InitEncode(const VideoCodec* codecSettings,
2876 int32_t numberOfCores,
2877 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002878 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2879 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002880 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002881 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2882 codecSettings->minBitrate);
2883 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2884 codecSettings->startBitrate);
2885 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2886 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002887 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002888 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002889 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2890 codecSettings->maxBitrate);
2891 // The start bitrate should be kept (-1) and capped to the max bitrate.
2892 // Since this is not an end-to-end call no receiver should have been
2893 // returning a REMB that could lower this estimate.
2894 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002895 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002896 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2897 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002898 // The start bitrate will be whatever the rate BitRateController
2899 // has currently configured but in the span of the set max and min
2900 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002901 }
2902 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002903 init_encode_event_.Set();
2904
pbos@webrtc.org00873182014-11-25 14:03:34 +00002905 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2906 maxPayloadSize);
2907 }
2908
Erik Språng566124a2018-04-23 12:32:22 +02002909 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Erik Språng08127a92016-11-16 16:41:30 +01002910 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002911 {
2912 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002913 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2914 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002915 }
Erik Språng08127a92016-11-16 16:41:30 +01002916 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002917 }
2918 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002919 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002920 }
2921
2922 void WaitForSetRates(uint32_t expected_bitrate) {
2923 EXPECT_TRUE(
2924 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2925 << "Timed out while waiting encoder rate to be set.";
2926 rtc::CritScope lock(&crit_);
2927 EXPECT_EQ(expected_bitrate, target_bitrate_);
2928 }
2929
Sebastian Jansson72582242018-07-13 13:19:42 +02002930 void ModifySenderCallConfig(Call::Config* config) override {
2931 config->bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2932 config->bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2933 config->bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002934 }
2935
perkjfa10b552016-10-02 23:45:26 -07002936 class VideoStreamFactory
2937 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2938 public:
2939 explicit VideoStreamFactory(int min_bitrate_bps)
2940 : min_bitrate_bps_(min_bitrate_bps) {}
2941
2942 private:
2943 std::vector<VideoStream> CreateEncoderStreams(
2944 int width,
2945 int height,
2946 const VideoEncoderConfig& encoder_config) override {
2947 std::vector<VideoStream> streams =
2948 test::CreateVideoStreams(width, height, encoder_config);
2949 streams[0].min_bitrate_bps = min_bitrate_bps_;
2950 return streams;
2951 }
2952
2953 const int min_bitrate_bps_;
2954 };
2955
stefanff483612015-12-21 03:14:00 -08002956 void ModifyVideoConfigs(
2957 VideoSendStream::Config* send_config,
2958 std::vector<VideoReceiveStream::Config>* receive_configs,
2959 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002960 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002961 // Set bitrates lower/higher than min/max to make sure they are properly
2962 // capped.
perkjfa10b552016-10-02 23:45:26 -07002963 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2964 // Create a new StreamFactory to be able to set
2965 // |VideoStream.min_bitrate_bps|.
2966 encoder_config->video_stream_factory =
2967 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002968 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002969 }
2970
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002971 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002972 call_ = sender_call;
2973 }
2974
stefanff483612015-12-21 03:14:00 -08002975 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002976 VideoSendStream* send_stream,
2977 const std::vector<VideoReceiveStream*>& receive_streams) override {
2978 send_stream_ = send_stream;
2979 }
2980
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002981 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002982 ASSERT_TRUE(
2983 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002984 << "Timed out while waiting for encoder to be configured.";
2985 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002986 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002987 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2988 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002989 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002990 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2991 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002992 });
perkj26091b12016-09-01 01:17:40 -07002993 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2994 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002995 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002996 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002997 ASSERT_TRUE(
2998 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002999 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00003000 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07003001 WaitForSetRates(kLowerMaxBitrateKbps);
3002
3003 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
3004 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
3005 ASSERT_TRUE(
3006 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01003007 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07003008 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07003009 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003010 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07003011 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003012 }
3013
eladalon413ee9a2017-08-22 04:02:52 -07003014 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07003015 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07003016 rtc::Event bitrate_changed_event_;
3017 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003018 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07003019
pbos@webrtc.org00873182014-11-25 14:03:34 +00003020 int num_initializations_;
3021 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01003022 webrtc::VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02003023 test::EncoderProxyFactory encoder_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01003024 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07003025 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003026
stefane74eef12016-01-08 06:47:13 -08003027 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003028}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003029
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003030TEST_P(VideoSendStreamTest, ReportsSentResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003031 static const size_t kNumStreams = 3;
3032 // Unusual resolutions to make sure that they are the ones being reported.
3033 static const struct {
3034 int width;
3035 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02003036 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003037 class ScreencastTargetBitrateTest : public test::SendTest,
3038 public test::FakeEncoder {
3039 public:
3040 ScreencastTargetBitrateTest()
3041 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02003042 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02003043 send_stream_(nullptr),
3044 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003045
3046 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003047 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003048 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07003049 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003050 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003051 specifics.codecType = kVideoCodecGeneric;
3052
3053 uint8_t buffer[16] = {0};
3054 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
Niels Möller23775882018-08-16 10:24:12 +02003055 encoded.SetTimestamp(input_image.timestamp());
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003056 encoded.capture_time_ms_ = input_image.render_time_ms();
3057
3058 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003059 encoded._frameType = (*frame_types)[i];
3060 encoded._encodedWidth = kEncodedResolution[i].width;
3061 encoded._encodedHeight = kEncodedResolution[i].height;
Niels Möllerd3b8c632018-08-27 15:33:42 +02003062 encoded.SetSpatialIndex(i);
brandtre78d2662017-01-16 05:57:16 -08003063 EncodedImageCallback* callback;
3064 {
3065 rtc::CritScope cs(&crit_sect_);
3066 callback = callback_;
3067 }
3068 RTC_DCHECK(callback);
3069 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003070 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003071 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003072 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003073 }
3074
Peter Boström5811a392015-12-10 13:02:50 +01003075 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003076 return 0;
3077 }
stefanff483612015-12-21 03:14:00 -08003078 void ModifyVideoConfigs(
3079 VideoSendStream::Config* send_config,
3080 std::vector<VideoReceiveStream::Config>* receive_configs,
3081 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003082 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003083 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003084 }
3085
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003086 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003087
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003088 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003089 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003090 << "Timed out while waiting for the encoder to send one frame.";
3091 VideoSendStream::Stats stats = send_stream_->GetStats();
3092
3093 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003094 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003095 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003096 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003097 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003098 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003099 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003100 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3101 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003102 }
3103 }
3104
stefanff483612015-12-21 03:14:00 -08003105 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003106 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003107 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003108 send_stream_ = send_stream;
3109 }
3110
3111 VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02003112 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003113 } test;
3114
stefane74eef12016-01-08 06:47:13 -08003115 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003116}
philipel0f9af012015-09-01 07:01:51 -07003117
Peter Boström12996152016-05-14 02:03:18 +02003118#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003119class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003120 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003121 Vp9HeaderObserver()
3122 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003123 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003124 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3125 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003126 frames_sent_(0),
3127 expected_width_(0),
3128 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003129
stefanff483612015-12-21 03:14:00 -08003130 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003131 VideoSendStream::Config* send_config,
3132 std::vector<VideoReceiveStream::Config>* receive_configs,
3133 VideoEncoderConfig* encoder_config) {}
3134
Åsa Perssonff24c042015-12-04 10:58:08 +01003135 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003136
3137 private:
minyue20c84cc2017-04-10 16:57:57 -07003138 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003139
perkjfa10b552016-10-02 23:45:26 -07003140 class VideoStreamFactory
3141 : public VideoEncoderConfig::VideoStreamFactoryInterface {
3142 public:
3143 explicit VideoStreamFactory(size_t number_of_temporal_layers)
3144 : number_of_temporal_layers_(number_of_temporal_layers) {}
3145
3146 private:
3147 std::vector<VideoStream> CreateEncoderStreams(
3148 int width,
3149 int height,
3150 const VideoEncoderConfig& encoder_config) override {
3151 std::vector<VideoStream> streams =
3152 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01003153 streams.back().num_temporal_layers = number_of_temporal_layers_;
perkjfa10b552016-10-02 23:45:26 -07003154 return streams;
3155 }
3156
3157 const size_t number_of_temporal_layers_;
3158 };
3159
stefanff483612015-12-21 03:14:00 -08003160 void ModifyVideoConfigs(
3161 VideoSendStream::Config* send_config,
3162 std::vector<VideoReceiveStream::Config>* receive_configs,
3163 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003164 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003165 send_config->rtp.payload_name = "VP9";
3166 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003167 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003168 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003169 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003170 EXPECT_EQ(1u, encoder_config->number_of_streams);
3171 encoder_config->video_stream_factory =
3172 new rtc::RefCountedObject<VideoStreamFactory>(
3173 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07003174 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003175 }
3176
perkjfa10b552016-10-02 23:45:26 -07003177 void ModifyVideoCaptureStartResolution(int* width,
3178 int* height,
3179 int* frame_rate) override {
3180 expected_width_ = *width;
3181 expected_height_ = *height;
3182 }
3183
philipel0f9af012015-09-01 07:01:51 -07003184 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003185 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3186 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003187 }
3188
3189 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3190 RTPHeader header;
3191 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3192
Åsa Perssonff24c042015-12-04 10:58:08 +01003193 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3194 const uint8_t* payload = packet + header.headerLength;
3195 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003196
Åsa Perssonff24c042015-12-04 10:58:08 +01003197 bool new_packet = packets_sent_ == 0 ||
3198 IsNewerSequenceNumber(header.sequenceNumber,
3199 last_header_.sequenceNumber);
3200 if (payload_length > 0 && new_packet) {
3201 RtpDepacketizer::ParsedPayload parsed;
3202 RtpDepacketizerVp9 depacketizer;
3203 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003204 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003205 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003206 const auto& vp9_header =
3207 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3208 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003209 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003210 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003211 InspectHeader(vp9_header);
philipel0f9af012015-09-01 07:01:51 -07003212
Åsa Perssonff24c042015-12-04 10:58:08 +01003213 ++packets_sent_;
3214 if (header.markerBit) {
3215 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003216 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003217 last_header_ = header;
philipel29d88462018-08-08 14:26:00 +02003218 last_vp9_ = vp9_header;
philipel0f9af012015-09-01 07:01:51 -07003219 }
philipel0f9af012015-09-01 07:01:51 -07003220 return SEND_PACKET;
3221 }
3222
philipel7fabd462015-09-03 04:42:32 -07003223 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003224 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3225 if (last_vp9_.picture_id > vp9.picture_id) {
3226 return vp9.picture_id == 0; // Wrap.
3227 } else {
3228 return vp9.picture_id == last_vp9_.picture_id + 1;
3229 }
3230 }
3231
3232 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003233 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3234 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3235 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3236 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3237 vp9.spatial_idx);
3238 }
3239
3240 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3241 uint8_t num_layers) const {
3242 switch (num_layers) {
3243 case 0:
3244 VerifyTemporalLayerStructure0(vp9);
3245 break;
3246 case 1:
3247 VerifyTemporalLayerStructure1(vp9);
3248 break;
3249 case 2:
3250 VerifyTemporalLayerStructure2(vp9);
3251 break;
3252 case 3:
3253 VerifyTemporalLayerStructure3(vp9);
3254 break;
3255 default:
3256 RTC_NOTREACHED();
3257 }
3258 }
3259
3260 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3261 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3262 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3263 EXPECT_FALSE(vp9.temporal_up_switch);
3264 }
3265
3266 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3267 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3268 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3269 EXPECT_FALSE(vp9.temporal_up_switch);
3270 }
3271
3272 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3273 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3274 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3275 EXPECT_LE(vp9.temporal_idx, 1);
3276 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3277 if (IsNewPictureId(vp9)) {
3278 uint8_t expected_tid =
3279 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3280 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3281 }
3282 }
3283
3284 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3285 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3286 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3287 EXPECT_LE(vp9.temporal_idx, 2);
3288 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3289 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3290 switch (vp9.temporal_idx) {
3291 case 0:
3292 EXPECT_EQ(2, last_vp9_.temporal_idx);
3293 EXPECT_FALSE(vp9.temporal_up_switch);
3294 break;
3295 case 1:
3296 EXPECT_EQ(2, last_vp9_.temporal_idx);
3297 EXPECT_TRUE(vp9.temporal_up_switch);
3298 break;
3299 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003300 EXPECT_LT(last_vp9_.temporal_idx, 2);
3301 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003302 break;
3303 }
3304 }
3305 }
3306
3307 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3308 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3309 return;
3310
3311 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3312 if (vp9.temporal_idx == 0)
3313 ++expected_tl0_idx;
3314 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3315 }
3316
3317 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3318 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3319 }
3320
3321 // Flexible mode (F=1): Non-flexible mode (F=0):
3322 //
3323 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3324 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3325 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3326 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3327 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3328 // M: | EXTENDED PID | M: | EXTENDED PID |
3329 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3330 // L: | T |U| S |D| L: | T |U| S |D|
3331 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3332 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3333 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3334 // X: |EXTENDED P_DIFF| V: | SS .. |
3335 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3336 // V: | SS .. |
3337 // +-+-+-+-+-+-+-+-+
3338 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3339 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3340 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3341 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003342
3343 if (vp9_settings_.numberOfSpatialLayers > 1) {
3344 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3345 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3346 EXPECT_EQ(vp9.spatial_idx, 0);
3347 } else {
3348 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3349 }
3350
3351 if (vp9_settings_.numberOfTemporalLayers > 1) {
3352 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3353 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3354 EXPECT_EQ(vp9.temporal_idx, 0);
3355 } else {
3356 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3357 }
3358
Åsa Perssonff24c042015-12-04 10:58:08 +01003359 if (vp9.ss_data_available) // V
3360 VerifySsData(vp9);
3361
3362 if (frames_sent_ == 0)
3363 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3364
3365 if (!vp9.inter_pic_predicted) {
3366 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3367 EXPECT_FALSE(vp9.temporal_up_switch);
3368 }
3369 }
3370
3371 // Scalability structure (SS).
3372 //
3373 // +-+-+-+-+-+-+-+-+
3374 // V: | N_S |Y|G|-|-|-|
3375 // +-+-+-+-+-+-+-+-+
3376 // Y: | WIDTH | N_S + 1 times
3377 // +-+-+-+-+-+-+-+-+
3378 // | HEIGHT |
3379 // +-+-+-+-+-+-+-+-+
3380 // G: | N_G |
3381 // +-+-+-+-+-+-+-+-+
3382 // N_G: | T |U| R |-|-| N_G times
3383 // +-+-+-+-+-+-+-+-+
3384 // | P_DIFF | R times
3385 // +-+-+-+-+-+-+-+-+
3386 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3387 EXPECT_TRUE(vp9.ss_data_available); // V
3388 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3389 vp9.num_spatial_layers);
3390 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003391 int expected_width = expected_width_;
3392 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003393 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003394 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3395 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3396 expected_width /= 2;
3397 expected_height /= 2;
3398 }
3399 }
3400
3401 void CompareConsecutiveFrames(const RTPHeader& header,
3402 const RTPVideoHeader& video) const {
philipel29d88462018-08-08 14:26:00 +02003403 const auto& vp9_header =
3404 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003405
3406 bool new_frame = packets_sent_ == 0 ||
3407 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003408 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003409 if (!new_frame) {
3410 EXPECT_FALSE(last_header_.markerBit);
3411 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003412 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3413 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3414 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3415 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003416 return;
3417 }
3418 // New frame.
philipel29d88462018-08-08 14:26:00 +02003419 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003420
3421 // Compare with last packet in previous frame.
3422 if (frames_sent_ == 0)
3423 return;
3424 EXPECT_TRUE(last_vp9_.end_of_frame);
3425 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003426 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3427 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003428 }
3429
Niels Möller4db138e2018-04-19 09:04:13 +02003430 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003431 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003432 webrtc::VideoEncoderConfig encoder_config_;
3433 RTPHeader last_header_;
3434 RTPVideoHeaderVP9 last_vp9_;
3435 size_t packets_sent_;
3436 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003437 int expected_width_;
3438 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003439};
3440
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003441TEST_P(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003442 const uint8_t kNumTemporalLayers = 1;
3443 const uint8_t kNumSpatialLayers = 1;
3444 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3445}
3446
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003447TEST_P(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003448 const uint8_t kNumTemporalLayers = 2;
3449 const uint8_t kNumSpatialLayers = 1;
3450 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3451}
3452
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003453TEST_P(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003454 const uint8_t kNumTemporalLayers = 3;
3455 const uint8_t kNumSpatialLayers = 1;
3456 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3457}
3458
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003459TEST_P(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003460 const uint8_t kNumTemporalLayers = 1;
3461 const uint8_t kNumSpatialLayers = 2;
3462 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3463}
3464
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003465TEST_P(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003466 const uint8_t kNumTemporalLayers = 2;
3467 const uint8_t kNumSpatialLayers = 2;
3468 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3469}
3470
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003471TEST_P(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003472 const uint8_t kNumTemporalLayers = 3;
3473 const uint8_t kNumSpatialLayers = 2;
3474 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3475}
3476
3477void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3478 uint8_t num_spatial_layers) {
3479 static const size_t kNumFramesToSend = 100;
3480 // Set to < kNumFramesToSend and coprime to length of temporal layer
3481 // structures to verify temporal id reset on key frame.
3482 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003483
3484 static const int kWidth = kMinVp9SpatialLayerWidth;
3485 static const int kHeight = kMinVp9SpatialLayerHeight;
3486 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003487 class NonFlexibleMode : public Vp9HeaderObserver {
3488 public:
3489 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3490 : num_temporal_layers_(num_temporal_layers),
3491 num_spatial_layers_(num_spatial_layers),
3492 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003493
stefanff483612015-12-21 03:14:00 -08003494 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003495 VideoSendStream::Config* send_config,
3496 std::vector<VideoReceiveStream::Config>* receive_configs,
3497 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003498 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003499 int bitrate_bps = 0;
3500 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3501 const int width = kWidth << sl_idx;
3502 const int height = kHeight << sl_idx;
3503 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3504 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3505 }
3506 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3507
Åsa Perssonff24c042015-12-04 10:58:08 +01003508 vp9_settings_.flexibleMode = false;
3509 vp9_settings_.frameDroppingOn = false;
3510 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3511 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3512 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003513 }
3514
Sergey Silkin86684962018-03-28 19:32:37 +02003515 void ModifyVideoCaptureStartResolution(int* width,
3516 int* height,
3517 int* frame_rate) override {
3518 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3519 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3520 *width = expected_width_;
3521 *height = expected_height_;
3522 }
3523
Åsa Perssonff24c042015-12-04 10:58:08 +01003524 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003525 bool ss_data_expected =
3526 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3527 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003528 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003529 if (num_spatial_layers_ > 1) {
3530 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3531 } else {
3532 EXPECT_FALSE(vp9.inter_layer_predicted);
3533 }
3534
asapersson38bb8ad2015-12-14 01:41:19 -08003535 EXPECT_EQ(!vp9.inter_pic_predicted,
3536 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003537
3538 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003539 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3540 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3541 } else {
3542 EXPECT_EQ(0, vp9.spatial_idx);
3543 }
3544 if (num_spatial_layers_ > 1)
3545 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003546 }
3547
3548 VerifyFixedTemporalLayerStructure(vp9,
3549 l_field_ ? num_temporal_layers_ : 0);
3550
3551 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003552 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003553 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003554 const uint8_t num_temporal_layers_;
3555 const uint8_t num_spatial_layers_;
3556 const bool l_field_;
3557 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003558
stefane74eef12016-01-08 06:47:13 -08003559 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003560}
3561
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003562TEST_P(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
asaperssond9f641e2016-01-21 01:11:35 -08003563 static const size_t kNumFramesToSend = 50;
3564 static const int kWidth = 4;
3565 static const int kHeight = 4;
3566 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3567 void ModifyVideoConfigsHook(
3568 VideoSendStream::Config* send_config,
3569 std::vector<VideoReceiveStream::Config>* receive_configs,
3570 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003571 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003572 vp9_settings_.flexibleMode = false;
3573 vp9_settings_.numberOfTemporalLayers = 1;
3574 vp9_settings_.numberOfSpatialLayers = 1;
3575
perkjfa10b552016-10-02 23:45:26 -07003576 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003577 }
3578
3579 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3580 if (frames_sent_ > kNumFramesToSend)
3581 observation_complete_.Set();
3582 }
perkjfa10b552016-10-02 23:45:26 -07003583
3584 void ModifyVideoCaptureStartResolution(int* width,
3585 int* height,
3586 int* frame_rate) override {
3587 expected_width_ = kWidth;
3588 expected_height_ = kHeight;
3589 *width = kWidth;
3590 *height = kHeight;
3591 }
asaperssond9f641e2016-01-21 01:11:35 -08003592 } test;
3593
3594 RunBaseTest(&test);
3595}
3596
kjellanderf9e2a362017-03-24 12:17:33 -07003597#if defined(WEBRTC_ANDROID)
3598// Crashes on Android; bugs.webrtc.org/7401
3599#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3600#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003601// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3602// the test after webrtc:9270 is implemented.
3603#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3604// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003605#endif
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003606TEST_P(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003607 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003608 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003609 VideoSendStream::Config* send_config,
3610 std::vector<VideoReceiveStream::Config>* receive_configs,
3611 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003612 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003613 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003614 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003615 vp9_settings_.numberOfTemporalLayers = 1;
3616 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003617 }
3618
Åsa Perssonff24c042015-12-04 10:58:08 +01003619 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3620 EXPECT_TRUE(vp9_header.flexible_mode);
3621 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3622 if (vp9_header.inter_pic_predicted) {
3623 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003624 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003625 }
3626 }
3627 } test;
3628
stefane74eef12016-01-08 06:47:13 -08003629 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003630}
Peter Boström12996152016-05-14 02:03:18 +02003631#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003632
perkj803d97f2016-11-01 11:45:46 -07003633void VideoSendStreamTest::TestRequestSourceRotateVideo(
3634 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003635 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003636
3637 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003638 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003639 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003640 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003641 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003642 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3643 }
3644
3645 CreateVideoStreams();
3646 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003647 GetVideoSendStream()->SetSource(&forwarder,
3648 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003649
3650 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3651 support_orientation_ext);
3652
3653 DestroyStreams();
3654}
3655
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003656TEST_P(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003657 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3658 TestRequestSourceRotateVideo(false);
3659}
3660
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003661TEST_P(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003662 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3663 TestRequestSourceRotateVideo(true);
3664}
3665
michaelta3328772016-11-29 09:25:03 -08003666// This test verifies that overhead is removed from the bandwidth estimate by
3667// testing that the maximum possible target payload rate is smaller than the
3668// maximum bandwidth estimate by the overhead rate.
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003669TEST_P(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003670 test::ScopedFieldTrials override_field_trials(
3671 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3672 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3673 public test::FakeEncoder {
3674 public:
eladalon413ee9a2017-08-22 04:02:52 -07003675 explicit RemoveOverheadFromBandwidthTest(
3676 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003677 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3678 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003679 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003680 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003681 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003682 max_bitrate_bps_(0),
3683 first_packet_sent_(false),
3684 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003685
Erik Språng566124a2018-04-23 12:32:22 +02003686 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
michaelta3328772016-11-29 09:25:03 -08003687 uint32_t frameRate) override {
3688 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003689 // Wait for the first sent packet so that videosendstream knows
3690 // rtp_overhead.
3691 if (first_packet_sent_) {
3692 max_bitrate_bps_ = bitrate.get_sum_bps();
3693 bitrate_changed_event_.Set();
3694 }
michaelta3328772016-11-29 09:25:03 -08003695 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3696 }
3697
3698 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3699 call_ = sender_call;
3700 }
3701
3702 void ModifyVideoConfigs(
3703 VideoSendStream::Config* send_config,
3704 std::vector<VideoReceiveStream::Config>* receive_configs,
3705 VideoEncoderConfig* encoder_config) override {
3706 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003707 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003708 EXPECT_FALSE(send_config->rtp.extensions.empty());
3709 }
3710
michaelt192132e2017-01-26 09:05:27 -08003711 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3712 rtc::CritScope lock(&crit_);
3713 first_packet_sent_ = true;
3714 return SEND_PACKET;
3715 }
3716
michaelta3328772016-11-29 09:25:03 -08003717 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003718 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003719 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003720 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003721 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003722 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3723 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003724 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003725 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003726 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3727 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07003728 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3729 });
michaelta3328772016-11-29 09:25:03 -08003730
3731 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003732 // overhead of 40B per packet video produces 2240bps overhead.
3733 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003734 EXPECT_TRUE(
3735 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003736 {
3737 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003738 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003739 }
3740 }
3741
3742 private:
eladalon413ee9a2017-08-22 04:02:52 -07003743 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möller4db138e2018-04-19 09:04:13 +02003744 test::EncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003745 Call* call_;
3746 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003747 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3748 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003749 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003750 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003751 RunBaseTest(&test);
3752}
3753
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003754TEST_P(VideoSendStreamTest, SendsKeepAlive) {
sprang168794c2017-07-06 04:38:06 -07003755 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003756
3757 class KeepaliveObserver : public test::SendTest {
3758 public:
3759 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3760
sprangdb2a9fc2017-08-09 06:42:32 -07003761 void OnRtpTransportControllerSendCreated(
3762 RtpTransportControllerSend* controller) override {
3763 RtpKeepAliveConfig config;
3764 config.timeout_interval_ms = kTimeoutMs;
3765 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3766 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003767 }
3768
sprang168794c2017-07-06 04:38:06 -07003769 private:
3770 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3771 RTPHeader header;
3772 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3773
sprangd2702ef2017-07-10 08:41:10 -07003774 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003775 // The video stream has started. Stop it now.
3776 if (capturer_)
3777 capturer_->Stop();
3778 } else {
3779 observation_complete_.Set();
3780 }
3781
3782 return SEND_PACKET;
3783 }
3784
sprang168794c2017-07-06 04:38:06 -07003785 void PerformTest() override {
3786 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3787 }
3788
3789 void OnFrameGeneratorCapturerCreated(
3790 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3791 capturer_ = frame_generator_capturer;
3792 }
3793
3794 test::FrameGeneratorCapturer* capturer_ = nullptr;
3795 } test;
3796
3797 RunBaseTest(&test);
3798}
3799
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003800class PacingFactorObserver : public test::SendTest {
3801 public:
3802 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003803 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003804 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3805 configure_send_side_(configure_send_side),
3806 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003807
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003808 void ModifyVideoConfigs(
3809 VideoSendStream::Config* send_config,
3810 std::vector<VideoReceiveStream::Config>* receive_configs,
3811 VideoEncoderConfig* encoder_config) override {
3812 // Check if send-side bwe extension is already present, and remove it if
3813 // it is not desired.
3814 bool has_send_side = false;
3815 for (auto it = send_config->rtp.extensions.begin();
3816 it != send_config->rtp.extensions.end(); ++it) {
3817 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3818 if (configure_send_side_) {
3819 has_send_side = true;
3820 } else {
3821 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003822 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003823 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003824 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003825 }
3826
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003827 if (configure_send_side_ && !has_send_side) {
3828 // Want send side, not present by default, so add it.
3829 send_config->rtp.extensions.emplace_back(
3830 RtpExtension::kTransportSequenceNumberUri,
3831 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003832 }
3833
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003834 // ALR only enabled for screenshare.
3835 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3836 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003837
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003838 void OnVideoStreamsCreated(
3839 VideoSendStream* send_stream,
3840 const std::vector<VideoReceiveStream*>& receive_streams) override {
3841 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3842 // Video streams created, check that pacing factor is correctly configured.
3843 EXPECT_EQ(expected_pacing_factor_,
3844 internal_send_peer.GetPacingFactorOverride());
3845 observation_complete_.Set();
3846 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003847
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003848 void PerformTest() override {
3849 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3850 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003851
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003852 private:
3853 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003854 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003855};
3856
3857std::string GetAlrProbingExperimentString() {
3858 return std::string(
3859 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3860 "/1.0,2875,80,40,-60,3/";
3861}
3862const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3863
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003864TEST_P(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003865 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003866 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003867 PacingFactorObserver test_with_send_side(true,
3868 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003869 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003870}
Erik Språng7c8cca32017-10-24 17:05:18 +02003871
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02003872TEST_P(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003873 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3874 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003875 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003876 RunBaseTest(&test_without_send_side);
3877}
3878
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003879// Test class takes as argument a function pointer to reset the send
3880// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3881// change the content type of a VideoSendStream, you need to recreate it.
3882// Stopping and recreating the stream can only be done on the main thread and in
3883// the context of VideoSendStreamTest (not BaseTest). The test switches from
3884// realtime to screenshare and back.
3885template <typename T>
3886class ContentSwitchTest : public test::SendTest {
3887 public:
3888 enum class StreamState {
3889 kBeforeSwitch = 0,
3890 kInScreenshare = 1,
3891 kAfterSwitchBack = 2,
3892 };
3893 static const uint32_t kMinPacketsToSend = 50;
3894
3895 explicit ContentSwitchTest(T* stream_reset_fun)
3896 : SendTest(test::CallTest::kDefaultTimeoutMs),
3897 content_switch_event_(false, false),
3898 call_(nullptr),
3899 state_(StreamState::kBeforeSwitch),
3900 send_stream_(nullptr),
3901 send_stream_config_(nullptr),
3902 packets_sent_(0),
3903 stream_resetter_(stream_reset_fun) {
3904 RTC_DCHECK(stream_resetter_);
3905 }
3906
3907 void OnVideoStreamsCreated(
3908 VideoSendStream* send_stream,
3909 const std::vector<VideoReceiveStream*>& receive_streams) override {
3910 rtc::CritScope lock(&crit_);
3911 send_stream_ = send_stream;
3912 }
3913
3914 void ModifyVideoConfigs(
3915 VideoSendStream::Config* send_config,
3916 std::vector<VideoReceiveStream::Config>* receive_configs,
3917 VideoEncoderConfig* encoder_config) override {
3918 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3919 encoder_config->min_transmit_bitrate_bps = 0;
3920 encoder_config->content_type =
3921 VideoEncoderConfig::ContentType::kRealtimeVideo;
3922 send_stream_config_ = send_config->Copy();
3923 encoder_config_ = encoder_config->Copy();
3924 }
3925
3926 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3927 call_ = sender_call;
3928 }
3929
3930 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3931 rtc::CritScope lock(&crit_);
3932
3933 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3934 float pacing_factor =
3935 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3936 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3937 if (send_stream_->GetStats().content_type ==
3938 webrtc::VideoContentType::SCREENSHARE) {
3939 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3940 }
3941
3942 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3943
3944 // Wait until at least kMinPacketsToSend packets to be sent, so that
3945 // some frames would be encoded.
3946 if (++packets_sent_ < kMinPacketsToSend)
3947 return SEND_PACKET;
3948
3949 if (state_ != StreamState::kAfterSwitchBack) {
3950 // We've sent kMinPacketsToSend packets, switch the content type and move
3951 // move to the next state.
3952 // Note that we need to recreate the stream if changing content type.
3953 packets_sent_ = 0;
3954 if (encoder_config_.content_type ==
3955 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3956 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3957 } else {
3958 encoder_config_.content_type =
3959 VideoEncoderConfig::ContentType::kRealtimeVideo;
3960 }
3961 switch (state_) {
3962 case StreamState::kBeforeSwitch:
3963 state_ = StreamState::kInScreenshare;
3964 break;
3965 case StreamState::kInScreenshare:
3966 state_ = StreamState::kAfterSwitchBack;
3967 break;
3968 case StreamState::kAfterSwitchBack:
3969 RTC_NOTREACHED();
3970 break;
3971 }
3972 content_switch_event_.Set();
3973 return SEND_PACKET;
3974 }
3975
3976 observation_complete_.Set();
3977 return SEND_PACKET;
3978 }
3979
3980 void PerformTest() override {
3981 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3982 ASSERT_TRUE(
3983 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3984 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3985 }
3986
3987 ASSERT_TRUE(Wait())
3988 << "Timed out waiting for a frame sent after switch back";
3989 }
3990
3991 private:
3992 StreamState GetStreamState() {
3993 rtc::CritScope lock(&crit_);
3994 return state_;
3995 }
3996
3997 rtc::CriticalSection crit_;
3998 rtc::Event content_switch_event_;
3999 Call* call_;
4000 StreamState state_ RTC_GUARDED_BY(crit_);
4001 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
4002 VideoSendStream::Config send_stream_config_;
4003 VideoEncoderConfig encoder_config_;
4004 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
4005 T* stream_resetter_;
4006};
4007
Sebastian Janssonc714b6e2018-08-30 15:45:41 +02004008TEST_P(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01004009 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
4010 const VideoEncoderConfig& encoder_config,
4011 test::BaseTest* test) {
4012 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
4013 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02004014 DestroyVideoSendStreams();
4015 SetVideoSendConfig(send_stream_config);
4016 SetVideoEncoderConfig(encoder_config);
4017 CreateVideoSendStreams();
4018 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
4019 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01004020 Start();
4021 });
4022 };
4023 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
4024 RunBaseTest(&test);
4025}
4026
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00004027} // namespace webrtc