blob: e2f490828609649f68c96bb14c6029e4c2a655ce [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"
41#include "test/gtest.h"
42#include "test/null_transport.h"
43#include "test/rtcp_packet_parser.h"
44#include "test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070045
Sebastian Janssona45c8da2018-01-16 10:55:29 +010046#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020047#include "video/send_statistics_proxy.h"
48#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010049#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000050
51namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010052namespace test {
53class VideoSendStreamPeer {
54 public:
55 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
56 : internal_stream_(
57 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
58 rtc::Optional<float> GetPacingFactorOverride() const {
59 return internal_stream_->GetPacingFactorOverride();
60 }
61
62 private:
63 internal::VideoSendStream const* const internal_stream_;
64};
65} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000066
sprang@webrtc.org346094c2014-02-18 08:40:33 +000067enum VideoFormat { kGeneric, kVP8, };
68
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070069void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
70 const std::vector<VideoFrame>& frames2);
71VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000072
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000073class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000074 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000075 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000076 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000077 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010078
79 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
80 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070081
82 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000083};
84
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000085TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070086 task_queue_.SendTask([this]() {
87 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000088
eladalon413ee9a2017-08-22 04:02:52 -070089 test::NullTransport transport;
90 CreateSendConfig(1, 0, 0, &transport);
91 CreateVideoStreams();
92 video_send_stream_->Start();
93 video_send_stream_->Start();
94 DestroyStreams();
95 DestroyCalls();
96 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000097}
98
99TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700100 task_queue_.SendTask([this]() {
101 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000102
eladalon413ee9a2017-08-22 04:02:52 -0700103 test::NullTransport transport;
104 CreateSendConfig(1, 0, 0, &transport);
105 CreateVideoStreams();
106 video_send_stream_->Stop();
107 video_send_stream_->Stop();
108 DestroyStreams();
109 DestroyCalls();
110 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000111}
112
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000113TEST_F(VideoSendStreamTest, SupportsCName) {
114 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000115 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000116 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000117 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000118
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000119 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000120 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700121 test::RtcpPacketParser parser;
122 EXPECT_TRUE(parser.Parse(packet, length));
123 if (parser.sdes()->num_packets() > 0) {
124 EXPECT_EQ(1u, parser.sdes()->chunks().size());
125 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000126
danilchap3dc929e2016-11-02 08:21:59 -0700127 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000128 }
129
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000130 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000131 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000132
stefanff483612015-12-21 03:14:00 -0800133 void ModifyVideoConfigs(
134 VideoSendStream::Config* send_config,
135 std::vector<VideoReceiveStream::Config>* receive_configs,
136 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000137 send_config->rtp.c_name = kCName;
138 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000139
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000140 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100141 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000142 }
143 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000144
stefane74eef12016-01-08 06:47:13 -0800145 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000146}
147
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000148TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000149 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000150 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000151 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000152 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100153 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000154 }
155
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000156 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000157 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000158 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000159
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000160 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
161 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
162 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700163 if (header.extension.absoluteSendTime != 0) {
164 // Wait for at least one packet with a non-zero send time. The send time
165 // is a 16-bit value derived from the system clock, and it is valid
166 // for a packet to have a zero send time. To tell that from an
167 // unpopulated value we'll wait for a packet with non-zero send time.
168 observation_complete_.Set();
169 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100170 RTC_LOG(LS_WARNING)
171 << "Got a packet with zero absoluteSendTime, waiting"
172 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700173 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000174
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000175 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000176 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000177
stefanff483612015-12-21 03:14:00 -0800178 void ModifyVideoConfigs(
179 VideoSendStream::Config* send_config,
180 std::vector<VideoReceiveStream::Config>* receive_configs,
181 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200182 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100183 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700184 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000185 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000186
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000187 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100188 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000189 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000190 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000191
stefane74eef12016-01-08 06:47:13 -0800192 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000193}
194
pbos@webrtc.org29023282013-09-11 10:14:56 +0000195TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000196 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000197 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000198 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000199 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000200 : SendTest(kDefaultTimeoutMs),
201 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000202 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100203 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000204 }
205
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000206 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000207 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000208 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000209 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000210
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000211 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
212 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000213 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000214 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100215 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000216
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000217 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000218 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000219
stefanff483612015-12-21 03:14:00 -0800220 void ModifyVideoConfigs(
221 VideoSendStream::Config* send_config,
222 std::vector<VideoReceiveStream::Config>* receive_configs,
223 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000224 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100225 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700226 send_config->rtp.extensions.push_back(RtpExtension(
227 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000228 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000229
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000230 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100231 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000232 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000233
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000234 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000235 } test;
236
stefane74eef12016-01-08 06:47:13 -0800237 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000238}
239
sprang867fb522015-08-03 04:38:41 -0700240TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700241 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700242 class TransportWideSequenceNumberObserver : public test::SendTest {
243 public:
244 TransportWideSequenceNumberObserver()
245 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
246 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
247 kRtpExtensionTransportSequenceNumber, kExtensionId));
248 }
249
250 private:
251 Action OnSendRtp(const uint8_t* packet, size_t length) override {
252 RTPHeader header;
253 EXPECT_TRUE(parser_->Parse(packet, length, &header));
254
255 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
256 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
257 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
258
Peter Boström5811a392015-12-10 13:02:50 +0100259 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700260
261 return SEND_PACKET;
262 }
263
stefanff483612015-12-21 03:14:00 -0800264 void ModifyVideoConfigs(
265 VideoSendStream::Config* send_config,
266 std::vector<VideoReceiveStream::Config>* receive_configs,
267 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700268 send_config->encoder_settings.encoder = &encoder_;
sprang867fb522015-08-03 04:38:41 -0700269 }
270
271 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100272 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700273 }
274
275 test::FakeEncoder encoder_;
276 } test;
277
stefane74eef12016-01-08 06:47:13 -0800278 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700279}
280
perkj803d97f2016-11-01 11:45:46 -0700281TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
282 class VideoRotationObserver : public test::SendTest {
283 public:
284 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
285 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
286 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
287 }
288
289 Action OnSendRtp(const uint8_t* packet, size_t length) override {
290 RTPHeader header;
291 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700292 // Only the last packet of the frame is required to have the extension.
293 if (!header.markerBit)
294 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700295 EXPECT_TRUE(header.extension.hasVideoRotation);
296 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
297 observation_complete_.Set();
298 return SEND_PACKET;
299 }
300
301 void ModifyVideoConfigs(
302 VideoSendStream::Config* send_config,
303 std::vector<VideoReceiveStream::Config>* receive_configs,
304 VideoEncoderConfig* encoder_config) override {
305 send_config->rtp.extensions.clear();
306 send_config->rtp.extensions.push_back(RtpExtension(
307 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
308 }
309
310 void OnFrameGeneratorCapturerCreated(
311 test::FrameGeneratorCapturer* frame_generator_capturer) override {
312 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
313 }
314
315 void PerformTest() override {
316 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
317 }
318 } test;
319
320 RunBaseTest(&test);
321}
322
ilnik00d802b2017-04-11 10:34:31 -0700323TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700324 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700325 public:
ilnik10894992017-06-21 08:23:19 -0700326 VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
ilnik00d802b2017-04-11 10:34:31 -0700327 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
328 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
329 }
330
331 Action OnSendRtp(const uint8_t* packet, size_t length) override {
332 RTPHeader header;
333 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700334 // Only the last packet of the frame must have extension.
335 if (!header.markerBit)
336 return SEND_PACKET;
ilnik00d802b2017-04-11 10:34:31 -0700337 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700338 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
339 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700340 observation_complete_.Set();
341 return SEND_PACKET;
342 }
343
344 void ModifyVideoConfigs(
345 VideoSendStream::Config* send_config,
346 std::vector<VideoReceiveStream::Config>* receive_configs,
347 VideoEncoderConfig* encoder_config) override {
348 send_config->rtp.extensions.clear();
349 send_config->rtp.extensions.push_back(
350 RtpExtension(RtpExtension::kVideoContentTypeUri,
351 test::kVideoContentTypeExtensionId));
352 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
353 }
354
355 void PerformTest() override {
356 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
357 }
358 } test;
359
360 RunBaseTest(&test);
361}
362
ilnik04f4d122017-06-19 07:18:55 -0700363TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700364 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700365 public:
ilnik10894992017-06-21 08:23:19 -0700366 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700367 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
368 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
369 }
370
371 Action OnSendRtp(const uint8_t* packet, size_t length) override {
372 RTPHeader header;
373 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700374 // Only the last packet of the frame must have extension.
375 if (!header.markerBit)
376 return SEND_PACKET;
377 EXPECT_TRUE(header.extension.has_video_timing);
378 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700379 return SEND_PACKET;
380 }
381
382 void ModifyVideoConfigs(
383 VideoSendStream::Config* send_config,
384 std::vector<VideoReceiveStream::Config>* receive_configs,
385 VideoEncoderConfig* encoder_config) override {
386 send_config->rtp.extensions.clear();
387 send_config->rtp.extensions.push_back(RtpExtension(
388 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
389 }
390
391 void PerformTest() override {
392 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
393 }
394 } test;
395
396 RunBaseTest(&test);
397}
398
danilchap901b2df2017-07-28 08:56:04 -0700399class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000400 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000401 FakeReceiveStatistics(uint32_t send_ssrc,
402 uint32_t last_sequence_number,
403 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700404 uint8_t fraction_lost) {
405 stat_.SetMediaSsrc(send_ssrc);
406 stat_.SetExtHighestSeqNum(last_sequence_number);
407 stat_.SetCumulativeLost(cumulative_lost);
408 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000409 }
410
danilchap901b2df2017-07-28 08:56:04 -0700411 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
412 EXPECT_GE(max_blocks, 1u);
413 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000414 }
415
416 private:
danilchap901b2df2017-07-28 08:56:04 -0700417 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000418};
419
brandtre602f0a2016-10-31 03:40:49 -0700420class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100421 public:
brandtre602f0a2016-10-31 03:40:49 -0700422 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800423 bool use_nack,
424 bool expect_red,
425 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800426 const std::string& codec,
427 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800428 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800429 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100430 payload_name_(codec),
431 use_nack_(use_nack),
432 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700433 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800434 sent_media_(false),
435 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800436 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100437
brandtr20d45472017-01-02 00:34:27 -0800438 // Some of the test cases are expected to time out and thus we are using
439 // a shorter timeout window than the default here.
440 static constexpr size_t kTimeoutMs = 10000;
441
Stefan Holmer4654d202015-12-08 09:10:43 +0100442 private:
443 Action OnSendRtp(const uint8_t* packet, size_t length) override {
444 RTPHeader header;
445 EXPECT_TRUE(parser_->Parse(packet, length, &header));
446
Stefan Holmer4654d202015-12-08 09:10:43 +0100447 int encapsulated_payload_type = -1;
448 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100449 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100450 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
451 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100452 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100453 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
454 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100455 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100456 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100457 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
458 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100459 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
460 length) {
461 // Not padding-only, media received outside of RED.
462 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800463 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100464 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100465 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000466
Stefan Holmer4654d202015-12-08 09:10:43 +0100467 if (header_extensions_enabled_) {
468 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
469 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
470 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
471 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
472 // 24 bits wrap.
473 EXPECT_GT(prev_header_.extension.absoluteSendTime,
474 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000475 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100476 EXPECT_GE(header.extension.absoluteSendTime,
477 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200478 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100479 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
480 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
481 prev_header_.extension.transportSequenceNumber;
482 EXPECT_EQ(1, seq_num_diff);
483 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200484
Stefan Holmer4654d202015-12-08 09:10:43 +0100485 if (encapsulated_payload_type != -1) {
486 if (encapsulated_payload_type ==
487 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700488 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800489 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100490 } else {
brandtr65a1e772016-12-12 01:54:58 -0800491 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000492 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000493 }
494
brandtr20d45472017-01-02 00:34:27 -0800495 if (sent_media_ && sent_ulpfec_) {
496 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100497 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000498
Stefan Holmer4654d202015-12-08 09:10:43 +0100499 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000500
Stefan Holmer4654d202015-12-08 09:10:43 +0100501 return SEND_PACKET;
502 }
503
eladalon413ee9a2017-08-22 04:02:52 -0700504 test::PacketTransport* CreateSendTransport(
505 test::SingleThreadedTaskQueueForTesting* task_queue,
506 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100507 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
508 // Configure some network delay.
509 const int kNetworkDelayMs = 100;
510 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800511 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100512 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700513 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700514 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700515 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100516 }
517
stefanff483612015-12-21 03:14:00 -0800518 void ModifyVideoConfigs(
519 VideoSendStream::Config* send_config,
520 std::vector<VideoReceiveStream::Config>* receive_configs,
521 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100522 if (use_nack_) {
523 send_config->rtp.nack.rtp_history_ms =
524 (*receive_configs)[0].rtp.nack.rtp_history_ms =
525 VideoSendStreamTest::kNackRtpHistoryMs;
526 }
brandtr696c9c62016-12-19 05:47:28 -0800527 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100528 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700529 send_config->rtp.ulpfec.red_payload_type =
530 VideoSendStreamTest::kRedPayloadType;
531 send_config->rtp.ulpfec.ulpfec_payload_type =
532 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800533 EXPECT_FALSE(send_config->rtp.extensions.empty());
534 if (!header_extensions_enabled_) {
535 send_config->rtp.extensions.clear();
536 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100537 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700538 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100539 }
nisse3b3622f2017-09-26 02:49:21 -0700540 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700541 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700542 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700543 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100544 }
545
546 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800547 EXPECT_EQ(expect_ulpfec_, Wait())
548 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100549 }
550
brandtr696c9c62016-12-19 05:47:28 -0800551 VideoEncoder* const encoder_;
552 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100553 const bool use_nack_;
554 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700555 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800556 bool sent_media_;
557 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100558 bool header_extensions_enabled_;
559 RTPHeader prev_header_;
560};
561
brandtre602f0a2016-10-31 03:40:49 -0700562TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800563 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
564 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800565 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100566}
567
brandtre602f0a2016-10-31 03:40:49 -0700568TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800569 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
570 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100571 RunBaseTest(&test);
572}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000573
stefan60e10c72017-08-23 10:40:00 -0700574class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
575 protected:
576 VideoSendStreamWithoutUlpfecTest()
577 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
578
579 test::ScopedFieldTrials field_trial_;
580};
581
582TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
583 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
584 UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
585 RunBaseTest(&test);
586}
587
Peter Boström39593972016-02-15 11:27:15 +0100588// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
589// since we'll still have to re-request FEC packets, effectively wasting
590// bandwidth since the receiver has to wait for FEC retransmissions to determine
591// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700592TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800593 std::unique_ptr<VideoEncoder> encoder(
594 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
595 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100596 RunBaseTest(&test);
597}
598
599// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800600TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800601 std::unique_ptr<VideoEncoder> encoder(
602 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
603 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100604 RunBaseTest(&test);
605}
606
danilchap9f5b6222017-03-02 06:22:21 -0800607// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
608TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800609 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
610 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100611 RunBaseTest(&test);
612}
613
Peter Boström12996152016-05-14 02:03:18 +0200614#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800615// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
616TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800617 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
618 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800619 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000620}
Peter Boström12996152016-05-14 02:03:18 +0200621#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000622
brandtre78d2662017-01-16 05:57:16 -0800623TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800624 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800625 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800626 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
627 RunBaseTest(&test);
628}
629
brandtr39f97292016-11-16 22:57:50 -0800630// TODO(brandtr): Move these FlexFEC tests when we have created
631// FlexfecSendStream.
632class FlexfecObserver : public test::EndToEndTest {
633 public:
634 FlexfecObserver(bool header_extensions_enabled,
635 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800636 const std::string& codec,
637 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800638 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800639 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800640 payload_name_(codec),
641 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800642 sent_media_(false),
643 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800644 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800645
646 size_t GetNumFlexfecStreams() const override { return 1; }
647
648 private:
649 Action OnSendRtp(const uint8_t* packet, size_t length) override {
650 RTPHeader header;
651 EXPECT_TRUE(parser_->Parse(packet, length, &header));
652
brandtr39f97292016-11-16 22:57:50 -0800653 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
654 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
655 sent_flexfec_ = true;
656 } else {
657 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
658 header.payloadType);
659 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
660 sent_media_ = true;
661 }
662
663 if (header_extensions_enabled_) {
664 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
665 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
666 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
667 }
668
brandtr0c5a1542016-11-23 04:42:26 -0800669 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800670 observation_complete_.Set();
671 }
672
673 return SEND_PACKET;
674 }
675
eladalon413ee9a2017-08-22 04:02:52 -0700676 test::PacketTransport* CreateSendTransport(
677 test::SingleThreadedTaskQueueForTesting* task_queue,
678 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800679 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
680 // Therefore we need some network delay.
681 const int kNetworkDelayMs = 100;
682 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800683 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800684 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700685 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700686 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700687 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800688 }
689
690 void ModifyVideoConfigs(
691 VideoSendStream::Config* send_config,
692 std::vector<VideoReceiveStream::Config>* receive_configs,
693 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800694 if (use_nack_) {
695 send_config->rtp.nack.rtp_history_ms =
696 (*receive_configs)[0].rtp.nack.rtp_history_ms =
697 VideoSendStreamTest::kNackRtpHistoryMs;
698 }
brandtr696c9c62016-12-19 05:47:28 -0800699 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800700 send_config->encoder_settings.payload_name = payload_name_;
701 if (header_extensions_enabled_) {
702 send_config->rtp.extensions.push_back(RtpExtension(
703 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
704 send_config->rtp.extensions.push_back(RtpExtension(
705 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800706 } else {
707 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800708 }
709 }
710
711 void PerformTest() override {
712 EXPECT_TRUE(Wait())
713 << "Timed out waiting for FlexFEC and/or media packets.";
714 }
715
brandtr696c9c62016-12-19 05:47:28 -0800716 VideoEncoder* const encoder_;
717 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800718 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800719 bool sent_media_;
720 bool sent_flexfec_;
721 bool header_extensions_enabled_;
722};
723
brandtrd654a9b2016-12-05 05:38:19 -0800724TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800725 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
726 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800727 RunBaseTest(&test);
728}
729
730TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800731 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
732 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800733 RunBaseTest(&test);
734}
735
brandtr39f97292016-11-16 22:57:50 -0800736TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800737 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
738 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800739 RunBaseTest(&test);
740}
741
brandtr39f97292016-11-16 22:57:50 -0800742#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800743TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800744 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
745 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800746 RunBaseTest(&test);
747}
748
brandtrd654a9b2016-12-05 05:38:19 -0800749TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800750 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
751 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800752 RunBaseTest(&test);
753}
754#endif // defined(RTC_DISABLE_VP9)
755
brandtrd654a9b2016-12-05 05:38:19 -0800756TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800757 std::unique_ptr<VideoEncoder> encoder(
758 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
759 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800760 RunBaseTest(&test);
761}
762
brandtrd654a9b2016-12-05 05:38:19 -0800763TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800764 std::unique_ptr<VideoEncoder> encoder(
765 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
766 FlexfecObserver test(false, true, "H264", encoder.get());
767 RunBaseTest(&test);
768}
769
brandtre78d2662017-01-16 05:57:16 -0800770TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800771 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800772 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800773 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800774 RunBaseTest(&test);
775}
776
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000777void VideoSendStreamTest::TestNackRetransmission(
778 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000779 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000780 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000781 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000782 explicit NackObserver(uint32_t retransmit_ssrc,
783 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000784 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000785 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000786 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000787 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000788 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000789 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000790
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000791 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000792 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000793 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000794 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000795
796 // Nack second packet after receiving the third one.
797 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000798 uint16_t nack_sequence_number = header.sequenceNumber - 1;
799 nacked_sequence_number_ = nack_sequence_number;
danilchap8a1d2a32017-08-01 03:21:37 -0700800 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
terelius429c3452016-01-21 05:42:04 -0800801 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000802
pbosda903ea2015-10-02 02:36:56 -0700803 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100804 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000805
806 RTCPSender::FeedbackState feedback_state;
807
808 EXPECT_EQ(0,
809 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000810 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000811 }
812
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000813 uint16_t sequence_number = header.sequenceNumber;
814
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000815 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100816 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
817 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000818 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000819 const uint8_t* rtx_header = packet + header.headerLength;
820 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
821 }
822
823 if (sequence_number == nacked_sequence_number_) {
824 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000825 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100826 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000827 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000828
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000829 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000830 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000831
stefanff483612015-12-21 03:14:00 -0800832 void ModifyVideoConfigs(
833 VideoSendStream::Config* send_config,
834 std::vector<VideoReceiveStream::Config>* receive_configs,
835 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700836 transport_adapter_.reset(
837 new internal::TransportAdapter(send_config->send_transport));
838 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000839 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000840 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100841 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000842 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
843 }
844
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000845 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100846 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000847 }
848
kwiberg27f982b2016-03-01 11:52:33 -0800849 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000850 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000851 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000852 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000853 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000854 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000855
stefane74eef12016-01-08 06:47:13 -0800856 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000857}
858
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000859TEST_F(VideoSendStreamTest, RetransmitsNack) {
860 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100861 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000862}
863
864TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
865 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000866 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000867}
868
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000869void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
870 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000871 // Use a fake encoder to output a frame of every size in the range [90, 290],
872 // for each size making sure that the exact number of payload bytes received
873 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000874 static const size_t kMaxPacketSize = 128;
875 static const size_t start = 90;
876 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000877
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000878 // Observer that verifies that the expected number of packets and bytes
879 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000880 class FrameFragmentationTest : public test::SendTest,
881 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000882 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000883 FrameFragmentationTest(size_t max_packet_size,
884 size_t start_size,
885 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000886 bool test_generic_packetization,
887 bool use_fec)
888 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000889 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000890 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000891 stop_size_(stop_size),
892 test_generic_packetization_(test_generic_packetization),
893 use_fec_(use_fec),
894 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000895 accumulated_size_(0),
896 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000897 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000898 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700899 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000900 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000901 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700902 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000903 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000904
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000905 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000906 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000907 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000908 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000909 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000910
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000911 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000912
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000913 if (use_fec_) {
914 uint8_t payload_type = packet[header.headerLength];
915 bool is_fec = header.payloadType == kRedPayloadType &&
916 payload_type == kUlpfecPayloadType;
917 if (is_fec) {
918 fec_packet_received_ = true;
919 return SEND_PACKET;
920 }
921 }
922
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000923 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000924
925 if (use_fec_)
926 TriggerLossReport(header);
927
928 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200929 size_t overhead = header.headerLength + header.paddingLength;
930 // Only remove payload header and RED header if the packet actually
931 // contains payload.
932 if (length > overhead) {
933 overhead += (1 /* Generic header */);
934 if (use_fec_)
935 overhead += 1; // RED for FEC header.
936 }
937 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000938 accumulated_payload_ += length - overhead;
939 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000940
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000941 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000942 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000943 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
944 // With FEC enabled, frame size is incremented asynchronously, so
945 // "old" frames one byte too small may arrive. Accept, but don't
946 // increase expected frame size.
947 accumulated_size_ = 0;
948 accumulated_payload_ = 0;
949 return SEND_PACKET;
950 }
951
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000952 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000953 if (test_generic_packetization_) {
954 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
955 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000956
957 // Last packet of frame; reset counters.
958 accumulated_size_ = 0;
959 accumulated_payload_ = 0;
960 if (current_size_rtp_ == stop_size_) {
961 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100962 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000963 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000964 // Increase next expected frame size. If testing with FEC, make sure
965 // a FEC packet has been received for this frame size before
966 // proceeding, to make sure that redundancy packets don't exceed
967 // size limit.
968 if (!use_fec_) {
969 ++current_size_rtp_;
970 } else if (fec_packet_received_) {
971 fec_packet_received_ = false;
972 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700973
974 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000975 ++current_size_frame_;
976 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000977 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000978 }
979
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000980 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000981 }
982
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000983 void TriggerLossReport(const RTPHeader& header) {
984 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -0700985 const int kLossPercent = 5;
986 if (packet_count_++ % (100 / kLossPercent) != 0) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000987 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -0700988 kVideoSendSsrcs[0], header.sequenceNumber,
989 (packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
990 static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +0200991 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800992 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700993 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000994
pbosda903ea2015-10-02 02:36:56 -0700995 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100996 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000997
998 RTCPSender::FeedbackState feedback_state;
999
1000 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1001 }
1002 }
1003
nisseef8b61e2016-04-29 06:09:15 -07001004 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001005 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001006 // Increase frame size for next encoded frame, in the context of the
1007 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001008 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001009 ++current_size_frame_;
1010 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001011 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001012 }
1013
Stefan Holmere5904162015-03-26 11:11:06 +01001014 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07001015 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001016 const int kMinBitrateBps = 30000;
1017 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1018 return config;
1019 }
1020
stefanff483612015-12-21 03:14:00 -08001021 void ModifyVideoConfigs(
1022 VideoSendStream::Config* send_config,
1023 std::vector<VideoReceiveStream::Config>* receive_configs,
1024 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001025 transport_adapter_.reset(
1026 new internal::TransportAdapter(send_config->send_transport));
1027 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001028 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001029 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1030 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001031 }
1032
1033 if (!test_generic_packetization_)
1034 send_config->encoder_settings.payload_name = "VP8";
1035
1036 send_config->encoder_settings.encoder = &encoder_;
1037 send_config->rtp.max_packet_size = kMaxPacketSize;
1038 send_config->post_encode_callback = this;
1039
Erik Språng95261872015-04-10 11:58:49 +02001040 // Make sure there is at least one extension header, to make the RTP
1041 // header larger than the base length of 12 bytes.
1042 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001043
1044 // Setup screen content disables frame dropping which makes this easier.
1045 class VideoStreamFactory
1046 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1047 public:
1048 explicit VideoStreamFactory(size_t num_temporal_layers)
1049 : num_temporal_layers_(num_temporal_layers) {
1050 EXPECT_GT(num_temporal_layers, 0u);
1051 }
1052
1053 private:
1054 std::vector<VideoStream> CreateEncoderStreams(
1055 int width,
1056 int height,
1057 const VideoEncoderConfig& encoder_config) override {
1058 std::vector<VideoStream> streams =
1059 test::CreateVideoStreams(width, height, encoder_config);
1060 for (VideoStream& stream : streams) {
1061 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1062 1);
1063 }
1064 return streams;
1065 }
1066 const size_t num_temporal_layers_;
1067 };
1068
1069 encoder_config->video_stream_factory =
1070 new rtc::RefCountedObject<VideoStreamFactory>(2);
1071 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001072 }
1073
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001074 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001075 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001076 }
1077
kwiberg27f982b2016-03-01 11:52:33 -08001078 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001079 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001080
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001081 const size_t max_packet_size_;
1082 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001083 const bool test_generic_packetization_;
1084 const bool use_fec_;
1085
1086 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001087 size_t accumulated_size_;
1088 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001089 bool fec_packet_received_;
1090
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001091 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001092 rtc::CriticalSection mutex_;
1093 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001094 };
1095
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001096 // Don't auto increment if FEC is used; continue sending frame size until
1097 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001098 FrameFragmentationTest test(
1099 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001100
stefane74eef12016-01-08 06:47:13 -08001101 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001102}
1103
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001104// TODO(sprang): Is there any way of speeding up these tests?
1105TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1106 TestPacketFragmentationSize(kGeneric, false);
1107}
1108
1109TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1110 TestPacketFragmentationSize(kGeneric, true);
1111}
1112
1113TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1114 TestPacketFragmentationSize(kVP8, false);
1115}
1116
1117TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1118 TestPacketFragmentationSize(kVP8, true);
1119}
1120
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001121// The test will go through a number of phases.
1122// 1. Start sending packets.
1123// 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 +00001124// suspend the stream.
1125// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001126// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001127// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001128// When the stream is detected again, and the stats show that the stream
1129// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001130TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1131 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001132
nissed30a1112016-04-18 05:15:22 -07001133 class RembObserver : public test::SendTest,
1134 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001135 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001136 RembObserver()
1137 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001138 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001139 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001140 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001141 rtp_count_(0),
1142 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001143 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001144 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001145 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001146
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001147 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001148 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001149 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001150 ++rtp_count_;
1151 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001152 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001153 last_sequence_number_ = header.sequenceNumber;
1154
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001155 if (test_state_ == kBeforeSuspend) {
1156 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001157 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001158 test_state_ = kDuringSuspend;
1159 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001160 if (header.paddingLength == 0) {
1161 // Received non-padding packet during suspension period. Reset the
1162 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001163 suspended_frame_count_ = 0;
1164 }
stefanf116bd02015-10-27 08:29:42 -07001165 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001166 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001167 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001168 // Non-padding packet observed. Test is almost complete. Will just
1169 // have to wait for the stats to change.
1170 test_state_ = kWaitingForStats;
1171 }
stefanf116bd02015-10-27 08:29:42 -07001172 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001173 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001174 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001175 if (stats.suspended == false) {
1176 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001177 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001178 }
stefanf116bd02015-10-27 08:29:42 -07001179 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001180 }
1181
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001182 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001183 }
1184
perkj26091b12016-09-01 01:17:40 -07001185 // This method implements the rtc::VideoSinkInterface. This is called when
1186 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001187 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001188 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001189 if (test_state_ == kDuringSuspend &&
1190 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001191 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001192 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001193 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001194 test_state_ = kWaitingForPacket;
1195 }
1196 }
1197
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001198 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001199 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001200 low_remb_bps_ = value;
1201 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001202
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001203 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001204 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001205 high_remb_bps_ = value;
1206 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001207
stefanff483612015-12-21 03:14:00 -08001208 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001209 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001210 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001211 stream_ = send_stream;
1212 }
1213
stefanff483612015-12-21 03:14:00 -08001214 void ModifyVideoConfigs(
1215 VideoSendStream::Config* send_config,
1216 std::vector<VideoReceiveStream::Config>* receive_configs,
1217 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001218 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001219 transport_adapter_.reset(
1220 new internal::TransportAdapter(send_config->send_transport));
1221 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001222 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001223 send_config->pre_encode_callback = this;
1224 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001225 int min_bitrate_bps =
1226 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001227 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001228 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001229 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001230 min_bitrate_bps + threshold_window + 5000);
1231 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1232 }
1233
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001234 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001235 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001236 }
1237
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001238 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001239 kBeforeSuspend,
1240 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001241 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001242 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001243 };
1244
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001245 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001246 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001247 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1248 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001249 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001250 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001251
pbosda903ea2015-10-02 02:36:56 -07001252 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001253 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001254 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001255 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001256 }
1257 RTCPSender::FeedbackState feedback_state;
1258 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1259 }
1260
kwiberg27f982b2016-03-01 11:52:33 -08001261 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001262 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001263 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001264
Peter Boströmf2f82832015-05-01 13:00:41 +02001265 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001266 TestState test_state_ RTC_GUARDED_BY(crit_);
1267 int rtp_count_ RTC_GUARDED_BY(crit_);
1268 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1269 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1270 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1271 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001272 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001273
stefane74eef12016-01-08 06:47:13 -08001274 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001275}
1276
perkj71ee44c2016-06-15 00:47:53 -07001277// This test that padding stops being send after a while if the Camera stops
1278// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001279TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001280 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001281 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001282 NoPaddingWhenVideoIsMuted()
1283 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001284 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001285 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001286 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001287 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001288
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001289 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001290 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001291 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001292 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001293
1294 RTPHeader header;
1295 parser_->Parse(packet, length, &header);
1296 const bool only_padding =
1297 header.headerLength + header.paddingLength == length;
1298
1299 if (test_state_ == kBeforeStopCapture) {
1300 capturer_->Stop();
1301 test_state_ = kWaitingForPadding;
1302 } else if (test_state_ == kWaitingForPadding && only_padding) {
1303 test_state_ = kWaitingForNoPackets;
1304 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1305 only_padding) {
1306 observation_complete_.Set();
1307 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001308 return SEND_PACKET;
1309 }
1310
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001311 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001312 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001313 const int kNoPacketsThresholdMs = 2000;
1314 if (test_state_ == kWaitingForNoPackets &&
1315 (last_packet_time_ms_ > 0 &&
1316 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1317 kNoPacketsThresholdMs)) {
1318 capturer_->Start();
1319 test_state_ = kWaitingForPaddingAfterCameraRestart;
1320 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001321 return SEND_PACKET;
1322 }
1323
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001324 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001325
nisseef8b61e2016-04-29 06:09:15 -07001326 void OnFrameGeneratorCapturerCreated(
1327 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001328 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001329 capturer_ = frame_generator_capturer;
1330 }
1331
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001332 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001333 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001334 << "Timed out while waiting for RTP packets to stop being sent.";
1335 }
1336
perkj71ee44c2016-06-15 00:47:53 -07001337 enum TestState {
1338 kBeforeStopCapture,
1339 kWaitingForPadding,
1340 kWaitingForNoPackets,
1341 kWaitingForPaddingAfterCameraRestart
1342 };
1343
1344 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001345 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001346 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001347 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001348 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1349 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001350 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001351
stefane74eef12016-01-08 06:47:13 -08001352 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001353}
1354
isheriffcc5903e2016-10-04 08:29:38 -07001355TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1356 const int kCapacityKbps = 10000; // 10 Mbps
1357 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1358 public:
1359 PaddingIsPrimarilyRetransmissions()
1360 : EndToEndTest(kDefaultTimeoutMs),
1361 clock_(Clock::GetRealTimeClock()),
1362 padding_length_(0),
1363 total_length_(0),
1364 call_(nullptr) {}
1365
1366 private:
1367 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1368 call_ = sender_call;
1369 }
1370
1371 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1372 rtc::CritScope lock(&crit_);
1373
1374 RTPHeader header;
1375 parser_->Parse(packet, length, &header);
1376 padding_length_ += header.paddingLength;
1377 total_length_ += length;
1378 return SEND_PACKET;
1379 }
1380
eladalon413ee9a2017-08-22 04:02:52 -07001381 test::PacketTransport* CreateSendTransport(
1382 test::SingleThreadedTaskQueueForTesting* task_queue,
1383 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001384 const int kNetworkDelayMs = 50;
1385 FakeNetworkPipe::Config config;
1386 config.loss_percent = 10;
1387 config.link_capacity_kbps = kCapacityKbps;
1388 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001389 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001390 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001391 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001392 }
1393
1394 void ModifyVideoConfigs(
1395 VideoSendStream::Config* send_config,
1396 std::vector<VideoReceiveStream::Config>* receive_configs,
1397 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001398 // Turn on RTX.
1399 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1400 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001401 }
1402
1403 void PerformTest() override {
1404 // TODO(isheriff): Some platforms do not ramp up as expected to full
1405 // capacity due to packet scheduling delays. Fix that before getting
1406 // rid of this.
1407 SleepMs(5000);
1408 {
1409 rtc::CritScope lock(&crit_);
1410 // Expect padding to be a small percentage of total bytes sent.
1411 EXPECT_LT(padding_length_, .1 * total_length_);
1412 }
1413 }
1414
1415 rtc::CriticalSection crit_;
1416 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001417 size_t padding_length_ RTC_GUARDED_BY(crit_);
1418 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001419 Call* call_;
1420 } test;
1421
1422 RunBaseTest(&test);
1423}
1424
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001425// This test first observes "high" bitrate use at which point it sends a REMB to
1426// indicate that it should be lowered significantly. The test then observes that
1427// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1428// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001429//
1430// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1431// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001432TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1433 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001434 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001435 static const int kRembBitrateBps = 80000;
1436 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001437 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001438 public:
1439 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001440 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001441 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1442 stream_(nullptr),
1443 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001444
1445 private:
nisseef8b61e2016-04-29 06:09:15 -07001446 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001447 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001448 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001449
1450 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001451 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001452 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001453 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001454 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001455 if (!stats.substreams.empty()) {
1456 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001457 int total_bitrate_bps =
1458 stats.substreams.begin()->second.total_bitrate_bps;
1459 test::PrintResult("bitrate_stats_",
1460 "min_transmit_bitrate_low_remb",
1461 "bitrate_bps",
1462 static_cast<size_t>(total_bitrate_bps),
1463 "bps",
1464 false);
1465 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001466 rtp_rtcp_->SetRemb(kRembBitrateBps,
1467 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001468 rtp_rtcp_->Process();
1469 bitrate_capped_ = true;
1470 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001471 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001472 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001473 }
1474 }
stefanf116bd02015-10-27 08:29:42 -07001475 // Packets don't have to be delivered since the test is the receiver.
1476 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001477 }
1478
stefanff483612015-12-21 03:14:00 -08001479 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001480 VideoSendStream* send_stream,
1481 const std::vector<VideoReceiveStream*>& receive_streams) override {
1482 stream_ = send_stream;
1483 RtpRtcp::Configuration config;
1484 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001485 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001486 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001487 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001488 }
1489
stefanff483612015-12-21 03:14:00 -08001490 void ModifyVideoConfigs(
1491 VideoSendStream::Config* send_config,
1492 std::vector<VideoReceiveStream::Config>* receive_configs,
1493 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001494 feedback_transport_.reset(
1495 new internal::TransportAdapter(send_config->send_transport));
1496 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001497 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001498 }
1499
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001500 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001501 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001502 << "Timeout while waiting for low bitrate stats after REMB.";
1503 }
1504
kwiberg27f982b2016-03-01 11:52:33 -08001505 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1506 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001507 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001508 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001509 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001510 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001511
stefane74eef12016-01-08 06:47:13 -08001512 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001513}
1514
Stefan Holmer280de9e2016-09-30 10:06:51 +02001515TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1516 static const int kStartBitrateBps = 300000;
1517 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001518 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001519 class ChangingNetworkRouteTest : public test::EndToEndTest {
1520 public:
eladalon413ee9a2017-08-22 04:02:52 -07001521 explicit ChangingNetworkRouteTest(
1522 test::SingleThreadedTaskQueueForTesting* task_queue)
1523 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1524 task_queue_(task_queue),
1525 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001526 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1527 kRtpExtensionTransportSequenceNumber, kExtensionId));
1528 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001529
1530 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1531 call_ = sender_call;
1532 }
1533
Stefan Holmer280de9e2016-09-30 10:06:51 +02001534 void ModifyVideoConfigs(
1535 VideoSendStream::Config* send_config,
1536 std::vector<VideoReceiveStream::Config>* receive_configs,
1537 VideoEncoderConfig* encoder_config) override {
1538 send_config->rtp.extensions.clear();
1539 send_config->rtp.extensions.push_back(RtpExtension(
1540 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1541 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1542 (*receive_configs)[0].rtp.transport_cc = true;
1543 }
1544
1545 void ModifyAudioConfigs(
1546 AudioSendStream::Config* send_config,
1547 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1548 send_config->rtp.extensions.clear();
1549 send_config->rtp.extensions.push_back(RtpExtension(
1550 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1551 (*receive_configs)[0].rtp.extensions.clear();
1552 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1553 (*receive_configs)[0].rtp.transport_cc = true;
1554 }
1555
Stefan Holmerbe402962016-07-08 16:16:41 +02001556 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1557 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1558 observation_complete_.Set();
1559 }
1560
1561 return SEND_PACKET;
1562 }
1563
1564 void PerformTest() override {
1565 rtc::NetworkRoute new_route(true, 10, 20, -1);
Stefan Holmerbe402962016-07-08 16:16:41 +02001566 Call::Config::BitrateConfig bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001567
1568 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1569 call_->OnNetworkRouteChanged("transport", new_route);
1570 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1571 call_->SetBitrateConfig(bitrate_config);
1572 });
1573
Stefan Holmerbe402962016-07-08 16:16:41 +02001574 EXPECT_TRUE(Wait())
1575 << "Timed out while waiting for start bitrate to be exceeded.";
1576
eladalon413ee9a2017-08-22 04:02:52 -07001577 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1578 bitrate_config.start_bitrate_bps = -1;
1579 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1580 call_->SetBitrateConfig(bitrate_config);
1581 // TODO(holmer): We should set the last sent packet id here and verify
1582 // that we correctly ignore any packet loss reported prior to that id.
1583 ++new_route.local_network_id;
1584 call_->OnNetworkRouteChanged("transport", new_route);
1585 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1586 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001587 }
1588
1589 private:
eladalon413ee9a2017-08-22 04:02:52 -07001590 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001591 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001592 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001593
1594 RunBaseTest(&test);
1595}
1596
michaelt79e05882016-11-08 02:50:09 -08001597TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1598 class ChangingTransportOverheadTest : public test::EndToEndTest {
1599 public:
eladalon413ee9a2017-08-22 04:02:52 -07001600 explicit ChangingTransportOverheadTest(
1601 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001602 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001603 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001604 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001605 packets_sent_(0),
1606 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001607
1608 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1609 call_ = sender_call;
1610 }
1611
1612 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001613 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001614 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001615 if (++packets_sent_ < 100)
1616 return SEND_PACKET;
1617 observation_complete_.Set();
1618 return SEND_PACKET;
1619 }
1620
michaelta3328772016-11-29 09:25:03 -08001621 void ModifyVideoConfigs(
1622 VideoSendStream::Config* send_config,
1623 std::vector<VideoReceiveStream::Config>* receive_configs,
1624 VideoEncoderConfig* encoder_config) override {
1625 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1626 }
1627
michaelt79e05882016-11-08 02:50:09 -08001628 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001629 task_queue_->SendTask([this]() {
1630 transport_overhead_ = 100;
1631 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1632 transport_overhead_);
1633 });
1634
michaelt79e05882016-11-08 02:50:09 -08001635 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001636
sprang21253fc2017-02-27 03:35:47 -08001637 {
1638 rtc::CritScope cs(&lock_);
1639 packets_sent_ = 0;
1640 }
eladalon413ee9a2017-08-22 04:02:52 -07001641
1642 task_queue_->SendTask([this]() {
1643 transport_overhead_ = 500;
1644 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1645 transport_overhead_);
1646 });
1647
michaelt79e05882016-11-08 02:50:09 -08001648 EXPECT_TRUE(Wait());
1649 }
1650
1651 private:
eladalon413ee9a2017-08-22 04:02:52 -07001652 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001653 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001654 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001655 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001656 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001657 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001658 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001659
1660 RunBaseTest(&test);
1661}
1662
sprangf24a0642017-02-28 13:23:26 -08001663// Test class takes takes as argument a switch selecting if type switch should
1664// occur and a function pointer to reset the send stream. This is necessary
1665// since you cannot change the content type of a VideoSendStream, you need to
1666// recreate it. Stopping and recreating the stream can only be done on the main
1667// thread and in the context of VideoSendStreamTest (not BaseTest).
1668template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001669class MaxPaddingSetTest : public test::SendTest {
1670 public:
1671 static const uint32_t kMinTransmitBitrateBps = 400000;
1672 static const uint32_t kActualEncodeBitrateBps = 40000;
1673 static const uint32_t kMinPacketsToSend = 50;
1674
sprangf24a0642017-02-28 13:23:26 -08001675 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001676 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001677 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001678 call_(nullptr),
1679 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001680 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001681 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001682 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001683 stream_resetter_(stream_reset_fun) {
1684 RTC_DCHECK(stream_resetter_);
1685 }
sprang9c0b5512016-07-06 00:54:28 -07001686
1687 void OnVideoStreamsCreated(
1688 VideoSendStream* send_stream,
1689 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001690 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001691 send_stream_ = send_stream;
1692 }
1693
1694 void ModifyVideoConfigs(
1695 VideoSendStream::Config* send_config,
1696 std::vector<VideoReceiveStream::Config>* receive_configs,
1697 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001698 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001699 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001700 encoder_config->min_transmit_bitrate_bps = 0;
1701 encoder_config->content_type =
1702 VideoEncoderConfig::ContentType::kRealtimeVideo;
1703 } else {
1704 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1705 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1706 }
sprangf24a0642017-02-28 13:23:26 -08001707 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001708 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001709 }
1710
1711 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1712 call_ = sender_call;
1713 }
1714
1715 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1716 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001717 if (running_without_padding_)
1718 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1719
1720 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1721 // we have reliable data.
1722 if (++packets_sent_ < kMinPacketsToSend)
1723 return SEND_PACKET;
1724
1725 if (running_without_padding_) {
1726 // We've sent kMinPacketsToSend packets with default configuration, switch
1727 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001728 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001729 packets_sent_ = 0;
1730 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1731 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001732 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001733 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001734 return SEND_PACKET;
1735 }
1736
1737 // Make sure the pacer has been configured with a min transmit bitrate.
1738 if (call_->GetStats().max_padding_bitrate_bps > 0)
1739 observation_complete_.Set();
1740
1741 return SEND_PACKET;
1742 }
1743
1744 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001745 if (RunningWithoutPadding()) {
1746 ASSERT_TRUE(
1747 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001748 (*stream_resetter_)(send_stream_config_, encoder_config_);
1749 }
1750
sprang9c0b5512016-07-06 00:54:28 -07001751 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1752 }
1753
1754 private:
sprangf24a0642017-02-28 13:23:26 -08001755 bool RunningWithoutPadding() const {
1756 rtc::CritScope lock(&crit_);
1757 return running_without_padding_;
1758 }
1759
sprang9c0b5512016-07-06 00:54:28 -07001760 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001761 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001762 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001763 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001764 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001765 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001766 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001767 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001768 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001769};
1770
1771TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001772 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1773 const VideoEncoderConfig& encoder_config) {};
1774 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001775 RunBaseTest(&test);
1776}
1777
1778TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001779 // Function for removing and recreating the send stream with a new config.
1780 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1781 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001782 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1783 Stop();
1784 sender_call_->DestroyVideoSendStream(video_send_stream_);
1785 video_send_config_ = send_stream_config.Copy();
1786 video_encoder_config_ = encoder_config.Copy();
1787 video_send_stream_ = sender_call_->CreateVideoSendStream(
1788 video_send_config_.Copy(), video_encoder_config_.Copy());
1789 video_send_stream_->SetSource(
1790 frame_generator_capturer_.get(),
1791 VideoSendStream::DegradationPreference::kMaintainResolution);
1792 Start();
1793 });
sprangf24a0642017-02-28 13:23:26 -08001794 };
1795 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001796 RunBaseTest(&test);
1797}
1798
perkjfa10b552016-10-02 23:45:26 -07001799// This test verifies that new frame sizes reconfigures encoders even though not
1800// (yet) sending. The purpose of this is to permit encoding as quickly as
1801// possible once we start sending. Likely the frames being input are from the
1802// same source that will be sent later, which just means that we're ready
1803// earlier.
1804TEST_F(VideoSendStreamTest,
1805 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1806 class EncoderObserver : public test::FakeEncoder {
1807 public:
1808 EncoderObserver()
1809 : FakeEncoder(Clock::GetRealTimeClock()),
1810 init_encode_called_(false, false),
1811 number_of_initializations_(0),
1812 last_initialized_frame_width_(0),
1813 last_initialized_frame_height_(0) {}
1814
1815 void WaitForResolution(int width, int height) {
1816 {
1817 rtc::CritScope lock(&crit_);
1818 if (last_initialized_frame_width_ == width &&
1819 last_initialized_frame_height_ == height) {
1820 return;
1821 }
1822 }
Erik Språng08127a92016-11-16 16:41:30 +01001823 EXPECT_TRUE(
1824 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001825 {
1826 rtc::CritScope lock(&crit_);
1827 EXPECT_EQ(width, last_initialized_frame_width_);
1828 EXPECT_EQ(height, last_initialized_frame_height_);
1829 }
1830 }
1831
1832 private:
1833 int32_t InitEncode(const VideoCodec* config,
1834 int32_t number_of_cores,
1835 size_t max_payload_size) override {
1836 rtc::CritScope lock(&crit_);
1837 last_initialized_frame_width_ = config->width;
1838 last_initialized_frame_height_ = config->height;
1839 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001840 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001841 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1842 }
1843
1844 int32_t Encode(const VideoFrame& input_image,
1845 const CodecSpecificInfo* codec_specific_info,
1846 const std::vector<FrameType>* frame_types) override {
1847 ADD_FAILURE()
1848 << "Unexpected Encode call since the send stream is not started";
1849 return 0;
1850 }
1851
1852 rtc::CriticalSection crit_;
1853 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001854 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1855 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1856 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001857 };
1858
perkjfa10b552016-10-02 23:45:26 -07001859 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001860 EncoderObserver encoder;
eladalon413ee9a2017-08-22 04:02:52 -07001861
1862 task_queue_.SendTask([this, &transport, &encoder]() {
1863 CreateSenderCall(Call::Config(event_log_.get()));
1864 CreateSendConfig(1, 0, 0, &transport);
1865 video_send_config_.encoder_settings.encoder = &encoder;
1866 CreateVideoStreams();
1867 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1868 kDefaultHeight);
1869 frame_generator_capturer_->Start();
1870 });
perkjfa10b552016-10-02 23:45:26 -07001871
1872 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001873
1874 task_queue_.SendTask([this]() {
1875 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1876 kDefaultHeight * 2);
1877 });
1878
perkjfa10b552016-10-02 23:45:26 -07001879 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001880
1881 task_queue_.SendTask([this]() {
1882 DestroyStreams();
1883 DestroyCalls();
1884 });
perkjfa10b552016-10-02 23:45:26 -07001885}
1886
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001887TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1888 class StartBitrateObserver : public test::FakeEncoder {
1889 public:
1890 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001891 : FakeEncoder(Clock::GetRealTimeClock()),
1892 start_bitrate_changed_(false, false),
1893 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001894 int32_t InitEncode(const VideoCodec* config,
1895 int32_t number_of_cores,
1896 size_t max_payload_size) override {
1897 rtc::CritScope lock(&crit_);
1898 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001899 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001900 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1901 }
1902
1903 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1904 rtc::CritScope lock(&crit_);
1905 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001906 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001907 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1908 }
1909
1910 int GetStartBitrateKbps() const {
1911 rtc::CritScope lock(&crit_);
1912 return start_bitrate_kbps_;
1913 }
1914
pbos14fe7082016-04-20 06:35:56 -07001915 bool WaitForStartBitrate() {
1916 return start_bitrate_changed_.Wait(
1917 VideoSendStreamTest::kDefaultTimeoutMs);
1918 }
1919
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001920 private:
pbos5ad935c2016-01-25 03:52:44 -08001921 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001922 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001923 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001924 };
1925
philipel4fb651d2017-04-10 03:54:05 -07001926 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001927
solenberg4fbae2b2015-08-28 04:07:10 -07001928 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001929 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001930
1931 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001932 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001933 sender_call_->SetBitrateConfig(bitrate_config);
1934
1935 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001936 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001937 // Since this test does not use a capturer, set |internal_source| = true.
1938 // Encoder configuration is otherwise updated on the next video frame.
1939 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001940
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001941 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001942
pbos14fe7082016-04-20 06:35:56 -07001943 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001944 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001945 encoder.GetStartBitrateKbps());
1946
perkjfa10b552016-10-02 23:45:26 -07001947 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001948 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001949
1950 // New bitrate should be reconfigured above the previous max. As there's no
1951 // network connection this shouldn't be flaky, as no bitrate should've been
1952 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001953 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001954 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1955 encoder.GetStartBitrateKbps());
1956
1957 DestroyStreams();
1958}
1959
perkj57c21f92016-06-17 07:27:16 -07001960// This test that if the encoder use an internal source, VideoEncoder::SetRates
1961// will be called with zero bitrate during initialization and that
1962// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1963// with zero bitrate.
1964TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1965 class StartStopBitrateObserver : public test::FakeEncoder {
1966 public:
1967 StartStopBitrateObserver()
1968 : FakeEncoder(Clock::GetRealTimeClock()),
1969 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001970 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001971 int32_t InitEncode(const VideoCodec* config,
1972 int32_t number_of_cores,
1973 size_t max_payload_size) override {
1974 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001975 encoder_init_.Set();
1976 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1977 }
1978
Erik Språng08127a92016-11-16 16:41:30 +01001979 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1980 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001981 rtc::CritScope lock(&crit_);
Oskar Sundbom8e07c132018-01-08 16:45:42 +01001982 bitrate_kbps_ = bitrate.get_sum_kbps();
perkj57c21f92016-06-17 07:27:16 -07001983 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001984 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001985 }
1986
1987 bool WaitForEncoderInit() {
1988 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1989 }
Erik Språng08127a92016-11-16 16:41:30 +01001990
1991 bool WaitBitrateChanged(bool non_zero) {
1992 do {
1993 rtc::Optional<int> bitrate_kbps;
1994 {
1995 rtc::CritScope lock(&crit_);
1996 bitrate_kbps = bitrate_kbps_;
1997 }
1998 if (!bitrate_kbps)
1999 continue;
2000
2001 if ((non_zero && *bitrate_kbps > 0) ||
2002 (!non_zero && *bitrate_kbps == 0)) {
2003 return true;
2004 }
2005 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2006 return false;
perkj57c21f92016-06-17 07:27:16 -07002007 }
2008
2009 private:
2010 rtc::CriticalSection crit_;
2011 rtc::Event encoder_init_;
2012 rtc::Event bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002013 rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07002014 };
2015
perkj57c21f92016-06-17 07:27:16 -07002016 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002017 StartStopBitrateObserver encoder;
perkj57c21f92016-06-17 07:27:16 -07002018
eladalon413ee9a2017-08-22 04:02:52 -07002019 task_queue_.SendTask([this, &transport, &encoder]() {
2020 CreateSenderCall(Call::Config(event_log_.get()));
2021 CreateSendConfig(1, 0, 0, &transport);
2022
2023 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2024
2025 video_send_config_.encoder_settings.encoder = &encoder;
2026 video_send_config_.encoder_settings.internal_source = true;
2027
2028 CreateVideoStreams();
2029 });
perkj57c21f92016-06-17 07:27:16 -07002030
2031 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002032
eladalon413ee9a2017-08-22 04:02:52 -07002033 task_queue_.SendTask([this]() {
2034 video_send_stream_->Start();
2035 });
Erik Språng08127a92016-11-16 16:41:30 +01002036 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2037
eladalon413ee9a2017-08-22 04:02:52 -07002038 task_queue_.SendTask([this]() {
2039 video_send_stream_->Stop();
2040 });
Erik Språng08127a92016-11-16 16:41:30 +01002041 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2042
eladalon413ee9a2017-08-22 04:02:52 -07002043 task_queue_.SendTask([this]() {
2044 video_send_stream_->Start();
2045 });
Erik Språng08127a92016-11-16 16:41:30 +01002046 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002047
eladalon413ee9a2017-08-22 04:02:52 -07002048 task_queue_.SendTask([this]() {
2049 DestroyStreams();
2050 DestroyCalls();
2051 });
perkj57c21f92016-06-17 07:27:16 -07002052}
2053
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002054TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002055 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002056 public:
Peter Boström5811a392015-12-10 13:02:50 +01002057 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002058
nissed30a1112016-04-18 05:15:22 -07002059 void OnFrame(const VideoFrame& video_frame) override {
2060 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002061 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002062 }
2063
2064 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002065 const int kWaitFrameTimeoutMs = 3000;
2066 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002067 << "Timeout while waiting for output frames.";
2068 }
2069
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002070 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002071 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002072 }
2073
2074 private:
2075 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002076 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002077
2078 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002079 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002080 };
2081
solenberg4fbae2b2015-08-28 04:07:10 -07002082 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002083 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002084 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002085
eladalon413ee9a2017-08-22 04:02:52 -07002086 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2087 // Initialize send stream.
2088 CreateSenderCall(Call::Config(event_log_.get()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002089
eladalon413ee9a2017-08-22 04:02:52 -07002090 CreateSendConfig(1, 0, 0, &transport);
2091 video_send_config_.pre_encode_callback = &observer;
2092 CreateVideoStreams();
2093
2094 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2095 // alternatively.
2096 int width = 168;
2097 int height = 132;
2098
2099 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2100 width, height, 1, 1, kVideoRotation_0));
2101 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2102 width, height, 2, 2, kVideoRotation_0));
2103 input_frames.push_back(CreateVideoFrame(width, height, 3));
2104 input_frames.push_back(CreateVideoFrame(width, height, 4));
2105 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2106 width, height, 5, 5, kVideoRotation_0));
2107
2108 video_send_stream_->Start();
2109 test::FrameForwarder forwarder;
2110 video_send_stream_->SetSource(
2111 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
2112 for (size_t i = 0; i < input_frames.size(); i++) {
2113 forwarder.IncomingCapturedFrame(input_frames[i]);
2114 // Wait until the output frame is received before sending the next input
2115 // frame. Or the previous input frame may be replaced without delivering.
2116 observer.WaitOutputFrame();
2117 }
2118 video_send_stream_->Stop();
2119 video_send_stream_->SetSource(
2120 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
2121 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002122
2123 // Test if the input and output frames are the same. render_time_ms and
2124 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002125 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002126
eladalon413ee9a2017-08-22 04:02:52 -07002127 task_queue_.SendTask([this]() {
2128 DestroyStreams();
2129 DestroyCalls();
2130 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002131}
2132
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002133void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2134 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002135 EXPECT_EQ(frames1.size(), frames2.size());
2136 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002137 // Compare frame buffers, since we don't care about differing timestamps.
2138 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2139 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002140}
2141
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002142VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002143 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002144 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002145 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002146 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002147 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002148 // Use data as a ms timestamp.
2149 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002150 return frame;
2151}
2152
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002153TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2154 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2155 public:
eladalon413ee9a2017-08-22 04:02:52 -07002156 explicit EncoderStateObserver(
2157 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002158 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002159 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002160 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002161 initialized_(false),
2162 callback_registered_(false),
2163 num_releases_(0),
2164 released_(false) {}
2165
2166 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002167 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002168 return released_;
2169 }
2170
2171 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002172 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002173 return initialized_ && callback_registered_;
2174 }
2175
2176 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002177 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002178 return num_releases_;
2179 }
2180
2181 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002182 int32_t InitEncode(const VideoCodec* codecSettings,
2183 int32_t numberOfCores,
2184 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002185 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002186 EXPECT_FALSE(initialized_);
2187 initialized_ = true;
2188 released_ = false;
2189 return 0;
2190 }
2191
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002192 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002193 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002194 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002195 EXPECT_TRUE(IsReadyForEncode());
2196
Peter Boström5811a392015-12-10 13:02:50 +01002197 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002198 return 0;
2199 }
2200
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002201 int32_t RegisterEncodeCompleteCallback(
2202 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002203 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002204 EXPECT_TRUE(initialized_);
2205 callback_registered_ = true;
2206 return 0;
2207 }
2208
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002209 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002210 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002211 EXPECT_TRUE(IsReadyForEncode());
2212 EXPECT_FALSE(released_);
2213 initialized_ = false;
2214 callback_registered_ = false;
2215 released_ = true;
2216 ++num_releases_;
2217 return 0;
2218 }
2219
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002220 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002221 EXPECT_TRUE(IsReadyForEncode());
2222 return 0;
2223 }
2224
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002225 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002226 EXPECT_TRUE(IsReadyForEncode());
2227 return 0;
2228 }
2229
stefanff483612015-12-21 03:14:00 -08002230 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002231 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002232 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002233 stream_ = send_stream;
2234 }
2235
stefanff483612015-12-21 03:14:00 -08002236 void ModifyVideoConfigs(
2237 VideoSendStream::Config* send_config,
2238 std::vector<VideoReceiveStream::Config>* receive_configs,
2239 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002240 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002241 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002242 }
2243
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002244 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002245 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002246
2247 task_queue_->SendTask([this]() {
2248 EXPECT_EQ(0u, num_releases());
2249 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2250 EXPECT_EQ(0u, num_releases());
2251 stream_->Stop();
2252 // Encoder should not be released before destroying the VideoSendStream.
2253 EXPECT_FALSE(IsReleased());
2254 EXPECT_TRUE(IsReadyForEncode());
2255 stream_->Start();
2256 });
2257
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002258 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002259 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002260 }
2261
eladalon413ee9a2017-08-22 04:02:52 -07002262 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002263 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002264 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002265 bool initialized_ RTC_GUARDED_BY(crit_);
2266 bool callback_registered_ RTC_GUARDED_BY(crit_);
2267 size_t num_releases_ RTC_GUARDED_BY(crit_);
2268 bool released_ RTC_GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002269 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002270 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002271
stefane74eef12016-01-08 06:47:13 -08002272 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002273
2274 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002275 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002276}
2277
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002278TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2279 class VideoCodecConfigObserver : public test::SendTest,
2280 public test::FakeEncoder {
2281 public:
2282 VideoCodecConfigObserver()
2283 : SendTest(kDefaultTimeoutMs),
2284 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002285 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002286 num_initializations_(0),
2287 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002288
2289 private:
stefanff483612015-12-21 03:14:00 -08002290 void ModifyVideoConfigs(
2291 VideoSendStream::Config* send_config,
2292 std::vector<VideoReceiveStream::Config>* receive_configs,
2293 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002294 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002295 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002296 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002297 }
2298
stefanff483612015-12-21 03:14:00 -08002299 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002300 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002301 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002302 stream_ = send_stream;
2303 }
2304
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002305 int32_t InitEncode(const VideoCodec* config,
2306 int32_t number_of_cores,
2307 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002308 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002309 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002310 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002311 } else {
2312 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002313 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002314 }
2315 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002316 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002317 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2318 }
2319
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002320 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002321 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002322 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002323
sprangf24a0642017-02-28 13:23:26 -08002324 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002325 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002326 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002327 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002328 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2329 "new encoder settings.";
2330 }
2331
sprangf24a0642017-02-28 13:23:26 -08002332 const uint32_t kFirstMaxBitrateBps = 1000000;
2333 const uint32_t kSecondMaxBitrateBps = 2000000;
2334
pbos14fe7082016-04-20 06:35:56 -07002335 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002336 size_t num_initializations_;
2337 VideoSendStream* stream_;
2338 VideoEncoderConfig encoder_config_;
2339 } test;
2340
stefane74eef12016-01-08 06:47:13 -08002341 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002342}
2343
Peter Boström53eda3d2015-03-27 15:53:18 +01002344static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2345template <typename T>
2346class VideoCodecConfigObserver : public test::SendTest,
2347 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002348 public:
2349 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2350 const char* codec_name)
2351 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2352 FakeEncoder(Clock::GetRealTimeClock()),
2353 video_codec_type_(video_codec_type),
2354 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002355 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002356 num_initializations_(0),
2357 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002358 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2359 }
2360
2361 private:
perkjfa10b552016-10-02 23:45:26 -07002362 class VideoStreamFactory
2363 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2364 public:
2365 VideoStreamFactory() {}
2366
2367 private:
2368 std::vector<VideoStream> CreateEncoderStreams(
2369 int width,
2370 int height,
2371 const VideoEncoderConfig& encoder_config) override {
2372 std::vector<VideoStream> streams =
2373 test::CreateVideoStreams(width, height, encoder_config);
2374 for (size_t i = 0; i < streams.size(); ++i) {
2375 streams[i].temporal_layer_thresholds_bps.resize(
2376 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2377 }
2378 return streams;
2379 }
2380 };
2381
stefanff483612015-12-21 03:14:00 -08002382 void ModifyVideoConfigs(
2383 VideoSendStream::Config* send_config,
2384 std::vector<VideoReceiveStream::Config>* receive_configs,
2385 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002386 send_config->encoder_settings.encoder = this;
2387 send_config->encoder_settings.payload_name = codec_name_;
2388
kthelgason29a44e32016-09-27 03:52:02 -07002389 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002390 encoder_config->video_stream_factory =
2391 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002392 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002393 }
2394
stefanff483612015-12-21 03:14:00 -08002395 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002396 VideoSendStream* send_stream,
2397 const std::vector<VideoReceiveStream*>& receive_streams) override {
2398 stream_ = send_stream;
2399 }
2400
2401 int32_t InitEncode(const VideoCodec* config,
2402 int32_t number_of_cores,
2403 size_t max_payload_size) override {
2404 EXPECT_EQ(video_codec_type_, config->codecType);
2405 VerifyCodecSpecifics(*config);
2406 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002407 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002408 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2409 }
2410
2411 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002412 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2413 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002414
2415 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002416 EXPECT_TRUE(
2417 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002418 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002419
2420 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002421 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002422 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002423 ASSERT_TRUE(
2424 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002425 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002426 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2427 "new encoder settings.";
2428 }
2429
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002430 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002431 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002432 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002433 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2434 return 0;
2435 }
2436
2437 T encoder_settings_;
2438 const VideoCodecType video_codec_type_;
2439 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002440 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002441 size_t num_initializations_;
2442 VideoSendStream* stream_;
2443 VideoEncoderConfig encoder_config_;
2444};
2445
2446template <>
2447void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2448 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002449 EXPECT_EQ(
2450 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002451}
kthelgason29a44e32016-09-27 03:52:02 -07002452
2453template <>
2454rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2455VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2456 return new rtc::RefCountedObject<
2457 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2458}
2459
Peter Boström53eda3d2015-03-27 15:53:18 +01002460template <>
2461void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2462 const VideoCodec& config) const {
2463 // Check that the number of temporal layers has propagated properly to
2464 // VideoCodec.
2465 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002466 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002467
2468 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2469 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2470 config.simulcastStream[i].numberOfTemporalLayers);
2471 }
2472
2473 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002474 // reconfiguring the encoder and not match the set config. Also copy the
mflodmancc3d4422017-08-03 08:27:51 -07002475 // TemporalLayersFactory pointer that has been injected by VideoStreamEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002476 VideoCodecVP8 encoder_settings = encoder_settings_;
2477 encoder_settings.numberOfTemporalLayers =
2478 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002479 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002480 EXPECT_EQ(
2481 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002482}
kthelgason29a44e32016-09-27 03:52:02 -07002483
2484template <>
2485rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2486VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2487 return new rtc::RefCountedObject<
2488 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2489}
2490
Peter Boström53eda3d2015-03-27 15:53:18 +01002491template <>
2492void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2493 const VideoCodec& config) const {
2494 // Check that the number of temporal layers has propagated properly to
2495 // VideoCodec.
2496 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002497 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002498
2499 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2500 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2501 config.simulcastStream[i].numberOfTemporalLayers);
2502 }
2503
2504 // Set expected temporal layers as they should have been set when
2505 // reconfiguring the encoder and not match the set config.
2506 VideoCodecVP9 encoder_settings = encoder_settings_;
2507 encoder_settings.numberOfTemporalLayers =
2508 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002509 EXPECT_EQ(
2510 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002511}
2512
kthelgason29a44e32016-09-27 03:52:02 -07002513template <>
2514rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2515VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2516 return new rtc::RefCountedObject<
2517 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2518}
2519
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002520TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002521 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002522 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002523}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002524
Peter Boström53eda3d2015-03-27 15:53:18 +01002525TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2526 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002527 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002528}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002529
Peter Boström53eda3d2015-03-27 15:53:18 +01002530TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2531 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002532 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002533}
2534
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002535TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002536 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002537 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002538 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2539 rtp_packets_sent_(0),
2540 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002541
2542 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002543 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002544 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002545 RTPHeader header;
2546 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002547 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002548 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2549 return SEND_PACKET;
2550 }
2551
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002552 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002553 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002554 test::RtcpPacketParser parser;
2555 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002556
danilchap3dc929e2016-11-02 08:21:59 -07002557 if (parser.sender_report()->num_packets() > 0) {
2558 // Only compare sent media bytes if SenderPacketCount matches the
2559 // number of sent rtp packets (a new rtp packet could be sent before
2560 // the rtcp packet).
2561 if (parser.sender_report()->sender_octet_count() > 0 &&
2562 parser.sender_report()->sender_packet_count() ==
2563 rtp_packets_sent_) {
2564 EXPECT_EQ(media_bytes_sent_,
2565 parser.sender_report()->sender_octet_count());
2566 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002567 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002568 }
2569
2570 return SEND_PACKET;
2571 }
2572
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002573 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002574 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002575 }
2576
stefan4b569042015-11-11 06:39:57 -08002577 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002578 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2579 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002580 } test;
2581
stefane74eef12016-01-08 06:47:13 -08002582 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002583}
2584
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002585TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2586 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002587
2588 class VideoStreamFactory
2589 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2590 public:
2591 VideoStreamFactory() {}
2592
2593 private:
2594 std::vector<VideoStream> CreateEncoderStreams(
2595 int width,
2596 int height,
2597 const VideoEncoderConfig& encoder_config) override {
2598 std::vector<VideoStream> streams =
2599 test::CreateVideoStreams(width, height, encoder_config);
2600 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2601 streams[0].temporal_layer_thresholds_bps.push_back(
2602 kScreencastTargetBitrateKbps * 1000);
2603 return streams;
2604 }
2605 };
2606
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002607 class ScreencastTargetBitrateTest : public test::SendTest,
2608 public test::FakeEncoder {
2609 public:
2610 ScreencastTargetBitrateTest()
2611 : SendTest(kDefaultTimeoutMs),
2612 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2613
2614 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002615 int32_t InitEncode(const VideoCodec* config,
2616 int32_t number_of_cores,
2617 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002618 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2619 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002620 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002621 return test::FakeEncoder::InitEncode(
2622 config, number_of_cores, max_payload_size);
2623 }
stefanff483612015-12-21 03:14:00 -08002624 void ModifyVideoConfigs(
2625 VideoSendStream::Config* send_config,
2626 std::vector<VideoReceiveStream::Config>* receive_configs,
2627 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002628 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002629 EXPECT_EQ(1u, encoder_config->number_of_streams);
2630 encoder_config->video_stream_factory =
2631 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002632 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002633 }
2634
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002635 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002636 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002637 << "Timed out while waiting for the encoder to be initialized.";
2638 }
2639 } test;
2640
stefane74eef12016-01-08 06:47:13 -08002641 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002642}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002643
philipelc6957c72016-04-28 15:52:49 +02002644TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002645 // These are chosen to be "kind of odd" to not be accidentally checked against
2646 // default values.
2647 static const int kMinBitrateKbps = 137;
2648 static const int kStartBitrateKbps = 345;
2649 static const int kLowerMaxBitrateKbps = 312;
2650 static const int kMaxBitrateKbps = 413;
2651 static const int kIncreasedStartBitrateKbps = 451;
2652 static const int kIncreasedMaxBitrateKbps = 597;
2653 class EncoderBitrateThresholdObserver : public test::SendTest,
2654 public test::FakeEncoder {
2655 public:
eladalon413ee9a2017-08-22 04:02:52 -07002656 explicit EncoderBitrateThresholdObserver(
2657 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002658 : SendTest(kDefaultTimeoutMs),
2659 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002660 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002661 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002662 bitrate_changed_event_(false, false),
2663 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002664 num_initializations_(0),
2665 call_(nullptr),
2666 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002667
2668 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002669 int32_t InitEncode(const VideoCodec* codecSettings,
2670 int32_t numberOfCores,
2671 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002672 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2673 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002674 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002675 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2676 codecSettings->minBitrate);
2677 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2678 codecSettings->startBitrate);
2679 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2680 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002681 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002682 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002683 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2684 codecSettings->maxBitrate);
2685 // The start bitrate should be kept (-1) and capped to the max bitrate.
2686 // Since this is not an end-to-end call no receiver should have been
2687 // returning a REMB that could lower this estimate.
2688 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002689 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002690 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2691 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002692 // The start bitrate will be whatever the rate BitRateController
2693 // has currently configured but in the span of the set max and min
2694 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002695 }
2696 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002697 init_encode_event_.Set();
2698
pbos@webrtc.org00873182014-11-25 14:03:34 +00002699 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2700 maxPayloadSize);
2701 }
2702
Erik Språng08127a92016-11-16 16:41:30 +01002703 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2704 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002705 {
2706 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002707 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2708 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002709 }
Erik Språng08127a92016-11-16 16:41:30 +01002710 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002711 }
2712 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002713 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002714 }
2715
2716 void WaitForSetRates(uint32_t expected_bitrate) {
2717 EXPECT_TRUE(
2718 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2719 << "Timed out while waiting encoder rate to be set.";
2720 rtc::CritScope lock(&crit_);
2721 EXPECT_EQ(expected_bitrate, target_bitrate_);
2722 }
2723
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002724 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002725 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002726 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2727 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2728 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002729 return config;
2730 }
2731
perkjfa10b552016-10-02 23:45:26 -07002732 class VideoStreamFactory
2733 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2734 public:
2735 explicit VideoStreamFactory(int min_bitrate_bps)
2736 : min_bitrate_bps_(min_bitrate_bps) {}
2737
2738 private:
2739 std::vector<VideoStream> CreateEncoderStreams(
2740 int width,
2741 int height,
2742 const VideoEncoderConfig& encoder_config) override {
2743 std::vector<VideoStream> streams =
2744 test::CreateVideoStreams(width, height, encoder_config);
2745 streams[0].min_bitrate_bps = min_bitrate_bps_;
2746 return streams;
2747 }
2748
2749 const int min_bitrate_bps_;
2750 };
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.org00873182014-11-25 14:03:34 +00002756 send_config->encoder_settings.encoder = this;
2757 // Set bitrates lower/higher than min/max to make sure they are properly
2758 // capped.
perkjfa10b552016-10-02 23:45:26 -07002759 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2760 // Create a new StreamFactory to be able to set
2761 // |VideoStream.min_bitrate_bps|.
2762 encoder_config->video_stream_factory =
2763 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002764 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002765 }
2766
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002767 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002768 call_ = sender_call;
2769 }
2770
stefanff483612015-12-21 03:14:00 -08002771 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002772 VideoSendStream* send_stream,
2773 const std::vector<VideoReceiveStream*>& receive_streams) override {
2774 send_stream_ = send_stream;
2775 }
2776
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002777 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002778 ASSERT_TRUE(
2779 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002780 << "Timed out while waiting for encoder to be configured.";
2781 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002782 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002783 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2784 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002785 task_queue_->SendTask([this, &bitrate_config]() {
2786 call_->SetBitrateConfig(bitrate_config);
2787 });
perkj26091b12016-09-01 01:17:40 -07002788 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2789 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002790 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002791 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002792 ASSERT_TRUE(
2793 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002794 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002795 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002796 WaitForSetRates(kLowerMaxBitrateKbps);
2797
2798 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2799 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2800 ASSERT_TRUE(
2801 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002802 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002803 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002804 // Expected target bitrate is the start bitrate set in the call to
2805 // call_->SetBitrateConfig.
2806 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002807 }
2808
eladalon413ee9a2017-08-22 04:02:52 -07002809 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002810 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002811 rtc::Event bitrate_changed_event_;
2812 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002813 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002814
pbos@webrtc.org00873182014-11-25 14:03:34 +00002815 int num_initializations_;
2816 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002817 webrtc::VideoSendStream* send_stream_;
2818 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002819 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002820
stefane74eef12016-01-08 06:47:13 -08002821 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002822}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002823
2824TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2825 static const size_t kNumStreams = 3;
2826 // Unusual resolutions to make sure that they are the ones being reported.
2827 static const struct {
2828 int width;
2829 int height;
2830 } kEncodedResolution[kNumStreams] = {
2831 {241, 181}, {300, 121}, {121, 221}};
2832 class ScreencastTargetBitrateTest : public test::SendTest,
2833 public test::FakeEncoder {
2834 public:
2835 ScreencastTargetBitrateTest()
2836 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002837 test::FakeEncoder(Clock::GetRealTimeClock()),
2838 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002839
2840 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002841 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002842 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002843 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002844 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002845 specifics.codecType = kVideoCodecGeneric;
2846
2847 uint8_t buffer[16] = {0};
2848 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2849 encoded._timeStamp = input_image.timestamp();
2850 encoded.capture_time_ms_ = input_image.render_time_ms();
2851
2852 for (size_t i = 0; i < kNumStreams; ++i) {
2853 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2854 encoded._frameType = (*frame_types)[i];
2855 encoded._encodedWidth = kEncodedResolution[i].width;
2856 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002857 EncodedImageCallback* callback;
2858 {
2859 rtc::CritScope cs(&crit_sect_);
2860 callback = callback_;
2861 }
2862 RTC_DCHECK(callback);
2863 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002864 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002865 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002866 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002867 }
2868
Peter Boström5811a392015-12-10 13:02:50 +01002869 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002870 return 0;
2871 }
stefanff483612015-12-21 03:14:00 -08002872 void ModifyVideoConfigs(
2873 VideoSendStream::Config* send_config,
2874 std::vector<VideoReceiveStream::Config>* receive_configs,
2875 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002876 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002877 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002878 }
2879
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002880 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002881
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002882 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002883 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002884 << "Timed out while waiting for the encoder to send one frame.";
2885 VideoSendStream::Stats stats = send_stream_->GetStats();
2886
2887 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002888 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002889 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002890 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002891 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002892 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002893 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002894 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2895 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002896 }
2897 }
2898
stefanff483612015-12-21 03:14:00 -08002899 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002900 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002901 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002902 send_stream_ = send_stream;
2903 }
2904
2905 VideoSendStream* send_stream_;
2906 } test;
2907
stefane74eef12016-01-08 06:47:13 -08002908 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002909}
philipel0f9af012015-09-01 07:01:51 -07002910
Peter Boström12996152016-05-14 02:03:18 +02002911#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002912class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002913 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002914 Vp9HeaderObserver()
2915 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002916 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002917 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2918 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002919 frames_sent_(0),
2920 expected_width_(0),
2921 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002922
stefanff483612015-12-21 03:14:00 -08002923 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002924 VideoSendStream::Config* send_config,
2925 std::vector<VideoReceiveStream::Config>* receive_configs,
2926 VideoEncoderConfig* encoder_config) {}
2927
Åsa Perssonff24c042015-12-04 10:58:08 +01002928 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002929
2930 private:
minyue20c84cc2017-04-10 16:57:57 -07002931 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002932
perkjfa10b552016-10-02 23:45:26 -07002933 class VideoStreamFactory
2934 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2935 public:
2936 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2937 : number_of_temporal_layers_(number_of_temporal_layers) {}
2938
2939 private:
2940 std::vector<VideoStream> CreateEncoderStreams(
2941 int width,
2942 int height,
2943 const VideoEncoderConfig& encoder_config) override {
2944 std::vector<VideoStream> streams =
2945 test::CreateVideoStreams(width, height, encoder_config);
2946 streams[0].temporal_layer_thresholds_bps.resize(
2947 number_of_temporal_layers_ - 1);
2948 return streams;
2949 }
2950
2951 const size_t number_of_temporal_layers_;
2952 };
2953
stefanff483612015-12-21 03:14:00 -08002954 void ModifyVideoConfigs(
2955 VideoSendStream::Config* send_config,
2956 std::vector<VideoReceiveStream::Config>* receive_configs,
2957 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002958 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002959 send_config->encoder_settings.payload_name = "VP9";
2960 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002961 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002962 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2963 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002964 EXPECT_EQ(1u, encoder_config->number_of_streams);
2965 encoder_config->video_stream_factory =
2966 new rtc::RefCountedObject<VideoStreamFactory>(
2967 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002968 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002969 }
2970
perkjfa10b552016-10-02 23:45:26 -07002971 void ModifyVideoCaptureStartResolution(int* width,
2972 int* height,
2973 int* frame_rate) override {
2974 expected_width_ = *width;
2975 expected_height_ = *height;
2976 }
2977
philipel0f9af012015-09-01 07:01:51 -07002978 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002979 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2980 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002981 }
2982
2983 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2984 RTPHeader header;
2985 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2986
Åsa Perssonff24c042015-12-04 10:58:08 +01002987 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2988 const uint8_t* payload = packet + header.headerLength;
2989 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002990
Åsa Perssonff24c042015-12-04 10:58:08 +01002991 bool new_packet = packets_sent_ == 0 ||
2992 IsNewerSequenceNumber(header.sequenceNumber,
2993 last_header_.sequenceNumber);
2994 if (payload_length > 0 && new_packet) {
2995 RtpDepacketizer::ParsedPayload parsed;
2996 RtpDepacketizerVp9 depacketizer;
2997 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2998 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2999 // Verify common fields for all configurations.
3000 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
3001 CompareConsecutiveFrames(header, parsed.type.Video);
3002 // Verify configuration specific settings.
3003 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07003004
Åsa Perssonff24c042015-12-04 10:58:08 +01003005 ++packets_sent_;
3006 if (header.markerBit) {
3007 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003008 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003009 last_header_ = header;
3010 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07003011 }
philipel0f9af012015-09-01 07:01:51 -07003012 return SEND_PACKET;
3013 }
3014
philipel7fabd462015-09-03 04:42:32 -07003015 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003016 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3017 if (last_vp9_.picture_id > vp9.picture_id) {
3018 return vp9.picture_id == 0; // Wrap.
3019 } else {
3020 return vp9.picture_id == last_vp9_.picture_id + 1;
3021 }
3022 }
3023
3024 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003025 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3026 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3027 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3028 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3029 vp9.spatial_idx);
3030 }
3031
3032 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3033 uint8_t num_layers) const {
3034 switch (num_layers) {
3035 case 0:
3036 VerifyTemporalLayerStructure0(vp9);
3037 break;
3038 case 1:
3039 VerifyTemporalLayerStructure1(vp9);
3040 break;
3041 case 2:
3042 VerifyTemporalLayerStructure2(vp9);
3043 break;
3044 case 3:
3045 VerifyTemporalLayerStructure3(vp9);
3046 break;
3047 default:
3048 RTC_NOTREACHED();
3049 }
3050 }
3051
3052 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3053 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3054 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3055 EXPECT_FALSE(vp9.temporal_up_switch);
3056 }
3057
3058 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3059 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3060 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3061 EXPECT_FALSE(vp9.temporal_up_switch);
3062 }
3063
3064 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3065 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3066 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3067 EXPECT_LE(vp9.temporal_idx, 1);
3068 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3069 if (IsNewPictureId(vp9)) {
3070 uint8_t expected_tid =
3071 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3072 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3073 }
3074 }
3075
3076 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3077 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3078 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3079 EXPECT_LE(vp9.temporal_idx, 2);
3080 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3081 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3082 switch (vp9.temporal_idx) {
3083 case 0:
3084 EXPECT_EQ(2, last_vp9_.temporal_idx);
3085 EXPECT_FALSE(vp9.temporal_up_switch);
3086 break;
3087 case 1:
3088 EXPECT_EQ(2, last_vp9_.temporal_idx);
3089 EXPECT_TRUE(vp9.temporal_up_switch);
3090 break;
3091 case 2:
3092 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3093 break;
3094 }
3095 }
3096 }
3097
3098 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3099 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3100 return;
3101
3102 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3103 if (vp9.temporal_idx == 0)
3104 ++expected_tl0_idx;
3105 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3106 }
3107
3108 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3109 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3110 }
3111
3112 // Flexible mode (F=1): Non-flexible mode (F=0):
3113 //
3114 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3115 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3116 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3117 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3118 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3119 // M: | EXTENDED PID | M: | EXTENDED PID |
3120 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3121 // L: | T |U| S |D| L: | T |U| S |D|
3122 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3123 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3124 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3125 // X: |EXTENDED P_DIFF| V: | SS .. |
3126 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3127 // V: | SS .. |
3128 // +-+-+-+-+-+-+-+-+
3129 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3130 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3131 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3132 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003133
3134 if (vp9_settings_.numberOfSpatialLayers > 1) {
3135 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3136 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3137 EXPECT_EQ(vp9.spatial_idx, 0);
3138 } else {
3139 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3140 }
3141
3142 if (vp9_settings_.numberOfTemporalLayers > 1) {
3143 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3144 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3145 EXPECT_EQ(vp9.temporal_idx, 0);
3146 } else {
3147 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3148 }
3149
Åsa Perssonff24c042015-12-04 10:58:08 +01003150 if (vp9.ss_data_available) // V
3151 VerifySsData(vp9);
3152
3153 if (frames_sent_ == 0)
3154 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3155
3156 if (!vp9.inter_pic_predicted) {
3157 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3158 EXPECT_FALSE(vp9.temporal_up_switch);
3159 }
3160 }
3161
3162 // Scalability structure (SS).
3163 //
3164 // +-+-+-+-+-+-+-+-+
3165 // V: | N_S |Y|G|-|-|-|
3166 // +-+-+-+-+-+-+-+-+
3167 // Y: | WIDTH | N_S + 1 times
3168 // +-+-+-+-+-+-+-+-+
3169 // | HEIGHT |
3170 // +-+-+-+-+-+-+-+-+
3171 // G: | N_G |
3172 // +-+-+-+-+-+-+-+-+
3173 // N_G: | T |U| R |-|-| N_G times
3174 // +-+-+-+-+-+-+-+-+
3175 // | P_DIFF | R times
3176 // +-+-+-+-+-+-+-+-+
3177 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3178 EXPECT_TRUE(vp9.ss_data_available); // V
3179 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3180 vp9.num_spatial_layers);
3181 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003182 int expected_width = expected_width_;
3183 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003184 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003185 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3186 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3187 expected_width /= 2;
3188 expected_height /= 2;
3189 }
3190 }
3191
3192 void CompareConsecutiveFrames(const RTPHeader& header,
3193 const RTPVideoHeader& video) const {
3194 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3195
3196 bool new_frame = packets_sent_ == 0 ||
3197 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003198 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003199 if (!new_frame) {
3200 EXPECT_FALSE(last_header_.markerBit);
3201 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3202 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3203 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3204 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3205 VerifySpatialIdxWithinFrame(vp9);
3206 return;
3207 }
3208 // New frame.
3209 EXPECT_TRUE(vp9.beginning_of_frame);
3210
3211 // Compare with last packet in previous frame.
3212 if (frames_sent_ == 0)
3213 return;
3214 EXPECT_TRUE(last_vp9_.end_of_frame);
3215 EXPECT_TRUE(last_header_.markerBit);
3216 EXPECT_TRUE(ContinuousPictureId(vp9));
3217 VerifyTl0Idx(vp9);
3218 }
3219
kwiberg27f982b2016-03-01 11:52:33 -08003220 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003221 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003222 webrtc::VideoEncoderConfig encoder_config_;
3223 RTPHeader last_header_;
3224 RTPVideoHeaderVP9 last_vp9_;
3225 size_t packets_sent_;
3226 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003227 int expected_width_;
3228 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003229};
3230
Åsa Perssonff24c042015-12-04 10:58:08 +01003231TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3232 const uint8_t kNumTemporalLayers = 1;
3233 const uint8_t kNumSpatialLayers = 1;
3234 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3235}
3236
3237TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3238 const uint8_t kNumTemporalLayers = 2;
3239 const uint8_t kNumSpatialLayers = 1;
3240 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3241}
3242
3243TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3244 const uint8_t kNumTemporalLayers = 3;
3245 const uint8_t kNumSpatialLayers = 1;
3246 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3247}
3248
3249TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3250 const uint8_t kNumTemporalLayers = 1;
3251 const uint8_t kNumSpatialLayers = 2;
3252 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3253}
3254
3255TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3256 const uint8_t kNumTemporalLayers = 2;
3257 const uint8_t kNumSpatialLayers = 2;
3258 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3259}
3260
3261TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3262 const uint8_t kNumTemporalLayers = 3;
3263 const uint8_t kNumSpatialLayers = 2;
3264 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3265}
3266
3267void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3268 uint8_t num_spatial_layers) {
3269 static const size_t kNumFramesToSend = 100;
3270 // Set to < kNumFramesToSend and coprime to length of temporal layer
3271 // structures to verify temporal id reset on key frame.
3272 static const int kKeyFrameInterval = 31;
3273 class NonFlexibleMode : public Vp9HeaderObserver {
3274 public:
3275 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3276 : num_temporal_layers_(num_temporal_layers),
3277 num_spatial_layers_(num_spatial_layers),
3278 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003279 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003280 VideoSendStream::Config* send_config,
3281 std::vector<VideoReceiveStream::Config>* receive_configs,
3282 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003283 vp9_settings_.flexibleMode = false;
3284 vp9_settings_.frameDroppingOn = false;
3285 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3286 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3287 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003288 }
3289
Åsa Perssonff24c042015-12-04 10:58:08 +01003290 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003291 bool ss_data_expected =
3292 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3293 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003294 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003295 if (num_spatial_layers_ > 1) {
3296 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3297 } else {
3298 EXPECT_FALSE(vp9.inter_layer_predicted);
3299 }
3300
asapersson38bb8ad2015-12-14 01:41:19 -08003301 EXPECT_EQ(!vp9.inter_pic_predicted,
3302 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003303
3304 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003305 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3306 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3307 } else {
3308 EXPECT_EQ(0, vp9.spatial_idx);
3309 }
3310 if (num_spatial_layers_ > 1)
3311 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003312 }
3313
3314 VerifyFixedTemporalLayerStructure(vp9,
3315 l_field_ ? num_temporal_layers_ : 0);
3316
3317 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003318 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003319 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003320 const uint8_t num_temporal_layers_;
3321 const uint8_t num_spatial_layers_;
3322 const bool l_field_;
3323 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003324
stefane74eef12016-01-08 06:47:13 -08003325 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003326}
3327
asaperssond9f641e2016-01-21 01:11:35 -08003328TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3329 static const size_t kNumFramesToSend = 50;
3330 static const int kWidth = 4;
3331 static const int kHeight = 4;
3332 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3333 void ModifyVideoConfigsHook(
3334 VideoSendStream::Config* send_config,
3335 std::vector<VideoReceiveStream::Config>* receive_configs,
3336 VideoEncoderConfig* encoder_config) override {
3337 vp9_settings_.flexibleMode = false;
3338 vp9_settings_.numberOfTemporalLayers = 1;
3339 vp9_settings_.numberOfSpatialLayers = 1;
3340
perkjfa10b552016-10-02 23:45:26 -07003341 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003342 }
3343
3344 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3345 if (frames_sent_ > kNumFramesToSend)
3346 observation_complete_.Set();
3347 }
perkjfa10b552016-10-02 23:45:26 -07003348
3349 void ModifyVideoCaptureStartResolution(int* width,
3350 int* height,
3351 int* frame_rate) override {
3352 expected_width_ = kWidth;
3353 expected_height_ = kHeight;
3354 *width = kWidth;
3355 *height = kHeight;
3356 }
asaperssond9f641e2016-01-21 01:11:35 -08003357 } test;
3358
3359 RunBaseTest(&test);
3360}
3361
kjellanderf9e2a362017-03-24 12:17:33 -07003362#if defined(WEBRTC_ANDROID)
3363// Crashes on Android; bugs.webrtc.org/7401
3364#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3365#else
3366#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3367#endif
3368TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003369 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003370 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003371 VideoSendStream::Config* send_config,
3372 std::vector<VideoReceiveStream::Config>* receive_configs,
3373 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003374 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003375 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003376 vp9_settings_.numberOfTemporalLayers = 1;
3377 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003378 }
3379
Åsa Perssonff24c042015-12-04 10:58:08 +01003380 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3381 EXPECT_TRUE(vp9_header.flexible_mode);
3382 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3383 if (vp9_header.inter_pic_predicted) {
3384 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003385 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003386 }
3387 }
3388 } test;
3389
stefane74eef12016-01-08 06:47:13 -08003390 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003391}
Peter Boström12996152016-05-14 02:03:18 +02003392#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003393
perkj803d97f2016-11-01 11:45:46 -07003394void VideoSendStreamTest::TestRequestSourceRotateVideo(
3395 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003396 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003397
3398 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003399 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003400 video_send_config_.rtp.extensions.clear();
3401 if (support_orientation_ext) {
3402 video_send_config_.rtp.extensions.push_back(
3403 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3404 }
3405
3406 CreateVideoStreams();
3407 test::FrameForwarder forwarder;
3408 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003409 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003410
3411 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3412 support_orientation_ext);
3413
3414 DestroyStreams();
3415}
3416
3417TEST_F(VideoSendStreamTest,
3418 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3419 TestRequestSourceRotateVideo(false);
3420}
3421
3422TEST_F(VideoSendStreamTest,
3423 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3424 TestRequestSourceRotateVideo(true);
3425}
3426
michaelta3328772016-11-29 09:25:03 -08003427// This test verifies that overhead is removed from the bandwidth estimate by
3428// testing that the maximum possible target payload rate is smaller than the
3429// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003430TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003431 test::ScopedFieldTrials override_field_trials(
3432 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3433 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3434 public test::FakeEncoder {
3435 public:
eladalon413ee9a2017-08-22 04:02:52 -07003436 explicit RemoveOverheadFromBandwidthTest(
3437 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003438 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3439 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003440 task_queue_(task_queue),
michaelta3328772016-11-29 09:25:03 -08003441 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003442 max_bitrate_bps_(0),
3443 first_packet_sent_(false),
3444 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003445
3446 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3447 uint32_t frameRate) override {
3448 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003449 // Wait for the first sent packet so that videosendstream knows
3450 // rtp_overhead.
3451 if (first_packet_sent_) {
3452 max_bitrate_bps_ = bitrate.get_sum_bps();
3453 bitrate_changed_event_.Set();
3454 }
michaelta3328772016-11-29 09:25:03 -08003455 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3456 }
3457
3458 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3459 call_ = sender_call;
3460 }
3461
3462 void ModifyVideoConfigs(
3463 VideoSendStream::Config* send_config,
3464 std::vector<VideoReceiveStream::Config>* receive_configs,
3465 VideoEncoderConfig* encoder_config) override {
3466 send_config->rtp.max_packet_size = 1200;
3467 send_config->encoder_settings.encoder = this;
3468 EXPECT_FALSE(send_config->rtp.extensions.empty());
3469 }
3470
michaelt192132e2017-01-26 09:05:27 -08003471 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3472 rtc::CritScope lock(&crit_);
3473 first_packet_sent_ = true;
3474 return SEND_PACKET;
3475 }
3476
michaelta3328772016-11-29 09:25:03 -08003477 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003478 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003479 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003480 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003481 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003482 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3483 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003484 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003485 task_queue_->SendTask([this, &bitrate_config]() {
3486 call_->SetBitrateConfig(bitrate_config);
3487 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3488 });
michaelta3328772016-11-29 09:25:03 -08003489
3490 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003491 // overhead of 40B per packet video produces 2240bps overhead.
3492 // So the encoder BW should be set to 57760bps.
3493 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003494 {
3495 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003496 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003497 }
3498 }
3499
3500 private:
eladalon413ee9a2017-08-22 04:02:52 -07003501 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelta3328772016-11-29 09:25:03 -08003502 Call* call_;
3503 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003504 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3505 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003506 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003507 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003508 RunBaseTest(&test);
3509}
3510
sprang168794c2017-07-06 04:38:06 -07003511TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3512 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003513
3514 class KeepaliveObserver : public test::SendTest {
3515 public:
3516 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3517
sprangdb2a9fc2017-08-09 06:42:32 -07003518 void OnRtpTransportControllerSendCreated(
3519 RtpTransportControllerSend* controller) override {
3520 RtpKeepAliveConfig config;
3521 config.timeout_interval_ms = kTimeoutMs;
3522 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3523 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003524 }
3525
sprang168794c2017-07-06 04:38:06 -07003526 private:
3527 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3528 RTPHeader header;
3529 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3530
sprangd2702ef2017-07-10 08:41:10 -07003531 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003532 // The video stream has started. Stop it now.
3533 if (capturer_)
3534 capturer_->Stop();
3535 } else {
3536 observation_complete_.Set();
3537 }
3538
3539 return SEND_PACKET;
3540 }
3541
sprang168794c2017-07-06 04:38:06 -07003542 void PerformTest() override {
3543 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3544 }
3545
3546 void OnFrameGeneratorCapturerCreated(
3547 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3548 capturer_ = frame_generator_capturer;
3549 }
3550
3551 test::FrameGeneratorCapturer* capturer_ = nullptr;
3552 } test;
3553
3554 RunBaseTest(&test);
3555}
3556
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003557class PacingFactorObserver : public test::SendTest {
3558 public:
3559 PacingFactorObserver(bool configure_send_side,
3560 rtc::Optional<float> expected_pacing_factor)
3561 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3562 configure_send_side_(configure_send_side),
3563 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003564
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003565 void ModifyVideoConfigs(
3566 VideoSendStream::Config* send_config,
3567 std::vector<VideoReceiveStream::Config>* receive_configs,
3568 VideoEncoderConfig* encoder_config) override {
3569 // Check if send-side bwe extension is already present, and remove it if
3570 // it is not desired.
3571 bool has_send_side = false;
3572 for (auto it = send_config->rtp.extensions.begin();
3573 it != send_config->rtp.extensions.end(); ++it) {
3574 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3575 if (configure_send_side_) {
3576 has_send_side = true;
3577 } else {
3578 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003579 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003580 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003581 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003582 }
3583
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003584 if (configure_send_side_ && !has_send_side) {
3585 // Want send side, not present by default, so add it.
3586 send_config->rtp.extensions.emplace_back(
3587 RtpExtension::kTransportSequenceNumberUri,
3588 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003589 }
3590
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003591 // ALR only enabled for screenshare.
3592 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3593 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003594
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003595 void OnVideoStreamsCreated(
3596 VideoSendStream* send_stream,
3597 const std::vector<VideoReceiveStream*>& receive_streams) override {
3598 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3599 // Video streams created, check that pacing factor is correctly configured.
3600 EXPECT_EQ(expected_pacing_factor_,
3601 internal_send_peer.GetPacingFactorOverride());
3602 observation_complete_.Set();
3603 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003604
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003605 void PerformTest() override {
3606 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3607 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003608
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003609 private:
3610 const bool configure_send_side_;
3611 const rtc::Optional<float> expected_pacing_factor_;
3612};
3613
3614std::string GetAlrProbingExperimentString() {
3615 return std::string(
3616 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3617 "/1.0,2875,80,40,-60,3/";
3618}
3619const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3620
3621TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
3622 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003623 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003624 PacingFactorObserver test_with_send_side(true,
3625 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003626 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003627}
Erik Språng7c8cca32017-10-24 17:05:18 +02003628
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003629TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
3630 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3631 // Send-side bwe off, use configuration should not be overridden.
3632 PacingFactorObserver test_without_send_side(false, rtc::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003633 RunBaseTest(&test_without_send_side);
3634}
3635
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003636} // namespace webrtc