blob: 03991100d63c967682656c1a4e4811fc1f073998 [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:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100327 VideoContentTypeObserver()
328 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700329 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
330 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
331 }
332
333 Action OnSendRtp(const uint8_t* packet, size_t length) override {
334 RTPHeader header;
335 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100336 // Only the last packet of the key-frame must have extension.
337 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700338 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100339 // First marker bit seen means that the first frame is sent.
340 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700341 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700342 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
343 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700344 observation_complete_.Set();
345 return SEND_PACKET;
346 }
347
348 void ModifyVideoConfigs(
349 VideoSendStream::Config* send_config,
350 std::vector<VideoReceiveStream::Config>* receive_configs,
351 VideoEncoderConfig* encoder_config) override {
352 send_config->rtp.extensions.clear();
353 send_config->rtp.extensions.push_back(
354 RtpExtension(RtpExtension::kVideoContentTypeUri,
355 test::kVideoContentTypeExtensionId));
356 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
357 }
358
359 void PerformTest() override {
360 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
361 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100362
363 private:
364 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700365 } test;
366
367 RunBaseTest(&test);
368}
369
ilnik04f4d122017-06-19 07:18:55 -0700370TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700371 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700372 public:
ilnik10894992017-06-21 08:23:19 -0700373 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700374 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
375 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
376 }
377
378 Action OnSendRtp(const uint8_t* packet, size_t length) override {
379 RTPHeader header;
380 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700381 // Only the last packet of the frame must have extension.
382 if (!header.markerBit)
383 return SEND_PACKET;
384 EXPECT_TRUE(header.extension.has_video_timing);
385 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700386 return SEND_PACKET;
387 }
388
389 void ModifyVideoConfigs(
390 VideoSendStream::Config* send_config,
391 std::vector<VideoReceiveStream::Config>* receive_configs,
392 VideoEncoderConfig* encoder_config) override {
393 send_config->rtp.extensions.clear();
394 send_config->rtp.extensions.push_back(RtpExtension(
395 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
396 }
397
398 void PerformTest() override {
399 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
400 }
401 } test;
402
403 RunBaseTest(&test);
404}
405
danilchap901b2df2017-07-28 08:56:04 -0700406class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000407 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000408 FakeReceiveStatistics(uint32_t send_ssrc,
409 uint32_t last_sequence_number,
410 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700411 uint8_t fraction_lost) {
412 stat_.SetMediaSsrc(send_ssrc);
413 stat_.SetExtHighestSeqNum(last_sequence_number);
414 stat_.SetCumulativeLost(cumulative_lost);
415 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000416 }
417
danilchap901b2df2017-07-28 08:56:04 -0700418 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
419 EXPECT_GE(max_blocks, 1u);
420 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000421 }
422
423 private:
danilchap901b2df2017-07-28 08:56:04 -0700424 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000425};
426
brandtre602f0a2016-10-31 03:40:49 -0700427class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100428 public:
brandtre602f0a2016-10-31 03:40:49 -0700429 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800430 bool use_nack,
431 bool expect_red,
432 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800433 const std::string& codec,
434 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800435 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800436 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100437 payload_name_(codec),
438 use_nack_(use_nack),
439 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700440 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800441 sent_media_(false),
442 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800443 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100444
brandtr20d45472017-01-02 00:34:27 -0800445 // Some of the test cases are expected to time out and thus we are using
446 // a shorter timeout window than the default here.
447 static constexpr size_t kTimeoutMs = 10000;
448
Stefan Holmer4654d202015-12-08 09:10:43 +0100449 private:
450 Action OnSendRtp(const uint8_t* packet, size_t length) override {
451 RTPHeader header;
452 EXPECT_TRUE(parser_->Parse(packet, length, &header));
453
Stefan Holmer4654d202015-12-08 09:10:43 +0100454 int encapsulated_payload_type = -1;
455 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100456 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100457 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
458 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100459 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100460 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
461 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100462 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100463 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100464 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
465 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100466 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
467 length) {
468 // Not padding-only, media received outside of RED.
469 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800470 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100471 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100472 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000473
Stefan Holmer4654d202015-12-08 09:10:43 +0100474 if (header_extensions_enabled_) {
475 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
476 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
477 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
478 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
479 // 24 bits wrap.
480 EXPECT_GT(prev_header_.extension.absoluteSendTime,
481 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000482 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100483 EXPECT_GE(header.extension.absoluteSendTime,
484 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200485 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100486 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
487 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
488 prev_header_.extension.transportSequenceNumber;
489 EXPECT_EQ(1, seq_num_diff);
490 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200491
Stefan Holmer4654d202015-12-08 09:10:43 +0100492 if (encapsulated_payload_type != -1) {
493 if (encapsulated_payload_type ==
494 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700495 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800496 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100497 } else {
brandtr65a1e772016-12-12 01:54:58 -0800498 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000499 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000500 }
501
brandtr20d45472017-01-02 00:34:27 -0800502 if (sent_media_ && sent_ulpfec_) {
503 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100504 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000505
Stefan Holmer4654d202015-12-08 09:10:43 +0100506 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000507
Stefan Holmer4654d202015-12-08 09:10:43 +0100508 return SEND_PACKET;
509 }
510
eladalon413ee9a2017-08-22 04:02:52 -0700511 test::PacketTransport* CreateSendTransport(
512 test::SingleThreadedTaskQueueForTesting* task_queue,
513 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100514 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
515 // Configure some network delay.
516 const int kNetworkDelayMs = 100;
517 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800518 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100519 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700520 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700521 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700522 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100523 }
524
stefanff483612015-12-21 03:14:00 -0800525 void ModifyVideoConfigs(
526 VideoSendStream::Config* send_config,
527 std::vector<VideoReceiveStream::Config>* receive_configs,
528 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100529 if (use_nack_) {
530 send_config->rtp.nack.rtp_history_ms =
531 (*receive_configs)[0].rtp.nack.rtp_history_ms =
532 VideoSendStreamTest::kNackRtpHistoryMs;
533 }
brandtr696c9c62016-12-19 05:47:28 -0800534 send_config->encoder_settings.encoder = encoder_;
Niels Möller04dd1762018-03-23 16:05:22 +0100535 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700536 send_config->rtp.ulpfec.red_payload_type =
537 VideoSendStreamTest::kRedPayloadType;
538 send_config->rtp.ulpfec.ulpfec_payload_type =
539 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800540 EXPECT_FALSE(send_config->rtp.extensions.empty());
541 if (!header_extensions_enabled_) {
542 send_config->rtp.extensions.clear();
543 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100544 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700545 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100546 }
nisse3b3622f2017-09-26 02:49:21 -0700547 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700548 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700549 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700550 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100551 }
552
553 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800554 EXPECT_EQ(expect_ulpfec_, Wait())
555 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100556 }
557
brandtr696c9c62016-12-19 05:47:28 -0800558 VideoEncoder* const encoder_;
559 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100560 const bool use_nack_;
561 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700562 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800563 bool sent_media_;
564 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100565 bool header_extensions_enabled_;
566 RTPHeader prev_header_;
567};
568
brandtre602f0a2016-10-31 03:40:49 -0700569TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800570 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
571 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800572 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100573}
574
brandtre602f0a2016-10-31 03:40:49 -0700575TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800576 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
577 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100578 RunBaseTest(&test);
579}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000580
stefan60e10c72017-08-23 10:40:00 -0700581class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
582 protected:
583 VideoSendStreamWithoutUlpfecTest()
584 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
585
586 test::ScopedFieldTrials field_trial_;
587};
588
589TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
590 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
591 UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
592 RunBaseTest(&test);
593}
594
Peter Boström39593972016-02-15 11:27:15 +0100595// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
596// since we'll still have to re-request FEC packets, effectively wasting
597// bandwidth since the receiver has to wait for FEC retransmissions to determine
598// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700599TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800600 std::unique_ptr<VideoEncoder> encoder(
601 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
602 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100603 RunBaseTest(&test);
604}
605
606// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800607TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800608 std::unique_ptr<VideoEncoder> encoder(
609 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
610 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100611 RunBaseTest(&test);
612}
613
danilchap9f5b6222017-03-02 06:22:21 -0800614// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
615TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800616 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
617 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100618 RunBaseTest(&test);
619}
620
Peter Boström12996152016-05-14 02:03:18 +0200621#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800622// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
623TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800624 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
625 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800626 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000627}
Peter Boström12996152016-05-14 02:03:18 +0200628#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000629
brandtre78d2662017-01-16 05:57:16 -0800630TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800631 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800632 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800633 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
634 RunBaseTest(&test);
635}
636
brandtr39f97292016-11-16 22:57:50 -0800637// TODO(brandtr): Move these FlexFEC tests when we have created
638// FlexfecSendStream.
639class FlexfecObserver : public test::EndToEndTest {
640 public:
641 FlexfecObserver(bool header_extensions_enabled,
642 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800643 const std::string& codec,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100644 VideoEncoder* encoder,
645 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800646 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800647 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800648 payload_name_(codec),
649 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800650 sent_media_(false),
651 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100652 header_extensions_enabled_(header_extensions_enabled),
653 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800654
655 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100656 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800657
658 private:
659 Action OnSendRtp(const uint8_t* packet, size_t length) override {
660 RTPHeader header;
661 EXPECT_TRUE(parser_->Parse(packet, length, &header));
662
brandtr39f97292016-11-16 22:57:50 -0800663 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
664 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
665 sent_flexfec_ = true;
666 } else {
667 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
668 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100669 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
670 num_video_streams_),
671 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800672 sent_media_ = true;
673 }
674
675 if (header_extensions_enabled_) {
676 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
677 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
678 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
679 }
680
brandtr0c5a1542016-11-23 04:42:26 -0800681 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800682 observation_complete_.Set();
683 }
684
685 return SEND_PACKET;
686 }
687
eladalon413ee9a2017-08-22 04:02:52 -0700688 test::PacketTransport* CreateSendTransport(
689 test::SingleThreadedTaskQueueForTesting* task_queue,
690 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800691 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
692 // Therefore we need some network delay.
693 const int kNetworkDelayMs = 100;
694 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800695 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800696 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700697 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700698 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700699 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800700 }
701
702 void ModifyVideoConfigs(
703 VideoSendStream::Config* send_config,
704 std::vector<VideoReceiveStream::Config>* receive_configs,
705 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800706 if (use_nack_) {
707 send_config->rtp.nack.rtp_history_ms =
708 (*receive_configs)[0].rtp.nack.rtp_history_ms =
709 VideoSendStreamTest::kNackRtpHistoryMs;
710 }
brandtr696c9c62016-12-19 05:47:28 -0800711 send_config->encoder_settings.encoder = encoder_;
Niels Möller04dd1762018-03-23 16:05:22 +0100712 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800713 if (header_extensions_enabled_) {
714 send_config->rtp.extensions.push_back(RtpExtension(
715 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
716 send_config->rtp.extensions.push_back(RtpExtension(
717 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800718 } else {
719 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800720 }
Niels Möller04dd1762018-03-23 16:05:22 +0100721 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800722 }
723
724 void PerformTest() override {
725 EXPECT_TRUE(Wait())
726 << "Timed out waiting for FlexFEC and/or media packets.";
727 }
728
brandtr696c9c62016-12-19 05:47:28 -0800729 VideoEncoder* const encoder_;
730 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800731 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800732 bool sent_media_;
733 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100734 const bool header_extensions_enabled_;
735 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800736};
737
brandtrd654a9b2016-12-05 05:38:19 -0800738TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800739 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100740 FlexfecObserver test(false, false, "VP8", encoder.get(), 1);
741 RunBaseTest(&test);
742}
743
744TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
745 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
746 FlexfecObserver test(false, false, "VP8", encoder.get(), 2);
brandtrd654a9b2016-12-05 05:38:19 -0800747 RunBaseTest(&test);
748}
749
750TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800751 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100752 FlexfecObserver test(false, true, "VP8", encoder.get(), 1);
brandtrd654a9b2016-12-05 05:38:19 -0800753 RunBaseTest(&test);
754}
755
brandtr39f97292016-11-16 22:57:50 -0800756TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800757 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100758 FlexfecObserver test(true, false, "VP8", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800759 RunBaseTest(&test);
760}
761
brandtr39f97292016-11-16 22:57:50 -0800762#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800763TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800764 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100765 FlexfecObserver test(false, false, "VP9", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800766 RunBaseTest(&test);
767}
768
brandtrd654a9b2016-12-05 05:38:19 -0800769TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800770 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100771 FlexfecObserver test(false, true, "VP9", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800772 RunBaseTest(&test);
773}
774#endif // defined(RTC_DISABLE_VP9)
775
brandtrd654a9b2016-12-05 05:38:19 -0800776TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
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, false, "H264", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800780 RunBaseTest(&test);
781}
782
brandtrd654a9b2016-12-05 05:38:19 -0800783TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800784 std::unique_ptr<VideoEncoder> encoder(
785 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100786 FlexfecObserver test(false, true, "H264", encoder.get(), 1);
brandtr696c9c62016-12-19 05:47:28 -0800787 RunBaseTest(&test);
788}
789
brandtre78d2662017-01-16 05:57:16 -0800790TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800791 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800792 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100793 FlexfecObserver test(false, false, "H264", encoder.get(), 1);
brandtr39f97292016-11-16 22:57:50 -0800794 RunBaseTest(&test);
795}
796
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000797void VideoSendStreamTest::TestNackRetransmission(
798 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000799 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000800 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000801 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000802 explicit NackObserver(uint32_t retransmit_ssrc,
803 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000804 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000805 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100806 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000807 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100808 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000809
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000810 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000811 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000812 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000813 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000814
Sebastian Janssond3f38162018-02-28 16:14:44 +0100815 int kRetransmitTarget = 6;
816 ++send_count_;
817 if (send_count_ == 5 || send_count_ == 25) {
818 nacked_sequence_numbers_.push_back(
819 static_cast<uint16_t>(header.sequenceNumber - 3));
820 nacked_sequence_numbers_.push_back(
821 static_cast<uint16_t>(header.sequenceNumber - 2));
822 nacked_sequence_numbers_.push_back(
823 static_cast<uint16_t>(header.sequenceNumber - 1));
824
danilchap8a1d2a32017-08-01 03:21:37 -0700825 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800826 nullptr, nullptr, transport_adapter_.get(),
827 RtcpIntervalConfig{});
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000828
pbosda903ea2015-10-02 02:36:56 -0700829 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100830 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000831
832 RTCPSender::FeedbackState feedback_state;
833
Sebastian Janssond3f38162018-02-28 16:14:44 +0100834 EXPECT_EQ(0, rtcp_sender.SendRTCP(
835 feedback_state, kRtcpNack,
836 static_cast<int>(nacked_sequence_numbers_.size()),
837 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000838 }
839
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000840 uint16_t sequence_number = header.sequenceNumber;
841
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000842 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100843 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
844 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000845 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000846 const uint8_t* rtx_header = packet + header.headerLength;
847 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
848 }
Sebastian Janssond3f38162018-02-28 16:14:44 +0100849 auto found = std::find(nacked_sequence_numbers_.begin(),
850 nacked_sequence_numbers_.end(), sequence_number);
851 if (found != nacked_sequence_numbers_.end()) {
852 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000853
Sebastian Janssond3f38162018-02-28 16:14:44 +0100854 if (++retransmit_count_ == kRetransmitTarget) {
855 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
856 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
857 observation_complete_.Set();
858 }
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000859 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000860
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000861 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000862 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000863
stefanff483612015-12-21 03:14:00 -0800864 void ModifyVideoConfigs(
865 VideoSendStream::Config* send_config,
866 std::vector<VideoReceiveStream::Config>* receive_configs,
867 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700868 transport_adapter_.reset(
869 new internal::TransportAdapter(send_config->send_transport));
870 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000871 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000872 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100873 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000874 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
875 }
876
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000877 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100878 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000879 }
880
kwiberg27f982b2016-03-01 11:52:33 -0800881 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000882 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100883 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000884 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000885 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100886 std::vector<uint16_t> nacked_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000887 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000888
stefane74eef12016-01-08 06:47:13 -0800889 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000890}
891
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000892TEST_F(VideoSendStreamTest, RetransmitsNack) {
893 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100894 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000895}
896
897TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
898 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000899 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000900}
901
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000902void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
903 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000904 // Use a fake encoder to output a frame of every size in the range [90, 290],
905 // for each size making sure that the exact number of payload bytes received
906 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000907 static const size_t kMaxPacketSize = 128;
908 static const size_t start = 90;
909 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000910
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000911 // Observer that verifies that the expected number of packets and bytes
912 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000913 class FrameFragmentationTest : public test::SendTest,
914 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000915 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000916 FrameFragmentationTest(size_t max_packet_size,
917 size_t start_size,
918 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000919 bool test_generic_packetization,
920 bool use_fec)
921 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000922 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000923 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000924 stop_size_(stop_size),
925 test_generic_packetization_(test_generic_packetization),
926 use_fec_(use_fec),
927 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100928 packets_lost_(0),
929 last_packet_count_(0),
930 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000931 accumulated_size_(0),
932 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000933 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000934 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700935 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000936 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000937 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700938 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000939 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000940
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000941 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000942 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000943 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000944 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000945 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000946
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000947 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000948
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000949 if (use_fec_) {
950 uint8_t payload_type = packet[header.headerLength];
951 bool is_fec = header.payloadType == kRedPayloadType &&
952 payload_type == kUlpfecPayloadType;
953 if (is_fec) {
954 fec_packet_received_ = true;
955 return SEND_PACKET;
956 }
957 }
958
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000959 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000960
961 if (use_fec_)
962 TriggerLossReport(header);
963
964 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200965 size_t overhead = header.headerLength + header.paddingLength;
966 // Only remove payload header and RED header if the packet actually
967 // contains payload.
968 if (length > overhead) {
969 overhead += (1 /* Generic header */);
970 if (use_fec_)
971 overhead += 1; // RED for FEC header.
972 }
973 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000974 accumulated_payload_ += length - overhead;
975 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000976
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000977 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000978 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000979 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
980 // With FEC enabled, frame size is incremented asynchronously, so
981 // "old" frames one byte too small may arrive. Accept, but don't
982 // increase expected frame size.
983 accumulated_size_ = 0;
984 accumulated_payload_ = 0;
985 return SEND_PACKET;
986 }
987
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000988 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000989 if (test_generic_packetization_) {
990 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
991 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000992
993 // Last packet of frame; reset counters.
994 accumulated_size_ = 0;
995 accumulated_payload_ = 0;
996 if (current_size_rtp_ == stop_size_) {
997 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100998 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000999 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001000 // Increase next expected frame size. If testing with FEC, make sure
1001 // a FEC packet has been received for this frame size before
1002 // proceeding, to make sure that redundancy packets don't exceed
1003 // size limit.
1004 if (!use_fec_) {
1005 ++current_size_rtp_;
1006 } else if (fec_packet_received_) {
1007 fec_packet_received_ = false;
1008 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001009
1010 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001011 ++current_size_frame_;
1012 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001013 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001014 }
1015
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001016 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001017 }
1018
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001019 void TriggerLossReport(const RTPHeader& header) {
1020 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001021 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001022 if (++packet_count_ % (100 / kLossPercent) == 0) {
1023 packets_lost_++;
1024 int loss_delta = packets_lost_ - last_packets_lost_;
1025 int packets_delta = packet_count_ - last_packet_count_;
1026 last_packet_count_ = packet_count_;
1027 last_packets_lost_ = packets_lost_;
1028 uint8_t loss_ratio =
1029 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001030 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001031 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001032 packets_lost_, // Cumulative lost.
1033 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001034 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001035 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001036 transport_adapter_.get(), RtcpIntervalConfig{});
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001037
pbosda903ea2015-10-02 02:36:56 -07001038 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001039 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001040
1041 RTCPSender::FeedbackState feedback_state;
1042
1043 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1044 }
1045 }
1046
nisseef8b61e2016-04-29 06:09:15 -07001047 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001048 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001049 // Increase frame size for next encoded frame, in the context of the
1050 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001051 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001052 ++current_size_frame_;
1053 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001054 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001055 }
1056
Stefan Holmere5904162015-03-26 11:11:06 +01001057 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07001058 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001059 const int kMinBitrateBps = 30000;
1060 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1061 return config;
1062 }
1063
stefanff483612015-12-21 03:14:00 -08001064 void ModifyVideoConfigs(
1065 VideoSendStream::Config* send_config,
1066 std::vector<VideoReceiveStream::Config>* receive_configs,
1067 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001068 transport_adapter_.reset(
1069 new internal::TransportAdapter(send_config->send_transport));
1070 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001071 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001072 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1073 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001074 }
1075
1076 if (!test_generic_packetization_)
Niels Möller04dd1762018-03-23 16:05:22 +01001077 send_config->rtp.payload_name = "VP8";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001078
1079 send_config->encoder_settings.encoder = &encoder_;
1080 send_config->rtp.max_packet_size = kMaxPacketSize;
1081 send_config->post_encode_callback = this;
1082
Erik Språng95261872015-04-10 11:58:49 +02001083 // Make sure there is at least one extension header, to make the RTP
1084 // header larger than the base length of 12 bytes.
1085 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001086
1087 // Setup screen content disables frame dropping which makes this easier.
1088 class VideoStreamFactory
1089 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1090 public:
1091 explicit VideoStreamFactory(size_t num_temporal_layers)
1092 : num_temporal_layers_(num_temporal_layers) {
1093 EXPECT_GT(num_temporal_layers, 0u);
1094 }
1095
1096 private:
1097 std::vector<VideoStream> CreateEncoderStreams(
1098 int width,
1099 int height,
1100 const VideoEncoderConfig& encoder_config) override {
1101 std::vector<VideoStream> streams =
1102 test::CreateVideoStreams(width, height, encoder_config);
1103 for (VideoStream& stream : streams) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01001104 stream.num_temporal_layers = num_temporal_layers_;
sprang4847ae62017-06-27 07:06:52 -07001105 }
1106 return streams;
1107 }
1108 const size_t num_temporal_layers_;
1109 };
1110
1111 encoder_config->video_stream_factory =
1112 new rtc::RefCountedObject<VideoStreamFactory>(2);
1113 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001114 }
1115
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001116 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001117 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001118 }
1119
kwiberg27f982b2016-03-01 11:52:33 -08001120 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001121 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001122
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001123 const size_t max_packet_size_;
1124 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001125 const bool test_generic_packetization_;
1126 const bool use_fec_;
1127
1128 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001129 uint32_t packets_lost_;
1130 uint32_t last_packet_count_;
1131 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001132 size_t accumulated_size_;
1133 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001134 bool fec_packet_received_;
1135
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001136 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001137 rtc::CriticalSection mutex_;
1138 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001139 };
1140
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001141 // Don't auto increment if FEC is used; continue sending frame size until
1142 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001143 FrameFragmentationTest test(
1144 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001145
stefane74eef12016-01-08 06:47:13 -08001146 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001147}
1148
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001149// TODO(sprang): Is there any way of speeding up these tests?
1150TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1151 TestPacketFragmentationSize(kGeneric, false);
1152}
1153
1154TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1155 TestPacketFragmentationSize(kGeneric, true);
1156}
1157
1158TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1159 TestPacketFragmentationSize(kVP8, false);
1160}
1161
1162TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1163 TestPacketFragmentationSize(kVP8, true);
1164}
1165
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001166// The test will go through a number of phases.
1167// 1. Start sending packets.
1168// 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 +00001169// suspend the stream.
1170// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001171// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001172// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001173// When the stream is detected again, and the stats show that the stream
1174// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001175TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1176 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001177
nissed30a1112016-04-18 05:15:22 -07001178 class RembObserver : public test::SendTest,
1179 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001180 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001181 RembObserver()
1182 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001183 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001184 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001185 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001186 rtp_count_(0),
1187 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001188 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001189 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001190 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001191
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001192 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001193 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001194 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001195 ++rtp_count_;
1196 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001197 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001198 last_sequence_number_ = header.sequenceNumber;
1199
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001200 if (test_state_ == kBeforeSuspend) {
1201 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001202 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001203 test_state_ = kDuringSuspend;
1204 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001205 if (header.paddingLength == 0) {
1206 // Received non-padding packet during suspension period. Reset the
1207 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001208 suspended_frame_count_ = 0;
1209 }
stefanf116bd02015-10-27 08:29:42 -07001210 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001211 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001212 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001213 // Non-padding packet observed. Test is almost complete. Will just
1214 // have to wait for the stats to change.
1215 test_state_ = kWaitingForStats;
1216 }
stefanf116bd02015-10-27 08:29:42 -07001217 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001218 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001219 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001220 if (stats.suspended == false) {
1221 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001222 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001223 }
stefanf116bd02015-10-27 08:29:42 -07001224 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001225 }
1226
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001227 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001228 }
1229
perkj26091b12016-09-01 01:17:40 -07001230 // This method implements the rtc::VideoSinkInterface. This is called when
1231 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001232 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001233 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001234 if (test_state_ == kDuringSuspend &&
1235 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001236 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001237 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001238 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001239 test_state_ = kWaitingForPacket;
1240 }
1241 }
1242
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001243 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001244 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001245 low_remb_bps_ = value;
1246 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001247
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001248 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001249 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001250 high_remb_bps_ = value;
1251 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001252
stefanff483612015-12-21 03:14:00 -08001253 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001254 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001255 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001256 stream_ = send_stream;
1257 }
1258
stefanff483612015-12-21 03:14:00 -08001259 void ModifyVideoConfigs(
1260 VideoSendStream::Config* send_config,
1261 std::vector<VideoReceiveStream::Config>* receive_configs,
1262 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001263 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001264 transport_adapter_.reset(
1265 new internal::TransportAdapter(send_config->send_transport));
1266 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001267 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001268 send_config->pre_encode_callback = this;
1269 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001270 int min_bitrate_bps =
1271 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001272 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001273 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001274 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001275 min_bitrate_bps + threshold_window + 5000);
1276 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1277 }
1278
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001279 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001280 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001281 }
1282
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001283 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001284 kBeforeSuspend,
1285 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001286 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001287 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001288 };
1289
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001290 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001291 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001292 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1293 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001294 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001295 transport_adapter_.get(), RtcpIntervalConfig{});
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001296
pbosda903ea2015-10-02 02:36:56 -07001297 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001298 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001299 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001300 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001301 }
1302 RTCPSender::FeedbackState feedback_state;
1303 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1304 }
1305
kwiberg27f982b2016-03-01 11:52:33 -08001306 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001307 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001308 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001309
Peter Boströmf2f82832015-05-01 13:00:41 +02001310 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001311 TestState test_state_ RTC_GUARDED_BY(crit_);
1312 int rtp_count_ RTC_GUARDED_BY(crit_);
1313 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1314 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1315 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1316 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001317 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001318
stefane74eef12016-01-08 06:47:13 -08001319 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001320}
1321
perkj71ee44c2016-06-15 00:47:53 -07001322// This test that padding stops being send after a while if the Camera stops
1323// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001324TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001325 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001326 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001327 NoPaddingWhenVideoIsMuted()
1328 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001329 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001330 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001331 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001332 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001333
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001334 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001335 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001336 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001337 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001338
1339 RTPHeader header;
1340 parser_->Parse(packet, length, &header);
1341 const bool only_padding =
1342 header.headerLength + header.paddingLength == length;
1343
1344 if (test_state_ == kBeforeStopCapture) {
1345 capturer_->Stop();
1346 test_state_ = kWaitingForPadding;
1347 } else if (test_state_ == kWaitingForPadding && only_padding) {
1348 test_state_ = kWaitingForNoPackets;
1349 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1350 only_padding) {
1351 observation_complete_.Set();
1352 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001353 return SEND_PACKET;
1354 }
1355
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001356 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001357 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001358 const int kNoPacketsThresholdMs = 2000;
1359 if (test_state_ == kWaitingForNoPackets &&
1360 (last_packet_time_ms_ > 0 &&
1361 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1362 kNoPacketsThresholdMs)) {
1363 capturer_->Start();
1364 test_state_ = kWaitingForPaddingAfterCameraRestart;
1365 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001366 return SEND_PACKET;
1367 }
1368
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001369 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001370
nisseef8b61e2016-04-29 06:09:15 -07001371 void OnFrameGeneratorCapturerCreated(
1372 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001373 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001374 capturer_ = frame_generator_capturer;
1375 }
1376
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001377 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001378 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001379 << "Timed out while waiting for RTP packets to stop being sent.";
1380 }
1381
perkj71ee44c2016-06-15 00:47:53 -07001382 enum TestState {
1383 kBeforeStopCapture,
1384 kWaitingForPadding,
1385 kWaitingForNoPackets,
1386 kWaitingForPaddingAfterCameraRestart
1387 };
1388
1389 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001390 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001391 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001392 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001393 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1394 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001395 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001396
stefane74eef12016-01-08 06:47:13 -08001397 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001398}
1399
isheriffcc5903e2016-10-04 08:29:38 -07001400TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1401 const int kCapacityKbps = 10000; // 10 Mbps
1402 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1403 public:
1404 PaddingIsPrimarilyRetransmissions()
1405 : EndToEndTest(kDefaultTimeoutMs),
1406 clock_(Clock::GetRealTimeClock()),
1407 padding_length_(0),
1408 total_length_(0),
1409 call_(nullptr) {}
1410
1411 private:
1412 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1413 call_ = sender_call;
1414 }
1415
1416 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1417 rtc::CritScope lock(&crit_);
1418
1419 RTPHeader header;
1420 parser_->Parse(packet, length, &header);
1421 padding_length_ += header.paddingLength;
1422 total_length_ += length;
1423 return SEND_PACKET;
1424 }
1425
eladalon413ee9a2017-08-22 04:02:52 -07001426 test::PacketTransport* CreateSendTransport(
1427 test::SingleThreadedTaskQueueForTesting* task_queue,
1428 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001429 const int kNetworkDelayMs = 50;
1430 FakeNetworkPipe::Config config;
1431 config.loss_percent = 10;
1432 config.link_capacity_kbps = kCapacityKbps;
1433 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001434 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001435 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001436 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001437 }
1438
1439 void ModifyVideoConfigs(
1440 VideoSendStream::Config* send_config,
1441 std::vector<VideoReceiveStream::Config>* receive_configs,
1442 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001443 // Turn on RTX.
1444 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1445 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001446 }
1447
1448 void PerformTest() override {
1449 // TODO(isheriff): Some platforms do not ramp up as expected to full
1450 // capacity due to packet scheduling delays. Fix that before getting
1451 // rid of this.
1452 SleepMs(5000);
1453 {
1454 rtc::CritScope lock(&crit_);
1455 // Expect padding to be a small percentage of total bytes sent.
1456 EXPECT_LT(padding_length_, .1 * total_length_);
1457 }
1458 }
1459
1460 rtc::CriticalSection crit_;
1461 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001462 size_t padding_length_ RTC_GUARDED_BY(crit_);
1463 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001464 Call* call_;
1465 } test;
1466
1467 RunBaseTest(&test);
1468}
1469
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001470// This test first observes "high" bitrate use at which point it sends a REMB to
1471// indicate that it should be lowered significantly. The test then observes that
1472// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1473// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001474//
1475// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1476// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001477TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1478 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001479 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001480 static const int kRembBitrateBps = 80000;
1481 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001482 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001483 public:
1484 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001485 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001486 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1487 stream_(nullptr),
1488 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001489
1490 private:
nisseef8b61e2016-04-29 06:09:15 -07001491 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001492 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001493 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001494
1495 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001496 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001497 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001498 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001499 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001500 if (!stats.substreams.empty()) {
1501 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001502 int total_bitrate_bps =
1503 stats.substreams.begin()->second.total_bitrate_bps;
1504 test::PrintResult("bitrate_stats_",
1505 "min_transmit_bitrate_low_remb",
1506 "bitrate_bps",
1507 static_cast<size_t>(total_bitrate_bps),
1508 "bps",
1509 false);
1510 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001511 rtp_rtcp_->SetRemb(kRembBitrateBps,
1512 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001513 rtp_rtcp_->Process();
1514 bitrate_capped_ = true;
1515 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001516 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001517 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001518 }
1519 }
stefanf116bd02015-10-27 08:29:42 -07001520 // Packets don't have to be delivered since the test is the receiver.
1521 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001522 }
1523
stefanff483612015-12-21 03:14:00 -08001524 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001525 VideoSendStream* send_stream,
1526 const std::vector<VideoReceiveStream*>& receive_streams) override {
1527 stream_ = send_stream;
1528 RtpRtcp::Configuration config;
1529 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001530 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001531 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001532 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001533 }
1534
stefanff483612015-12-21 03:14:00 -08001535 void ModifyVideoConfigs(
1536 VideoSendStream::Config* send_config,
1537 std::vector<VideoReceiveStream::Config>* receive_configs,
1538 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001539 feedback_transport_.reset(
1540 new internal::TransportAdapter(send_config->send_transport));
1541 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001542 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001543 }
1544
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001545 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001546 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001547 << "Timeout while waiting for low bitrate stats after REMB.";
1548 }
1549
kwiberg27f982b2016-03-01 11:52:33 -08001550 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1551 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001552 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001553 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001554 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001555 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001556
stefane74eef12016-01-08 06:47:13 -08001557 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001558}
1559
Stefan Holmer280de9e2016-09-30 10:06:51 +02001560TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1561 static const int kStartBitrateBps = 300000;
1562 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001563 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001564 class ChangingNetworkRouteTest : public test::EndToEndTest {
1565 public:
eladalon413ee9a2017-08-22 04:02:52 -07001566 explicit ChangingNetworkRouteTest(
1567 test::SingleThreadedTaskQueueForTesting* task_queue)
1568 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1569 task_queue_(task_queue),
1570 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001571 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1572 kRtpExtensionTransportSequenceNumber, kExtensionId));
1573 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001574
1575 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1576 call_ = sender_call;
1577 }
1578
Stefan Holmer280de9e2016-09-30 10:06:51 +02001579 void ModifyVideoConfigs(
1580 VideoSendStream::Config* send_config,
1581 std::vector<VideoReceiveStream::Config>* receive_configs,
1582 VideoEncoderConfig* encoder_config) override {
1583 send_config->rtp.extensions.clear();
1584 send_config->rtp.extensions.push_back(RtpExtension(
1585 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1586 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1587 (*receive_configs)[0].rtp.transport_cc = true;
1588 }
1589
1590 void ModifyAudioConfigs(
1591 AudioSendStream::Config* send_config,
1592 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1593 send_config->rtp.extensions.clear();
1594 send_config->rtp.extensions.push_back(RtpExtension(
1595 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1596 (*receive_configs)[0].rtp.extensions.clear();
1597 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1598 (*receive_configs)[0].rtp.transport_cc = true;
1599 }
1600
Stefan Holmerbe402962016-07-08 16:16:41 +02001601 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1602 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1603 observation_complete_.Set();
1604 }
1605
1606 return SEND_PACKET;
1607 }
1608
1609 void PerformTest() override {
1610 rtc::NetworkRoute new_route(true, 10, 20, -1);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001611 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001612
1613 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001614 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1615 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001616 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001617 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1618 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001619 });
1620
Stefan Holmerbe402962016-07-08 16:16:41 +02001621 EXPECT_TRUE(Wait())
1622 << "Timed out while waiting for start bitrate to be exceeded.";
1623
eladalon413ee9a2017-08-22 04:02:52 -07001624 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1625 bitrate_config.start_bitrate_bps = -1;
1626 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001627 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1628 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001629 // TODO(holmer): We should set the last sent packet id here and verify
1630 // that we correctly ignore any packet loss reported prior to that id.
1631 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001632 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1633 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001634 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1635 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001636 }
1637
1638 private:
eladalon413ee9a2017-08-22 04:02:52 -07001639 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001640 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001641 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001642
1643 RunBaseTest(&test);
1644}
1645
michaelt79e05882016-11-08 02:50:09 -08001646TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1647 class ChangingTransportOverheadTest : public test::EndToEndTest {
1648 public:
eladalon413ee9a2017-08-22 04:02:52 -07001649 explicit ChangingTransportOverheadTest(
1650 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001651 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001652 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001653 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001654 packets_sent_(0),
1655 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001656
1657 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1658 call_ = sender_call;
1659 }
1660
1661 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001662 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001663 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001664 if (++packets_sent_ < 100)
1665 return SEND_PACKET;
1666 observation_complete_.Set();
1667 return SEND_PACKET;
1668 }
1669
michaelta3328772016-11-29 09:25:03 -08001670 void ModifyVideoConfigs(
1671 VideoSendStream::Config* send_config,
1672 std::vector<VideoReceiveStream::Config>* receive_configs,
1673 VideoEncoderConfig* encoder_config) override {
1674 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1675 }
1676
michaelt79e05882016-11-08 02:50:09 -08001677 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001678 task_queue_->SendTask([this]() {
1679 transport_overhead_ = 100;
1680 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1681 transport_overhead_);
1682 });
1683
michaelt79e05882016-11-08 02:50:09 -08001684 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001685
sprang21253fc2017-02-27 03:35:47 -08001686 {
1687 rtc::CritScope cs(&lock_);
1688 packets_sent_ = 0;
1689 }
eladalon413ee9a2017-08-22 04:02:52 -07001690
1691 task_queue_->SendTask([this]() {
1692 transport_overhead_ = 500;
1693 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1694 transport_overhead_);
1695 });
1696
michaelt79e05882016-11-08 02:50:09 -08001697 EXPECT_TRUE(Wait());
1698 }
1699
1700 private:
eladalon413ee9a2017-08-22 04:02:52 -07001701 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001702 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001703 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001704 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001705 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001706 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001707 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001708
1709 RunBaseTest(&test);
1710}
1711
sprangf24a0642017-02-28 13:23:26 -08001712// Test class takes takes as argument a switch selecting if type switch should
1713// occur and a function pointer to reset the send stream. This is necessary
1714// since you cannot change the content type of a VideoSendStream, you need to
1715// recreate it. Stopping and recreating the stream can only be done on the main
1716// thread and in the context of VideoSendStreamTest (not BaseTest).
1717template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001718class MaxPaddingSetTest : public test::SendTest {
1719 public:
1720 static const uint32_t kMinTransmitBitrateBps = 400000;
1721 static const uint32_t kActualEncodeBitrateBps = 40000;
1722 static const uint32_t kMinPacketsToSend = 50;
1723
sprangf24a0642017-02-28 13:23:26 -08001724 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001725 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001726 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001727 call_(nullptr),
1728 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001729 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001730 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001731 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001732 stream_resetter_(stream_reset_fun) {
1733 RTC_DCHECK(stream_resetter_);
1734 }
sprang9c0b5512016-07-06 00:54:28 -07001735
1736 void OnVideoStreamsCreated(
1737 VideoSendStream* send_stream,
1738 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001739 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001740 send_stream_ = send_stream;
1741 }
1742
1743 void ModifyVideoConfigs(
1744 VideoSendStream::Config* send_config,
1745 std::vector<VideoReceiveStream::Config>* receive_configs,
1746 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001747 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001748 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001749 encoder_config->min_transmit_bitrate_bps = 0;
1750 encoder_config->content_type =
1751 VideoEncoderConfig::ContentType::kRealtimeVideo;
1752 } else {
1753 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1754 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1755 }
sprangf24a0642017-02-28 13:23:26 -08001756 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001757 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001758 }
1759
1760 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1761 call_ = sender_call;
1762 }
1763
1764 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1765 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001766 if (running_without_padding_)
1767 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1768
1769 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1770 // we have reliable data.
1771 if (++packets_sent_ < kMinPacketsToSend)
1772 return SEND_PACKET;
1773
1774 if (running_without_padding_) {
1775 // We've sent kMinPacketsToSend packets with default configuration, switch
1776 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001777 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001778 packets_sent_ = 0;
1779 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1780 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001781 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001782 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001783 return SEND_PACKET;
1784 }
1785
1786 // Make sure the pacer has been configured with a min transmit bitrate.
1787 if (call_->GetStats().max_padding_bitrate_bps > 0)
1788 observation_complete_.Set();
1789
1790 return SEND_PACKET;
1791 }
1792
1793 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001794 if (RunningWithoutPadding()) {
1795 ASSERT_TRUE(
1796 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001797 (*stream_resetter_)(send_stream_config_, encoder_config_);
1798 }
1799
sprang9c0b5512016-07-06 00:54:28 -07001800 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1801 }
1802
1803 private:
sprangf24a0642017-02-28 13:23:26 -08001804 bool RunningWithoutPadding() const {
1805 rtc::CritScope lock(&crit_);
1806 return running_without_padding_;
1807 }
1808
sprang9c0b5512016-07-06 00:54:28 -07001809 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001810 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001811 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001812 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001813 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001814 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001815 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001816 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001817 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001818};
1819
1820TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001821 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1822 const VideoEncoderConfig& encoder_config) {};
1823 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001824 RunBaseTest(&test);
1825}
1826
1827TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001828 // Function for removing and recreating the send stream with a new config.
1829 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1830 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001831 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1832 Stop();
1833 sender_call_->DestroyVideoSendStream(video_send_stream_);
1834 video_send_config_ = send_stream_config.Copy();
1835 video_encoder_config_ = encoder_config.Copy();
1836 video_send_stream_ = sender_call_->CreateVideoSendStream(
1837 video_send_config_.Copy(), video_encoder_config_.Copy());
1838 video_send_stream_->SetSource(
1839 frame_generator_capturer_.get(),
1840 VideoSendStream::DegradationPreference::kMaintainResolution);
1841 Start();
1842 });
sprangf24a0642017-02-28 13:23:26 -08001843 };
1844 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001845 RunBaseTest(&test);
1846}
1847
perkjfa10b552016-10-02 23:45:26 -07001848// This test verifies that new frame sizes reconfigures encoders even though not
1849// (yet) sending. The purpose of this is to permit encoding as quickly as
1850// possible once we start sending. Likely the frames being input are from the
1851// same source that will be sent later, which just means that we're ready
1852// earlier.
1853TEST_F(VideoSendStreamTest,
1854 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1855 class EncoderObserver : public test::FakeEncoder {
1856 public:
1857 EncoderObserver()
1858 : FakeEncoder(Clock::GetRealTimeClock()),
1859 init_encode_called_(false, false),
1860 number_of_initializations_(0),
1861 last_initialized_frame_width_(0),
1862 last_initialized_frame_height_(0) {}
1863
1864 void WaitForResolution(int width, int height) {
1865 {
1866 rtc::CritScope lock(&crit_);
1867 if (last_initialized_frame_width_ == width &&
1868 last_initialized_frame_height_ == height) {
1869 return;
1870 }
1871 }
Erik Språng08127a92016-11-16 16:41:30 +01001872 EXPECT_TRUE(
1873 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001874 {
1875 rtc::CritScope lock(&crit_);
1876 EXPECT_EQ(width, last_initialized_frame_width_);
1877 EXPECT_EQ(height, last_initialized_frame_height_);
1878 }
1879 }
1880
1881 private:
1882 int32_t InitEncode(const VideoCodec* config,
1883 int32_t number_of_cores,
1884 size_t max_payload_size) override {
1885 rtc::CritScope lock(&crit_);
1886 last_initialized_frame_width_ = config->width;
1887 last_initialized_frame_height_ = config->height;
1888 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001889 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001890 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1891 }
1892
1893 int32_t Encode(const VideoFrame& input_image,
1894 const CodecSpecificInfo* codec_specific_info,
1895 const std::vector<FrameType>* frame_types) override {
1896 ADD_FAILURE()
1897 << "Unexpected Encode call since the send stream is not started";
1898 return 0;
1899 }
1900
1901 rtc::CriticalSection crit_;
1902 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001903 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1904 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1905 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001906 };
1907
perkjfa10b552016-10-02 23:45:26 -07001908 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001909 EncoderObserver encoder;
eladalon413ee9a2017-08-22 04:02:52 -07001910
1911 task_queue_.SendTask([this, &transport, &encoder]() {
1912 CreateSenderCall(Call::Config(event_log_.get()));
1913 CreateSendConfig(1, 0, 0, &transport);
1914 video_send_config_.encoder_settings.encoder = &encoder;
1915 CreateVideoStreams();
1916 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1917 kDefaultHeight);
1918 frame_generator_capturer_->Start();
1919 });
perkjfa10b552016-10-02 23:45:26 -07001920
1921 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001922
1923 task_queue_.SendTask([this]() {
1924 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1925 kDefaultHeight * 2);
1926 });
1927
perkjfa10b552016-10-02 23:45:26 -07001928 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001929
1930 task_queue_.SendTask([this]() {
1931 DestroyStreams();
1932 DestroyCalls();
1933 });
perkjfa10b552016-10-02 23:45:26 -07001934}
1935
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001936TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1937 class StartBitrateObserver : public test::FakeEncoder {
1938 public:
1939 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001940 : FakeEncoder(Clock::GetRealTimeClock()),
1941 start_bitrate_changed_(false, false),
1942 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001943 int32_t InitEncode(const VideoCodec* config,
1944 int32_t number_of_cores,
1945 size_t max_payload_size) override {
1946 rtc::CritScope lock(&crit_);
1947 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001948 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001949 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1950 }
1951
1952 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1953 rtc::CritScope lock(&crit_);
1954 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001955 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001956 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1957 }
1958
1959 int GetStartBitrateKbps() const {
1960 rtc::CritScope lock(&crit_);
1961 return start_bitrate_kbps_;
1962 }
1963
pbos14fe7082016-04-20 06:35:56 -07001964 bool WaitForStartBitrate() {
1965 return start_bitrate_changed_.Wait(
1966 VideoSendStreamTest::kDefaultTimeoutMs);
1967 }
1968
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001969 private:
pbos5ad935c2016-01-25 03:52:44 -08001970 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001971 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001972 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001973 };
1974
philipel4fb651d2017-04-10 03:54:05 -07001975 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001976
solenberg4fbae2b2015-08-28 04:07:10 -07001977 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001978 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001979
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001980 BitrateConstraints bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001981 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001982 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1983 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001984
1985 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001986 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001987 // Since this test does not use a capturer, set |internal_source| = true.
1988 // Encoder configuration is otherwise updated on the next video frame.
1989 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001990
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001991 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001992
pbos14fe7082016-04-20 06:35:56 -07001993 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001994 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001995 encoder.GetStartBitrateKbps());
1996
perkjfa10b552016-10-02 23:45:26 -07001997 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001998 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001999
2000 // New bitrate should be reconfigured above the previous max. As there's no
2001 // network connection this shouldn't be flaky, as no bitrate should've been
2002 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002003 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002004 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2005 encoder.GetStartBitrateKbps());
2006
2007 DestroyStreams();
2008}
2009
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002010class StartStopBitrateObserver : public test::FakeEncoder {
2011 public:
2012 StartStopBitrateObserver()
2013 : FakeEncoder(Clock::GetRealTimeClock()),
2014 encoder_init_(false, false),
2015 bitrate_changed_(false, false) {}
2016 int32_t InitEncode(const VideoCodec* config,
2017 int32_t number_of_cores,
2018 size_t max_payload_size) override {
2019 rtc::CritScope lock(&crit_);
2020 encoder_init_.Set();
2021 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2022 }
2023
2024 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2025 uint32_t framerate) override {
2026 rtc::CritScope lock(&crit_);
2027 bitrate_kbps_ = bitrate.get_sum_kbps();
2028 bitrate_changed_.Set();
2029 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2030 }
2031
2032 bool WaitForEncoderInit() {
2033 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2034 }
2035
2036 bool WaitBitrateChanged(bool non_zero) {
2037 do {
2038 rtc::Optional<int> bitrate_kbps;
2039 {
2040 rtc::CritScope lock(&crit_);
2041 bitrate_kbps = bitrate_kbps_;
2042 }
2043 if (!bitrate_kbps)
2044 continue;
2045
2046 if ((non_zero && *bitrate_kbps > 0) ||
2047 (!non_zero && *bitrate_kbps == 0)) {
2048 return true;
2049 }
2050 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2051 return false;
2052 }
2053
2054 private:
2055 rtc::CriticalSection crit_;
2056 rtc::Event encoder_init_;
2057 rtc::Event bitrate_changed_;
2058 rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
2059};
2060
perkj57c21f92016-06-17 07:27:16 -07002061// This test that if the encoder use an internal source, VideoEncoder::SetRates
2062// will be called with zero bitrate during initialization and that
2063// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2064// with zero bitrate.
2065TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002066 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002067 StartStopBitrateObserver encoder;
perkj57c21f92016-06-17 07:27:16 -07002068
eladalon413ee9a2017-08-22 04:02:52 -07002069 task_queue_.SendTask([this, &transport, &encoder]() {
2070 CreateSenderCall(Call::Config(event_log_.get()));
2071 CreateSendConfig(1, 0, 0, &transport);
2072
2073 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2074
2075 video_send_config_.encoder_settings.encoder = &encoder;
2076 video_send_config_.encoder_settings.internal_source = true;
2077
2078 CreateVideoStreams();
2079 });
perkj57c21f92016-06-17 07:27:16 -07002080
2081 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002082
eladalon413ee9a2017-08-22 04:02:52 -07002083 task_queue_.SendTask([this]() {
2084 video_send_stream_->Start();
2085 });
Erik Språng08127a92016-11-16 16:41:30 +01002086 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2087
eladalon413ee9a2017-08-22 04:02:52 -07002088 task_queue_.SendTask([this]() {
2089 video_send_stream_->Stop();
2090 });
Erik Språng08127a92016-11-16 16:41:30 +01002091 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2092
eladalon413ee9a2017-08-22 04:02:52 -07002093 task_queue_.SendTask([this]() {
2094 video_send_stream_->Start();
2095 });
Erik Språng08127a92016-11-16 16:41:30 +01002096 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002097
eladalon413ee9a2017-08-22 04:02:52 -07002098 task_queue_.SendTask([this]() {
2099 DestroyStreams();
2100 DestroyCalls();
2101 });
perkj57c21f92016-06-17 07:27:16 -07002102}
2103
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002104// Tests that when the encoder uses an internal source, the VideoEncoder will
2105// be updated with a new bitrate when turning the VideoSendStream on/off with
2106// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2107// is reconfigured with new active layers.
2108TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
2109 test::NullTransport transport;
2110 StartStopBitrateObserver encoder;
2111
2112 task_queue_.SendTask([this, &transport, &encoder]() {
2113 CreateSenderCall(Call::Config(event_log_.get()));
2114 // Create two simulcast streams.
2115 CreateSendConfig(2, 0, 0, &transport);
2116
2117 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2118
2119 video_send_config_.encoder_settings.encoder = &encoder;
2120 video_send_config_.encoder_settings.internal_source = true;
Niels Möller04dd1762018-03-23 16:05:22 +01002121 video_send_config_.rtp.payload_name = "VP8";
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002122
2123 CreateVideoStreams();
2124 });
2125
2126 EXPECT_TRUE(encoder.WaitForEncoderInit());
2127
2128 // When we turn on the simulcast layers it will update the BitrateAllocator,
2129 // which in turn updates the VideoEncoder's bitrate.
2130 task_queue_.SendTask([this]() {
2131 video_send_stream_->UpdateActiveSimulcastLayers({true, true});
2132 });
2133 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2134
2135 video_encoder_config_.simulcast_layers[0].active = true;
2136 video_encoder_config_.simulcast_layers[1].active = false;
2137 task_queue_.SendTask([this]() {
2138 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
2139 });
2140 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2141 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2142 // active. Once the change is made for a "soft" reconfiguration we can remove
2143 // the expecation for an encoder init. We can also test that bitrate changes
2144 // when just updating individual active layers, which should change the
2145 // bitrate set to the video encoder.
2146 EXPECT_TRUE(encoder.WaitForEncoderInit());
2147 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2148
2149 // Turning off both simulcast layers should trigger a bitrate change of 0.
2150 video_encoder_config_.simulcast_layers[0].active = false;
2151 video_encoder_config_.simulcast_layers[1].active = false;
2152 task_queue_.SendTask([this]() {
2153 video_send_stream_->UpdateActiveSimulcastLayers({false, false});
2154 });
2155 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2156
2157 task_queue_.SendTask([this]() {
2158 DestroyStreams();
2159 DestroyCalls();
2160 });
2161}
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002162TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002163 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002164 public:
Peter Boström5811a392015-12-10 13:02:50 +01002165 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002166
nissed30a1112016-04-18 05:15:22 -07002167 void OnFrame(const VideoFrame& video_frame) override {
2168 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002169 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002170 }
2171
2172 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002173 const int kWaitFrameTimeoutMs = 3000;
2174 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002175 << "Timeout while waiting for output frames.";
2176 }
2177
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002178 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002179 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002180 }
2181
2182 private:
2183 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002184 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002185
2186 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002187 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002188 };
2189
solenberg4fbae2b2015-08-28 04:07:10 -07002190 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002191 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002192 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002193
eladalon413ee9a2017-08-22 04:02:52 -07002194 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2195 // Initialize send stream.
2196 CreateSenderCall(Call::Config(event_log_.get()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002197
eladalon413ee9a2017-08-22 04:02:52 -07002198 CreateSendConfig(1, 0, 0, &transport);
2199 video_send_config_.pre_encode_callback = &observer;
2200 CreateVideoStreams();
2201
2202 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2203 // alternatively.
2204 int width = 168;
2205 int height = 132;
2206
2207 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2208 width, height, 1, 1, kVideoRotation_0));
2209 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2210 width, height, 2, 2, kVideoRotation_0));
2211 input_frames.push_back(CreateVideoFrame(width, height, 3));
2212 input_frames.push_back(CreateVideoFrame(width, height, 4));
2213 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2214 width, height, 5, 5, kVideoRotation_0));
2215
2216 video_send_stream_->Start();
2217 test::FrameForwarder forwarder;
2218 video_send_stream_->SetSource(
2219 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
2220 for (size_t i = 0; i < input_frames.size(); i++) {
2221 forwarder.IncomingCapturedFrame(input_frames[i]);
2222 // Wait until the output frame is received before sending the next input
2223 // frame. Or the previous input frame may be replaced without delivering.
2224 observer.WaitOutputFrame();
2225 }
2226 video_send_stream_->Stop();
2227 video_send_stream_->SetSource(
2228 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
2229 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002230
2231 // Test if the input and output frames are the same. render_time_ms and
2232 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002233 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002234
eladalon413ee9a2017-08-22 04:02:52 -07002235 task_queue_.SendTask([this]() {
2236 DestroyStreams();
2237 DestroyCalls();
2238 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002239}
2240
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002241void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2242 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002243 EXPECT_EQ(frames1.size(), frames2.size());
2244 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002245 // Compare frame buffers, since we don't care about differing timestamps.
2246 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2247 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002248}
2249
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002250VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002251 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002252 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002253 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002254 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002255 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002256 // Use data as a ms timestamp.
2257 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002258 return frame;
2259}
2260
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002261TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2262 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2263 public:
eladalon413ee9a2017-08-22 04:02:52 -07002264 explicit EncoderStateObserver(
2265 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002266 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002267 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002268 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002269 initialized_(false),
2270 callback_registered_(false),
2271 num_releases_(0),
2272 released_(false) {}
2273
2274 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002275 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002276 return released_;
2277 }
2278
2279 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002280 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002281 return initialized_ && callback_registered_;
2282 }
2283
2284 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002285 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002286 return num_releases_;
2287 }
2288
2289 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002290 int32_t InitEncode(const VideoCodec* codecSettings,
2291 int32_t numberOfCores,
2292 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002293 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002294 EXPECT_FALSE(initialized_);
2295 initialized_ = true;
2296 released_ = false;
2297 return 0;
2298 }
2299
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002300 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002301 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002302 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002303 EXPECT_TRUE(IsReadyForEncode());
2304
Peter Boström5811a392015-12-10 13:02:50 +01002305 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002306 return 0;
2307 }
2308
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002309 int32_t RegisterEncodeCompleteCallback(
2310 EncodedImageCallback* callback) 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(initialized_);
2313 callback_registered_ = true;
2314 return 0;
2315 }
2316
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002317 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002318 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002319 EXPECT_TRUE(IsReadyForEncode());
2320 EXPECT_FALSE(released_);
2321 initialized_ = false;
2322 callback_registered_ = false;
2323 released_ = true;
2324 ++num_releases_;
2325 return 0;
2326 }
2327
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002328 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002329 EXPECT_TRUE(IsReadyForEncode());
2330 return 0;
2331 }
2332
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002333 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002334 EXPECT_TRUE(IsReadyForEncode());
2335 return 0;
2336 }
2337
stefanff483612015-12-21 03:14:00 -08002338 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002339 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002340 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002341 stream_ = send_stream;
2342 }
2343
stefanff483612015-12-21 03:14:00 -08002344 void ModifyVideoConfigs(
2345 VideoSendStream::Config* send_config,
2346 std::vector<VideoReceiveStream::Config>* receive_configs,
2347 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002348 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002349 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002350 }
2351
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002352 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002353 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002354
2355 task_queue_->SendTask([this]() {
2356 EXPECT_EQ(0u, num_releases());
2357 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2358 EXPECT_EQ(0u, num_releases());
2359 stream_->Stop();
2360 // Encoder should not be released before destroying the VideoSendStream.
2361 EXPECT_FALSE(IsReleased());
2362 EXPECT_TRUE(IsReadyForEncode());
2363 stream_->Start();
2364 });
2365
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002366 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002367 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002368 }
2369
eladalon413ee9a2017-08-22 04:02:52 -07002370 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002371 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002372 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002373 bool initialized_ RTC_GUARDED_BY(crit_);
2374 bool callback_registered_ RTC_GUARDED_BY(crit_);
2375 size_t num_releases_ RTC_GUARDED_BY(crit_);
2376 bool released_ RTC_GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002377 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002378 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002379
stefane74eef12016-01-08 06:47:13 -08002380 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002381
2382 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002383 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002384}
2385
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002386TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2387 class VideoCodecConfigObserver : public test::SendTest,
2388 public test::FakeEncoder {
2389 public:
2390 VideoCodecConfigObserver()
2391 : SendTest(kDefaultTimeoutMs),
2392 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002393 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002394 num_initializations_(0),
2395 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002396
2397 private:
stefanff483612015-12-21 03:14:00 -08002398 void ModifyVideoConfigs(
2399 VideoSendStream::Config* send_config,
2400 std::vector<VideoReceiveStream::Config>* receive_configs,
2401 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002402 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002403 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002404 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002405 }
2406
stefanff483612015-12-21 03:14:00 -08002407 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002408 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002409 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002410 stream_ = send_stream;
2411 }
2412
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002413 int32_t InitEncode(const VideoCodec* config,
2414 int32_t number_of_cores,
2415 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002416 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002417 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002418 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002419 } else {
2420 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002421 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002422 }
2423 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002424 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002425 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2426 }
2427
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002428 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002429 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002430 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002431
sprangf24a0642017-02-28 13:23:26 -08002432 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002433 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002434 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002435 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002436 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2437 "new encoder settings.";
2438 }
2439
sprangf24a0642017-02-28 13:23:26 -08002440 const uint32_t kFirstMaxBitrateBps = 1000000;
2441 const uint32_t kSecondMaxBitrateBps = 2000000;
2442
pbos14fe7082016-04-20 06:35:56 -07002443 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002444 size_t num_initializations_;
2445 VideoSendStream* stream_;
2446 VideoEncoderConfig encoder_config_;
2447 } test;
2448
stefane74eef12016-01-08 06:47:13 -08002449 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002450}
2451
Peter Boström53eda3d2015-03-27 15:53:18 +01002452static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2453template <typename T>
2454class VideoCodecConfigObserver : public test::SendTest,
2455 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002456 public:
2457 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2458 const char* codec_name)
2459 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2460 FakeEncoder(Clock::GetRealTimeClock()),
2461 video_codec_type_(video_codec_type),
2462 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002463 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002464 num_initializations_(0),
2465 stream_(nullptr) {
Sergey Silkin86684962018-03-28 19:32:37 +02002466 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002467 }
2468
2469 private:
perkjfa10b552016-10-02 23:45:26 -07002470 class VideoStreamFactory
2471 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2472 public:
2473 VideoStreamFactory() {}
2474
2475 private:
2476 std::vector<VideoStream> CreateEncoderStreams(
2477 int width,
2478 int height,
2479 const VideoEncoderConfig& encoder_config) override {
2480 std::vector<VideoStream> streams =
2481 test::CreateVideoStreams(width, height, encoder_config);
2482 for (size_t i = 0; i < streams.size(); ++i) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002483 streams[i].num_temporal_layers =
2484 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkjfa10b552016-10-02 23:45:26 -07002485 }
2486 return streams;
2487 }
2488 };
2489
stefanff483612015-12-21 03:14:00 -08002490 void ModifyVideoConfigs(
2491 VideoSendStream::Config* send_config,
2492 std::vector<VideoReceiveStream::Config>* receive_configs,
2493 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002494 send_config->encoder_settings.encoder = this;
Niels Möller04dd1762018-03-23 16:05:22 +01002495 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002496
Niels Möller04dd1762018-03-23 16:05:22 +01002497 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002498 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002499 encoder_config->video_stream_factory =
2500 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002501 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002502 }
2503
stefanff483612015-12-21 03:14:00 -08002504 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002505 VideoSendStream* send_stream,
2506 const std::vector<VideoReceiveStream*>& receive_streams) override {
2507 stream_ = send_stream;
2508 }
2509
2510 int32_t InitEncode(const VideoCodec* config,
2511 int32_t number_of_cores,
2512 size_t max_payload_size) override {
2513 EXPECT_EQ(video_codec_type_, config->codecType);
2514 VerifyCodecSpecifics(*config);
2515 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002516 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002517 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2518 }
2519
Sergey Silkin86684962018-03-28 19:32:37 +02002520 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002521 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002522 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2523 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002524
2525 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002526 EXPECT_TRUE(
2527 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002528 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002529
Sergey Silkin86684962018-03-28 19:32:37 +02002530 // Change encoder settings to actually trigger reconfiguration.
2531 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002532 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002533 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002534 ASSERT_TRUE(
2535 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002536 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002537 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2538 "new encoder settings.";
2539 }
2540
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002541 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002542 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002543 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002544 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2545 return 0;
2546 }
2547
2548 T encoder_settings_;
2549 const VideoCodecType video_codec_type_;
2550 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002551 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002552 size_t num_initializations_;
2553 VideoSendStream* stream_;
2554 VideoEncoderConfig encoder_config_;
2555};
2556
2557template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002558void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2559 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2560}
2561
2562template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002563void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2564 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002565 EXPECT_EQ(
2566 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002567}
kthelgason29a44e32016-09-27 03:52:02 -07002568
2569template <>
2570rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2571VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2572 return new rtc::RefCountedObject<
2573 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2574}
2575
Peter Boström53eda3d2015-03-27 15:53:18 +01002576template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002577void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2578 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2579}
2580
2581template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002582void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2583 const VideoCodec& config) const {
2584 // Check that the number of temporal layers has propagated properly to
2585 // VideoCodec.
2586 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002587 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002588
2589 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2590 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2591 config.simulcastStream[i].numberOfTemporalLayers);
2592 }
2593
2594 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002595 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002596 VideoCodecVP8 encoder_settings = encoder_settings_;
2597 encoder_settings.numberOfTemporalLayers =
2598 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002599 EXPECT_EQ(
2600 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002601}
kthelgason29a44e32016-09-27 03:52:02 -07002602
2603template <>
2604rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2605VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2606 return new rtc::RefCountedObject<
2607 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2608}
2609
Peter Boström53eda3d2015-03-27 15:53:18 +01002610template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002611void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2612 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2613}
2614
2615template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002616void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2617 const VideoCodec& config) const {
2618 // Check that the number of temporal layers has propagated properly to
2619 // VideoCodec.
2620 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002621 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002622
2623 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2624 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2625 config.simulcastStream[i].numberOfTemporalLayers);
2626 }
2627
2628 // Set expected temporal layers as they should have been set when
2629 // reconfiguring the encoder and not match the set config.
2630 VideoCodecVP9 encoder_settings = encoder_settings_;
2631 encoder_settings.numberOfTemporalLayers =
2632 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002633 EXPECT_EQ(
2634 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002635}
2636
kthelgason29a44e32016-09-27 03:52:02 -07002637template <>
2638rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2639VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2640 return new rtc::RefCountedObject<
2641 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2642}
2643
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002644TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002645 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002646 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002647}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002648
Peter Boström53eda3d2015-03-27 15:53:18 +01002649TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2650 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002651 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002652}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002653
Peter Boström53eda3d2015-03-27 15:53:18 +01002654TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2655 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002656 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002657}
2658
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002659TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002660 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002661 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002662 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2663 rtp_packets_sent_(0),
2664 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002665
2666 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002667 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002668 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002669 RTPHeader header;
2670 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002671 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002672 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2673 return SEND_PACKET;
2674 }
2675
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002676 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002677 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002678 test::RtcpPacketParser parser;
2679 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002680
danilchap3dc929e2016-11-02 08:21:59 -07002681 if (parser.sender_report()->num_packets() > 0) {
2682 // Only compare sent media bytes if SenderPacketCount matches the
2683 // number of sent rtp packets (a new rtp packet could be sent before
2684 // the rtcp packet).
2685 if (parser.sender_report()->sender_octet_count() > 0 &&
2686 parser.sender_report()->sender_packet_count() ==
2687 rtp_packets_sent_) {
2688 EXPECT_EQ(media_bytes_sent_,
2689 parser.sender_report()->sender_octet_count());
2690 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002691 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002692 }
2693
2694 return SEND_PACKET;
2695 }
2696
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002697 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002698 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002699 }
2700
stefan4b569042015-11-11 06:39:57 -08002701 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002702 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2703 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002704 } test;
2705
stefane74eef12016-01-08 06:47:13 -08002706 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002707}
2708
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002709TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002710 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002711
2712 class VideoStreamFactory
2713 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2714 public:
2715 VideoStreamFactory() {}
2716
2717 private:
2718 std::vector<VideoStream> CreateEncoderStreams(
2719 int width,
2720 int height,
2721 const VideoEncoderConfig& encoder_config) override {
2722 std::vector<VideoStream> streams =
2723 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002724 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
2725 streams[0].num_temporal_layers = 2;
2726 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2727 kScreencastMaxTargetBitrateDeltaKbps);
2728 streams[0].target_bitrate_bps =
2729 streams[0].max_bitrate_bps -
2730 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002731 return streams;
2732 }
2733 };
2734
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002735 class ScreencastTargetBitrateTest : public test::SendTest,
2736 public test::FakeEncoder {
2737 public:
2738 ScreencastTargetBitrateTest()
2739 : SendTest(kDefaultTimeoutMs),
2740 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2741
2742 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002743 int32_t InitEncode(const VideoCodec* config,
2744 int32_t number_of_cores,
2745 size_t max_payload_size) override {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002746 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
2747 config->maxBitrate - config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002748 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002749 return test::FakeEncoder::InitEncode(
2750 config, number_of_cores, max_payload_size);
2751 }
stefanff483612015-12-21 03:14:00 -08002752 void ModifyVideoConfigs(
2753 VideoSendStream::Config* send_config,
2754 std::vector<VideoReceiveStream::Config>* receive_configs,
2755 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002756 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002757 EXPECT_EQ(1u, encoder_config->number_of_streams);
2758 encoder_config->video_stream_factory =
2759 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002760 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002761 }
2762
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002763 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002764 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002765 << "Timed out while waiting for the encoder to be initialized.";
2766 }
2767 } test;
2768
stefane74eef12016-01-08 06:47:13 -08002769 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002770}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002771
philipelc6957c72016-04-28 15:52:49 +02002772TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002773 // These are chosen to be "kind of odd" to not be accidentally checked against
2774 // default values.
2775 static const int kMinBitrateKbps = 137;
2776 static const int kStartBitrateKbps = 345;
2777 static const int kLowerMaxBitrateKbps = 312;
2778 static const int kMaxBitrateKbps = 413;
2779 static const int kIncreasedStartBitrateKbps = 451;
2780 static const int kIncreasedMaxBitrateKbps = 597;
2781 class EncoderBitrateThresholdObserver : public test::SendTest,
2782 public test::FakeEncoder {
2783 public:
eladalon413ee9a2017-08-22 04:02:52 -07002784 explicit EncoderBitrateThresholdObserver(
2785 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002786 : SendTest(kDefaultTimeoutMs),
2787 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002788 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002789 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002790 bitrate_changed_event_(false, false),
2791 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002792 num_initializations_(0),
2793 call_(nullptr),
2794 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002795
2796 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002797 int32_t InitEncode(const VideoCodec* codecSettings,
2798 int32_t numberOfCores,
2799 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002800 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2801 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002802 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002803 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2804 codecSettings->minBitrate);
2805 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2806 codecSettings->startBitrate);
2807 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2808 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002809 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002810 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002811 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2812 codecSettings->maxBitrate);
2813 // The start bitrate should be kept (-1) and capped to the max bitrate.
2814 // Since this is not an end-to-end call no receiver should have been
2815 // returning a REMB that could lower this estimate.
2816 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002817 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002818 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2819 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002820 // The start bitrate will be whatever the rate BitRateController
2821 // has currently configured but in the span of the set max and min
2822 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002823 }
2824 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002825 init_encode_event_.Set();
2826
pbos@webrtc.org00873182014-11-25 14:03:34 +00002827 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2828 maxPayloadSize);
2829 }
2830
Erik Språng08127a92016-11-16 16:41:30 +01002831 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2832 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002833 {
2834 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002835 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2836 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002837 }
Erik Språng08127a92016-11-16 16:41:30 +01002838 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002839 }
2840 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002841 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002842 }
2843
2844 void WaitForSetRates(uint32_t expected_bitrate) {
2845 EXPECT_TRUE(
2846 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2847 << "Timed out while waiting encoder rate to be set.";
2848 rtc::CritScope lock(&crit_);
2849 EXPECT_EQ(expected_bitrate, target_bitrate_);
2850 }
2851
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002852 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002853 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002854 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2855 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2856 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002857 return config;
2858 }
2859
perkjfa10b552016-10-02 23:45:26 -07002860 class VideoStreamFactory
2861 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2862 public:
2863 explicit VideoStreamFactory(int min_bitrate_bps)
2864 : min_bitrate_bps_(min_bitrate_bps) {}
2865
2866 private:
2867 std::vector<VideoStream> CreateEncoderStreams(
2868 int width,
2869 int height,
2870 const VideoEncoderConfig& encoder_config) override {
2871 std::vector<VideoStream> streams =
2872 test::CreateVideoStreams(width, height, encoder_config);
2873 streams[0].min_bitrate_bps = min_bitrate_bps_;
2874 return streams;
2875 }
2876
2877 const int min_bitrate_bps_;
2878 };
2879
stefanff483612015-12-21 03:14:00 -08002880 void ModifyVideoConfigs(
2881 VideoSendStream::Config* send_config,
2882 std::vector<VideoReceiveStream::Config>* receive_configs,
2883 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002884 send_config->encoder_settings.encoder = this;
2885 // Set bitrates lower/higher than min/max to make sure they are properly
2886 // capped.
perkjfa10b552016-10-02 23:45:26 -07002887 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2888 // Create a new StreamFactory to be able to set
2889 // |VideoStream.min_bitrate_bps|.
2890 encoder_config->video_stream_factory =
2891 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002892 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002893 }
2894
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002895 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002896 call_ = sender_call;
2897 }
2898
stefanff483612015-12-21 03:14:00 -08002899 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002900 VideoSendStream* send_stream,
2901 const std::vector<VideoReceiveStream*>& receive_streams) override {
2902 send_stream_ = send_stream;
2903 }
2904
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002905 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002906 ASSERT_TRUE(
2907 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002908 << "Timed out while waiting for encoder to be configured.";
2909 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002910 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002911 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2912 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002913 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002914 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2915 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002916 });
perkj26091b12016-09-01 01:17:40 -07002917 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2918 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002919 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002920 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002921 ASSERT_TRUE(
2922 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002923 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002924 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002925 WaitForSetRates(kLowerMaxBitrateKbps);
2926
2927 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2928 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2929 ASSERT_TRUE(
2930 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002931 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002932 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002933 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002934 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002935 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002936 }
2937
eladalon413ee9a2017-08-22 04:02:52 -07002938 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002939 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002940 rtc::Event bitrate_changed_event_;
2941 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002942 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002943
pbos@webrtc.org00873182014-11-25 14:03:34 +00002944 int num_initializations_;
2945 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002946 webrtc::VideoSendStream* send_stream_;
2947 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002948 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002949
stefane74eef12016-01-08 06:47:13 -08002950 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002951}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002952
2953TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2954 static const size_t kNumStreams = 3;
2955 // Unusual resolutions to make sure that they are the ones being reported.
2956 static const struct {
2957 int width;
2958 int height;
2959 } kEncodedResolution[kNumStreams] = {
2960 {241, 181}, {300, 121}, {121, 221}};
2961 class ScreencastTargetBitrateTest : public test::SendTest,
2962 public test::FakeEncoder {
2963 public:
2964 ScreencastTargetBitrateTest()
2965 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002966 test::FakeEncoder(Clock::GetRealTimeClock()),
2967 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002968
2969 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002970 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002971 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002972 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002973 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002974 specifics.codecType = kVideoCodecGeneric;
2975
2976 uint8_t buffer[16] = {0};
2977 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2978 encoded._timeStamp = input_image.timestamp();
2979 encoded.capture_time_ms_ = input_image.render_time_ms();
2980
2981 for (size_t i = 0; i < kNumStreams; ++i) {
2982 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2983 encoded._frameType = (*frame_types)[i];
2984 encoded._encodedWidth = kEncodedResolution[i].width;
2985 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002986 EncodedImageCallback* callback;
2987 {
2988 rtc::CritScope cs(&crit_sect_);
2989 callback = callback_;
2990 }
2991 RTC_DCHECK(callback);
2992 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002993 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002994 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002995 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002996 }
2997
Peter Boström5811a392015-12-10 13:02:50 +01002998 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002999 return 0;
3000 }
stefanff483612015-12-21 03:14:00 -08003001 void ModifyVideoConfigs(
3002 VideoSendStream::Config* send_config,
3003 std::vector<VideoReceiveStream::Config>* receive_configs,
3004 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003005 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07003006 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003007 }
3008
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003009 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003010
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003011 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003012 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003013 << "Timed out while waiting for the encoder to send one frame.";
3014 VideoSendStream::Stats stats = send_stream_->GetStats();
3015
3016 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003017 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003018 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003019 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003020 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003021 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003022 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003023 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3024 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003025 }
3026 }
3027
stefanff483612015-12-21 03:14:00 -08003028 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003029 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003030 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003031 send_stream_ = send_stream;
3032 }
3033
3034 VideoSendStream* send_stream_;
3035 } test;
3036
stefane74eef12016-01-08 06:47:13 -08003037 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003038}
philipel0f9af012015-09-01 07:01:51 -07003039
Peter Boström12996152016-05-14 02:03:18 +02003040#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003041class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003042 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003043 Vp9HeaderObserver()
3044 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07003045 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01003046 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3047 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003048 frames_sent_(0),
3049 expected_width_(0),
3050 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003051
stefanff483612015-12-21 03:14:00 -08003052 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003053 VideoSendStream::Config* send_config,
3054 std::vector<VideoReceiveStream::Config>* receive_configs,
3055 VideoEncoderConfig* encoder_config) {}
3056
Åsa Perssonff24c042015-12-04 10:58:08 +01003057 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003058
3059 private:
minyue20c84cc2017-04-10 16:57:57 -07003060 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003061
perkjfa10b552016-10-02 23:45:26 -07003062 class VideoStreamFactory
3063 : public VideoEncoderConfig::VideoStreamFactoryInterface {
3064 public:
3065 explicit VideoStreamFactory(size_t number_of_temporal_layers)
3066 : number_of_temporal_layers_(number_of_temporal_layers) {}
3067
3068 private:
3069 std::vector<VideoStream> CreateEncoderStreams(
3070 int width,
3071 int height,
3072 const VideoEncoderConfig& encoder_config) override {
3073 std::vector<VideoStream> streams =
3074 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01003075 streams.back().num_temporal_layers = number_of_temporal_layers_;
perkjfa10b552016-10-02 23:45:26 -07003076 return streams;
3077 }
3078
3079 const size_t number_of_temporal_layers_;
3080 };
3081
stefanff483612015-12-21 03:14:00 -08003082 void ModifyVideoConfigs(
3083 VideoSendStream::Config* send_config,
3084 std::vector<VideoReceiveStream::Config>* receive_configs,
3085 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07003086 send_config->encoder_settings.encoder = vp9_encoder_.get();
Niels Möller04dd1762018-03-23 16:05:22 +01003087 send_config->rtp.payload_name = "VP9";
3088 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003089 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003090 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
3091 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003092 EXPECT_EQ(1u, encoder_config->number_of_streams);
3093 encoder_config->video_stream_factory =
3094 new rtc::RefCountedObject<VideoStreamFactory>(
3095 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07003096 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003097 }
3098
perkjfa10b552016-10-02 23:45:26 -07003099 void ModifyVideoCaptureStartResolution(int* width,
3100 int* height,
3101 int* frame_rate) override {
3102 expected_width_ = *width;
3103 expected_height_ = *height;
3104 }
3105
philipel0f9af012015-09-01 07:01:51 -07003106 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003107 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3108 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003109 }
3110
3111 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3112 RTPHeader header;
3113 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3114
Åsa Perssonff24c042015-12-04 10:58:08 +01003115 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3116 const uint8_t* payload = packet + header.headerLength;
3117 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003118
Åsa Perssonff24c042015-12-04 10:58:08 +01003119 bool new_packet = packets_sent_ == 0 ||
3120 IsNewerSequenceNumber(header.sequenceNumber,
3121 last_header_.sequenceNumber);
3122 if (payload_length > 0 && new_packet) {
3123 RtpDepacketizer::ParsedPayload parsed;
3124 RtpDepacketizerVp9 depacketizer;
3125 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
3126 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
3127 // Verify common fields for all configurations.
3128 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
3129 CompareConsecutiveFrames(header, parsed.type.Video);
3130 // Verify configuration specific settings.
3131 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07003132
Åsa Perssonff24c042015-12-04 10:58:08 +01003133 ++packets_sent_;
3134 if (header.markerBit) {
3135 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003136 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003137 last_header_ = header;
3138 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07003139 }
philipel0f9af012015-09-01 07:01:51 -07003140 return SEND_PACKET;
3141 }
3142
philipel7fabd462015-09-03 04:42:32 -07003143 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003144 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3145 if (last_vp9_.picture_id > vp9.picture_id) {
3146 return vp9.picture_id == 0; // Wrap.
3147 } else {
3148 return vp9.picture_id == last_vp9_.picture_id + 1;
3149 }
3150 }
3151
3152 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003153 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3154 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3155 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3156 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3157 vp9.spatial_idx);
3158 }
3159
3160 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3161 uint8_t num_layers) const {
3162 switch (num_layers) {
3163 case 0:
3164 VerifyTemporalLayerStructure0(vp9);
3165 break;
3166 case 1:
3167 VerifyTemporalLayerStructure1(vp9);
3168 break;
3169 case 2:
3170 VerifyTemporalLayerStructure2(vp9);
3171 break;
3172 case 3:
3173 VerifyTemporalLayerStructure3(vp9);
3174 break;
3175 default:
3176 RTC_NOTREACHED();
3177 }
3178 }
3179
3180 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3181 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3182 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3183 EXPECT_FALSE(vp9.temporal_up_switch);
3184 }
3185
3186 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3187 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3188 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3189 EXPECT_FALSE(vp9.temporal_up_switch);
3190 }
3191
3192 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3193 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3194 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3195 EXPECT_LE(vp9.temporal_idx, 1);
3196 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3197 if (IsNewPictureId(vp9)) {
3198 uint8_t expected_tid =
3199 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3200 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3201 }
3202 }
3203
3204 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3205 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3206 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3207 EXPECT_LE(vp9.temporal_idx, 2);
3208 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3209 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3210 switch (vp9.temporal_idx) {
3211 case 0:
3212 EXPECT_EQ(2, last_vp9_.temporal_idx);
3213 EXPECT_FALSE(vp9.temporal_up_switch);
3214 break;
3215 case 1:
3216 EXPECT_EQ(2, last_vp9_.temporal_idx);
3217 EXPECT_TRUE(vp9.temporal_up_switch);
3218 break;
3219 case 2:
3220 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3221 break;
3222 }
3223 }
3224 }
3225
3226 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3227 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3228 return;
3229
3230 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3231 if (vp9.temporal_idx == 0)
3232 ++expected_tl0_idx;
3233 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3234 }
3235
3236 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3237 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3238 }
3239
3240 // Flexible mode (F=1): Non-flexible mode (F=0):
3241 //
3242 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3243 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3244 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3245 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3246 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3247 // M: | EXTENDED PID | M: | EXTENDED PID |
3248 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3249 // L: | T |U| S |D| L: | T |U| S |D|
3250 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3251 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3252 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3253 // X: |EXTENDED P_DIFF| V: | SS .. |
3254 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3255 // V: | SS .. |
3256 // +-+-+-+-+-+-+-+-+
3257 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3258 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3259 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3260 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003261
3262 if (vp9_settings_.numberOfSpatialLayers > 1) {
3263 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3264 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3265 EXPECT_EQ(vp9.spatial_idx, 0);
3266 } else {
3267 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3268 }
3269
3270 if (vp9_settings_.numberOfTemporalLayers > 1) {
3271 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3272 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3273 EXPECT_EQ(vp9.temporal_idx, 0);
3274 } else {
3275 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3276 }
3277
Åsa Perssonff24c042015-12-04 10:58:08 +01003278 if (vp9.ss_data_available) // V
3279 VerifySsData(vp9);
3280
3281 if (frames_sent_ == 0)
3282 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3283
3284 if (!vp9.inter_pic_predicted) {
3285 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3286 EXPECT_FALSE(vp9.temporal_up_switch);
3287 }
3288 }
3289
3290 // Scalability structure (SS).
3291 //
3292 // +-+-+-+-+-+-+-+-+
3293 // V: | N_S |Y|G|-|-|-|
3294 // +-+-+-+-+-+-+-+-+
3295 // Y: | WIDTH | N_S + 1 times
3296 // +-+-+-+-+-+-+-+-+
3297 // | HEIGHT |
3298 // +-+-+-+-+-+-+-+-+
3299 // G: | N_G |
3300 // +-+-+-+-+-+-+-+-+
3301 // N_G: | T |U| R |-|-| N_G times
3302 // +-+-+-+-+-+-+-+-+
3303 // | P_DIFF | R times
3304 // +-+-+-+-+-+-+-+-+
3305 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3306 EXPECT_TRUE(vp9.ss_data_available); // V
3307 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3308 vp9.num_spatial_layers);
3309 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003310 int expected_width = expected_width_;
3311 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003312 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003313 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3314 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3315 expected_width /= 2;
3316 expected_height /= 2;
3317 }
3318 }
3319
3320 void CompareConsecutiveFrames(const RTPHeader& header,
3321 const RTPVideoHeader& video) const {
3322 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3323
3324 bool new_frame = packets_sent_ == 0 ||
3325 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003326 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003327 if (!new_frame) {
3328 EXPECT_FALSE(last_header_.markerBit);
3329 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3330 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3331 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3332 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3333 VerifySpatialIdxWithinFrame(vp9);
3334 return;
3335 }
3336 // New frame.
3337 EXPECT_TRUE(vp9.beginning_of_frame);
3338
3339 // Compare with last packet in previous frame.
3340 if (frames_sent_ == 0)
3341 return;
3342 EXPECT_TRUE(last_vp9_.end_of_frame);
3343 EXPECT_TRUE(last_header_.markerBit);
3344 EXPECT_TRUE(ContinuousPictureId(vp9));
3345 VerifyTl0Idx(vp9);
3346 }
3347
kwiberg27f982b2016-03-01 11:52:33 -08003348 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003349 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003350 webrtc::VideoEncoderConfig encoder_config_;
3351 RTPHeader last_header_;
3352 RTPVideoHeaderVP9 last_vp9_;
3353 size_t packets_sent_;
3354 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003355 int expected_width_;
3356 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003357};
3358
Åsa Perssonff24c042015-12-04 10:58:08 +01003359TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3360 const uint8_t kNumTemporalLayers = 1;
3361 const uint8_t kNumSpatialLayers = 1;
3362 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3363}
3364
3365TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3366 const uint8_t kNumTemporalLayers = 2;
3367 const uint8_t kNumSpatialLayers = 1;
3368 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3369}
3370
3371TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3372 const uint8_t kNumTemporalLayers = 3;
3373 const uint8_t kNumSpatialLayers = 1;
3374 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3375}
3376
3377TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3378 const uint8_t kNumTemporalLayers = 1;
3379 const uint8_t kNumSpatialLayers = 2;
3380 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3381}
3382
3383TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3384 const uint8_t kNumTemporalLayers = 2;
3385 const uint8_t kNumSpatialLayers = 2;
3386 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3387}
3388
3389TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3390 const uint8_t kNumTemporalLayers = 3;
3391 const uint8_t kNumSpatialLayers = 2;
3392 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3393}
3394
3395void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3396 uint8_t num_spatial_layers) {
3397 static const size_t kNumFramesToSend = 100;
3398 // Set to < kNumFramesToSend and coprime to length of temporal layer
3399 // structures to verify temporal id reset on key frame.
3400 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003401
3402 static const int kWidth = kMinVp9SpatialLayerWidth;
3403 static const int kHeight = kMinVp9SpatialLayerHeight;
3404 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003405 class NonFlexibleMode : public Vp9HeaderObserver {
3406 public:
3407 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3408 : num_temporal_layers_(num_temporal_layers),
3409 num_spatial_layers_(num_spatial_layers),
3410 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003411
stefanff483612015-12-21 03:14:00 -08003412 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003413 VideoSendStream::Config* send_config,
3414 std::vector<VideoReceiveStream::Config>* receive_configs,
3415 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003416 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003417 int bitrate_bps = 0;
3418 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3419 const int width = kWidth << sl_idx;
3420 const int height = kHeight << sl_idx;
3421 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3422 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3423 }
3424 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3425
Åsa Perssonff24c042015-12-04 10:58:08 +01003426 vp9_settings_.flexibleMode = false;
3427 vp9_settings_.frameDroppingOn = false;
3428 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3429 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3430 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003431 }
3432
Sergey Silkin86684962018-03-28 19:32:37 +02003433 void ModifyVideoCaptureStartResolution(int* width,
3434 int* height,
3435 int* frame_rate) override {
3436 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3437 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3438 *width = expected_width_;
3439 *height = expected_height_;
3440 }
3441
Åsa Perssonff24c042015-12-04 10:58:08 +01003442 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003443 bool ss_data_expected =
3444 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3445 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003446 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003447 if (num_spatial_layers_ > 1) {
3448 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3449 } else {
3450 EXPECT_FALSE(vp9.inter_layer_predicted);
3451 }
3452
asapersson38bb8ad2015-12-14 01:41:19 -08003453 EXPECT_EQ(!vp9.inter_pic_predicted,
3454 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003455
3456 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003457 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3458 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3459 } else {
3460 EXPECT_EQ(0, vp9.spatial_idx);
3461 }
3462 if (num_spatial_layers_ > 1)
3463 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003464 }
3465
3466 VerifyFixedTemporalLayerStructure(vp9,
3467 l_field_ ? num_temporal_layers_ : 0);
3468
3469 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003470 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003471 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003472 const uint8_t num_temporal_layers_;
3473 const uint8_t num_spatial_layers_;
3474 const bool l_field_;
3475 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003476
stefane74eef12016-01-08 06:47:13 -08003477 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003478}
3479
asaperssond9f641e2016-01-21 01:11:35 -08003480TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3481 static const size_t kNumFramesToSend = 50;
3482 static const int kWidth = 4;
3483 static const int kHeight = 4;
3484 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3485 void ModifyVideoConfigsHook(
3486 VideoSendStream::Config* send_config,
3487 std::vector<VideoReceiveStream::Config>* receive_configs,
3488 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003489 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003490 vp9_settings_.flexibleMode = false;
3491 vp9_settings_.numberOfTemporalLayers = 1;
3492 vp9_settings_.numberOfSpatialLayers = 1;
3493
perkjfa10b552016-10-02 23:45:26 -07003494 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003495 }
3496
3497 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3498 if (frames_sent_ > kNumFramesToSend)
3499 observation_complete_.Set();
3500 }
perkjfa10b552016-10-02 23:45:26 -07003501
3502 void ModifyVideoCaptureStartResolution(int* width,
3503 int* height,
3504 int* frame_rate) override {
3505 expected_width_ = kWidth;
3506 expected_height_ = kHeight;
3507 *width = kWidth;
3508 *height = kHeight;
3509 }
asaperssond9f641e2016-01-21 01:11:35 -08003510 } test;
3511
3512 RunBaseTest(&test);
3513}
3514
kjellanderf9e2a362017-03-24 12:17:33 -07003515#if defined(WEBRTC_ANDROID)
3516// Crashes on Android; bugs.webrtc.org/7401
3517#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3518#else
3519#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3520#endif
3521TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003522 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003523 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003524 VideoSendStream::Config* send_config,
3525 std::vector<VideoReceiveStream::Config>* receive_configs,
3526 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003527 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003528 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003529 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003530 vp9_settings_.numberOfTemporalLayers = 1;
3531 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003532 }
3533
Åsa Perssonff24c042015-12-04 10:58:08 +01003534 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3535 EXPECT_TRUE(vp9_header.flexible_mode);
3536 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3537 if (vp9_header.inter_pic_predicted) {
3538 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003539 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003540 }
3541 }
3542 } test;
3543
stefane74eef12016-01-08 06:47:13 -08003544 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003545}
Peter Boström12996152016-05-14 02:03:18 +02003546#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003547
perkj803d97f2016-11-01 11:45:46 -07003548void VideoSendStreamTest::TestRequestSourceRotateVideo(
3549 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003550 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003551
3552 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003553 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003554 video_send_config_.rtp.extensions.clear();
3555 if (support_orientation_ext) {
3556 video_send_config_.rtp.extensions.push_back(
3557 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3558 }
3559
3560 CreateVideoStreams();
3561 test::FrameForwarder forwarder;
3562 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003563 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003564
3565 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3566 support_orientation_ext);
3567
3568 DestroyStreams();
3569}
3570
3571TEST_F(VideoSendStreamTest,
3572 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3573 TestRequestSourceRotateVideo(false);
3574}
3575
3576TEST_F(VideoSendStreamTest,
3577 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3578 TestRequestSourceRotateVideo(true);
3579}
3580
michaelta3328772016-11-29 09:25:03 -08003581// This test verifies that overhead is removed from the bandwidth estimate by
3582// testing that the maximum possible target payload rate is smaller than the
3583// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003584TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003585 test::ScopedFieldTrials override_field_trials(
3586 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3587 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3588 public test::FakeEncoder {
3589 public:
eladalon413ee9a2017-08-22 04:02:52 -07003590 explicit RemoveOverheadFromBandwidthTest(
3591 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003592 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3593 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003594 task_queue_(task_queue),
michaelta3328772016-11-29 09:25:03 -08003595 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003596 max_bitrate_bps_(0),
3597 first_packet_sent_(false),
3598 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003599
3600 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3601 uint32_t frameRate) override {
3602 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003603 // Wait for the first sent packet so that videosendstream knows
3604 // rtp_overhead.
3605 if (first_packet_sent_) {
3606 max_bitrate_bps_ = bitrate.get_sum_bps();
3607 bitrate_changed_event_.Set();
3608 }
michaelta3328772016-11-29 09:25:03 -08003609 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3610 }
3611
3612 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3613 call_ = sender_call;
3614 }
3615
3616 void ModifyVideoConfigs(
3617 VideoSendStream::Config* send_config,
3618 std::vector<VideoReceiveStream::Config>* receive_configs,
3619 VideoEncoderConfig* encoder_config) override {
3620 send_config->rtp.max_packet_size = 1200;
3621 send_config->encoder_settings.encoder = this;
3622 EXPECT_FALSE(send_config->rtp.extensions.empty());
3623 }
3624
michaelt192132e2017-01-26 09:05:27 -08003625 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3626 rtc::CritScope lock(&crit_);
3627 first_packet_sent_ = true;
3628 return SEND_PACKET;
3629 }
3630
michaelta3328772016-11-29 09:25:03 -08003631 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003632 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003633 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003634 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003635 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003636 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3637 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003638 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003639 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003640 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3641 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07003642 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3643 });
michaelta3328772016-11-29 09:25:03 -08003644
3645 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003646 // overhead of 40B per packet video produces 2240bps overhead.
3647 // So the encoder BW should be set to 57760bps.
3648 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003649 {
3650 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003651 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003652 }
3653 }
3654
3655 private:
eladalon413ee9a2017-08-22 04:02:52 -07003656 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelta3328772016-11-29 09:25:03 -08003657 Call* call_;
3658 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003659 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3660 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003661 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003662 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003663 RunBaseTest(&test);
3664}
3665
sprang168794c2017-07-06 04:38:06 -07003666TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3667 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003668
3669 class KeepaliveObserver : public test::SendTest {
3670 public:
3671 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3672
sprangdb2a9fc2017-08-09 06:42:32 -07003673 void OnRtpTransportControllerSendCreated(
3674 RtpTransportControllerSend* controller) override {
3675 RtpKeepAliveConfig config;
3676 config.timeout_interval_ms = kTimeoutMs;
3677 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3678 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003679 }
3680
sprang168794c2017-07-06 04:38:06 -07003681 private:
3682 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3683 RTPHeader header;
3684 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3685
sprangd2702ef2017-07-10 08:41:10 -07003686 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003687 // The video stream has started. Stop it now.
3688 if (capturer_)
3689 capturer_->Stop();
3690 } else {
3691 observation_complete_.Set();
3692 }
3693
3694 return SEND_PACKET;
3695 }
3696
sprang168794c2017-07-06 04:38:06 -07003697 void PerformTest() override {
3698 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3699 }
3700
3701 void OnFrameGeneratorCapturerCreated(
3702 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3703 capturer_ = frame_generator_capturer;
3704 }
3705
3706 test::FrameGeneratorCapturer* capturer_ = nullptr;
3707 } test;
3708
3709 RunBaseTest(&test);
3710}
3711
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003712class PacingFactorObserver : public test::SendTest {
3713 public:
3714 PacingFactorObserver(bool configure_send_side,
3715 rtc::Optional<float> expected_pacing_factor)
3716 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3717 configure_send_side_(configure_send_side),
3718 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003719
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003720 void ModifyVideoConfigs(
3721 VideoSendStream::Config* send_config,
3722 std::vector<VideoReceiveStream::Config>* receive_configs,
3723 VideoEncoderConfig* encoder_config) override {
3724 // Check if send-side bwe extension is already present, and remove it if
3725 // it is not desired.
3726 bool has_send_side = false;
3727 for (auto it = send_config->rtp.extensions.begin();
3728 it != send_config->rtp.extensions.end(); ++it) {
3729 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3730 if (configure_send_side_) {
3731 has_send_side = true;
3732 } else {
3733 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003734 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003735 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003736 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003737 }
3738
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003739 if (configure_send_side_ && !has_send_side) {
3740 // Want send side, not present by default, so add it.
3741 send_config->rtp.extensions.emplace_back(
3742 RtpExtension::kTransportSequenceNumberUri,
3743 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003744 }
3745
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003746 // ALR only enabled for screenshare.
3747 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3748 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003749
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003750 void OnVideoStreamsCreated(
3751 VideoSendStream* send_stream,
3752 const std::vector<VideoReceiveStream*>& receive_streams) override {
3753 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3754 // Video streams created, check that pacing factor is correctly configured.
3755 EXPECT_EQ(expected_pacing_factor_,
3756 internal_send_peer.GetPacingFactorOverride());
3757 observation_complete_.Set();
3758 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003759
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003760 void PerformTest() override {
3761 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3762 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003763
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003764 private:
3765 const bool configure_send_side_;
3766 const rtc::Optional<float> expected_pacing_factor_;
3767};
3768
3769std::string GetAlrProbingExperimentString() {
3770 return std::string(
3771 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3772 "/1.0,2875,80,40,-60,3/";
3773}
3774const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3775
3776TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
3777 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003778 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003779 PacingFactorObserver test_with_send_side(true,
3780 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003781 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003782}
Erik Språng7c8cca32017-10-24 17:05:18 +02003783
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003784TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
3785 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3786 // Send-side bwe off, use configuration should not be overridden.
3787 PacingFactorObserver test_without_send_side(false, rtc::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003788 RunBaseTest(&test_without_send_side);
3789}
3790
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003791// Test class takes as argument a function pointer to reset the send
3792// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3793// change the content type of a VideoSendStream, you need to recreate it.
3794// Stopping and recreating the stream can only be done on the main thread and in
3795// the context of VideoSendStreamTest (not BaseTest). The test switches from
3796// realtime to screenshare and back.
3797template <typename T>
3798class ContentSwitchTest : public test::SendTest {
3799 public:
3800 enum class StreamState {
3801 kBeforeSwitch = 0,
3802 kInScreenshare = 1,
3803 kAfterSwitchBack = 2,
3804 };
3805 static const uint32_t kMinPacketsToSend = 50;
3806
3807 explicit ContentSwitchTest(T* stream_reset_fun)
3808 : SendTest(test::CallTest::kDefaultTimeoutMs),
3809 content_switch_event_(false, false),
3810 call_(nullptr),
3811 state_(StreamState::kBeforeSwitch),
3812 send_stream_(nullptr),
3813 send_stream_config_(nullptr),
3814 packets_sent_(0),
3815 stream_resetter_(stream_reset_fun) {
3816 RTC_DCHECK(stream_resetter_);
3817 }
3818
3819 void OnVideoStreamsCreated(
3820 VideoSendStream* send_stream,
3821 const std::vector<VideoReceiveStream*>& receive_streams) override {
3822 rtc::CritScope lock(&crit_);
3823 send_stream_ = send_stream;
3824 }
3825
3826 void ModifyVideoConfigs(
3827 VideoSendStream::Config* send_config,
3828 std::vector<VideoReceiveStream::Config>* receive_configs,
3829 VideoEncoderConfig* encoder_config) override {
3830 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3831 encoder_config->min_transmit_bitrate_bps = 0;
3832 encoder_config->content_type =
3833 VideoEncoderConfig::ContentType::kRealtimeVideo;
3834 send_stream_config_ = send_config->Copy();
3835 encoder_config_ = encoder_config->Copy();
3836 }
3837
3838 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3839 call_ = sender_call;
3840 }
3841
3842 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3843 rtc::CritScope lock(&crit_);
3844
3845 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3846 float pacing_factor =
3847 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3848 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3849 if (send_stream_->GetStats().content_type ==
3850 webrtc::VideoContentType::SCREENSHARE) {
3851 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3852 }
3853
3854 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3855
3856 // Wait until at least kMinPacketsToSend packets to be sent, so that
3857 // some frames would be encoded.
3858 if (++packets_sent_ < kMinPacketsToSend)
3859 return SEND_PACKET;
3860
3861 if (state_ != StreamState::kAfterSwitchBack) {
3862 // We've sent kMinPacketsToSend packets, switch the content type and move
3863 // move to the next state.
3864 // Note that we need to recreate the stream if changing content type.
3865 packets_sent_ = 0;
3866 if (encoder_config_.content_type ==
3867 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3868 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3869 } else {
3870 encoder_config_.content_type =
3871 VideoEncoderConfig::ContentType::kRealtimeVideo;
3872 }
3873 switch (state_) {
3874 case StreamState::kBeforeSwitch:
3875 state_ = StreamState::kInScreenshare;
3876 break;
3877 case StreamState::kInScreenshare:
3878 state_ = StreamState::kAfterSwitchBack;
3879 break;
3880 case StreamState::kAfterSwitchBack:
3881 RTC_NOTREACHED();
3882 break;
3883 }
3884 content_switch_event_.Set();
3885 return SEND_PACKET;
3886 }
3887
3888 observation_complete_.Set();
3889 return SEND_PACKET;
3890 }
3891
3892 void PerformTest() override {
3893 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3894 ASSERT_TRUE(
3895 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3896 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3897 }
3898
3899 ASSERT_TRUE(Wait())
3900 << "Timed out waiting for a frame sent after switch back";
3901 }
3902
3903 private:
3904 StreamState GetStreamState() {
3905 rtc::CritScope lock(&crit_);
3906 return state_;
3907 }
3908
3909 rtc::CriticalSection crit_;
3910 rtc::Event content_switch_event_;
3911 Call* call_;
3912 StreamState state_ RTC_GUARDED_BY(crit_);
3913 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3914 VideoSendStream::Config send_stream_config_;
3915 VideoEncoderConfig encoder_config_;
3916 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3917 T* stream_resetter_;
3918};
3919
3920TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
3921 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3922 const VideoEncoderConfig& encoder_config,
3923 test::BaseTest* test) {
3924 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3925 Stop();
3926 sender_call_->DestroyVideoSendStream(video_send_stream_);
3927 video_send_config_ = send_stream_config.Copy();
3928 video_encoder_config_ = encoder_config.Copy();
3929 video_send_stream_ = sender_call_->CreateVideoSendStream(
3930 video_send_config_.Copy(), video_encoder_config_.Copy());
3931 video_send_stream_->SetSource(
3932 frame_generator_capturer_.get(),
3933 VideoSendStream::DegradationPreference::kMaintainResolution);
3934 test->OnVideoStreamsCreated(video_send_stream_, video_receive_streams_);
3935 Start();
3936 });
3937 };
3938 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3939 RunBaseTest(&test);
3940}
3941
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003942} // namespace webrtc