blob: b93db533244eba976a9e1e845dc5977e0d3e6814 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "call/call.h"
15#include "call/rtp_transport_controller_send.h"
16#include "common_video/include/frame_callback.h"
17#include "common_video/include/video_frame.h"
18#include "modules/rtp_rtcp/include/rtp_header_parser.h"
19#include "modules/rtp_rtcp/include/rtp_rtcp.h"
20#include "modules/rtp_rtcp/source/rtcp_sender.h"
21#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
22#include "modules/video_coding/codecs/vp8/include/vp8.h"
23#include "modules/video_coding/codecs/vp9/include/vp9.h"
24#include "rtc_base/bind.h"
25#include "rtc_base/checks.h"
26#include "rtc_base/criticalsection.h"
27#include "rtc_base/event.h"
Sebastian Janssoncabe3832018-01-12 10:54:18 +010028#include "rtc_base/experiments/alr_experiment.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/logging.h"
30#include "rtc_base/platform_thread.h"
31#include "rtc_base/rate_limiter.h"
32#include "rtc_base/timeutils.h"
33#include "system_wrappers/include/sleep.h"
34#include "test/call_test.h"
35#include "test/configurable_frame_size_encoder.h"
36#include "test/fake_texture_frame.h"
37#include "test/field_trial.h"
38#include "test/frame_generator.h"
39#include "test/frame_generator_capturer.h"
40#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010041#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020042#include "test/gtest.h"
43#include "test/null_transport.h"
44#include "test/rtcp_packet_parser.h"
45#include "test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070046
Sebastian Janssona45c8da2018-01-16 10:55:29 +010047#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020048#include "video/send_statistics_proxy.h"
49#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010050#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000051
52namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010053namespace test {
54class VideoSendStreamPeer {
55 public:
56 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
57 : internal_stream_(
58 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
59 rtc::Optional<float> GetPacingFactorOverride() const {
60 return internal_stream_->GetPacingFactorOverride();
61 }
62
63 private:
64 internal::VideoSendStream const* const internal_stream_;
65};
66} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000067
sprang@webrtc.org346094c2014-02-18 08:40:33 +000068enum VideoFormat { kGeneric, kVP8, };
69
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070070void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
71 const std::vector<VideoFrame>& frames2);
72VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000073
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000074class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000075 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000076 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000077 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000078 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010079
80 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
81 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070082
83 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000084};
85
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000086TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070087 task_queue_.SendTask([this]() {
88 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000089
eladalon413ee9a2017-08-22 04:02:52 -070090 test::NullTransport transport;
91 CreateSendConfig(1, 0, 0, &transport);
92 CreateVideoStreams();
93 video_send_stream_->Start();
94 video_send_stream_->Start();
95 DestroyStreams();
96 DestroyCalls();
97 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000098}
99
100TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700101 task_queue_.SendTask([this]() {
102 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000103
eladalon413ee9a2017-08-22 04:02:52 -0700104 test::NullTransport transport;
105 CreateSendConfig(1, 0, 0, &transport);
106 CreateVideoStreams();
107 video_send_stream_->Stop();
108 video_send_stream_->Stop();
109 DestroyStreams();
110 DestroyCalls();
111 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000112}
113
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000114TEST_F(VideoSendStreamTest, SupportsCName) {
115 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000116 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000117 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000118 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000119
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000120 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000121 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700122 test::RtcpPacketParser parser;
123 EXPECT_TRUE(parser.Parse(packet, length));
124 if (parser.sdes()->num_packets() > 0) {
125 EXPECT_EQ(1u, parser.sdes()->chunks().size());
126 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000127
danilchap3dc929e2016-11-02 08:21:59 -0700128 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000129 }
130
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000131 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000132 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000133
stefanff483612015-12-21 03:14:00 -0800134 void ModifyVideoConfigs(
135 VideoSendStream::Config* send_config,
136 std::vector<VideoReceiveStream::Config>* receive_configs,
137 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000138 send_config->rtp.c_name = kCName;
139 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000140
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000141 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100142 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000143 }
144 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000145
stefane74eef12016-01-08 06:47:13 -0800146 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000147}
148
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000149TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000150 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000151 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000152 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000153 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100154 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000155 }
156
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000157 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000158 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000159 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000160
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000161 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
162 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
163 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700164 if (header.extension.absoluteSendTime != 0) {
165 // Wait for at least one packet with a non-zero send time. The send time
166 // is a 16-bit value derived from the system clock, and it is valid
167 // for a packet to have a zero send time. To tell that from an
168 // unpopulated value we'll wait for a packet with non-zero send time.
169 observation_complete_.Set();
170 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100171 RTC_LOG(LS_WARNING)
172 << "Got a packet with zero absoluteSendTime, waiting"
173 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700174 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000175
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000176 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000177 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000178
stefanff483612015-12-21 03:14:00 -0800179 void ModifyVideoConfigs(
180 VideoSendStream::Config* send_config,
181 std::vector<VideoReceiveStream::Config>* receive_configs,
182 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200183 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100184 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700185 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000186 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000187
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000188 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100189 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000190 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000191 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000192
stefane74eef12016-01-08 06:47:13 -0800193 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000194}
195
pbos@webrtc.org29023282013-09-11 10:14:56 +0000196TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000197 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000198 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000199 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000200 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000201 : SendTest(kDefaultTimeoutMs),
202 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000203 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100204 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000205 }
206
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000207 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000208 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000209 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000210 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000211
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000212 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
213 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000214 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000215 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100216 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000217
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000218 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000219 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000220
stefanff483612015-12-21 03:14:00 -0800221 void ModifyVideoConfigs(
222 VideoSendStream::Config* send_config,
223 std::vector<VideoReceiveStream::Config>* receive_configs,
224 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000225 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100226 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700227 send_config->rtp.extensions.push_back(RtpExtension(
228 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000229 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000230
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000231 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100232 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000233 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000234
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000235 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000236 } test;
237
stefane74eef12016-01-08 06:47:13 -0800238 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000239}
240
sprang867fb522015-08-03 04:38:41 -0700241TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700242 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700243 class TransportWideSequenceNumberObserver : public test::SendTest {
244 public:
245 TransportWideSequenceNumberObserver()
246 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
247 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
248 kRtpExtensionTransportSequenceNumber, kExtensionId));
249 }
250
251 private:
252 Action OnSendRtp(const uint8_t* packet, size_t length) override {
253 RTPHeader header;
254 EXPECT_TRUE(parser_->Parse(packet, length, &header));
255
256 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
257 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
258 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
259
Peter Boström5811a392015-12-10 13:02:50 +0100260 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700261
262 return SEND_PACKET;
263 }
264
stefanff483612015-12-21 03:14:00 -0800265 void ModifyVideoConfigs(
266 VideoSendStream::Config* send_config,
267 std::vector<VideoReceiveStream::Config>* receive_configs,
268 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700269 send_config->encoder_settings.encoder = &encoder_;
sprang867fb522015-08-03 04:38:41 -0700270 }
271
272 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100273 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700274 }
275
276 test::FakeEncoder encoder_;
277 } test;
278
stefane74eef12016-01-08 06:47:13 -0800279 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700280}
281
perkj803d97f2016-11-01 11:45:46 -0700282TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
283 class VideoRotationObserver : public test::SendTest {
284 public:
285 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
286 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
287 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
288 }
289
290 Action OnSendRtp(const uint8_t* packet, size_t length) override {
291 RTPHeader header;
292 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700293 // Only the last packet of the frame is required to have the extension.
294 if (!header.markerBit)
295 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700296 EXPECT_TRUE(header.extension.hasVideoRotation);
297 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
298 observation_complete_.Set();
299 return SEND_PACKET;
300 }
301
302 void ModifyVideoConfigs(
303 VideoSendStream::Config* send_config,
304 std::vector<VideoReceiveStream::Config>* receive_configs,
305 VideoEncoderConfig* encoder_config) override {
306 send_config->rtp.extensions.clear();
307 send_config->rtp.extensions.push_back(RtpExtension(
308 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
309 }
310
311 void OnFrameGeneratorCapturerCreated(
312 test::FrameGeneratorCapturer* frame_generator_capturer) override {
313 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
314 }
315
316 void PerformTest() override {
317 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
318 }
319 } test;
320
321 RunBaseTest(&test);
322}
323
ilnik00d802b2017-04-11 10:34:31 -0700324TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700325 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700326 public:
ilnik10894992017-06-21 08:23:19 -0700327 VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
ilnik00d802b2017-04-11 10:34:31 -0700328 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
329 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
330 }
331
332 Action OnSendRtp(const uint8_t* packet, size_t length) override {
333 RTPHeader header;
334 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700335 // Only the last packet of the frame must have extension.
336 if (!header.markerBit)
337 return SEND_PACKET;
ilnik00d802b2017-04-11 10:34:31 -0700338 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700339 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
340 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700341 observation_complete_.Set();
342 return SEND_PACKET;
343 }
344
345 void ModifyVideoConfigs(
346 VideoSendStream::Config* send_config,
347 std::vector<VideoReceiveStream::Config>* receive_configs,
348 VideoEncoderConfig* encoder_config) override {
349 send_config->rtp.extensions.clear();
350 send_config->rtp.extensions.push_back(
351 RtpExtension(RtpExtension::kVideoContentTypeUri,
352 test::kVideoContentTypeExtensionId));
353 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
354 }
355
356 void PerformTest() override {
357 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
358 }
359 } test;
360
361 RunBaseTest(&test);
362}
363
ilnik04f4d122017-06-19 07:18:55 -0700364TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700365 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700366 public:
ilnik10894992017-06-21 08:23:19 -0700367 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700368 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
369 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
370 }
371
372 Action OnSendRtp(const uint8_t* packet, size_t length) override {
373 RTPHeader header;
374 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700375 // Only the last packet of the frame must have extension.
376 if (!header.markerBit)
377 return SEND_PACKET;
378 EXPECT_TRUE(header.extension.has_video_timing);
379 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700380 return SEND_PACKET;
381 }
382
383 void ModifyVideoConfigs(
384 VideoSendStream::Config* send_config,
385 std::vector<VideoReceiveStream::Config>* receive_configs,
386 VideoEncoderConfig* encoder_config) override {
387 send_config->rtp.extensions.clear();
388 send_config->rtp.extensions.push_back(RtpExtension(
389 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
390 }
391
392 void PerformTest() override {
393 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
394 }
395 } test;
396
397 RunBaseTest(&test);
398}
399
danilchap901b2df2017-07-28 08:56:04 -0700400class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000401 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000402 FakeReceiveStatistics(uint32_t send_ssrc,
403 uint32_t last_sequence_number,
404 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700405 uint8_t fraction_lost) {
406 stat_.SetMediaSsrc(send_ssrc);
407 stat_.SetExtHighestSeqNum(last_sequence_number);
408 stat_.SetCumulativeLost(cumulative_lost);
409 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000410 }
411
danilchap901b2df2017-07-28 08:56:04 -0700412 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
413 EXPECT_GE(max_blocks, 1u);
414 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000415 }
416
417 private:
danilchap901b2df2017-07-28 08:56:04 -0700418 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000419};
420
brandtre602f0a2016-10-31 03:40:49 -0700421class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100422 public:
brandtre602f0a2016-10-31 03:40:49 -0700423 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800424 bool use_nack,
425 bool expect_red,
426 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800427 const std::string& codec,
428 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800429 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800430 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100431 payload_name_(codec),
432 use_nack_(use_nack),
433 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700434 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800435 sent_media_(false),
436 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800437 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100438
brandtr20d45472017-01-02 00:34:27 -0800439 // Some of the test cases are expected to time out and thus we are using
440 // a shorter timeout window than the default here.
441 static constexpr size_t kTimeoutMs = 10000;
442
Stefan Holmer4654d202015-12-08 09:10:43 +0100443 private:
444 Action OnSendRtp(const uint8_t* packet, size_t length) override {
445 RTPHeader header;
446 EXPECT_TRUE(parser_->Parse(packet, length, &header));
447
Stefan Holmer4654d202015-12-08 09:10:43 +0100448 int encapsulated_payload_type = -1;
449 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100450 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100451 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
452 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100453 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100454 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
455 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100456 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100457 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100458 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
459 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100460 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
461 length) {
462 // Not padding-only, media received outside of RED.
463 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800464 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100465 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100466 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000467
Stefan Holmer4654d202015-12-08 09:10:43 +0100468 if (header_extensions_enabled_) {
469 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
470 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
471 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
472 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
473 // 24 bits wrap.
474 EXPECT_GT(prev_header_.extension.absoluteSendTime,
475 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000476 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100477 EXPECT_GE(header.extension.absoluteSendTime,
478 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200479 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100480 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
481 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
482 prev_header_.extension.transportSequenceNumber;
483 EXPECT_EQ(1, seq_num_diff);
484 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200485
Stefan Holmer4654d202015-12-08 09:10:43 +0100486 if (encapsulated_payload_type != -1) {
487 if (encapsulated_payload_type ==
488 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700489 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800490 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100491 } else {
brandtr65a1e772016-12-12 01:54:58 -0800492 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000493 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000494 }
495
brandtr20d45472017-01-02 00:34:27 -0800496 if (sent_media_ && sent_ulpfec_) {
497 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100498 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000499
Stefan Holmer4654d202015-12-08 09:10:43 +0100500 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000501
Stefan Holmer4654d202015-12-08 09:10:43 +0100502 return SEND_PACKET;
503 }
504
eladalon413ee9a2017-08-22 04:02:52 -0700505 test::PacketTransport* CreateSendTransport(
506 test::SingleThreadedTaskQueueForTesting* task_queue,
507 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100508 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
509 // Configure some network delay.
510 const int kNetworkDelayMs = 100;
511 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800512 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100513 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700514 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700515 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700516 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100517 }
518
stefanff483612015-12-21 03:14:00 -0800519 void ModifyVideoConfigs(
520 VideoSendStream::Config* send_config,
521 std::vector<VideoReceiveStream::Config>* receive_configs,
522 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100523 if (use_nack_) {
524 send_config->rtp.nack.rtp_history_ms =
525 (*receive_configs)[0].rtp.nack.rtp_history_ms =
526 VideoSendStreamTest::kNackRtpHistoryMs;
527 }
brandtr696c9c62016-12-19 05:47:28 -0800528 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100529 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700530 send_config->rtp.ulpfec.red_payload_type =
531 VideoSendStreamTest::kRedPayloadType;
532 send_config->rtp.ulpfec.ulpfec_payload_type =
533 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800534 EXPECT_FALSE(send_config->rtp.extensions.empty());
535 if (!header_extensions_enabled_) {
536 send_config->rtp.extensions.clear();
537 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100538 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700539 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100540 }
nisse3b3622f2017-09-26 02:49:21 -0700541 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700542 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700543 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700544 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100545 }
546
547 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800548 EXPECT_EQ(expect_ulpfec_, Wait())
549 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100550 }
551
brandtr696c9c62016-12-19 05:47:28 -0800552 VideoEncoder* const encoder_;
553 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100554 const bool use_nack_;
555 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700556 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800557 bool sent_media_;
558 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100559 bool header_extensions_enabled_;
560 RTPHeader prev_header_;
561};
562
brandtre602f0a2016-10-31 03:40:49 -0700563TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800564 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
565 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800566 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100567}
568
brandtre602f0a2016-10-31 03:40:49 -0700569TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800570 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
571 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100572 RunBaseTest(&test);
573}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000574
stefan60e10c72017-08-23 10:40:00 -0700575class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
576 protected:
577 VideoSendStreamWithoutUlpfecTest()
578 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
579
580 test::ScopedFieldTrials field_trial_;
581};
582
583TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
584 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
585 UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
586 RunBaseTest(&test);
587}
588
Peter Boström39593972016-02-15 11:27:15 +0100589// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
590// since we'll still have to re-request FEC packets, effectively wasting
591// bandwidth since the receiver has to wait for FEC retransmissions to determine
592// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700593TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800594 std::unique_ptr<VideoEncoder> encoder(
595 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
596 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100597 RunBaseTest(&test);
598}
599
600// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800601TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800602 std::unique_ptr<VideoEncoder> encoder(
603 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
604 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100605 RunBaseTest(&test);
606}
607
danilchap9f5b6222017-03-02 06:22:21 -0800608// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
609TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800610 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
611 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100612 RunBaseTest(&test);
613}
614
Peter Boström12996152016-05-14 02:03:18 +0200615#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800616// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
617TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800618 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
619 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800620 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000621}
Peter Boström12996152016-05-14 02:03:18 +0200622#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000623
brandtre78d2662017-01-16 05:57:16 -0800624TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800625 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800626 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800627 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
628 RunBaseTest(&test);
629}
630
brandtr39f97292016-11-16 22:57:50 -0800631// TODO(brandtr): Move these FlexFEC tests when we have created
632// FlexfecSendStream.
633class FlexfecObserver : public test::EndToEndTest {
634 public:
635 FlexfecObserver(bool header_extensions_enabled,
636 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800637 const std::string& codec,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100638 VideoEncoder* encoder,
639 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800640 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800641 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800642 payload_name_(codec),
643 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800644 sent_media_(false),
645 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100646 header_extensions_enabled_(header_extensions_enabled),
647 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800648
649 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100650 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800651
652 private:
653 Action OnSendRtp(const uint8_t* packet, size_t length) override {
654 RTPHeader header;
655 EXPECT_TRUE(parser_->Parse(packet, length, &header));
656
brandtr39f97292016-11-16 22:57:50 -0800657 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
658 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
659 sent_flexfec_ = true;
660 } else {
661 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
662 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100663 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
664 num_video_streams_),
665 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800666 sent_media_ = true;
667 }
668
669 if (header_extensions_enabled_) {
670 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
671 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
672 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
673 }
674
brandtr0c5a1542016-11-23 04:42:26 -0800675 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800676 observation_complete_.Set();
677 }
678
679 return SEND_PACKET;
680 }
681
eladalon413ee9a2017-08-22 04:02:52 -0700682 test::PacketTransport* CreateSendTransport(
683 test::SingleThreadedTaskQueueForTesting* task_queue,
684 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800685 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
686 // Therefore we need some network delay.
687 const int kNetworkDelayMs = 100;
688 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800689 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800690 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700691 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700692 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700693 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800694 }
695
696 void ModifyVideoConfigs(
697 VideoSendStream::Config* send_config,
698 std::vector<VideoReceiveStream::Config>* receive_configs,
699 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800700 if (use_nack_) {
701 send_config->rtp.nack.rtp_history_ms =
702 (*receive_configs)[0].rtp.nack.rtp_history_ms =
703 VideoSendStreamTest::kNackRtpHistoryMs;
704 }
brandtr696c9c62016-12-19 05:47:28 -0800705 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800706 send_config->encoder_settings.payload_name = payload_name_;
707 if (header_extensions_enabled_) {
708 send_config->rtp.extensions.push_back(RtpExtension(
709 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
710 send_config->rtp.extensions.push_back(RtpExtension(
711 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800712 } else {
713 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800714 }
715 }
716
717 void PerformTest() override {
718 EXPECT_TRUE(Wait())
719 << "Timed out waiting for FlexFEC and/or media packets.";
720 }
721
brandtr696c9c62016-12-19 05:47:28 -0800722 VideoEncoder* const encoder_;
723 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800724 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800725 bool sent_media_;
726 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100727 const bool header_extensions_enabled_;
728 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800729};
730
brandtrd654a9b2016-12-05 05:38:19 -0800731TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800732 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100733 FlexfecObserver test(false, false, "VP8", encoder.get(), 1);
734 RunBaseTest(&test);
735}
736
737TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
738 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
739 FlexfecObserver test(false, false, "VP8", encoder.get(), 2);
brandtrd654a9b2016-12-05 05:38:19 -0800740 RunBaseTest(&test);
741}
742
743TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800744 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100745 FlexfecObserver test(false, true, "VP8", encoder.get(), 1);
brandtrd654a9b2016-12-05 05:38:19 -0800746 RunBaseTest(&test);
747}
748
brandtr39f97292016-11-16 22:57:50 -0800749TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800750 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100751 FlexfecObserver test(true, false, "VP8", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800752 RunBaseTest(&test);
753}
754
brandtr39f97292016-11-16 22:57:50 -0800755#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800756TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800757 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100758 FlexfecObserver test(false, false, "VP9", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800759 RunBaseTest(&test);
760}
761
brandtrd654a9b2016-12-05 05:38:19 -0800762TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800763 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100764 FlexfecObserver test(false, true, "VP9", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800765 RunBaseTest(&test);
766}
767#endif // defined(RTC_DISABLE_VP9)
768
brandtrd654a9b2016-12-05 05:38:19 -0800769TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800770 std::unique_ptr<VideoEncoder> encoder(
771 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100772 FlexfecObserver test(false, false, "H264", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800773 RunBaseTest(&test);
774}
775
brandtrd654a9b2016-12-05 05:38:19 -0800776TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800777 std::unique_ptr<VideoEncoder> encoder(
778 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100779 FlexfecObserver test(false, true, "H264", encoder.get(), 1);
brandtr696c9c62016-12-19 05:47:28 -0800780 RunBaseTest(&test);
781}
782
brandtre78d2662017-01-16 05:57:16 -0800783TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800784 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800785 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100786 FlexfecObserver test(false, false, "H264", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800787 RunBaseTest(&test);
788}
789
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000790void VideoSendStreamTest::TestNackRetransmission(
791 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000792 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000793 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000794 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000795 explicit NackObserver(uint32_t retransmit_ssrc,
796 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000797 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000798 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100799 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000800 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100801 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000802
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000803 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000804 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000805 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000806 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000807
Sebastian Janssond3f38162018-02-28 16:14:44 +0100808 int kRetransmitTarget = 6;
809 ++send_count_;
810 if (send_count_ == 5 || send_count_ == 25) {
811 nacked_sequence_numbers_.push_back(
812 static_cast<uint16_t>(header.sequenceNumber - 3));
813 nacked_sequence_numbers_.push_back(
814 static_cast<uint16_t>(header.sequenceNumber - 2));
815 nacked_sequence_numbers_.push_back(
816 static_cast<uint16_t>(header.sequenceNumber - 1));
817
danilchap8a1d2a32017-08-01 03:21:37 -0700818 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800819 nullptr, nullptr, transport_adapter_.get(),
820 RtcpIntervalConfig{});
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000821
pbosda903ea2015-10-02 02:36:56 -0700822 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100823 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000824
825 RTCPSender::FeedbackState feedback_state;
826
Sebastian Janssond3f38162018-02-28 16:14:44 +0100827 EXPECT_EQ(0, rtcp_sender.SendRTCP(
828 feedback_state, kRtcpNack,
829 static_cast<int>(nacked_sequence_numbers_.size()),
830 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000831 }
832
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000833 uint16_t sequence_number = header.sequenceNumber;
834
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000835 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100836 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
837 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000838 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000839 const uint8_t* rtx_header = packet + header.headerLength;
840 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
841 }
Sebastian Janssond3f38162018-02-28 16:14:44 +0100842 auto found = std::find(nacked_sequence_numbers_.begin(),
843 nacked_sequence_numbers_.end(), sequence_number);
844 if (found != nacked_sequence_numbers_.end()) {
845 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000846
Sebastian Janssond3f38162018-02-28 16:14:44 +0100847 if (++retransmit_count_ == kRetransmitTarget) {
848 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
849 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
850 observation_complete_.Set();
851 }
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000852 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000853
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000854 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000855 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000856
stefanff483612015-12-21 03:14:00 -0800857 void ModifyVideoConfigs(
858 VideoSendStream::Config* send_config,
859 std::vector<VideoReceiveStream::Config>* receive_configs,
860 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700861 transport_adapter_.reset(
862 new internal::TransportAdapter(send_config->send_transport));
863 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000864 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000865 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100866 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000867 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
868 }
869
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000870 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100871 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000872 }
873
kwiberg27f982b2016-03-01 11:52:33 -0800874 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000875 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100876 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000877 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000878 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100879 std::vector<uint16_t> nacked_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000880 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000881
stefane74eef12016-01-08 06:47:13 -0800882 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000883}
884
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000885TEST_F(VideoSendStreamTest, RetransmitsNack) {
886 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100887 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000888}
889
890TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
891 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000892 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000893}
894
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000895void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
896 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000897 // Use a fake encoder to output a frame of every size in the range [90, 290],
898 // for each size making sure that the exact number of payload bytes received
899 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000900 static const size_t kMaxPacketSize = 128;
901 static const size_t start = 90;
902 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000903
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000904 // Observer that verifies that the expected number of packets and bytes
905 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000906 class FrameFragmentationTest : public test::SendTest,
907 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000908 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000909 FrameFragmentationTest(size_t max_packet_size,
910 size_t start_size,
911 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000912 bool test_generic_packetization,
913 bool use_fec)
914 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000915 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000916 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000917 stop_size_(stop_size),
918 test_generic_packetization_(test_generic_packetization),
919 use_fec_(use_fec),
920 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100921 packets_lost_(0),
922 last_packet_count_(0),
923 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000924 accumulated_size_(0),
925 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000926 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000927 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700928 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000929 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000930 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700931 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000932 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000933
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000934 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000935 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000936 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000937 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000938 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000939
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000940 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000941
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000942 if (use_fec_) {
943 uint8_t payload_type = packet[header.headerLength];
944 bool is_fec = header.payloadType == kRedPayloadType &&
945 payload_type == kUlpfecPayloadType;
946 if (is_fec) {
947 fec_packet_received_ = true;
948 return SEND_PACKET;
949 }
950 }
951
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000952 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000953
954 if (use_fec_)
955 TriggerLossReport(header);
956
957 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200958 size_t overhead = header.headerLength + header.paddingLength;
959 // Only remove payload header and RED header if the packet actually
960 // contains payload.
961 if (length > overhead) {
962 overhead += (1 /* Generic header */);
963 if (use_fec_)
964 overhead += 1; // RED for FEC header.
965 }
966 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000967 accumulated_payload_ += length - overhead;
968 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000969
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000970 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000971 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000972 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
973 // With FEC enabled, frame size is incremented asynchronously, so
974 // "old" frames one byte too small may arrive. Accept, but don't
975 // increase expected frame size.
976 accumulated_size_ = 0;
977 accumulated_payload_ = 0;
978 return SEND_PACKET;
979 }
980
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000981 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000982 if (test_generic_packetization_) {
983 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
984 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000985
986 // Last packet of frame; reset counters.
987 accumulated_size_ = 0;
988 accumulated_payload_ = 0;
989 if (current_size_rtp_ == stop_size_) {
990 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100991 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000992 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000993 // Increase next expected frame size. If testing with FEC, make sure
994 // a FEC packet has been received for this frame size before
995 // proceeding, to make sure that redundancy packets don't exceed
996 // size limit.
997 if (!use_fec_) {
998 ++current_size_rtp_;
999 } else if (fec_packet_received_) {
1000 fec_packet_received_ = false;
1001 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001002
1003 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001004 ++current_size_frame_;
1005 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001006 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001007 }
1008
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001009 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001010 }
1011
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001012 void TriggerLossReport(const RTPHeader& header) {
1013 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001014 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001015 if (++packet_count_ % (100 / kLossPercent) == 0) {
1016 packets_lost_++;
1017 int loss_delta = packets_lost_ - last_packets_lost_;
1018 int packets_delta = packet_count_ - last_packet_count_;
1019 last_packet_count_ = packet_count_;
1020 last_packets_lost_ = packets_lost_;
1021 uint8_t loss_ratio =
1022 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001023 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001024 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001025 packets_lost_, // Cumulative lost.
1026 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001027 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001028 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001029 transport_adapter_.get(), RtcpIntervalConfig{});
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001030
pbosda903ea2015-10-02 02:36:56 -07001031 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001032 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001033
1034 RTCPSender::FeedbackState feedback_state;
1035
1036 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1037 }
1038 }
1039
nisseef8b61e2016-04-29 06:09:15 -07001040 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001041 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001042 // Increase frame size for next encoded frame, in the context of the
1043 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001044 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001045 ++current_size_frame_;
1046 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001047 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001048 }
1049
Stefan Holmere5904162015-03-26 11:11:06 +01001050 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07001051 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001052 const int kMinBitrateBps = 30000;
1053 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1054 return config;
1055 }
1056
stefanff483612015-12-21 03:14:00 -08001057 void ModifyVideoConfigs(
1058 VideoSendStream::Config* send_config,
1059 std::vector<VideoReceiveStream::Config>* receive_configs,
1060 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001061 transport_adapter_.reset(
1062 new internal::TransportAdapter(send_config->send_transport));
1063 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001064 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001065 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1066 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001067 }
1068
1069 if (!test_generic_packetization_)
1070 send_config->encoder_settings.payload_name = "VP8";
1071
1072 send_config->encoder_settings.encoder = &encoder_;
1073 send_config->rtp.max_packet_size = kMaxPacketSize;
1074 send_config->post_encode_callback = this;
1075
Erik Språng95261872015-04-10 11:58:49 +02001076 // Make sure there is at least one extension header, to make the RTP
1077 // header larger than the base length of 12 bytes.
1078 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001079
1080 // Setup screen content disables frame dropping which makes this easier.
1081 class VideoStreamFactory
1082 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1083 public:
1084 explicit VideoStreamFactory(size_t num_temporal_layers)
1085 : num_temporal_layers_(num_temporal_layers) {
1086 EXPECT_GT(num_temporal_layers, 0u);
1087 }
1088
1089 private:
1090 std::vector<VideoStream> CreateEncoderStreams(
1091 int width,
1092 int height,
1093 const VideoEncoderConfig& encoder_config) override {
1094 std::vector<VideoStream> streams =
1095 test::CreateVideoStreams(width, height, encoder_config);
1096 for (VideoStream& stream : streams) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01001097 stream.num_temporal_layers = num_temporal_layers_;
sprang4847ae62017-06-27 07:06:52 -07001098 }
1099 return streams;
1100 }
1101 const size_t num_temporal_layers_;
1102 };
1103
1104 encoder_config->video_stream_factory =
1105 new rtc::RefCountedObject<VideoStreamFactory>(2);
1106 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001107 }
1108
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001109 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001110 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001111 }
1112
kwiberg27f982b2016-03-01 11:52:33 -08001113 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001114 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001115
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001116 const size_t max_packet_size_;
1117 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001118 const bool test_generic_packetization_;
1119 const bool use_fec_;
1120
1121 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001122 uint32_t packets_lost_;
1123 uint32_t last_packet_count_;
1124 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001125 size_t accumulated_size_;
1126 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001127 bool fec_packet_received_;
1128
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001129 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001130 rtc::CriticalSection mutex_;
1131 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001132 };
1133
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001134 // Don't auto increment if FEC is used; continue sending frame size until
1135 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001136 FrameFragmentationTest test(
1137 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001138
stefane74eef12016-01-08 06:47:13 -08001139 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001140}
1141
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001142// TODO(sprang): Is there any way of speeding up these tests?
1143TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1144 TestPacketFragmentationSize(kGeneric, false);
1145}
1146
1147TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1148 TestPacketFragmentationSize(kGeneric, true);
1149}
1150
1151TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1152 TestPacketFragmentationSize(kVP8, false);
1153}
1154
1155TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1156 TestPacketFragmentationSize(kVP8, true);
1157}
1158
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001159// The test will go through a number of phases.
1160// 1. Start sending packets.
1161// 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 +00001162// suspend the stream.
1163// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001164// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001165// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001166// When the stream is detected again, and the stats show that the stream
1167// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001168TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1169 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001170
nissed30a1112016-04-18 05:15:22 -07001171 class RembObserver : public test::SendTest,
1172 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001173 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001174 RembObserver()
1175 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001176 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001177 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001178 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001179 rtp_count_(0),
1180 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001181 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001182 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001183 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001184
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001185 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001186 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001187 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001188 ++rtp_count_;
1189 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001190 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001191 last_sequence_number_ = header.sequenceNumber;
1192
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001193 if (test_state_ == kBeforeSuspend) {
1194 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001195 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001196 test_state_ = kDuringSuspend;
1197 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001198 if (header.paddingLength == 0) {
1199 // Received non-padding packet during suspension period. Reset the
1200 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001201 suspended_frame_count_ = 0;
1202 }
stefanf116bd02015-10-27 08:29:42 -07001203 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001204 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001205 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001206 // Non-padding packet observed. Test is almost complete. Will just
1207 // have to wait for the stats to change.
1208 test_state_ = kWaitingForStats;
1209 }
stefanf116bd02015-10-27 08:29:42 -07001210 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001211 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001212 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001213 if (stats.suspended == false) {
1214 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001215 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001216 }
stefanf116bd02015-10-27 08:29:42 -07001217 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001218 }
1219
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001220 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001221 }
1222
perkj26091b12016-09-01 01:17:40 -07001223 // This method implements the rtc::VideoSinkInterface. This is called when
1224 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001225 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001226 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001227 if (test_state_ == kDuringSuspend &&
1228 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001229 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001230 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001231 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001232 test_state_ = kWaitingForPacket;
1233 }
1234 }
1235
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001236 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001237 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001238 low_remb_bps_ = value;
1239 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001240
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001241 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001242 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001243 high_remb_bps_ = value;
1244 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001245
stefanff483612015-12-21 03:14:00 -08001246 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001247 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001248 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001249 stream_ = send_stream;
1250 }
1251
stefanff483612015-12-21 03:14:00 -08001252 void ModifyVideoConfigs(
1253 VideoSendStream::Config* send_config,
1254 std::vector<VideoReceiveStream::Config>* receive_configs,
1255 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001256 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001257 transport_adapter_.reset(
1258 new internal::TransportAdapter(send_config->send_transport));
1259 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001260 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001261 send_config->pre_encode_callback = this;
1262 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001263 int min_bitrate_bps =
1264 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001265 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001266 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001267 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001268 min_bitrate_bps + threshold_window + 5000);
1269 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1270 }
1271
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001272 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001273 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001274 }
1275
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001276 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001277 kBeforeSuspend,
1278 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001279 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001280 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001281 };
1282
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001283 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001284 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001285 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1286 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001287 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001288 transport_adapter_.get(), RtcpIntervalConfig{});
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001289
pbosda903ea2015-10-02 02:36:56 -07001290 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001291 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001292 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001293 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001294 }
1295 RTCPSender::FeedbackState feedback_state;
1296 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1297 }
1298
kwiberg27f982b2016-03-01 11:52:33 -08001299 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001300 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001301 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001302
Peter Boströmf2f82832015-05-01 13:00:41 +02001303 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001304 TestState test_state_ RTC_GUARDED_BY(crit_);
1305 int rtp_count_ RTC_GUARDED_BY(crit_);
1306 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1307 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1308 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1309 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001310 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001311
stefane74eef12016-01-08 06:47:13 -08001312 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001313}
1314
perkj71ee44c2016-06-15 00:47:53 -07001315// This test that padding stops being send after a while if the Camera stops
1316// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001317TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001318 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001319 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001320 NoPaddingWhenVideoIsMuted()
1321 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001322 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001323 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001324 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001325 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001326
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001327 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001328 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001329 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001330 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001331
1332 RTPHeader header;
1333 parser_->Parse(packet, length, &header);
1334 const bool only_padding =
1335 header.headerLength + header.paddingLength == length;
1336
1337 if (test_state_ == kBeforeStopCapture) {
1338 capturer_->Stop();
1339 test_state_ = kWaitingForPadding;
1340 } else if (test_state_ == kWaitingForPadding && only_padding) {
1341 test_state_ = kWaitingForNoPackets;
1342 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1343 only_padding) {
1344 observation_complete_.Set();
1345 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001346 return SEND_PACKET;
1347 }
1348
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001349 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001350 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001351 const int kNoPacketsThresholdMs = 2000;
1352 if (test_state_ == kWaitingForNoPackets &&
1353 (last_packet_time_ms_ > 0 &&
1354 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1355 kNoPacketsThresholdMs)) {
1356 capturer_->Start();
1357 test_state_ = kWaitingForPaddingAfterCameraRestart;
1358 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001359 return SEND_PACKET;
1360 }
1361
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001362 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001363
nisseef8b61e2016-04-29 06:09:15 -07001364 void OnFrameGeneratorCapturerCreated(
1365 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001366 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001367 capturer_ = frame_generator_capturer;
1368 }
1369
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001370 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001371 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001372 << "Timed out while waiting for RTP packets to stop being sent.";
1373 }
1374
perkj71ee44c2016-06-15 00:47:53 -07001375 enum TestState {
1376 kBeforeStopCapture,
1377 kWaitingForPadding,
1378 kWaitingForNoPackets,
1379 kWaitingForPaddingAfterCameraRestart
1380 };
1381
1382 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001383 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001384 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001385 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001386 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1387 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001388 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001389
stefane74eef12016-01-08 06:47:13 -08001390 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001391}
1392
isheriffcc5903e2016-10-04 08:29:38 -07001393TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1394 const int kCapacityKbps = 10000; // 10 Mbps
1395 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1396 public:
1397 PaddingIsPrimarilyRetransmissions()
1398 : EndToEndTest(kDefaultTimeoutMs),
1399 clock_(Clock::GetRealTimeClock()),
1400 padding_length_(0),
1401 total_length_(0),
1402 call_(nullptr) {}
1403
1404 private:
1405 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1406 call_ = sender_call;
1407 }
1408
1409 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1410 rtc::CritScope lock(&crit_);
1411
1412 RTPHeader header;
1413 parser_->Parse(packet, length, &header);
1414 padding_length_ += header.paddingLength;
1415 total_length_ += length;
1416 return SEND_PACKET;
1417 }
1418
eladalon413ee9a2017-08-22 04:02:52 -07001419 test::PacketTransport* CreateSendTransport(
1420 test::SingleThreadedTaskQueueForTesting* task_queue,
1421 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001422 const int kNetworkDelayMs = 50;
1423 FakeNetworkPipe::Config config;
1424 config.loss_percent = 10;
1425 config.link_capacity_kbps = kCapacityKbps;
1426 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001427 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001428 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001429 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001430 }
1431
1432 void ModifyVideoConfigs(
1433 VideoSendStream::Config* send_config,
1434 std::vector<VideoReceiveStream::Config>* receive_configs,
1435 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001436 // Turn on RTX.
1437 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1438 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001439 }
1440
1441 void PerformTest() override {
1442 // TODO(isheriff): Some platforms do not ramp up as expected to full
1443 // capacity due to packet scheduling delays. Fix that before getting
1444 // rid of this.
1445 SleepMs(5000);
1446 {
1447 rtc::CritScope lock(&crit_);
1448 // Expect padding to be a small percentage of total bytes sent.
1449 EXPECT_LT(padding_length_, .1 * total_length_);
1450 }
1451 }
1452
1453 rtc::CriticalSection crit_;
1454 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001455 size_t padding_length_ RTC_GUARDED_BY(crit_);
1456 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001457 Call* call_;
1458 } test;
1459
1460 RunBaseTest(&test);
1461}
1462
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001463// This test first observes "high" bitrate use at which point it sends a REMB to
1464// indicate that it should be lowered significantly. The test then observes that
1465// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1466// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001467//
1468// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1469// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001470TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1471 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001472 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001473 static const int kRembBitrateBps = 80000;
1474 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001475 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001476 public:
1477 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001478 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001479 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1480 stream_(nullptr),
1481 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001482
1483 private:
nisseef8b61e2016-04-29 06:09:15 -07001484 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001485 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001486 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001487
1488 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001489 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001490 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001491 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001492 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001493 if (!stats.substreams.empty()) {
1494 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001495 int total_bitrate_bps =
1496 stats.substreams.begin()->second.total_bitrate_bps;
1497 test::PrintResult("bitrate_stats_",
1498 "min_transmit_bitrate_low_remb",
1499 "bitrate_bps",
1500 static_cast<size_t>(total_bitrate_bps),
1501 "bps",
1502 false);
1503 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001504 rtp_rtcp_->SetRemb(kRembBitrateBps,
1505 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001506 rtp_rtcp_->Process();
1507 bitrate_capped_ = true;
1508 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001509 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001510 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001511 }
1512 }
stefanf116bd02015-10-27 08:29:42 -07001513 // Packets don't have to be delivered since the test is the receiver.
1514 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001515 }
1516
stefanff483612015-12-21 03:14:00 -08001517 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001518 VideoSendStream* send_stream,
1519 const std::vector<VideoReceiveStream*>& receive_streams) override {
1520 stream_ = send_stream;
1521 RtpRtcp::Configuration config;
1522 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001523 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001524 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001525 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001526 }
1527
stefanff483612015-12-21 03:14:00 -08001528 void ModifyVideoConfigs(
1529 VideoSendStream::Config* send_config,
1530 std::vector<VideoReceiveStream::Config>* receive_configs,
1531 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001532 feedback_transport_.reset(
1533 new internal::TransportAdapter(send_config->send_transport));
1534 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001535 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001536 }
1537
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001538 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001539 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001540 << "Timeout while waiting for low bitrate stats after REMB.";
1541 }
1542
kwiberg27f982b2016-03-01 11:52:33 -08001543 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1544 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001545 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001546 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001547 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001548 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001549
stefane74eef12016-01-08 06:47:13 -08001550 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001551}
1552
Stefan Holmer280de9e2016-09-30 10:06:51 +02001553TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1554 static const int kStartBitrateBps = 300000;
1555 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001556 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001557 class ChangingNetworkRouteTest : public test::EndToEndTest {
1558 public:
eladalon413ee9a2017-08-22 04:02:52 -07001559 explicit ChangingNetworkRouteTest(
1560 test::SingleThreadedTaskQueueForTesting* task_queue)
1561 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1562 task_queue_(task_queue),
1563 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001564 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1565 kRtpExtensionTransportSequenceNumber, kExtensionId));
1566 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001567
1568 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1569 call_ = sender_call;
1570 }
1571
Stefan Holmer280de9e2016-09-30 10:06:51 +02001572 void ModifyVideoConfigs(
1573 VideoSendStream::Config* send_config,
1574 std::vector<VideoReceiveStream::Config>* receive_configs,
1575 VideoEncoderConfig* encoder_config) override {
1576 send_config->rtp.extensions.clear();
1577 send_config->rtp.extensions.push_back(RtpExtension(
1578 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1579 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1580 (*receive_configs)[0].rtp.transport_cc = true;
1581 }
1582
1583 void ModifyAudioConfigs(
1584 AudioSendStream::Config* send_config,
1585 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1586 send_config->rtp.extensions.clear();
1587 send_config->rtp.extensions.push_back(RtpExtension(
1588 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1589 (*receive_configs)[0].rtp.extensions.clear();
1590 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1591 (*receive_configs)[0].rtp.transport_cc = true;
1592 }
1593
Stefan Holmerbe402962016-07-08 16:16:41 +02001594 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1595 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1596 observation_complete_.Set();
1597 }
1598
1599 return SEND_PACKET;
1600 }
1601
1602 void PerformTest() override {
1603 rtc::NetworkRoute new_route(true, 10, 20, -1);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001604 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001605
1606 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001607 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1608 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001609 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001610 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1611 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001612 });
1613
Stefan Holmerbe402962016-07-08 16:16:41 +02001614 EXPECT_TRUE(Wait())
1615 << "Timed out while waiting for start bitrate to be exceeded.";
1616
eladalon413ee9a2017-08-22 04:02:52 -07001617 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1618 bitrate_config.start_bitrate_bps = -1;
1619 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001620 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1621 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001622 // TODO(holmer): We should set the last sent packet id here and verify
1623 // that we correctly ignore any packet loss reported prior to that id.
1624 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001625 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1626 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001627 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1628 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001629 }
1630
1631 private:
eladalon413ee9a2017-08-22 04:02:52 -07001632 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001633 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001634 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001635
1636 RunBaseTest(&test);
1637}
1638
michaelt79e05882016-11-08 02:50:09 -08001639TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1640 class ChangingTransportOverheadTest : public test::EndToEndTest {
1641 public:
eladalon413ee9a2017-08-22 04:02:52 -07001642 explicit ChangingTransportOverheadTest(
1643 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001644 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001645 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001646 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001647 packets_sent_(0),
1648 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001649
1650 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1651 call_ = sender_call;
1652 }
1653
1654 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001655 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001656 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001657 if (++packets_sent_ < 100)
1658 return SEND_PACKET;
1659 observation_complete_.Set();
1660 return SEND_PACKET;
1661 }
1662
michaelta3328772016-11-29 09:25:03 -08001663 void ModifyVideoConfigs(
1664 VideoSendStream::Config* send_config,
1665 std::vector<VideoReceiveStream::Config>* receive_configs,
1666 VideoEncoderConfig* encoder_config) override {
1667 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1668 }
1669
michaelt79e05882016-11-08 02:50:09 -08001670 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001671 task_queue_->SendTask([this]() {
1672 transport_overhead_ = 100;
1673 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1674 transport_overhead_);
1675 });
1676
michaelt79e05882016-11-08 02:50:09 -08001677 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001678
sprang21253fc2017-02-27 03:35:47 -08001679 {
1680 rtc::CritScope cs(&lock_);
1681 packets_sent_ = 0;
1682 }
eladalon413ee9a2017-08-22 04:02:52 -07001683
1684 task_queue_->SendTask([this]() {
1685 transport_overhead_ = 500;
1686 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1687 transport_overhead_);
1688 });
1689
michaelt79e05882016-11-08 02:50:09 -08001690 EXPECT_TRUE(Wait());
1691 }
1692
1693 private:
eladalon413ee9a2017-08-22 04:02:52 -07001694 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001695 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001696 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001697 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001698 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001699 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001700 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001701
1702 RunBaseTest(&test);
1703}
1704
sprangf24a0642017-02-28 13:23:26 -08001705// Test class takes takes as argument a switch selecting if type switch should
1706// occur and a function pointer to reset the send stream. This is necessary
1707// since you cannot change the content type of a VideoSendStream, you need to
1708// recreate it. Stopping and recreating the stream can only be done on the main
1709// thread and in the context of VideoSendStreamTest (not BaseTest).
1710template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001711class MaxPaddingSetTest : public test::SendTest {
1712 public:
1713 static const uint32_t kMinTransmitBitrateBps = 400000;
1714 static const uint32_t kActualEncodeBitrateBps = 40000;
1715 static const uint32_t kMinPacketsToSend = 50;
1716
sprangf24a0642017-02-28 13:23:26 -08001717 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001718 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001719 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001720 call_(nullptr),
1721 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001722 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001723 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001724 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001725 stream_resetter_(stream_reset_fun) {
1726 RTC_DCHECK(stream_resetter_);
1727 }
sprang9c0b5512016-07-06 00:54:28 -07001728
1729 void OnVideoStreamsCreated(
1730 VideoSendStream* send_stream,
1731 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001732 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001733 send_stream_ = send_stream;
1734 }
1735
1736 void ModifyVideoConfigs(
1737 VideoSendStream::Config* send_config,
1738 std::vector<VideoReceiveStream::Config>* receive_configs,
1739 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001740 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001741 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001742 encoder_config->min_transmit_bitrate_bps = 0;
1743 encoder_config->content_type =
1744 VideoEncoderConfig::ContentType::kRealtimeVideo;
1745 } else {
1746 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1747 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1748 }
sprangf24a0642017-02-28 13:23:26 -08001749 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001750 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001751 }
1752
1753 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1754 call_ = sender_call;
1755 }
1756
1757 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1758 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001759 if (running_without_padding_)
1760 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1761
1762 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1763 // we have reliable data.
1764 if (++packets_sent_ < kMinPacketsToSend)
1765 return SEND_PACKET;
1766
1767 if (running_without_padding_) {
1768 // We've sent kMinPacketsToSend packets with default configuration, switch
1769 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001770 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001771 packets_sent_ = 0;
1772 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1773 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001774 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001775 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001776 return SEND_PACKET;
1777 }
1778
1779 // Make sure the pacer has been configured with a min transmit bitrate.
1780 if (call_->GetStats().max_padding_bitrate_bps > 0)
1781 observation_complete_.Set();
1782
1783 return SEND_PACKET;
1784 }
1785
1786 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001787 if (RunningWithoutPadding()) {
1788 ASSERT_TRUE(
1789 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001790 (*stream_resetter_)(send_stream_config_, encoder_config_);
1791 }
1792
sprang9c0b5512016-07-06 00:54:28 -07001793 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1794 }
1795
1796 private:
sprangf24a0642017-02-28 13:23:26 -08001797 bool RunningWithoutPadding() const {
1798 rtc::CritScope lock(&crit_);
1799 return running_without_padding_;
1800 }
1801
sprang9c0b5512016-07-06 00:54:28 -07001802 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001803 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001804 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001805 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001806 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001807 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001808 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001809 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001810 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001811};
1812
1813TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001814 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1815 const VideoEncoderConfig& encoder_config) {};
1816 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001817 RunBaseTest(&test);
1818}
1819
1820TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001821 // Function for removing and recreating the send stream with a new config.
1822 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1823 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001824 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1825 Stop();
1826 sender_call_->DestroyVideoSendStream(video_send_stream_);
1827 video_send_config_ = send_stream_config.Copy();
1828 video_encoder_config_ = encoder_config.Copy();
1829 video_send_stream_ = sender_call_->CreateVideoSendStream(
1830 video_send_config_.Copy(), video_encoder_config_.Copy());
1831 video_send_stream_->SetSource(
1832 frame_generator_capturer_.get(),
1833 VideoSendStream::DegradationPreference::kMaintainResolution);
1834 Start();
1835 });
sprangf24a0642017-02-28 13:23:26 -08001836 };
1837 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001838 RunBaseTest(&test);
1839}
1840
perkjfa10b552016-10-02 23:45:26 -07001841// This test verifies that new frame sizes reconfigures encoders even though not
1842// (yet) sending. The purpose of this is to permit encoding as quickly as
1843// possible once we start sending. Likely the frames being input are from the
1844// same source that will be sent later, which just means that we're ready
1845// earlier.
1846TEST_F(VideoSendStreamTest,
1847 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1848 class EncoderObserver : public test::FakeEncoder {
1849 public:
1850 EncoderObserver()
1851 : FakeEncoder(Clock::GetRealTimeClock()),
1852 init_encode_called_(false, false),
1853 number_of_initializations_(0),
1854 last_initialized_frame_width_(0),
1855 last_initialized_frame_height_(0) {}
1856
1857 void WaitForResolution(int width, int height) {
1858 {
1859 rtc::CritScope lock(&crit_);
1860 if (last_initialized_frame_width_ == width &&
1861 last_initialized_frame_height_ == height) {
1862 return;
1863 }
1864 }
Erik Språng08127a92016-11-16 16:41:30 +01001865 EXPECT_TRUE(
1866 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001867 {
1868 rtc::CritScope lock(&crit_);
1869 EXPECT_EQ(width, last_initialized_frame_width_);
1870 EXPECT_EQ(height, last_initialized_frame_height_);
1871 }
1872 }
1873
1874 private:
1875 int32_t InitEncode(const VideoCodec* config,
1876 int32_t number_of_cores,
1877 size_t max_payload_size) override {
1878 rtc::CritScope lock(&crit_);
1879 last_initialized_frame_width_ = config->width;
1880 last_initialized_frame_height_ = config->height;
1881 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001882 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001883 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1884 }
1885
1886 int32_t Encode(const VideoFrame& input_image,
1887 const CodecSpecificInfo* codec_specific_info,
1888 const std::vector<FrameType>* frame_types) override {
1889 ADD_FAILURE()
1890 << "Unexpected Encode call since the send stream is not started";
1891 return 0;
1892 }
1893
1894 rtc::CriticalSection crit_;
1895 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001896 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1897 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1898 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001899 };
1900
perkjfa10b552016-10-02 23:45:26 -07001901 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001902 EncoderObserver encoder;
eladalon413ee9a2017-08-22 04:02:52 -07001903
1904 task_queue_.SendTask([this, &transport, &encoder]() {
1905 CreateSenderCall(Call::Config(event_log_.get()));
1906 CreateSendConfig(1, 0, 0, &transport);
1907 video_send_config_.encoder_settings.encoder = &encoder;
1908 CreateVideoStreams();
1909 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1910 kDefaultHeight);
1911 frame_generator_capturer_->Start();
1912 });
perkjfa10b552016-10-02 23:45:26 -07001913
1914 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001915
1916 task_queue_.SendTask([this]() {
1917 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1918 kDefaultHeight * 2);
1919 });
1920
perkjfa10b552016-10-02 23:45:26 -07001921 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001922
1923 task_queue_.SendTask([this]() {
1924 DestroyStreams();
1925 DestroyCalls();
1926 });
perkjfa10b552016-10-02 23:45:26 -07001927}
1928
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001929TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1930 class StartBitrateObserver : public test::FakeEncoder {
1931 public:
1932 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001933 : FakeEncoder(Clock::GetRealTimeClock()),
1934 start_bitrate_changed_(false, false),
1935 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001936 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 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001941 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001942 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1943 }
1944
1945 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1946 rtc::CritScope lock(&crit_);
1947 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001948 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001949 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1950 }
1951
1952 int GetStartBitrateKbps() const {
1953 rtc::CritScope lock(&crit_);
1954 return start_bitrate_kbps_;
1955 }
1956
pbos14fe7082016-04-20 06:35:56 -07001957 bool WaitForStartBitrate() {
1958 return start_bitrate_changed_.Wait(
1959 VideoSendStreamTest::kDefaultTimeoutMs);
1960 }
1961
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001962 private:
pbos5ad935c2016-01-25 03:52:44 -08001963 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001964 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001965 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001966 };
1967
philipel4fb651d2017-04-10 03:54:05 -07001968 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001969
solenberg4fbae2b2015-08-28 04:07:10 -07001970 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001971 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001972
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001973 BitrateConstraints bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001974 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001975 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1976 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001977
1978 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001979 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001980 // Since this test does not use a capturer, set |internal_source| = true.
1981 // Encoder configuration is otherwise updated on the next video frame.
1982 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001983
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001984 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001985
pbos14fe7082016-04-20 06:35:56 -07001986 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001987 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001988 encoder.GetStartBitrateKbps());
1989
perkjfa10b552016-10-02 23:45:26 -07001990 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001991 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001992
1993 // New bitrate should be reconfigured above the previous max. As there's no
1994 // network connection this shouldn't be flaky, as no bitrate should've been
1995 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001996 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001997 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1998 encoder.GetStartBitrateKbps());
1999
2000 DestroyStreams();
2001}
2002
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002003class StartStopBitrateObserver : public test::FakeEncoder {
2004 public:
2005 StartStopBitrateObserver()
2006 : FakeEncoder(Clock::GetRealTimeClock()),
2007 encoder_init_(false, false),
2008 bitrate_changed_(false, false) {}
2009 int32_t InitEncode(const VideoCodec* config,
2010 int32_t number_of_cores,
2011 size_t max_payload_size) override {
2012 rtc::CritScope lock(&crit_);
2013 encoder_init_.Set();
2014 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2015 }
2016
2017 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2018 uint32_t framerate) override {
2019 rtc::CritScope lock(&crit_);
2020 bitrate_kbps_ = bitrate.get_sum_kbps();
2021 bitrate_changed_.Set();
2022 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2023 }
2024
2025 bool WaitForEncoderInit() {
2026 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2027 }
2028
2029 bool WaitBitrateChanged(bool non_zero) {
2030 do {
2031 rtc::Optional<int> bitrate_kbps;
2032 {
2033 rtc::CritScope lock(&crit_);
2034 bitrate_kbps = bitrate_kbps_;
2035 }
2036 if (!bitrate_kbps)
2037 continue;
2038
2039 if ((non_zero && *bitrate_kbps > 0) ||
2040 (!non_zero && *bitrate_kbps == 0)) {
2041 return true;
2042 }
2043 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2044 return false;
2045 }
2046
2047 private:
2048 rtc::CriticalSection crit_;
2049 rtc::Event encoder_init_;
2050 rtc::Event bitrate_changed_;
2051 rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
2052};
2053
perkj57c21f92016-06-17 07:27:16 -07002054// This test that if the encoder use an internal source, VideoEncoder::SetRates
2055// will be called with zero bitrate during initialization and that
2056// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2057// with zero bitrate.
2058TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002059 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002060 StartStopBitrateObserver encoder;
perkj57c21f92016-06-17 07:27:16 -07002061
eladalon413ee9a2017-08-22 04:02:52 -07002062 task_queue_.SendTask([this, &transport, &encoder]() {
2063 CreateSenderCall(Call::Config(event_log_.get()));
2064 CreateSendConfig(1, 0, 0, &transport);
2065
2066 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2067
2068 video_send_config_.encoder_settings.encoder = &encoder;
2069 video_send_config_.encoder_settings.internal_source = true;
2070
2071 CreateVideoStreams();
2072 });
perkj57c21f92016-06-17 07:27:16 -07002073
2074 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002075
eladalon413ee9a2017-08-22 04:02:52 -07002076 task_queue_.SendTask([this]() {
2077 video_send_stream_->Start();
2078 });
Erik Språng08127a92016-11-16 16:41:30 +01002079 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2080
eladalon413ee9a2017-08-22 04:02:52 -07002081 task_queue_.SendTask([this]() {
2082 video_send_stream_->Stop();
2083 });
Erik Språng08127a92016-11-16 16:41:30 +01002084 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2085
eladalon413ee9a2017-08-22 04:02:52 -07002086 task_queue_.SendTask([this]() {
2087 video_send_stream_->Start();
2088 });
Erik Språng08127a92016-11-16 16:41:30 +01002089 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002090
eladalon413ee9a2017-08-22 04:02:52 -07002091 task_queue_.SendTask([this]() {
2092 DestroyStreams();
2093 DestroyCalls();
2094 });
perkj57c21f92016-06-17 07:27:16 -07002095}
2096
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002097// Tests that when the encoder uses an internal source, the VideoEncoder will
2098// be updated with a new bitrate when turning the VideoSendStream on/off with
2099// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2100// is reconfigured with new active layers.
2101TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
2102 test::NullTransport transport;
2103 StartStopBitrateObserver encoder;
2104
2105 task_queue_.SendTask([this, &transport, &encoder]() {
2106 CreateSenderCall(Call::Config(event_log_.get()));
2107 // Create two simulcast streams.
2108 CreateSendConfig(2, 0, 0, &transport);
2109
2110 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2111
2112 video_send_config_.encoder_settings.encoder = &encoder;
2113 video_send_config_.encoder_settings.internal_source = true;
2114 video_send_config_.encoder_settings.payload_name = "VP8";
2115
2116 CreateVideoStreams();
2117 });
2118
2119 EXPECT_TRUE(encoder.WaitForEncoderInit());
2120
2121 // When we turn on the simulcast layers it will update the BitrateAllocator,
2122 // which in turn updates the VideoEncoder's bitrate.
2123 task_queue_.SendTask([this]() {
2124 video_send_stream_->UpdateActiveSimulcastLayers({true, true});
2125 });
2126 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2127
2128 video_encoder_config_.simulcast_layers[0].active = true;
2129 video_encoder_config_.simulcast_layers[1].active = false;
2130 task_queue_.SendTask([this]() {
2131 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
2132 });
2133 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2134 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2135 // active. Once the change is made for a "soft" reconfiguration we can remove
2136 // the expecation for an encoder init. We can also test that bitrate changes
2137 // when just updating individual active layers, which should change the
2138 // bitrate set to the video encoder.
2139 EXPECT_TRUE(encoder.WaitForEncoderInit());
2140 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2141
2142 // Turning off both simulcast layers should trigger a bitrate change of 0.
2143 video_encoder_config_.simulcast_layers[0].active = false;
2144 video_encoder_config_.simulcast_layers[1].active = false;
2145 task_queue_.SendTask([this]() {
2146 video_send_stream_->UpdateActiveSimulcastLayers({false, false});
2147 });
2148 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2149
2150 task_queue_.SendTask([this]() {
2151 DestroyStreams();
2152 DestroyCalls();
2153 });
2154}
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002155TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002156 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002157 public:
Peter Boström5811a392015-12-10 13:02:50 +01002158 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002159
nissed30a1112016-04-18 05:15:22 -07002160 void OnFrame(const VideoFrame& video_frame) override {
2161 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002162 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002163 }
2164
2165 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002166 const int kWaitFrameTimeoutMs = 3000;
2167 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002168 << "Timeout while waiting for output frames.";
2169 }
2170
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002171 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002172 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002173 }
2174
2175 private:
2176 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002177 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002178
2179 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002180 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002181 };
2182
solenberg4fbae2b2015-08-28 04:07:10 -07002183 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002184 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002185 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002186
eladalon413ee9a2017-08-22 04:02:52 -07002187 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2188 // Initialize send stream.
2189 CreateSenderCall(Call::Config(event_log_.get()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002190
eladalon413ee9a2017-08-22 04:02:52 -07002191 CreateSendConfig(1, 0, 0, &transport);
2192 video_send_config_.pre_encode_callback = &observer;
2193 CreateVideoStreams();
2194
2195 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2196 // alternatively.
2197 int width = 168;
2198 int height = 132;
2199
2200 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2201 width, height, 1, 1, kVideoRotation_0));
2202 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2203 width, height, 2, 2, kVideoRotation_0));
2204 input_frames.push_back(CreateVideoFrame(width, height, 3));
2205 input_frames.push_back(CreateVideoFrame(width, height, 4));
2206 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2207 width, height, 5, 5, kVideoRotation_0));
2208
2209 video_send_stream_->Start();
2210 test::FrameForwarder forwarder;
2211 video_send_stream_->SetSource(
2212 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
2213 for (size_t i = 0; i < input_frames.size(); i++) {
2214 forwarder.IncomingCapturedFrame(input_frames[i]);
2215 // Wait until the output frame is received before sending the next input
2216 // frame. Or the previous input frame may be replaced without delivering.
2217 observer.WaitOutputFrame();
2218 }
2219 video_send_stream_->Stop();
2220 video_send_stream_->SetSource(
2221 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
2222 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002223
2224 // Test if the input and output frames are the same. render_time_ms and
2225 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002226 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002227
eladalon413ee9a2017-08-22 04:02:52 -07002228 task_queue_.SendTask([this]() {
2229 DestroyStreams();
2230 DestroyCalls();
2231 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002232}
2233
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002234void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2235 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002236 EXPECT_EQ(frames1.size(), frames2.size());
2237 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002238 // Compare frame buffers, since we don't care about differing timestamps.
2239 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2240 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002241}
2242
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002243VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002244 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002245 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002246 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002247 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002248 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002249 // Use data as a ms timestamp.
2250 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002251 return frame;
2252}
2253
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002254TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2255 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2256 public:
eladalon413ee9a2017-08-22 04:02:52 -07002257 explicit EncoderStateObserver(
2258 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002259 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002260 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002261 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002262 initialized_(false),
2263 callback_registered_(false),
2264 num_releases_(0),
2265 released_(false) {}
2266
2267 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002268 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002269 return released_;
2270 }
2271
2272 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002273 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002274 return initialized_ && callback_registered_;
2275 }
2276
2277 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002278 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002279 return num_releases_;
2280 }
2281
2282 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002283 int32_t InitEncode(const VideoCodec* codecSettings,
2284 int32_t numberOfCores,
2285 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002286 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002287 EXPECT_FALSE(initialized_);
2288 initialized_ = true;
2289 released_ = false;
2290 return 0;
2291 }
2292
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002293 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002294 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002295 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002296 EXPECT_TRUE(IsReadyForEncode());
2297
Peter Boström5811a392015-12-10 13:02:50 +01002298 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002299 return 0;
2300 }
2301
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002302 int32_t RegisterEncodeCompleteCallback(
2303 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002304 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002305 EXPECT_TRUE(initialized_);
2306 callback_registered_ = true;
2307 return 0;
2308 }
2309
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002310 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002311 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002312 EXPECT_TRUE(IsReadyForEncode());
2313 EXPECT_FALSE(released_);
2314 initialized_ = false;
2315 callback_registered_ = false;
2316 released_ = true;
2317 ++num_releases_;
2318 return 0;
2319 }
2320
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002321 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002322 EXPECT_TRUE(IsReadyForEncode());
2323 return 0;
2324 }
2325
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002326 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002327 EXPECT_TRUE(IsReadyForEncode());
2328 return 0;
2329 }
2330
stefanff483612015-12-21 03:14:00 -08002331 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002332 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002333 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002334 stream_ = send_stream;
2335 }
2336
stefanff483612015-12-21 03:14:00 -08002337 void ModifyVideoConfigs(
2338 VideoSendStream::Config* send_config,
2339 std::vector<VideoReceiveStream::Config>* receive_configs,
2340 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002341 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002342 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002343 }
2344
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002345 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002346 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002347
2348 task_queue_->SendTask([this]() {
2349 EXPECT_EQ(0u, num_releases());
2350 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2351 EXPECT_EQ(0u, num_releases());
2352 stream_->Stop();
2353 // Encoder should not be released before destroying the VideoSendStream.
2354 EXPECT_FALSE(IsReleased());
2355 EXPECT_TRUE(IsReadyForEncode());
2356 stream_->Start();
2357 });
2358
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002359 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002360 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002361 }
2362
eladalon413ee9a2017-08-22 04:02:52 -07002363 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002364 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002365 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002366 bool initialized_ RTC_GUARDED_BY(crit_);
2367 bool callback_registered_ RTC_GUARDED_BY(crit_);
2368 size_t num_releases_ RTC_GUARDED_BY(crit_);
2369 bool released_ RTC_GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002370 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002371 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002372
stefane74eef12016-01-08 06:47:13 -08002373 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002374
2375 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002376 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002377}
2378
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002379TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2380 class VideoCodecConfigObserver : public test::SendTest,
2381 public test::FakeEncoder {
2382 public:
2383 VideoCodecConfigObserver()
2384 : SendTest(kDefaultTimeoutMs),
2385 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002386 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002387 num_initializations_(0),
2388 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002389
2390 private:
stefanff483612015-12-21 03:14:00 -08002391 void ModifyVideoConfigs(
2392 VideoSendStream::Config* send_config,
2393 std::vector<VideoReceiveStream::Config>* receive_configs,
2394 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002395 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002396 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002397 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002398 }
2399
stefanff483612015-12-21 03:14:00 -08002400 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002401 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002402 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002403 stream_ = send_stream;
2404 }
2405
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002406 int32_t InitEncode(const VideoCodec* config,
2407 int32_t number_of_cores,
2408 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002409 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002410 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002411 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002412 } else {
2413 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002414 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002415 }
2416 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002417 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002418 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2419 }
2420
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002421 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002422 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002423 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002424
sprangf24a0642017-02-28 13:23:26 -08002425 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002426 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002427 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002428 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002429 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2430 "new encoder settings.";
2431 }
2432
sprangf24a0642017-02-28 13:23:26 -08002433 const uint32_t kFirstMaxBitrateBps = 1000000;
2434 const uint32_t kSecondMaxBitrateBps = 2000000;
2435
pbos14fe7082016-04-20 06:35:56 -07002436 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002437 size_t num_initializations_;
2438 VideoSendStream* stream_;
2439 VideoEncoderConfig encoder_config_;
2440 } test;
2441
stefane74eef12016-01-08 06:47:13 -08002442 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002443}
2444
Peter Boström53eda3d2015-03-27 15:53:18 +01002445static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2446template <typename T>
2447class VideoCodecConfigObserver : public test::SendTest,
2448 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002449 public:
2450 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2451 const char* codec_name)
2452 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2453 FakeEncoder(Clock::GetRealTimeClock()),
2454 video_codec_type_(video_codec_type),
2455 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002456 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002457 num_initializations_(0),
2458 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002459 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2460 }
2461
2462 private:
perkjfa10b552016-10-02 23:45:26 -07002463 class VideoStreamFactory
2464 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2465 public:
2466 VideoStreamFactory() {}
2467
2468 private:
2469 std::vector<VideoStream> CreateEncoderStreams(
2470 int width,
2471 int height,
2472 const VideoEncoderConfig& encoder_config) override {
2473 std::vector<VideoStream> streams =
2474 test::CreateVideoStreams(width, height, encoder_config);
2475 for (size_t i = 0; i < streams.size(); ++i) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002476 streams[i].num_temporal_layers =
2477 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkjfa10b552016-10-02 23:45:26 -07002478 }
2479 return streams;
2480 }
2481 };
2482
stefanff483612015-12-21 03:14:00 -08002483 void ModifyVideoConfigs(
2484 VideoSendStream::Config* send_config,
2485 std::vector<VideoReceiveStream::Config>* receive_configs,
2486 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002487 send_config->encoder_settings.encoder = this;
2488 send_config->encoder_settings.payload_name = codec_name_;
2489
kthelgason29a44e32016-09-27 03:52:02 -07002490 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002491 encoder_config->video_stream_factory =
2492 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002493 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002494 }
2495
stefanff483612015-12-21 03:14:00 -08002496 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002497 VideoSendStream* send_stream,
2498 const std::vector<VideoReceiveStream*>& receive_streams) override {
2499 stream_ = send_stream;
2500 }
2501
2502 int32_t InitEncode(const VideoCodec* config,
2503 int32_t number_of_cores,
2504 size_t max_payload_size) override {
2505 EXPECT_EQ(video_codec_type_, config->codecType);
2506 VerifyCodecSpecifics(*config);
2507 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002508 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002509 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2510 }
2511
2512 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002513 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2514 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002515
2516 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002517 EXPECT_TRUE(
2518 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002519 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002520
2521 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002522 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002523 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002524 ASSERT_TRUE(
2525 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002526 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002527 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2528 "new encoder settings.";
2529 }
2530
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002531 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002532 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002533 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002534 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2535 return 0;
2536 }
2537
2538 T encoder_settings_;
2539 const VideoCodecType video_codec_type_;
2540 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002541 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002542 size_t num_initializations_;
2543 VideoSendStream* stream_;
2544 VideoEncoderConfig encoder_config_;
2545};
2546
2547template <>
2548void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2549 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002550 EXPECT_EQ(
2551 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002552}
kthelgason29a44e32016-09-27 03:52:02 -07002553
2554template <>
2555rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2556VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2557 return new rtc::RefCountedObject<
2558 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2559}
2560
Peter Boström53eda3d2015-03-27 15:53:18 +01002561template <>
2562void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2563 const VideoCodec& config) const {
2564 // Check that the number of temporal layers has propagated properly to
2565 // VideoCodec.
2566 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002567 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002568
2569 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2570 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2571 config.simulcastStream[i].numberOfTemporalLayers);
2572 }
2573
2574 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002575 // reconfiguring the encoder and not match the set config. Also copy the
mflodmancc3d4422017-08-03 08:27:51 -07002576 // TemporalLayersFactory pointer that has been injected by VideoStreamEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002577 VideoCodecVP8 encoder_settings = encoder_settings_;
2578 encoder_settings.numberOfTemporalLayers =
2579 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002580 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002581 EXPECT_EQ(
2582 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002583}
kthelgason29a44e32016-09-27 03:52:02 -07002584
2585template <>
2586rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2587VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2588 return new rtc::RefCountedObject<
2589 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2590}
2591
Peter Boström53eda3d2015-03-27 15:53:18 +01002592template <>
2593void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2594 const VideoCodec& config) const {
2595 // Check that the number of temporal layers has propagated properly to
2596 // VideoCodec.
2597 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002598 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002599
2600 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2601 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2602 config.simulcastStream[i].numberOfTemporalLayers);
2603 }
2604
2605 // Set expected temporal layers as they should have been set when
2606 // reconfiguring the encoder and not match the set config.
2607 VideoCodecVP9 encoder_settings = encoder_settings_;
2608 encoder_settings.numberOfTemporalLayers =
2609 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002610 EXPECT_EQ(
2611 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002612}
2613
kthelgason29a44e32016-09-27 03:52:02 -07002614template <>
2615rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2616VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2617 return new rtc::RefCountedObject<
2618 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2619}
2620
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002621TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002622 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002623 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002624}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002625
Peter Boström53eda3d2015-03-27 15:53:18 +01002626TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2627 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002628 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002629}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002630
Peter Boström53eda3d2015-03-27 15:53:18 +01002631TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2632 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002633 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002634}
2635
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002636TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002637 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002638 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002639 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2640 rtp_packets_sent_(0),
2641 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002642
2643 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002644 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002645 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002646 RTPHeader header;
2647 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002648 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002649 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2650 return SEND_PACKET;
2651 }
2652
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002653 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002654 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002655 test::RtcpPacketParser parser;
2656 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002657
danilchap3dc929e2016-11-02 08:21:59 -07002658 if (parser.sender_report()->num_packets() > 0) {
2659 // Only compare sent media bytes if SenderPacketCount matches the
2660 // number of sent rtp packets (a new rtp packet could be sent before
2661 // the rtcp packet).
2662 if (parser.sender_report()->sender_octet_count() > 0 &&
2663 parser.sender_report()->sender_packet_count() ==
2664 rtp_packets_sent_) {
2665 EXPECT_EQ(media_bytes_sent_,
2666 parser.sender_report()->sender_octet_count());
2667 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002668 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002669 }
2670
2671 return SEND_PACKET;
2672 }
2673
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002674 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002675 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002676 }
2677
stefan4b569042015-11-11 06:39:57 -08002678 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002679 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2680 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002681 } test;
2682
stefane74eef12016-01-08 06:47:13 -08002683 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002684}
2685
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002686TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002687 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002688
2689 class VideoStreamFactory
2690 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2691 public:
2692 VideoStreamFactory() {}
2693
2694 private:
2695 std::vector<VideoStream> CreateEncoderStreams(
2696 int width,
2697 int height,
2698 const VideoEncoderConfig& encoder_config) override {
2699 std::vector<VideoStream> streams =
2700 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002701 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
2702 streams[0].num_temporal_layers = 2;
2703 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2704 kScreencastMaxTargetBitrateDeltaKbps);
2705 streams[0].target_bitrate_bps =
2706 streams[0].max_bitrate_bps -
2707 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002708 return streams;
2709 }
2710 };
2711
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002712 class ScreencastTargetBitrateTest : public test::SendTest,
2713 public test::FakeEncoder {
2714 public:
2715 ScreencastTargetBitrateTest()
2716 : SendTest(kDefaultTimeoutMs),
2717 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2718
2719 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002720 int32_t InitEncode(const VideoCodec* config,
2721 int32_t number_of_cores,
2722 size_t max_payload_size) override {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002723 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
2724 config->maxBitrate - config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002725 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002726 return test::FakeEncoder::InitEncode(
2727 config, number_of_cores, max_payload_size);
2728 }
stefanff483612015-12-21 03:14:00 -08002729 void ModifyVideoConfigs(
2730 VideoSendStream::Config* send_config,
2731 std::vector<VideoReceiveStream::Config>* receive_configs,
2732 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002733 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002734 EXPECT_EQ(1u, encoder_config->number_of_streams);
2735 encoder_config->video_stream_factory =
2736 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002737 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002738 }
2739
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002740 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002741 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002742 << "Timed out while waiting for the encoder to be initialized.";
2743 }
2744 } test;
2745
stefane74eef12016-01-08 06:47:13 -08002746 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002747}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002748
philipelc6957c72016-04-28 15:52:49 +02002749TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002750 // These are chosen to be "kind of odd" to not be accidentally checked against
2751 // default values.
2752 static const int kMinBitrateKbps = 137;
2753 static const int kStartBitrateKbps = 345;
2754 static const int kLowerMaxBitrateKbps = 312;
2755 static const int kMaxBitrateKbps = 413;
2756 static const int kIncreasedStartBitrateKbps = 451;
2757 static const int kIncreasedMaxBitrateKbps = 597;
2758 class EncoderBitrateThresholdObserver : public test::SendTest,
2759 public test::FakeEncoder {
2760 public:
eladalon413ee9a2017-08-22 04:02:52 -07002761 explicit EncoderBitrateThresholdObserver(
2762 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002763 : SendTest(kDefaultTimeoutMs),
2764 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002765 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002766 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002767 bitrate_changed_event_(false, false),
2768 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002769 num_initializations_(0),
2770 call_(nullptr),
2771 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002772
2773 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002774 int32_t InitEncode(const VideoCodec* codecSettings,
2775 int32_t numberOfCores,
2776 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002777 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2778 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002779 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002780 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2781 codecSettings->minBitrate);
2782 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2783 codecSettings->startBitrate);
2784 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2785 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002786 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002787 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002788 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2789 codecSettings->maxBitrate);
2790 // The start bitrate should be kept (-1) and capped to the max bitrate.
2791 // Since this is not an end-to-end call no receiver should have been
2792 // returning a REMB that could lower this estimate.
2793 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002794 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002795 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2796 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002797 // The start bitrate will be whatever the rate BitRateController
2798 // has currently configured but in the span of the set max and min
2799 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002800 }
2801 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002802 init_encode_event_.Set();
2803
pbos@webrtc.org00873182014-11-25 14:03:34 +00002804 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2805 maxPayloadSize);
2806 }
2807
Erik Språng08127a92016-11-16 16:41:30 +01002808 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2809 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002810 {
2811 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002812 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2813 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002814 }
Erik Språng08127a92016-11-16 16:41:30 +01002815 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002816 }
2817 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002818 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002819 }
2820
2821 void WaitForSetRates(uint32_t expected_bitrate) {
2822 EXPECT_TRUE(
2823 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2824 << "Timed out while waiting encoder rate to be set.";
2825 rtc::CritScope lock(&crit_);
2826 EXPECT_EQ(expected_bitrate, target_bitrate_);
2827 }
2828
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002829 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002830 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002831 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2832 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2833 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002834 return config;
2835 }
2836
perkjfa10b552016-10-02 23:45:26 -07002837 class VideoStreamFactory
2838 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2839 public:
2840 explicit VideoStreamFactory(int min_bitrate_bps)
2841 : min_bitrate_bps_(min_bitrate_bps) {}
2842
2843 private:
2844 std::vector<VideoStream> CreateEncoderStreams(
2845 int width,
2846 int height,
2847 const VideoEncoderConfig& encoder_config) override {
2848 std::vector<VideoStream> streams =
2849 test::CreateVideoStreams(width, height, encoder_config);
2850 streams[0].min_bitrate_bps = min_bitrate_bps_;
2851 return streams;
2852 }
2853
2854 const int min_bitrate_bps_;
2855 };
2856
stefanff483612015-12-21 03:14:00 -08002857 void ModifyVideoConfigs(
2858 VideoSendStream::Config* send_config,
2859 std::vector<VideoReceiveStream::Config>* receive_configs,
2860 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002861 send_config->encoder_settings.encoder = this;
2862 // Set bitrates lower/higher than min/max to make sure they are properly
2863 // capped.
perkjfa10b552016-10-02 23:45:26 -07002864 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2865 // Create a new StreamFactory to be able to set
2866 // |VideoStream.min_bitrate_bps|.
2867 encoder_config->video_stream_factory =
2868 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002869 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002870 }
2871
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002872 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002873 call_ = sender_call;
2874 }
2875
stefanff483612015-12-21 03:14:00 -08002876 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002877 VideoSendStream* send_stream,
2878 const std::vector<VideoReceiveStream*>& receive_streams) override {
2879 send_stream_ = send_stream;
2880 }
2881
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002882 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002883 ASSERT_TRUE(
2884 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002885 << "Timed out while waiting for encoder to be configured.";
2886 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002887 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002888 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2889 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002890 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002891 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2892 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002893 });
perkj26091b12016-09-01 01:17:40 -07002894 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2895 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002896 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002897 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002898 ASSERT_TRUE(
2899 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002900 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002901 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002902 WaitForSetRates(kLowerMaxBitrateKbps);
2903
2904 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2905 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2906 ASSERT_TRUE(
2907 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002908 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002909 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002910 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002911 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002912 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002913 }
2914
eladalon413ee9a2017-08-22 04:02:52 -07002915 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002916 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002917 rtc::Event bitrate_changed_event_;
2918 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002919 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002920
pbos@webrtc.org00873182014-11-25 14:03:34 +00002921 int num_initializations_;
2922 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002923 webrtc::VideoSendStream* send_stream_;
2924 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002925 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002926
stefane74eef12016-01-08 06:47:13 -08002927 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002928}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002929
2930TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2931 static const size_t kNumStreams = 3;
2932 // Unusual resolutions to make sure that they are the ones being reported.
2933 static const struct {
2934 int width;
2935 int height;
2936 } kEncodedResolution[kNumStreams] = {
2937 {241, 181}, {300, 121}, {121, 221}};
2938 class ScreencastTargetBitrateTest : public test::SendTest,
2939 public test::FakeEncoder {
2940 public:
2941 ScreencastTargetBitrateTest()
2942 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002943 test::FakeEncoder(Clock::GetRealTimeClock()),
2944 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002945
2946 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002947 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002948 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002949 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002950 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002951 specifics.codecType = kVideoCodecGeneric;
2952
2953 uint8_t buffer[16] = {0};
2954 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2955 encoded._timeStamp = input_image.timestamp();
2956 encoded.capture_time_ms_ = input_image.render_time_ms();
2957
2958 for (size_t i = 0; i < kNumStreams; ++i) {
2959 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2960 encoded._frameType = (*frame_types)[i];
2961 encoded._encodedWidth = kEncodedResolution[i].width;
2962 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002963 EncodedImageCallback* callback;
2964 {
2965 rtc::CritScope cs(&crit_sect_);
2966 callback = callback_;
2967 }
2968 RTC_DCHECK(callback);
2969 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002970 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002971 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002972 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002973 }
2974
Peter Boström5811a392015-12-10 13:02:50 +01002975 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002976 return 0;
2977 }
stefanff483612015-12-21 03:14:00 -08002978 void ModifyVideoConfigs(
2979 VideoSendStream::Config* send_config,
2980 std::vector<VideoReceiveStream::Config>* receive_configs,
2981 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002982 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002983 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002984 }
2985
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002986 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002987
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002988 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002989 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002990 << "Timed out while waiting for the encoder to send one frame.";
2991 VideoSendStream::Stats stats = send_stream_->GetStats();
2992
2993 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002994 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002995 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002996 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002997 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002998 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002999 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003000 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3001 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003002 }
3003 }
3004
stefanff483612015-12-21 03:14:00 -08003005 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003006 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003007 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003008 send_stream_ = send_stream;
3009 }
3010
3011 VideoSendStream* send_stream_;
3012 } test;
3013
stefane74eef12016-01-08 06:47:13 -08003014 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003015}
philipel0f9af012015-09-01 07:01:51 -07003016
Peter Boström12996152016-05-14 02:03:18 +02003017#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003018class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003019 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003020 Vp9HeaderObserver()
3021 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07003022 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01003023 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3024 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003025 frames_sent_(0),
3026 expected_width_(0),
3027 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003028
stefanff483612015-12-21 03:14:00 -08003029 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003030 VideoSendStream::Config* send_config,
3031 std::vector<VideoReceiveStream::Config>* receive_configs,
3032 VideoEncoderConfig* encoder_config) {}
3033
Åsa Perssonff24c042015-12-04 10:58:08 +01003034 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003035
3036 private:
minyue20c84cc2017-04-10 16:57:57 -07003037 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003038
perkjfa10b552016-10-02 23:45:26 -07003039 class VideoStreamFactory
3040 : public VideoEncoderConfig::VideoStreamFactoryInterface {
3041 public:
3042 explicit VideoStreamFactory(size_t number_of_temporal_layers)
3043 : number_of_temporal_layers_(number_of_temporal_layers) {}
3044
3045 private:
3046 std::vector<VideoStream> CreateEncoderStreams(
3047 int width,
3048 int height,
3049 const VideoEncoderConfig& encoder_config) override {
3050 std::vector<VideoStream> streams =
3051 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01003052 streams.back().num_temporal_layers = number_of_temporal_layers_;
perkjfa10b552016-10-02 23:45:26 -07003053 return streams;
3054 }
3055
3056 const size_t number_of_temporal_layers_;
3057 };
3058
stefanff483612015-12-21 03:14:00 -08003059 void ModifyVideoConfigs(
3060 VideoSendStream::Config* send_config,
3061 std::vector<VideoReceiveStream::Config>* receive_configs,
3062 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07003063 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07003064 send_config->encoder_settings.payload_name = "VP9";
3065 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003066 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003067 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
3068 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003069 EXPECT_EQ(1u, encoder_config->number_of_streams);
3070 encoder_config->video_stream_factory =
3071 new rtc::RefCountedObject<VideoStreamFactory>(
3072 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07003073 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003074 }
3075
perkjfa10b552016-10-02 23:45:26 -07003076 void ModifyVideoCaptureStartResolution(int* width,
3077 int* height,
3078 int* frame_rate) override {
3079 expected_width_ = *width;
3080 expected_height_ = *height;
3081 }
3082
philipel0f9af012015-09-01 07:01:51 -07003083 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003084 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3085 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003086 }
3087
3088 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3089 RTPHeader header;
3090 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3091
Åsa Perssonff24c042015-12-04 10:58:08 +01003092 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3093 const uint8_t* payload = packet + header.headerLength;
3094 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003095
Åsa Perssonff24c042015-12-04 10:58:08 +01003096 bool new_packet = packets_sent_ == 0 ||
3097 IsNewerSequenceNumber(header.sequenceNumber,
3098 last_header_.sequenceNumber);
3099 if (payload_length > 0 && new_packet) {
3100 RtpDepacketizer::ParsedPayload parsed;
3101 RtpDepacketizerVp9 depacketizer;
3102 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
3103 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
3104 // Verify common fields for all configurations.
3105 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
3106 CompareConsecutiveFrames(header, parsed.type.Video);
3107 // Verify configuration specific settings.
3108 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07003109
Åsa Perssonff24c042015-12-04 10:58:08 +01003110 ++packets_sent_;
3111 if (header.markerBit) {
3112 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003113 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003114 last_header_ = header;
3115 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07003116 }
philipel0f9af012015-09-01 07:01:51 -07003117 return SEND_PACKET;
3118 }
3119
philipel7fabd462015-09-03 04:42:32 -07003120 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003121 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3122 if (last_vp9_.picture_id > vp9.picture_id) {
3123 return vp9.picture_id == 0; // Wrap.
3124 } else {
3125 return vp9.picture_id == last_vp9_.picture_id + 1;
3126 }
3127 }
3128
3129 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003130 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3131 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3132 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3133 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3134 vp9.spatial_idx);
3135 }
3136
3137 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3138 uint8_t num_layers) const {
3139 switch (num_layers) {
3140 case 0:
3141 VerifyTemporalLayerStructure0(vp9);
3142 break;
3143 case 1:
3144 VerifyTemporalLayerStructure1(vp9);
3145 break;
3146 case 2:
3147 VerifyTemporalLayerStructure2(vp9);
3148 break;
3149 case 3:
3150 VerifyTemporalLayerStructure3(vp9);
3151 break;
3152 default:
3153 RTC_NOTREACHED();
3154 }
3155 }
3156
3157 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3158 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3159 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3160 EXPECT_FALSE(vp9.temporal_up_switch);
3161 }
3162
3163 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3164 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3165 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3166 EXPECT_FALSE(vp9.temporal_up_switch);
3167 }
3168
3169 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3170 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3171 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3172 EXPECT_LE(vp9.temporal_idx, 1);
3173 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3174 if (IsNewPictureId(vp9)) {
3175 uint8_t expected_tid =
3176 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3177 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3178 }
3179 }
3180
3181 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3182 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3183 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3184 EXPECT_LE(vp9.temporal_idx, 2);
3185 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3186 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3187 switch (vp9.temporal_idx) {
3188 case 0:
3189 EXPECT_EQ(2, last_vp9_.temporal_idx);
3190 EXPECT_FALSE(vp9.temporal_up_switch);
3191 break;
3192 case 1:
3193 EXPECT_EQ(2, last_vp9_.temporal_idx);
3194 EXPECT_TRUE(vp9.temporal_up_switch);
3195 break;
3196 case 2:
3197 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3198 break;
3199 }
3200 }
3201 }
3202
3203 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3204 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3205 return;
3206
3207 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3208 if (vp9.temporal_idx == 0)
3209 ++expected_tl0_idx;
3210 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3211 }
3212
3213 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3214 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3215 }
3216
3217 // Flexible mode (F=1): Non-flexible mode (F=0):
3218 //
3219 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3220 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3221 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3222 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3223 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3224 // M: | EXTENDED PID | M: | EXTENDED PID |
3225 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3226 // L: | T |U| S |D| L: | T |U| S |D|
3227 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3228 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3229 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3230 // X: |EXTENDED P_DIFF| V: | SS .. |
3231 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3232 // V: | SS .. |
3233 // +-+-+-+-+-+-+-+-+
3234 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3235 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3236 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3237 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003238
3239 if (vp9_settings_.numberOfSpatialLayers > 1) {
3240 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3241 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3242 EXPECT_EQ(vp9.spatial_idx, 0);
3243 } else {
3244 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3245 }
3246
3247 if (vp9_settings_.numberOfTemporalLayers > 1) {
3248 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3249 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3250 EXPECT_EQ(vp9.temporal_idx, 0);
3251 } else {
3252 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3253 }
3254
Åsa Perssonff24c042015-12-04 10:58:08 +01003255 if (vp9.ss_data_available) // V
3256 VerifySsData(vp9);
3257
3258 if (frames_sent_ == 0)
3259 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3260
3261 if (!vp9.inter_pic_predicted) {
3262 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3263 EXPECT_FALSE(vp9.temporal_up_switch);
3264 }
3265 }
3266
3267 // Scalability structure (SS).
3268 //
3269 // +-+-+-+-+-+-+-+-+
3270 // V: | N_S |Y|G|-|-|-|
3271 // +-+-+-+-+-+-+-+-+
3272 // Y: | WIDTH | N_S + 1 times
3273 // +-+-+-+-+-+-+-+-+
3274 // | HEIGHT |
3275 // +-+-+-+-+-+-+-+-+
3276 // G: | N_G |
3277 // +-+-+-+-+-+-+-+-+
3278 // N_G: | T |U| R |-|-| N_G times
3279 // +-+-+-+-+-+-+-+-+
3280 // | P_DIFF | R times
3281 // +-+-+-+-+-+-+-+-+
3282 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3283 EXPECT_TRUE(vp9.ss_data_available); // V
3284 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3285 vp9.num_spatial_layers);
3286 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003287 int expected_width = expected_width_;
3288 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003289 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003290 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3291 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3292 expected_width /= 2;
3293 expected_height /= 2;
3294 }
3295 }
3296
3297 void CompareConsecutiveFrames(const RTPHeader& header,
3298 const RTPVideoHeader& video) const {
3299 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3300
3301 bool new_frame = packets_sent_ == 0 ||
3302 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003303 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003304 if (!new_frame) {
3305 EXPECT_FALSE(last_header_.markerBit);
3306 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3307 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3308 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3309 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3310 VerifySpatialIdxWithinFrame(vp9);
3311 return;
3312 }
3313 // New frame.
3314 EXPECT_TRUE(vp9.beginning_of_frame);
3315
3316 // Compare with last packet in previous frame.
3317 if (frames_sent_ == 0)
3318 return;
3319 EXPECT_TRUE(last_vp9_.end_of_frame);
3320 EXPECT_TRUE(last_header_.markerBit);
3321 EXPECT_TRUE(ContinuousPictureId(vp9));
3322 VerifyTl0Idx(vp9);
3323 }
3324
kwiberg27f982b2016-03-01 11:52:33 -08003325 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003326 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003327 webrtc::VideoEncoderConfig encoder_config_;
3328 RTPHeader last_header_;
3329 RTPVideoHeaderVP9 last_vp9_;
3330 size_t packets_sent_;
3331 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003332 int expected_width_;
3333 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003334};
3335
Åsa Perssonff24c042015-12-04 10:58:08 +01003336TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3337 const uint8_t kNumTemporalLayers = 1;
3338 const uint8_t kNumSpatialLayers = 1;
3339 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3340}
3341
3342TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3343 const uint8_t kNumTemporalLayers = 2;
3344 const uint8_t kNumSpatialLayers = 1;
3345 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3346}
3347
3348TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3349 const uint8_t kNumTemporalLayers = 3;
3350 const uint8_t kNumSpatialLayers = 1;
3351 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3352}
3353
3354TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3355 const uint8_t kNumTemporalLayers = 1;
3356 const uint8_t kNumSpatialLayers = 2;
3357 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3358}
3359
3360TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3361 const uint8_t kNumTemporalLayers = 2;
3362 const uint8_t kNumSpatialLayers = 2;
3363 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3364}
3365
3366TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3367 const uint8_t kNumTemporalLayers = 3;
3368 const uint8_t kNumSpatialLayers = 2;
3369 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3370}
3371
3372void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3373 uint8_t num_spatial_layers) {
3374 static const size_t kNumFramesToSend = 100;
3375 // Set to < kNumFramesToSend and coprime to length of temporal layer
3376 // structures to verify temporal id reset on key frame.
3377 static const int kKeyFrameInterval = 31;
3378 class NonFlexibleMode : public Vp9HeaderObserver {
3379 public:
3380 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3381 : num_temporal_layers_(num_temporal_layers),
3382 num_spatial_layers_(num_spatial_layers),
3383 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003384 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003385 VideoSendStream::Config* send_config,
3386 std::vector<VideoReceiveStream::Config>* receive_configs,
3387 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003388 vp9_settings_.flexibleMode = false;
3389 vp9_settings_.frameDroppingOn = false;
3390 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3391 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3392 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003393 }
3394
Åsa Perssonff24c042015-12-04 10:58:08 +01003395 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003396 bool ss_data_expected =
3397 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3398 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003399 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003400 if (num_spatial_layers_ > 1) {
3401 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3402 } else {
3403 EXPECT_FALSE(vp9.inter_layer_predicted);
3404 }
3405
asapersson38bb8ad2015-12-14 01:41:19 -08003406 EXPECT_EQ(!vp9.inter_pic_predicted,
3407 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003408
3409 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003410 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3411 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3412 } else {
3413 EXPECT_EQ(0, vp9.spatial_idx);
3414 }
3415 if (num_spatial_layers_ > 1)
3416 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003417 }
3418
3419 VerifyFixedTemporalLayerStructure(vp9,
3420 l_field_ ? num_temporal_layers_ : 0);
3421
3422 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003423 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003424 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003425 const uint8_t num_temporal_layers_;
3426 const uint8_t num_spatial_layers_;
3427 const bool l_field_;
3428 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003429
stefane74eef12016-01-08 06:47:13 -08003430 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003431}
3432
asaperssond9f641e2016-01-21 01:11:35 -08003433TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3434 static const size_t kNumFramesToSend = 50;
3435 static const int kWidth = 4;
3436 static const int kHeight = 4;
3437 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3438 void ModifyVideoConfigsHook(
3439 VideoSendStream::Config* send_config,
3440 std::vector<VideoReceiveStream::Config>* receive_configs,
3441 VideoEncoderConfig* encoder_config) override {
3442 vp9_settings_.flexibleMode = false;
3443 vp9_settings_.numberOfTemporalLayers = 1;
3444 vp9_settings_.numberOfSpatialLayers = 1;
3445
perkjfa10b552016-10-02 23:45:26 -07003446 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003447 }
3448
3449 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3450 if (frames_sent_ > kNumFramesToSend)
3451 observation_complete_.Set();
3452 }
perkjfa10b552016-10-02 23:45:26 -07003453
3454 void ModifyVideoCaptureStartResolution(int* width,
3455 int* height,
3456 int* frame_rate) override {
3457 expected_width_ = kWidth;
3458 expected_height_ = kHeight;
3459 *width = kWidth;
3460 *height = kHeight;
3461 }
asaperssond9f641e2016-01-21 01:11:35 -08003462 } test;
3463
3464 RunBaseTest(&test);
3465}
3466
kjellanderf9e2a362017-03-24 12:17:33 -07003467#if defined(WEBRTC_ANDROID)
3468// Crashes on Android; bugs.webrtc.org/7401
3469#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3470#else
3471#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3472#endif
3473TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003474 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003475 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003476 VideoSendStream::Config* send_config,
3477 std::vector<VideoReceiveStream::Config>* receive_configs,
3478 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003479 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003480 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003481 vp9_settings_.numberOfTemporalLayers = 1;
3482 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003483 }
3484
Åsa Perssonff24c042015-12-04 10:58:08 +01003485 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3486 EXPECT_TRUE(vp9_header.flexible_mode);
3487 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3488 if (vp9_header.inter_pic_predicted) {
3489 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003490 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003491 }
3492 }
3493 } test;
3494
stefane74eef12016-01-08 06:47:13 -08003495 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003496}
Peter Boström12996152016-05-14 02:03:18 +02003497#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003498
perkj803d97f2016-11-01 11:45:46 -07003499void VideoSendStreamTest::TestRequestSourceRotateVideo(
3500 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003501 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003502
3503 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003504 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003505 video_send_config_.rtp.extensions.clear();
3506 if (support_orientation_ext) {
3507 video_send_config_.rtp.extensions.push_back(
3508 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3509 }
3510
3511 CreateVideoStreams();
3512 test::FrameForwarder forwarder;
3513 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003514 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003515
3516 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3517 support_orientation_ext);
3518
3519 DestroyStreams();
3520}
3521
3522TEST_F(VideoSendStreamTest,
3523 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3524 TestRequestSourceRotateVideo(false);
3525}
3526
3527TEST_F(VideoSendStreamTest,
3528 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3529 TestRequestSourceRotateVideo(true);
3530}
3531
michaelta3328772016-11-29 09:25:03 -08003532// This test verifies that overhead is removed from the bandwidth estimate by
3533// testing that the maximum possible target payload rate is smaller than the
3534// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003535TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003536 test::ScopedFieldTrials override_field_trials(
3537 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3538 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3539 public test::FakeEncoder {
3540 public:
eladalon413ee9a2017-08-22 04:02:52 -07003541 explicit RemoveOverheadFromBandwidthTest(
3542 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003543 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3544 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003545 task_queue_(task_queue),
michaelta3328772016-11-29 09:25:03 -08003546 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003547 max_bitrate_bps_(0),
3548 first_packet_sent_(false),
3549 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003550
3551 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3552 uint32_t frameRate) override {
3553 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003554 // Wait for the first sent packet so that videosendstream knows
3555 // rtp_overhead.
3556 if (first_packet_sent_) {
3557 max_bitrate_bps_ = bitrate.get_sum_bps();
3558 bitrate_changed_event_.Set();
3559 }
michaelta3328772016-11-29 09:25:03 -08003560 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3561 }
3562
3563 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3564 call_ = sender_call;
3565 }
3566
3567 void ModifyVideoConfigs(
3568 VideoSendStream::Config* send_config,
3569 std::vector<VideoReceiveStream::Config>* receive_configs,
3570 VideoEncoderConfig* encoder_config) override {
3571 send_config->rtp.max_packet_size = 1200;
3572 send_config->encoder_settings.encoder = this;
3573 EXPECT_FALSE(send_config->rtp.extensions.empty());
3574 }
3575
michaelt192132e2017-01-26 09:05:27 -08003576 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3577 rtc::CritScope lock(&crit_);
3578 first_packet_sent_ = true;
3579 return SEND_PACKET;
3580 }
3581
michaelta3328772016-11-29 09:25:03 -08003582 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003583 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003584 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003585 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003586 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003587 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3588 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003589 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003590 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003591 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3592 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07003593 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3594 });
michaelta3328772016-11-29 09:25:03 -08003595
3596 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003597 // overhead of 40B per packet video produces 2240bps overhead.
3598 // So the encoder BW should be set to 57760bps.
3599 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003600 {
3601 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003602 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003603 }
3604 }
3605
3606 private:
eladalon413ee9a2017-08-22 04:02:52 -07003607 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelta3328772016-11-29 09:25:03 -08003608 Call* call_;
3609 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003610 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3611 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003612 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003613 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003614 RunBaseTest(&test);
3615}
3616
sprang168794c2017-07-06 04:38:06 -07003617TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3618 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003619
3620 class KeepaliveObserver : public test::SendTest {
3621 public:
3622 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3623
sprangdb2a9fc2017-08-09 06:42:32 -07003624 void OnRtpTransportControllerSendCreated(
3625 RtpTransportControllerSend* controller) override {
3626 RtpKeepAliveConfig config;
3627 config.timeout_interval_ms = kTimeoutMs;
3628 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3629 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003630 }
3631
sprang168794c2017-07-06 04:38:06 -07003632 private:
3633 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3634 RTPHeader header;
3635 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3636
sprangd2702ef2017-07-10 08:41:10 -07003637 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003638 // The video stream has started. Stop it now.
3639 if (capturer_)
3640 capturer_->Stop();
3641 } else {
3642 observation_complete_.Set();
3643 }
3644
3645 return SEND_PACKET;
3646 }
3647
sprang168794c2017-07-06 04:38:06 -07003648 void PerformTest() override {
3649 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3650 }
3651
3652 void OnFrameGeneratorCapturerCreated(
3653 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3654 capturer_ = frame_generator_capturer;
3655 }
3656
3657 test::FrameGeneratorCapturer* capturer_ = nullptr;
3658 } test;
3659
3660 RunBaseTest(&test);
3661}
3662
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003663class PacingFactorObserver : public test::SendTest {
3664 public:
3665 PacingFactorObserver(bool configure_send_side,
3666 rtc::Optional<float> expected_pacing_factor)
3667 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3668 configure_send_side_(configure_send_side),
3669 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003670
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003671 void ModifyVideoConfigs(
3672 VideoSendStream::Config* send_config,
3673 std::vector<VideoReceiveStream::Config>* receive_configs,
3674 VideoEncoderConfig* encoder_config) override {
3675 // Check if send-side bwe extension is already present, and remove it if
3676 // it is not desired.
3677 bool has_send_side = false;
3678 for (auto it = send_config->rtp.extensions.begin();
3679 it != send_config->rtp.extensions.end(); ++it) {
3680 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3681 if (configure_send_side_) {
3682 has_send_side = true;
3683 } else {
3684 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003685 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003686 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003687 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003688 }
3689
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003690 if (configure_send_side_ && !has_send_side) {
3691 // Want send side, not present by default, so add it.
3692 send_config->rtp.extensions.emplace_back(
3693 RtpExtension::kTransportSequenceNumberUri,
3694 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003695 }
3696
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003697 // ALR only enabled for screenshare.
3698 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3699 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003700
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003701 void OnVideoStreamsCreated(
3702 VideoSendStream* send_stream,
3703 const std::vector<VideoReceiveStream*>& receive_streams) override {
3704 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3705 // Video streams created, check that pacing factor is correctly configured.
3706 EXPECT_EQ(expected_pacing_factor_,
3707 internal_send_peer.GetPacingFactorOverride());
3708 observation_complete_.Set();
3709 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003710
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003711 void PerformTest() override {
3712 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3713 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003714
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003715 private:
3716 const bool configure_send_side_;
3717 const rtc::Optional<float> expected_pacing_factor_;
3718};
3719
3720std::string GetAlrProbingExperimentString() {
3721 return std::string(
3722 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3723 "/1.0,2875,80,40,-60,3/";
3724}
3725const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3726
3727TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
3728 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003729 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003730 PacingFactorObserver test_with_send_side(true,
3731 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003732 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003733}
Erik Språng7c8cca32017-10-24 17:05:18 +02003734
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003735TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
3736 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3737 // Send-side bwe off, use configuration should not be overridden.
3738 PacingFactorObserver test_without_send_side(false, rtc::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003739 RunBaseTest(&test_without_send_side);
3740}
3741
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003742} // namespace webrtc