blob: 67758136a21bbb927cf034aecb2bcfe2ab580220 [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"
Niels Möller4db138e2018-04-19 09:04:13 +020036#include "test/encoder_proxy_factory.h"
37#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "test/fake_texture_frame.h"
39#include "test/field_trial.h"
40#include "test/frame_generator.h"
41#include "test/frame_generator_capturer.h"
42#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010043#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020044#include "test/gtest.h"
45#include "test/null_transport.h"
46#include "test/rtcp_packet_parser.h"
47#include "test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070048
Sebastian Janssona45c8da2018-01-16 10:55:29 +010049#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020050#include "video/send_statistics_proxy.h"
51#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010052#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000053
54namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010055namespace test {
56class VideoSendStreamPeer {
57 public:
58 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
59 : internal_stream_(
60 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
61 rtc::Optional<float> GetPacingFactorOverride() const {
62 return internal_stream_->GetPacingFactorOverride();
63 }
64
65 private:
66 internal::VideoSendStream const* const internal_stream_;
67};
68} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000069
sprang@webrtc.org346094c2014-02-18 08:40:33 +000070enum VideoFormat { kGeneric, kVP8, };
71
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070072void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
73 const std::vector<VideoFrame>& frames2);
74VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000075
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000076class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000077 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000078 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000079 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000080 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010081
82 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
83 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070084
85 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000086};
87
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000088TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070089 task_queue_.SendTask([this]() {
90 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000091
eladalon413ee9a2017-08-22 04:02:52 -070092 test::NullTransport transport;
93 CreateSendConfig(1, 0, 0, &transport);
94 CreateVideoStreams();
95 video_send_stream_->Start();
96 video_send_stream_->Start();
97 DestroyStreams();
98 DestroyCalls();
99 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000100}
101
102TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700103 task_queue_.SendTask([this]() {
104 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000105
eladalon413ee9a2017-08-22 04:02:52 -0700106 test::NullTransport transport;
107 CreateSendConfig(1, 0, 0, &transport);
108 CreateVideoStreams();
109 video_send_stream_->Stop();
110 video_send_stream_->Stop();
111 DestroyStreams();
112 DestroyCalls();
113 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000114}
115
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000116TEST_F(VideoSendStreamTest, SupportsCName) {
117 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000118 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000119 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000120 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000121
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000122 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000123 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700124 test::RtcpPacketParser parser;
125 EXPECT_TRUE(parser.Parse(packet, length));
126 if (parser.sdes()->num_packets() > 0) {
127 EXPECT_EQ(1u, parser.sdes()->chunks().size());
128 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000129
danilchap3dc929e2016-11-02 08:21:59 -0700130 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000131 }
132
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000133 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000134 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000135
stefanff483612015-12-21 03:14:00 -0800136 void ModifyVideoConfigs(
137 VideoSendStream::Config* send_config,
138 std::vector<VideoReceiveStream::Config>* receive_configs,
139 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000140 send_config->rtp.c_name = kCName;
141 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000142
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000143 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100144 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000145 }
146 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000147
stefane74eef12016-01-08 06:47:13 -0800148 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000149}
150
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000151TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000152 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000153 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000154 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000155 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100156 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000157 }
158
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000159 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000160 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000161 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000162
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000163 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
164 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
165 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700166 if (header.extension.absoluteSendTime != 0) {
167 // Wait for at least one packet with a non-zero send time. The send time
168 // is a 16-bit value derived from the system clock, and it is valid
169 // for a packet to have a zero send time. To tell that from an
170 // unpopulated value we'll wait for a packet with non-zero send time.
171 observation_complete_.Set();
172 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100173 RTC_LOG(LS_WARNING)
174 << "Got a packet with zero absoluteSendTime, waiting"
175 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700176 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000177
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000178 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000179 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000180
stefanff483612015-12-21 03:14:00 -0800181 void ModifyVideoConfigs(
182 VideoSendStream::Config* send_config,
183 std::vector<VideoReceiveStream::Config>* receive_configs,
184 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200185 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100186 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700187 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000188 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000189
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000190 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100191 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000192 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000193 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000194
stefane74eef12016-01-08 06:47:13 -0800195 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000196}
197
pbos@webrtc.org29023282013-09-11 10:14:56 +0000198TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000199 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000200 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000201 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000202 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200203 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
204 return rtc::MakeUnique<test::DelayedEncoder>(
205 Clock::GetRealTimeClock(), kEncodeDelayMs);
206 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000207 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100208 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000209 }
210
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000211 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000212 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000213 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000214 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000215
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000216 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
217 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000218 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000219 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100220 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000221
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000222 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000223 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000224
stefanff483612015-12-21 03:14:00 -0800225 void ModifyVideoConfigs(
226 VideoSendStream::Config* send_config,
227 std::vector<VideoReceiveStream::Config>* receive_configs,
228 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200229 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100230 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700231 send_config->rtp.extensions.push_back(RtpExtension(
232 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000233 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000234
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000235 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100236 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000237 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000238
Niels Möller4db138e2018-04-19 09:04:13 +0200239 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000240 } test;
241
stefane74eef12016-01-08 06:47:13 -0800242 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000243}
244
sprang867fb522015-08-03 04:38:41 -0700245TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700246 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700247 class TransportWideSequenceNumberObserver : public test::SendTest {
248 public:
249 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200250 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
251 return rtc::MakeUnique<test::FakeEncoder>(
252 Clock::GetRealTimeClock());
253 }) {
sprang867fb522015-08-03 04:38:41 -0700254 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
255 kRtpExtensionTransportSequenceNumber, kExtensionId));
256 }
257
258 private:
259 Action OnSendRtp(const uint8_t* packet, size_t length) override {
260 RTPHeader header;
261 EXPECT_TRUE(parser_->Parse(packet, length, &header));
262
263 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
264 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
265 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
266
Peter Boström5811a392015-12-10 13:02:50 +0100267 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700268
269 return SEND_PACKET;
270 }
271
stefanff483612015-12-21 03:14:00 -0800272 void ModifyVideoConfigs(
273 VideoSendStream::Config* send_config,
274 std::vector<VideoReceiveStream::Config>* receive_configs,
275 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200276 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700277 }
278
279 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100280 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700281 }
282
Niels Möller4db138e2018-04-19 09:04:13 +0200283 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700284 } test;
285
stefane74eef12016-01-08 06:47:13 -0800286 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700287}
288
perkj803d97f2016-11-01 11:45:46 -0700289TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
290 class VideoRotationObserver : public test::SendTest {
291 public:
292 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
293 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
294 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
295 }
296
297 Action OnSendRtp(const uint8_t* packet, size_t length) override {
298 RTPHeader header;
299 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700300 // Only the last packet of the frame is required to have the extension.
301 if (!header.markerBit)
302 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700303 EXPECT_TRUE(header.extension.hasVideoRotation);
304 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
305 observation_complete_.Set();
306 return SEND_PACKET;
307 }
308
309 void ModifyVideoConfigs(
310 VideoSendStream::Config* send_config,
311 std::vector<VideoReceiveStream::Config>* receive_configs,
312 VideoEncoderConfig* encoder_config) override {
313 send_config->rtp.extensions.clear();
314 send_config->rtp.extensions.push_back(RtpExtension(
315 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
316 }
317
318 void OnFrameGeneratorCapturerCreated(
319 test::FrameGeneratorCapturer* frame_generator_capturer) override {
320 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
321 }
322
323 void PerformTest() override {
324 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
325 }
326 } test;
327
328 RunBaseTest(&test);
329}
330
ilnik00d802b2017-04-11 10:34:31 -0700331TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700332 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700333 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100334 VideoContentTypeObserver()
335 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700336 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
337 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
338 }
339
340 Action OnSendRtp(const uint8_t* packet, size_t length) override {
341 RTPHeader header;
342 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100343 // Only the last packet of the key-frame must have extension.
344 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700345 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100346 // First marker bit seen means that the first frame is sent.
347 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700348 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700349 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
350 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700351 observation_complete_.Set();
352 return SEND_PACKET;
353 }
354
355 void ModifyVideoConfigs(
356 VideoSendStream::Config* send_config,
357 std::vector<VideoReceiveStream::Config>* receive_configs,
358 VideoEncoderConfig* encoder_config) override {
359 send_config->rtp.extensions.clear();
360 send_config->rtp.extensions.push_back(
361 RtpExtension(RtpExtension::kVideoContentTypeUri,
362 test::kVideoContentTypeExtensionId));
363 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
364 }
365
366 void PerformTest() override {
367 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
368 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100369
370 private:
371 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700372 } test;
373
374 RunBaseTest(&test);
375}
376
ilnik04f4d122017-06-19 07:18:55 -0700377TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700378 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700379 public:
ilnik10894992017-06-21 08:23:19 -0700380 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700381 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
382 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
383 }
384
385 Action OnSendRtp(const uint8_t* packet, size_t length) override {
386 RTPHeader header;
387 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700388 // Only the last packet of the frame must have extension.
389 if (!header.markerBit)
390 return SEND_PACKET;
391 EXPECT_TRUE(header.extension.has_video_timing);
392 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700393 return SEND_PACKET;
394 }
395
396 void ModifyVideoConfigs(
397 VideoSendStream::Config* send_config,
398 std::vector<VideoReceiveStream::Config>* receive_configs,
399 VideoEncoderConfig* encoder_config) override {
400 send_config->rtp.extensions.clear();
401 send_config->rtp.extensions.push_back(RtpExtension(
402 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
403 }
404
405 void PerformTest() override {
406 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
407 }
408 } test;
409
410 RunBaseTest(&test);
411}
412
danilchap901b2df2017-07-28 08:56:04 -0700413class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000414 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000415 FakeReceiveStatistics(uint32_t send_ssrc,
416 uint32_t last_sequence_number,
417 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700418 uint8_t fraction_lost) {
419 stat_.SetMediaSsrc(send_ssrc);
420 stat_.SetExtHighestSeqNum(last_sequence_number);
421 stat_.SetCumulativeLost(cumulative_lost);
422 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000423 }
424
danilchap901b2df2017-07-28 08:56:04 -0700425 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
426 EXPECT_GE(max_blocks, 1u);
427 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000428 }
429
430 private:
danilchap901b2df2017-07-28 08:56:04 -0700431 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000432};
433
brandtre602f0a2016-10-31 03:40:49 -0700434class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100435 public:
brandtre602f0a2016-10-31 03:40:49 -0700436 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800437 bool use_nack,
438 bool expect_red,
439 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800440 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200441 VideoEncoderFactory* encoder_factory)
brandtr20d45472017-01-02 00:34:27 -0800442 : EndToEndTest(kTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200443 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100444 payload_name_(codec),
445 use_nack_(use_nack),
446 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700447 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800448 sent_media_(false),
449 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800450 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100451
brandtr20d45472017-01-02 00:34:27 -0800452 // Some of the test cases are expected to time out and thus we are using
453 // a shorter timeout window than the default here.
454 static constexpr size_t kTimeoutMs = 10000;
455
Stefan Holmer4654d202015-12-08 09:10:43 +0100456 private:
457 Action OnSendRtp(const uint8_t* packet, size_t length) override {
458 RTPHeader header;
459 EXPECT_TRUE(parser_->Parse(packet, length, &header));
460
Stefan Holmer4654d202015-12-08 09:10:43 +0100461 int encapsulated_payload_type = -1;
462 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100463 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100464 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
465 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100466 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100467 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
468 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100469 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100470 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100471 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
472 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100473 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
474 length) {
475 // Not padding-only, media received outside of RED.
476 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800477 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100478 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100479 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000480
Stefan Holmer4654d202015-12-08 09:10:43 +0100481 if (header_extensions_enabled_) {
482 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
483 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
484 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
485 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
486 // 24 bits wrap.
487 EXPECT_GT(prev_header_.extension.absoluteSendTime,
488 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000489 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100490 EXPECT_GE(header.extension.absoluteSendTime,
491 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200492 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100493 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
494 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
495 prev_header_.extension.transportSequenceNumber;
496 EXPECT_EQ(1, seq_num_diff);
497 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200498
Stefan Holmer4654d202015-12-08 09:10:43 +0100499 if (encapsulated_payload_type != -1) {
500 if (encapsulated_payload_type ==
501 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700502 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800503 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100504 } else {
brandtr65a1e772016-12-12 01:54:58 -0800505 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000506 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000507 }
508
brandtr20d45472017-01-02 00:34:27 -0800509 if (sent_media_ && sent_ulpfec_) {
510 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100511 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000512
Stefan Holmer4654d202015-12-08 09:10:43 +0100513 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000514
Stefan Holmer4654d202015-12-08 09:10:43 +0100515 return SEND_PACKET;
516 }
517
eladalon413ee9a2017-08-22 04:02:52 -0700518 test::PacketTransport* CreateSendTransport(
519 test::SingleThreadedTaskQueueForTesting* task_queue,
520 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100521 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
522 // Configure some network delay.
523 const int kNetworkDelayMs = 100;
524 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800525 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100526 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700527 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700528 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700529 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100530 }
531
stefanff483612015-12-21 03:14:00 -0800532 void ModifyVideoConfigs(
533 VideoSendStream::Config* send_config,
534 std::vector<VideoReceiveStream::Config>* receive_configs,
535 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100536 if (use_nack_) {
537 send_config->rtp.nack.rtp_history_ms =
538 (*receive_configs)[0].rtp.nack.rtp_history_ms =
539 VideoSendStreamTest::kNackRtpHistoryMs;
540 }
Niels Möller4db138e2018-04-19 09:04:13 +0200541 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200542 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700543 send_config->rtp.ulpfec.red_payload_type =
544 VideoSendStreamTest::kRedPayloadType;
545 send_config->rtp.ulpfec.ulpfec_payload_type =
546 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800547 EXPECT_FALSE(send_config->rtp.extensions.empty());
548 if (!header_extensions_enabled_) {
549 send_config->rtp.extensions.clear();
550 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100551 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700552 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100553 }
Niels Möller259a4972018-04-05 15:36:51 +0200554 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700555 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700556 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700557 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700558 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100559 }
560
561 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800562 EXPECT_EQ(expect_ulpfec_, Wait())
563 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100564 }
565
Niels Möller4db138e2018-04-19 09:04:13 +0200566 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800567 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100568 const bool use_nack_;
569 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700570 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800571 bool sent_media_;
572 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100573 bool header_extensions_enabled_;
574 RTPHeader prev_header_;
575};
576
brandtre602f0a2016-10-31 03:40:49 -0700577TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200578 test::FunctionVideoEncoderFactory encoder_factory(
579 []() { return VP8Encoder::Create(); });
580 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800581 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100582}
583
brandtre602f0a2016-10-31 03:40:49 -0700584TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200585 test::FunctionVideoEncoderFactory encoder_factory(
586 []() { return VP8Encoder::Create(); });
587 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100588 RunBaseTest(&test);
589}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000590
stefan60e10c72017-08-23 10:40:00 -0700591class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
592 protected:
593 VideoSendStreamWithoutUlpfecTest()
594 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
595
596 test::ScopedFieldTrials field_trial_;
597};
598
599TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200600 test::FunctionVideoEncoderFactory encoder_factory(
601 []() { return VP8Encoder::Create(); });
602 UlpfecObserver test(false, false, true, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700603 RunBaseTest(&test);
604}
605
Peter Boström39593972016-02-15 11:27:15 +0100606// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
607// since we'll still have to re-request FEC packets, effectively wasting
608// bandwidth since the receiver has to wait for FEC retransmissions to determine
609// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700610TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200611 test::FunctionVideoEncoderFactory encoder_factory([]() {
612 return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
613 });
614 UlpfecObserver test(false, true, true, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100615 RunBaseTest(&test);
616}
617
618// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800619TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200620 test::FunctionVideoEncoderFactory encoder_factory([]() {
621 return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
622 });
623 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100624 RunBaseTest(&test);
625}
626
danilchap9f5b6222017-03-02 06:22:21 -0800627// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
628TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200629 test::FunctionVideoEncoderFactory encoder_factory(
630 []() { return VP8Encoder::Create(); });
631 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100632 RunBaseTest(&test);
633}
634
Peter Boström12996152016-05-14 02:03:18 +0200635#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800636// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
637TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200638 test::FunctionVideoEncoderFactory encoder_factory(
639 []() { return VP9Encoder::Create(); });
640 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800641 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000642}
Peter Boström12996152016-05-14 02:03:18 +0200643#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000644
brandtre78d2662017-01-16 05:57:16 -0800645TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200646 test::FunctionVideoEncoderFactory encoder_factory([]() {
647 return rtc::MakeUnique<test::MultithreadedFakeH264Encoder>(
648 Clock::GetRealTimeClock());
649 });
650 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800651 RunBaseTest(&test);
652}
653
brandtr39f97292016-11-16 22:57:50 -0800654// TODO(brandtr): Move these FlexFEC tests when we have created
655// FlexfecSendStream.
656class FlexfecObserver : public test::EndToEndTest {
657 public:
658 FlexfecObserver(bool header_extensions_enabled,
659 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800660 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200661 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100662 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800663 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200664 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800665 payload_name_(codec),
666 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800667 sent_media_(false),
668 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100669 header_extensions_enabled_(header_extensions_enabled),
670 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800671
672 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100673 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800674
675 private:
676 Action OnSendRtp(const uint8_t* packet, size_t length) override {
677 RTPHeader header;
678 EXPECT_TRUE(parser_->Parse(packet, length, &header));
679
brandtr39f97292016-11-16 22:57:50 -0800680 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
681 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
682 sent_flexfec_ = true;
683 } else {
684 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
685 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100686 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
687 num_video_streams_),
688 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800689 sent_media_ = true;
690 }
691
692 if (header_extensions_enabled_) {
693 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
694 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
695 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
696 }
697
brandtr0c5a1542016-11-23 04:42:26 -0800698 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800699 observation_complete_.Set();
700 }
701
702 return SEND_PACKET;
703 }
704
eladalon413ee9a2017-08-22 04:02:52 -0700705 test::PacketTransport* CreateSendTransport(
706 test::SingleThreadedTaskQueueForTesting* task_queue,
707 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800708 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
709 // Therefore we need some network delay.
710 const int kNetworkDelayMs = 100;
711 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800712 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800713 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700714 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700715 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700716 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800717 }
718
719 void ModifyVideoConfigs(
720 VideoSendStream::Config* send_config,
721 std::vector<VideoReceiveStream::Config>* receive_configs,
722 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800723 if (use_nack_) {
724 send_config->rtp.nack.rtp_history_ms =
725 (*receive_configs)[0].rtp.nack.rtp_history_ms =
726 VideoSendStreamTest::kNackRtpHistoryMs;
727 }
Niels Möller4db138e2018-04-19 09:04:13 +0200728 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200729 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800730 if (header_extensions_enabled_) {
731 send_config->rtp.extensions.push_back(RtpExtension(
732 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
733 send_config->rtp.extensions.push_back(RtpExtension(
734 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800735 } else {
736 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800737 }
Niels Möller259a4972018-04-05 15:36:51 +0200738 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800739 }
740
741 void PerformTest() override {
742 EXPECT_TRUE(Wait())
743 << "Timed out waiting for FlexFEC and/or media packets.";
744 }
745
Niels Möller4db138e2018-04-19 09:04:13 +0200746 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800747 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800748 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800749 bool sent_media_;
750 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100751 const bool header_extensions_enabled_;
752 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800753};
754
brandtrd654a9b2016-12-05 05:38:19 -0800755TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200756 test::FunctionVideoEncoderFactory encoder_factory(
757 []() { return VP8Encoder::Create(); });
758 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100759 RunBaseTest(&test);
760}
761
762TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200763 test::FunctionVideoEncoderFactory encoder_factory(
764 []() { return VP8Encoder::Create(); });
765 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800766 RunBaseTest(&test);
767}
768
769TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200770 test::FunctionVideoEncoderFactory encoder_factory(
771 []() { return VP8Encoder::Create(); });
772 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800773 RunBaseTest(&test);
774}
775
brandtr39f97292016-11-16 22:57:50 -0800776TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200777 test::FunctionVideoEncoderFactory encoder_factory(
778 []() { return VP8Encoder::Create(); });
779 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800780 RunBaseTest(&test);
781}
782
brandtr39f97292016-11-16 22:57:50 -0800783#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800784TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200785 test::FunctionVideoEncoderFactory encoder_factory(
786 []() { return VP9Encoder::Create(); });
787 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800788 RunBaseTest(&test);
789}
790
brandtrd654a9b2016-12-05 05:38:19 -0800791TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200792 test::FunctionVideoEncoderFactory encoder_factory(
793 []() { return VP9Encoder::Create(); });
794 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800795 RunBaseTest(&test);
796}
797#endif // defined(RTC_DISABLE_VP9)
798
brandtrd654a9b2016-12-05 05:38:19 -0800799TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200800 test::FunctionVideoEncoderFactory encoder_factory([]() {
801 return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
802 });
803 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800804 RunBaseTest(&test);
805}
806
brandtrd654a9b2016-12-05 05:38:19 -0800807TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200808 test::FunctionVideoEncoderFactory encoder_factory([]() {
809 return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
810 });
811 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800812 RunBaseTest(&test);
813}
814
brandtre78d2662017-01-16 05:57:16 -0800815TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200816 test::FunctionVideoEncoderFactory encoder_factory([]() {
817 return rtc::MakeUnique<test::MultithreadedFakeH264Encoder>(
818 Clock::GetRealTimeClock());
819 });
820
821 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800822 RunBaseTest(&test);
823}
824
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000825void VideoSendStreamTest::TestNackRetransmission(
826 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000827 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000828 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000829 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000830 explicit NackObserver(uint32_t retransmit_ssrc,
831 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000832 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000833 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100834 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000835 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100836 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000837
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000838 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000839 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000840 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000841 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000842
Sebastian Janssond3f38162018-02-28 16:14:44 +0100843 int kRetransmitTarget = 6;
844 ++send_count_;
845 if (send_count_ == 5 || send_count_ == 25) {
846 nacked_sequence_numbers_.push_back(
847 static_cast<uint16_t>(header.sequenceNumber - 3));
848 nacked_sequence_numbers_.push_back(
849 static_cast<uint16_t>(header.sequenceNumber - 2));
850 nacked_sequence_numbers_.push_back(
851 static_cast<uint16_t>(header.sequenceNumber - 1));
852
danilchap8a1d2a32017-08-01 03:21:37 -0700853 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800854 nullptr, nullptr, transport_adapter_.get(),
855 RtcpIntervalConfig{});
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000856
pbosda903ea2015-10-02 02:36:56 -0700857 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100858 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000859
860 RTCPSender::FeedbackState feedback_state;
861
Sebastian Janssond3f38162018-02-28 16:14:44 +0100862 EXPECT_EQ(0, rtcp_sender.SendRTCP(
863 feedback_state, kRtcpNack,
864 static_cast<int>(nacked_sequence_numbers_.size()),
865 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000866 }
867
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000868 uint16_t sequence_number = header.sequenceNumber;
869
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000870 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100871 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
872 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000873 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000874 const uint8_t* rtx_header = packet + header.headerLength;
875 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
876 }
Sebastian Janssond3f38162018-02-28 16:14:44 +0100877 auto found = std::find(nacked_sequence_numbers_.begin(),
878 nacked_sequence_numbers_.end(), sequence_number);
879 if (found != nacked_sequence_numbers_.end()) {
880 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000881
Sebastian Janssond3f38162018-02-28 16:14:44 +0100882 if (++retransmit_count_ == kRetransmitTarget) {
883 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
884 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
885 observation_complete_.Set();
886 }
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000887 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000888
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000889 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000890 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000891
stefanff483612015-12-21 03:14:00 -0800892 void ModifyVideoConfigs(
893 VideoSendStream::Config* send_config,
894 std::vector<VideoReceiveStream::Config>* receive_configs,
895 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700896 transport_adapter_.reset(
897 new internal::TransportAdapter(send_config->send_transport));
898 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000899 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000900 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100901 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000902 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
903 }
904
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000905 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100906 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000907 }
908
kwiberg27f982b2016-03-01 11:52:33 -0800909 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000910 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100911 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000912 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000913 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100914 std::vector<uint16_t> nacked_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000915 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000916
stefane74eef12016-01-08 06:47:13 -0800917 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000918}
919
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000920TEST_F(VideoSendStreamTest, RetransmitsNack) {
921 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100922 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000923}
924
925TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
926 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000927 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000928}
929
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000930void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
931 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000932 // Use a fake encoder to output a frame of every size in the range [90, 290],
933 // for each size making sure that the exact number of payload bytes received
934 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000935 static const size_t kMaxPacketSize = 128;
936 static const size_t start = 90;
937 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000938
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000939 // Observer that verifies that the expected number of packets and bytes
940 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000941 class FrameFragmentationTest : public test::SendTest,
942 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000943 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000944 FrameFragmentationTest(size_t max_packet_size,
945 size_t start_size,
946 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000947 bool test_generic_packetization,
948 bool use_fec)
949 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000950 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +0200951 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000952 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000953 stop_size_(stop_size),
954 test_generic_packetization_(test_generic_packetization),
955 use_fec_(use_fec),
956 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100957 packets_lost_(0),
958 last_packet_count_(0),
959 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000960 accumulated_size_(0),
961 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000962 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000963 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700964 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000965 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000966 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700967 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000968 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000969
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000970 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000971 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000972 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000973 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000974 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000975
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000976 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000977
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000978 if (use_fec_) {
979 uint8_t payload_type = packet[header.headerLength];
980 bool is_fec = header.payloadType == kRedPayloadType &&
981 payload_type == kUlpfecPayloadType;
982 if (is_fec) {
983 fec_packet_received_ = true;
984 return SEND_PACKET;
985 }
986 }
987
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000988 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000989
990 if (use_fec_)
991 TriggerLossReport(header);
992
993 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200994 size_t overhead = header.headerLength + header.paddingLength;
995 // Only remove payload header and RED header if the packet actually
996 // contains payload.
997 if (length > overhead) {
998 overhead += (1 /* Generic header */);
999 if (use_fec_)
1000 overhead += 1; // RED for FEC header.
1001 }
1002 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001003 accumulated_payload_ += length - overhead;
1004 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001005
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001006 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001007 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001008 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1009 // With FEC enabled, frame size is incremented asynchronously, so
1010 // "old" frames one byte too small may arrive. Accept, but don't
1011 // increase expected frame size.
1012 accumulated_size_ = 0;
1013 accumulated_payload_ = 0;
1014 return SEND_PACKET;
1015 }
1016
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001017 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001018 if (test_generic_packetization_) {
1019 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1020 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001021
1022 // Last packet of frame; reset counters.
1023 accumulated_size_ = 0;
1024 accumulated_payload_ = 0;
1025 if (current_size_rtp_ == stop_size_) {
1026 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001027 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001028 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001029 // Increase next expected frame size. If testing with FEC, make sure
1030 // a FEC packet has been received for this frame size before
1031 // proceeding, to make sure that redundancy packets don't exceed
1032 // size limit.
1033 if (!use_fec_) {
1034 ++current_size_rtp_;
1035 } else if (fec_packet_received_) {
1036 fec_packet_received_ = false;
1037 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001038
1039 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001040 ++current_size_frame_;
1041 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001042 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001043 }
1044
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001045 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001046 }
1047
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001048 void TriggerLossReport(const RTPHeader& header) {
1049 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001050 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001051 if (++packet_count_ % (100 / kLossPercent) == 0) {
1052 packets_lost_++;
1053 int loss_delta = packets_lost_ - last_packets_lost_;
1054 int packets_delta = packet_count_ - last_packet_count_;
1055 last_packet_count_ = packet_count_;
1056 last_packets_lost_ = packets_lost_;
1057 uint8_t loss_ratio =
1058 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001059 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001060 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001061 packets_lost_, // Cumulative lost.
1062 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001063 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001064 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001065 transport_adapter_.get(), RtcpIntervalConfig{});
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001066
pbosda903ea2015-10-02 02:36:56 -07001067 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001068 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001069
1070 RTCPSender::FeedbackState feedback_state;
1071
1072 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1073 }
1074 }
1075
nisseef8b61e2016-04-29 06:09:15 -07001076 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001077 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001078 // Increase frame size for next encoded frame, in the context of the
1079 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001080 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001081 ++current_size_frame_;
1082 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001083 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001084 }
1085
Stefan Holmere5904162015-03-26 11:11:06 +01001086 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07001087 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001088 const int kMinBitrateBps = 30000;
1089 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1090 return config;
1091 }
1092
stefanff483612015-12-21 03:14:00 -08001093 void ModifyVideoConfigs(
1094 VideoSendStream::Config* send_config,
1095 std::vector<VideoReceiveStream::Config>* receive_configs,
1096 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001097 transport_adapter_.reset(
1098 new internal::TransportAdapter(send_config->send_transport));
1099 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001100 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001101 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1102 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001103 }
1104
1105 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001106 send_config->rtp.payload_name = "VP8";
Niels Möller4db138e2018-04-19 09:04:13 +02001107 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001108 send_config->rtp.max_packet_size = kMaxPacketSize;
1109 send_config->post_encode_callback = this;
1110
Erik Språng95261872015-04-10 11:58:49 +02001111 // Make sure there is at least one extension header, to make the RTP
1112 // header larger than the base length of 12 bytes.
1113 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001114
1115 // Setup screen content disables frame dropping which makes this easier.
1116 class VideoStreamFactory
1117 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1118 public:
1119 explicit VideoStreamFactory(size_t num_temporal_layers)
1120 : num_temporal_layers_(num_temporal_layers) {
1121 EXPECT_GT(num_temporal_layers, 0u);
1122 }
1123
1124 private:
1125 std::vector<VideoStream> CreateEncoderStreams(
1126 int width,
1127 int height,
1128 const VideoEncoderConfig& encoder_config) override {
1129 std::vector<VideoStream> streams =
1130 test::CreateVideoStreams(width, height, encoder_config);
1131 for (VideoStream& stream : streams) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01001132 stream.num_temporal_layers = num_temporal_layers_;
sprang4847ae62017-06-27 07:06:52 -07001133 }
1134 return streams;
1135 }
1136 const size_t num_temporal_layers_;
1137 };
1138
1139 encoder_config->video_stream_factory =
1140 new rtc::RefCountedObject<VideoStreamFactory>(2);
1141 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001142 }
1143
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001144 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001145 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001146 }
1147
kwiberg27f982b2016-03-01 11:52:33 -08001148 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001149 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möller4db138e2018-04-19 09:04:13 +02001150 test::EncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001151
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001152 const size_t max_packet_size_;
1153 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001154 const bool test_generic_packetization_;
1155 const bool use_fec_;
1156
1157 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001158 uint32_t packets_lost_;
1159 uint32_t last_packet_count_;
1160 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001161 size_t accumulated_size_;
1162 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001163 bool fec_packet_received_;
1164
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001165 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001166 rtc::CriticalSection mutex_;
1167 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001168 };
1169
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001170 // Don't auto increment if FEC is used; continue sending frame size until
1171 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001172 FrameFragmentationTest test(
1173 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001174
stefane74eef12016-01-08 06:47:13 -08001175 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001176}
1177
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001178// TODO(sprang): Is there any way of speeding up these tests?
1179TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1180 TestPacketFragmentationSize(kGeneric, false);
1181}
1182
1183TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1184 TestPacketFragmentationSize(kGeneric, true);
1185}
1186
1187TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1188 TestPacketFragmentationSize(kVP8, false);
1189}
1190
1191TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1192 TestPacketFragmentationSize(kVP8, true);
1193}
1194
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001195// The test will go through a number of phases.
1196// 1. Start sending packets.
1197// 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 +00001198// suspend the stream.
1199// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001200// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001201// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001202// When the stream is detected again, and the stats show that the stream
1203// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001204TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1205 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001206
nissed30a1112016-04-18 05:15:22 -07001207 class RembObserver : public test::SendTest,
1208 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001209 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001210 RembObserver()
1211 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001212 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001213 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001214 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001215 rtp_count_(0),
1216 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001217 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001218 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001219 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001220
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001221 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001222 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001223 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001224 ++rtp_count_;
1225 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001226 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001227 last_sequence_number_ = header.sequenceNumber;
1228
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001229 if (test_state_ == kBeforeSuspend) {
1230 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001231 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001232 test_state_ = kDuringSuspend;
1233 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001234 if (header.paddingLength == 0) {
1235 // Received non-padding packet during suspension period. Reset the
1236 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001237 suspended_frame_count_ = 0;
1238 }
stefanf116bd02015-10-27 08:29:42 -07001239 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001240 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001241 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001242 // Non-padding packet observed. Test is almost complete. Will just
1243 // have to wait for the stats to change.
1244 test_state_ = kWaitingForStats;
1245 }
stefanf116bd02015-10-27 08:29:42 -07001246 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001247 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001248 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001249 if (stats.suspended == false) {
1250 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001251 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001252 }
stefanf116bd02015-10-27 08:29:42 -07001253 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001254 }
1255
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001256 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001257 }
1258
perkj26091b12016-09-01 01:17:40 -07001259 // This method implements the rtc::VideoSinkInterface. This is called when
1260 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001261 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001262 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001263 if (test_state_ == kDuringSuspend &&
1264 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001265 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001266 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001267 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001268 test_state_ = kWaitingForPacket;
1269 }
1270 }
1271
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001272 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001273 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001274 low_remb_bps_ = value;
1275 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001276
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001277 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001278 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001279 high_remb_bps_ = value;
1280 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001281
stefanff483612015-12-21 03:14:00 -08001282 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001283 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001284 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001285 stream_ = send_stream;
1286 }
1287
stefanff483612015-12-21 03:14:00 -08001288 void ModifyVideoConfigs(
1289 VideoSendStream::Config* send_config,
1290 std::vector<VideoReceiveStream::Config>* receive_configs,
1291 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001292 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001293 transport_adapter_.reset(
1294 new internal::TransportAdapter(send_config->send_transport));
1295 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001296 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001297 send_config->pre_encode_callback = this;
1298 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001299 int min_bitrate_bps =
1300 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001301 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001302 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001303 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001304 min_bitrate_bps + threshold_window + 5000);
1305 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1306 }
1307
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001308 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001309 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001310 }
1311
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001312 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001313 kBeforeSuspend,
1314 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001315 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001316 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001317 };
1318
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001319 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001320 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001321 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1322 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001323 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001324 transport_adapter_.get(), RtcpIntervalConfig{});
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001325
pbosda903ea2015-10-02 02:36:56 -07001326 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001327 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001328 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001329 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001330 }
1331 RTCPSender::FeedbackState feedback_state;
1332 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1333 }
1334
kwiberg27f982b2016-03-01 11:52:33 -08001335 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001336 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001337 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001338
Peter Boströmf2f82832015-05-01 13:00:41 +02001339 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001340 TestState test_state_ RTC_GUARDED_BY(crit_);
1341 int rtp_count_ RTC_GUARDED_BY(crit_);
1342 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1343 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1344 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1345 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001346 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001347
stefane74eef12016-01-08 06:47:13 -08001348 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001349}
1350
perkj71ee44c2016-06-15 00:47:53 -07001351// This test that padding stops being send after a while if the Camera stops
1352// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001353TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001354 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001355 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001356 NoPaddingWhenVideoIsMuted()
1357 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001358 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001359 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001360 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001361 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001362
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001363 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001364 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001365 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001366 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001367
1368 RTPHeader header;
1369 parser_->Parse(packet, length, &header);
1370 const bool only_padding =
1371 header.headerLength + header.paddingLength == length;
1372
1373 if (test_state_ == kBeforeStopCapture) {
1374 capturer_->Stop();
1375 test_state_ = kWaitingForPadding;
1376 } else if (test_state_ == kWaitingForPadding && only_padding) {
1377 test_state_ = kWaitingForNoPackets;
1378 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1379 only_padding) {
1380 observation_complete_.Set();
1381 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001382 return SEND_PACKET;
1383 }
1384
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001385 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001386 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001387 const int kNoPacketsThresholdMs = 2000;
1388 if (test_state_ == kWaitingForNoPackets &&
1389 (last_packet_time_ms_ > 0 &&
1390 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1391 kNoPacketsThresholdMs)) {
1392 capturer_->Start();
1393 test_state_ = kWaitingForPaddingAfterCameraRestart;
1394 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001395 return SEND_PACKET;
1396 }
1397
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001398 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001399
nisseef8b61e2016-04-29 06:09:15 -07001400 void OnFrameGeneratorCapturerCreated(
1401 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001402 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001403 capturer_ = frame_generator_capturer;
1404 }
1405
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001406 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001407 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001408 << "Timed out while waiting for RTP packets to stop being sent.";
1409 }
1410
perkj71ee44c2016-06-15 00:47:53 -07001411 enum TestState {
1412 kBeforeStopCapture,
1413 kWaitingForPadding,
1414 kWaitingForNoPackets,
1415 kWaitingForPaddingAfterCameraRestart
1416 };
1417
1418 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001419 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001420 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001421 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001422 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1423 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001424 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001425
stefane74eef12016-01-08 06:47:13 -08001426 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001427}
1428
isheriffcc5903e2016-10-04 08:29:38 -07001429TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1430 const int kCapacityKbps = 10000; // 10 Mbps
1431 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1432 public:
1433 PaddingIsPrimarilyRetransmissions()
1434 : EndToEndTest(kDefaultTimeoutMs),
1435 clock_(Clock::GetRealTimeClock()),
1436 padding_length_(0),
1437 total_length_(0),
1438 call_(nullptr) {}
1439
1440 private:
1441 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1442 call_ = sender_call;
1443 }
1444
1445 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1446 rtc::CritScope lock(&crit_);
1447
1448 RTPHeader header;
1449 parser_->Parse(packet, length, &header);
1450 padding_length_ += header.paddingLength;
1451 total_length_ += length;
1452 return SEND_PACKET;
1453 }
1454
eladalon413ee9a2017-08-22 04:02:52 -07001455 test::PacketTransport* CreateSendTransport(
1456 test::SingleThreadedTaskQueueForTesting* task_queue,
1457 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001458 const int kNetworkDelayMs = 50;
1459 FakeNetworkPipe::Config config;
1460 config.loss_percent = 10;
1461 config.link_capacity_kbps = kCapacityKbps;
1462 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001463 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001464 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001465 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001466 }
1467
1468 void ModifyVideoConfigs(
1469 VideoSendStream::Config* send_config,
1470 std::vector<VideoReceiveStream::Config>* receive_configs,
1471 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001472 // Turn on RTX.
1473 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1474 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001475 }
1476
1477 void PerformTest() override {
1478 // TODO(isheriff): Some platforms do not ramp up as expected to full
1479 // capacity due to packet scheduling delays. Fix that before getting
1480 // rid of this.
1481 SleepMs(5000);
1482 {
1483 rtc::CritScope lock(&crit_);
1484 // Expect padding to be a small percentage of total bytes sent.
1485 EXPECT_LT(padding_length_, .1 * total_length_);
1486 }
1487 }
1488
1489 rtc::CriticalSection crit_;
1490 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001491 size_t padding_length_ RTC_GUARDED_BY(crit_);
1492 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001493 Call* call_;
1494 } test;
1495
1496 RunBaseTest(&test);
1497}
1498
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001499// This test first observes "high" bitrate use at which point it sends a REMB to
1500// indicate that it should be lowered significantly. The test then observes that
1501// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1502// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001503//
1504// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1505// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001506TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1507 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001508 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001509 static const int kRembBitrateBps = 80000;
1510 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001511 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001512 public:
1513 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001514 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001515 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1516 stream_(nullptr),
1517 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001518
1519 private:
nisseef8b61e2016-04-29 06:09:15 -07001520 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001521 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001522 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001523
1524 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001525 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001526 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001527 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001528 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001529 if (!stats.substreams.empty()) {
1530 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001531 int total_bitrate_bps =
1532 stats.substreams.begin()->second.total_bitrate_bps;
1533 test::PrintResult("bitrate_stats_",
1534 "min_transmit_bitrate_low_remb",
1535 "bitrate_bps",
1536 static_cast<size_t>(total_bitrate_bps),
1537 "bps",
1538 false);
1539 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001540 rtp_rtcp_->SetRemb(kRembBitrateBps,
1541 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001542 rtp_rtcp_->Process();
1543 bitrate_capped_ = true;
1544 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001545 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001546 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001547 }
1548 }
stefanf116bd02015-10-27 08:29:42 -07001549 // Packets don't have to be delivered since the test is the receiver.
1550 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001551 }
1552
stefanff483612015-12-21 03:14:00 -08001553 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001554 VideoSendStream* send_stream,
1555 const std::vector<VideoReceiveStream*>& receive_streams) override {
1556 stream_ = send_stream;
1557 RtpRtcp::Configuration config;
1558 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001559 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001560 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001561 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001562 }
1563
stefanff483612015-12-21 03:14:00 -08001564 void ModifyVideoConfigs(
1565 VideoSendStream::Config* send_config,
1566 std::vector<VideoReceiveStream::Config>* receive_configs,
1567 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001568 feedback_transport_.reset(
1569 new internal::TransportAdapter(send_config->send_transport));
1570 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001571 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001572 }
1573
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001574 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001575 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001576 << "Timeout while waiting for low bitrate stats after REMB.";
1577 }
1578
kwiberg27f982b2016-03-01 11:52:33 -08001579 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1580 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001581 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001582 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001583 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001584 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001585
stefane74eef12016-01-08 06:47:13 -08001586 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001587}
1588
Stefan Holmer280de9e2016-09-30 10:06:51 +02001589TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1590 static const int kStartBitrateBps = 300000;
1591 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001592 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001593 class ChangingNetworkRouteTest : public test::EndToEndTest {
1594 public:
eladalon413ee9a2017-08-22 04:02:52 -07001595 explicit ChangingNetworkRouteTest(
1596 test::SingleThreadedTaskQueueForTesting* task_queue)
1597 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1598 task_queue_(task_queue),
1599 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001600 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1601 kRtpExtensionTransportSequenceNumber, kExtensionId));
1602 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001603
1604 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1605 call_ = sender_call;
1606 }
1607
Stefan Holmer280de9e2016-09-30 10:06:51 +02001608 void ModifyVideoConfigs(
1609 VideoSendStream::Config* send_config,
1610 std::vector<VideoReceiveStream::Config>* receive_configs,
1611 VideoEncoderConfig* encoder_config) override {
1612 send_config->rtp.extensions.clear();
1613 send_config->rtp.extensions.push_back(RtpExtension(
1614 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1615 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1616 (*receive_configs)[0].rtp.transport_cc = true;
1617 }
1618
1619 void ModifyAudioConfigs(
1620 AudioSendStream::Config* send_config,
1621 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1622 send_config->rtp.extensions.clear();
1623 send_config->rtp.extensions.push_back(RtpExtension(
1624 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1625 (*receive_configs)[0].rtp.extensions.clear();
1626 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1627 (*receive_configs)[0].rtp.transport_cc = true;
1628 }
1629
Stefan Holmerbe402962016-07-08 16:16:41 +02001630 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1631 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1632 observation_complete_.Set();
1633 }
1634
1635 return SEND_PACKET;
1636 }
1637
1638 void PerformTest() override {
1639 rtc::NetworkRoute new_route(true, 10, 20, -1);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001640 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001641
1642 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001643 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1644 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001645 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001646 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1647 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001648 });
1649
Stefan Holmerbe402962016-07-08 16:16:41 +02001650 EXPECT_TRUE(Wait())
1651 << "Timed out while waiting for start bitrate to be exceeded.";
1652
eladalon413ee9a2017-08-22 04:02:52 -07001653 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1654 bitrate_config.start_bitrate_bps = -1;
1655 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001656 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1657 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001658 // TODO(holmer): We should set the last sent packet id here and verify
1659 // that we correctly ignore any packet loss reported prior to that id.
1660 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001661 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1662 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001663 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1664 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001665 }
1666
1667 private:
eladalon413ee9a2017-08-22 04:02:52 -07001668 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001669 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001670 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001671
1672 RunBaseTest(&test);
1673}
1674
michaelt79e05882016-11-08 02:50:09 -08001675TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1676 class ChangingTransportOverheadTest : public test::EndToEndTest {
1677 public:
eladalon413ee9a2017-08-22 04:02:52 -07001678 explicit ChangingTransportOverheadTest(
1679 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001680 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001681 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001682 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001683 packets_sent_(0),
1684 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001685
1686 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1687 call_ = sender_call;
1688 }
1689
1690 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001691 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001692 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001693 if (++packets_sent_ < 100)
1694 return SEND_PACKET;
1695 observation_complete_.Set();
1696 return SEND_PACKET;
1697 }
1698
michaelta3328772016-11-29 09:25:03 -08001699 void ModifyVideoConfigs(
1700 VideoSendStream::Config* send_config,
1701 std::vector<VideoReceiveStream::Config>* receive_configs,
1702 VideoEncoderConfig* encoder_config) override {
1703 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1704 }
1705
michaelt79e05882016-11-08 02:50:09 -08001706 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001707 task_queue_->SendTask([this]() {
1708 transport_overhead_ = 100;
1709 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1710 transport_overhead_);
1711 });
1712
michaelt79e05882016-11-08 02:50:09 -08001713 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001714
sprang21253fc2017-02-27 03:35:47 -08001715 {
1716 rtc::CritScope cs(&lock_);
1717 packets_sent_ = 0;
1718 }
eladalon413ee9a2017-08-22 04:02:52 -07001719
1720 task_queue_->SendTask([this]() {
1721 transport_overhead_ = 500;
1722 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1723 transport_overhead_);
1724 });
1725
michaelt79e05882016-11-08 02:50:09 -08001726 EXPECT_TRUE(Wait());
1727 }
1728
1729 private:
eladalon413ee9a2017-08-22 04:02:52 -07001730 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001731 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001732 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001733 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001734 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001735 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001736 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001737
1738 RunBaseTest(&test);
1739}
1740
sprangf24a0642017-02-28 13:23:26 -08001741// Test class takes takes as argument a switch selecting if type switch should
1742// occur and a function pointer to reset the send stream. This is necessary
1743// since you cannot change the content type of a VideoSendStream, you need to
1744// recreate it. Stopping and recreating the stream can only be done on the main
1745// thread and in the context of VideoSendStreamTest (not BaseTest).
1746template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001747class MaxPaddingSetTest : public test::SendTest {
1748 public:
1749 static const uint32_t kMinTransmitBitrateBps = 400000;
1750 static const uint32_t kActualEncodeBitrateBps = 40000;
1751 static const uint32_t kMinPacketsToSend = 50;
1752
sprangf24a0642017-02-28 13:23:26 -08001753 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001754 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001755 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001756 call_(nullptr),
1757 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001758 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001759 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001760 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001761 stream_resetter_(stream_reset_fun) {
1762 RTC_DCHECK(stream_resetter_);
1763 }
sprang9c0b5512016-07-06 00:54:28 -07001764
1765 void OnVideoStreamsCreated(
1766 VideoSendStream* send_stream,
1767 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001768 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001769 send_stream_ = send_stream;
1770 }
1771
1772 void ModifyVideoConfigs(
1773 VideoSendStream::Config* send_config,
1774 std::vector<VideoReceiveStream::Config>* receive_configs,
1775 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001776 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001777 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001778 encoder_config->min_transmit_bitrate_bps = 0;
1779 encoder_config->content_type =
1780 VideoEncoderConfig::ContentType::kRealtimeVideo;
1781 } else {
1782 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1783 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1784 }
sprangf24a0642017-02-28 13:23:26 -08001785 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001786 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001787 }
1788
1789 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1790 call_ = sender_call;
1791 }
1792
1793 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1794 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001795 if (running_without_padding_)
1796 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1797
1798 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1799 // we have reliable data.
1800 if (++packets_sent_ < kMinPacketsToSend)
1801 return SEND_PACKET;
1802
1803 if (running_without_padding_) {
1804 // We've sent kMinPacketsToSend packets with default configuration, switch
1805 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001806 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001807 packets_sent_ = 0;
1808 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1809 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001810 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001811 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001812 return SEND_PACKET;
1813 }
1814
1815 // Make sure the pacer has been configured with a min transmit bitrate.
1816 if (call_->GetStats().max_padding_bitrate_bps > 0)
1817 observation_complete_.Set();
1818
1819 return SEND_PACKET;
1820 }
1821
1822 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001823 if (RunningWithoutPadding()) {
1824 ASSERT_TRUE(
1825 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001826 (*stream_resetter_)(send_stream_config_, encoder_config_);
1827 }
1828
sprang9c0b5512016-07-06 00:54:28 -07001829 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1830 }
1831
1832 private:
sprangf24a0642017-02-28 13:23:26 -08001833 bool RunningWithoutPadding() const {
1834 rtc::CritScope lock(&crit_);
1835 return running_without_padding_;
1836 }
1837
sprang9c0b5512016-07-06 00:54:28 -07001838 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001839 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001840 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001841 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001842 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001843 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001844 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001845 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001846 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001847};
1848
1849TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001850 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1851 const VideoEncoderConfig& encoder_config) {};
1852 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001853 RunBaseTest(&test);
1854}
1855
1856TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001857 // Function for removing and recreating the send stream with a new config.
1858 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1859 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001860 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1861 Stop();
1862 sender_call_->DestroyVideoSendStream(video_send_stream_);
1863 video_send_config_ = send_stream_config.Copy();
1864 video_encoder_config_ = encoder_config.Copy();
1865 video_send_stream_ = sender_call_->CreateVideoSendStream(
1866 video_send_config_.Copy(), video_encoder_config_.Copy());
Taylor Brandstetter49fcc102018-05-16 14:20:41 -07001867 video_send_stream_->SetSource(frame_generator_capturer_.get(),
1868 DegradationPreference::MAINTAIN_RESOLUTION);
eladalon413ee9a2017-08-22 04:02:52 -07001869 Start();
1870 });
sprangf24a0642017-02-28 13:23:26 -08001871 };
1872 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001873 RunBaseTest(&test);
1874}
1875
perkjfa10b552016-10-02 23:45:26 -07001876// This test verifies that new frame sizes reconfigures encoders even though not
1877// (yet) sending. The purpose of this is to permit encoding as quickly as
1878// possible once we start sending. Likely the frames being input are from the
1879// same source that will be sent later, which just means that we're ready
1880// earlier.
1881TEST_F(VideoSendStreamTest,
1882 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1883 class EncoderObserver : public test::FakeEncoder {
1884 public:
1885 EncoderObserver()
1886 : FakeEncoder(Clock::GetRealTimeClock()),
1887 init_encode_called_(false, false),
1888 number_of_initializations_(0),
1889 last_initialized_frame_width_(0),
1890 last_initialized_frame_height_(0) {}
1891
1892 void WaitForResolution(int width, int height) {
1893 {
1894 rtc::CritScope lock(&crit_);
1895 if (last_initialized_frame_width_ == width &&
1896 last_initialized_frame_height_ == height) {
1897 return;
1898 }
1899 }
Erik Språng08127a92016-11-16 16:41:30 +01001900 EXPECT_TRUE(
1901 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001902 {
1903 rtc::CritScope lock(&crit_);
1904 EXPECT_EQ(width, last_initialized_frame_width_);
1905 EXPECT_EQ(height, last_initialized_frame_height_);
1906 }
1907 }
1908
1909 private:
1910 int32_t InitEncode(const VideoCodec* config,
1911 int32_t number_of_cores,
1912 size_t max_payload_size) override {
1913 rtc::CritScope lock(&crit_);
1914 last_initialized_frame_width_ = config->width;
1915 last_initialized_frame_height_ = config->height;
1916 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001917 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001918 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1919 }
1920
1921 int32_t Encode(const VideoFrame& input_image,
1922 const CodecSpecificInfo* codec_specific_info,
1923 const std::vector<FrameType>* frame_types) override {
1924 ADD_FAILURE()
1925 << "Unexpected Encode call since the send stream is not started";
1926 return 0;
1927 }
1928
1929 rtc::CriticalSection crit_;
1930 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001931 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1932 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1933 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001934 };
1935
perkjfa10b552016-10-02 23:45:26 -07001936 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001937 EncoderObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02001938 test::EncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07001939
Niels Möller4db138e2018-04-19 09:04:13 +02001940 task_queue_.SendTask([this, &transport, &encoder_factory]() {
eladalon413ee9a2017-08-22 04:02:52 -07001941 CreateSenderCall(Call::Config(event_log_.get()));
1942 CreateSendConfig(1, 0, 0, &transport);
Niels Möller4db138e2018-04-19 09:04:13 +02001943 video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07001944 CreateVideoStreams();
1945 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1946 kDefaultHeight);
1947 frame_generator_capturer_->Start();
1948 });
perkjfa10b552016-10-02 23:45:26 -07001949
1950 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001951
1952 task_queue_.SendTask([this]() {
1953 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1954 kDefaultHeight * 2);
1955 });
1956
perkjfa10b552016-10-02 23:45:26 -07001957 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001958
1959 task_queue_.SendTask([this]() {
1960 DestroyStreams();
1961 DestroyCalls();
1962 });
perkjfa10b552016-10-02 23:45:26 -07001963}
1964
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001965TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1966 class StartBitrateObserver : public test::FakeEncoder {
1967 public:
1968 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001969 : FakeEncoder(Clock::GetRealTimeClock()),
1970 start_bitrate_changed_(false, false),
1971 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001972 int32_t InitEncode(const VideoCodec* config,
1973 int32_t number_of_cores,
1974 size_t max_payload_size) override {
1975 rtc::CritScope lock(&crit_);
1976 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001977 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001978 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1979 }
1980
1981 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1982 rtc::CritScope lock(&crit_);
1983 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001984 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001985 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1986 }
1987
1988 int GetStartBitrateKbps() const {
1989 rtc::CritScope lock(&crit_);
1990 return start_bitrate_kbps_;
1991 }
1992
pbos14fe7082016-04-20 06:35:56 -07001993 bool WaitForStartBitrate() {
1994 return start_bitrate_changed_.Wait(
1995 VideoSendStreamTest::kDefaultTimeoutMs);
1996 }
1997
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001998 private:
pbos5ad935c2016-01-25 03:52:44 -08001999 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002000 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002001 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002002 };
2003
philipel4fb651d2017-04-10 03:54:05 -07002004 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002005
solenberg4fbae2b2015-08-28 04:07:10 -07002006 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002007 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002008
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002009 BitrateConstraints bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07002010 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002011 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2012 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002013
2014 StartBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002015 test::EncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002016 // Since this test does not use a capturer, set |internal_source| = true.
2017 // Encoder configuration is otherwise updated on the next video frame.
Niels Möller4db138e2018-04-19 09:04:13 +02002018 encoder_factory.SetHasInternalSource(true);
2019 video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002020
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002021 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002022
pbos14fe7082016-04-20 06:35:56 -07002023 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07002024 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002025 encoder.GetStartBitrateKbps());
2026
perkjfa10b552016-10-02 23:45:26 -07002027 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07002028 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002029
2030 // New bitrate should be reconfigured above the previous max. As there's no
2031 // network connection this shouldn't be flaky, as no bitrate should've been
2032 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002033 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002034 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2035 encoder.GetStartBitrateKbps());
2036
2037 DestroyStreams();
2038}
2039
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002040class StartStopBitrateObserver : public test::FakeEncoder {
2041 public:
2042 StartStopBitrateObserver()
2043 : FakeEncoder(Clock::GetRealTimeClock()),
2044 encoder_init_(false, false),
2045 bitrate_changed_(false, false) {}
2046 int32_t InitEncode(const VideoCodec* config,
2047 int32_t number_of_cores,
2048 size_t max_payload_size) override {
2049 rtc::CritScope lock(&crit_);
2050 encoder_init_.Set();
2051 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2052 }
2053
Erik Språng566124a2018-04-23 12:32:22 +02002054 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002055 uint32_t framerate) override {
2056 rtc::CritScope lock(&crit_);
2057 bitrate_kbps_ = bitrate.get_sum_kbps();
2058 bitrate_changed_.Set();
2059 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2060 }
2061
2062 bool WaitForEncoderInit() {
2063 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2064 }
2065
2066 bool WaitBitrateChanged(bool non_zero) {
2067 do {
2068 rtc::Optional<int> bitrate_kbps;
2069 {
2070 rtc::CritScope lock(&crit_);
2071 bitrate_kbps = bitrate_kbps_;
2072 }
2073 if (!bitrate_kbps)
2074 continue;
2075
2076 if ((non_zero && *bitrate_kbps > 0) ||
2077 (!non_zero && *bitrate_kbps == 0)) {
2078 return true;
2079 }
2080 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2081 return false;
2082 }
2083
2084 private:
2085 rtc::CriticalSection crit_;
2086 rtc::Event encoder_init_;
2087 rtc::Event bitrate_changed_;
2088 rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
2089};
2090
perkj57c21f92016-06-17 07:27:16 -07002091// This test that if the encoder use an internal source, VideoEncoder::SetRates
2092// will be called with zero bitrate during initialization and that
2093// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2094// with zero bitrate.
2095TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002096 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002097 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002098 test::EncoderProxyFactory encoder_factory(&encoder);
2099 encoder_factory.SetHasInternalSource(true);
2100 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002101
Niels Möller4db138e2018-04-19 09:04:13 +02002102 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
eladalon413ee9a2017-08-22 04:02:52 -07002103 CreateSenderCall(Call::Config(event_log_.get()));
2104 CreateSendConfig(1, 0, 0, &transport);
2105
2106 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Niels Möller4db138e2018-04-19 09:04:13 +02002107 video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002108
2109 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002110 // Inject a frame, to force encoder creation.
2111 video_send_stream_->Start();
Taylor Brandstetter49fcc102018-05-16 14:20:41 -07002112 video_send_stream_->SetSource(&forwarder, DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002113 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002114 });
perkj57c21f92016-06-17 07:27:16 -07002115
2116 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002117
eladalon413ee9a2017-08-22 04:02:52 -07002118 task_queue_.SendTask([this]() {
2119 video_send_stream_->Start();
2120 });
Erik Språng08127a92016-11-16 16:41:30 +01002121 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2122
eladalon413ee9a2017-08-22 04:02:52 -07002123 task_queue_.SendTask([this]() {
2124 video_send_stream_->Stop();
2125 });
Erik Språng08127a92016-11-16 16:41:30 +01002126 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2127
eladalon413ee9a2017-08-22 04:02:52 -07002128 task_queue_.SendTask([this]() {
2129 video_send_stream_->Start();
2130 });
Erik Språng08127a92016-11-16 16:41:30 +01002131 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002132
eladalon413ee9a2017-08-22 04:02:52 -07002133 task_queue_.SendTask([this]() {
2134 DestroyStreams();
2135 DestroyCalls();
2136 });
perkj57c21f92016-06-17 07:27:16 -07002137}
2138
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002139// Tests that when the encoder uses an internal source, the VideoEncoder will
2140// be updated with a new bitrate when turning the VideoSendStream on/off with
2141// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2142// is reconfigured with new active layers.
2143TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
2144 test::NullTransport transport;
2145 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002146 test::EncoderProxyFactory encoder_factory(&encoder);
2147 encoder_factory.SetHasInternalSource(true);
2148 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002149
Niels Möller4db138e2018-04-19 09:04:13 +02002150 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002151 CreateSenderCall(Call::Config(event_log_.get()));
2152 // Create two simulcast streams.
2153 CreateSendConfig(2, 0, 0, &transport);
2154
2155 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Niels Möller4db138e2018-04-19 09:04:13 +02002156 video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002157
Niels Möller259a4972018-04-05 15:36:51 +02002158 video_send_config_.rtp.payload_name = "VP8";
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002159
2160 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002161
2162 // Inject a frame, to force encoder creation.
2163 video_send_stream_->Start();
Taylor Brandstetter49fcc102018-05-16 14:20:41 -07002164 video_send_stream_->SetSource(&forwarder, DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002165 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002166 });
2167
2168 EXPECT_TRUE(encoder.WaitForEncoderInit());
2169
2170 // When we turn on the simulcast layers it will update the BitrateAllocator,
2171 // which in turn updates the VideoEncoder's bitrate.
2172 task_queue_.SendTask([this]() {
2173 video_send_stream_->UpdateActiveSimulcastLayers({true, true});
2174 });
2175 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2176
2177 video_encoder_config_.simulcast_layers[0].active = true;
2178 video_encoder_config_.simulcast_layers[1].active = false;
2179 task_queue_.SendTask([this]() {
2180 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
2181 });
2182 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2183 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2184 // active. Once the change is made for a "soft" reconfiguration we can remove
2185 // the expecation for an encoder init. We can also test that bitrate changes
2186 // when just updating individual active layers, which should change the
2187 // bitrate set to the video encoder.
2188 EXPECT_TRUE(encoder.WaitForEncoderInit());
2189 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2190
2191 // Turning off both simulcast layers should trigger a bitrate change of 0.
2192 video_encoder_config_.simulcast_layers[0].active = false;
2193 video_encoder_config_.simulcast_layers[1].active = false;
2194 task_queue_.SendTask([this]() {
2195 video_send_stream_->UpdateActiveSimulcastLayers({false, false});
2196 });
2197 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2198
2199 task_queue_.SendTask([this]() {
2200 DestroyStreams();
2201 DestroyCalls();
2202 });
2203}
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002204TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002205 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002206 public:
Peter Boström5811a392015-12-10 13:02:50 +01002207 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002208
nissed30a1112016-04-18 05:15:22 -07002209 void OnFrame(const VideoFrame& video_frame) override {
2210 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002211 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002212 }
2213
2214 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002215 const int kWaitFrameTimeoutMs = 3000;
2216 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002217 << "Timeout while waiting for output frames.";
2218 }
2219
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002220 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002221 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002222 }
2223
2224 private:
2225 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002226 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002227
2228 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002229 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002230 };
2231
solenberg4fbae2b2015-08-28 04:07:10 -07002232 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002233 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002234 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002235
eladalon413ee9a2017-08-22 04:02:52 -07002236 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2237 // Initialize send stream.
2238 CreateSenderCall(Call::Config(event_log_.get()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002239
eladalon413ee9a2017-08-22 04:02:52 -07002240 CreateSendConfig(1, 0, 0, &transport);
2241 video_send_config_.pre_encode_callback = &observer;
2242 CreateVideoStreams();
2243
2244 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2245 // alternatively.
2246 int width = 168;
2247 int height = 132;
2248
2249 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2250 width, height, 1, 1, kVideoRotation_0));
2251 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2252 width, height, 2, 2, kVideoRotation_0));
2253 input_frames.push_back(CreateVideoFrame(width, height, 3));
2254 input_frames.push_back(CreateVideoFrame(width, height, 4));
2255 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2256 width, height, 5, 5, kVideoRotation_0));
2257
2258 video_send_stream_->Start();
2259 test::FrameForwarder forwarder;
Taylor Brandstetter49fcc102018-05-16 14:20:41 -07002260 video_send_stream_->SetSource(&forwarder,
2261 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002262 for (size_t i = 0; i < input_frames.size(); i++) {
2263 forwarder.IncomingCapturedFrame(input_frames[i]);
2264 // Wait until the output frame is received before sending the next input
2265 // frame. Or the previous input frame may be replaced without delivering.
2266 observer.WaitOutputFrame();
2267 }
2268 video_send_stream_->Stop();
Taylor Brandstetter49fcc102018-05-16 14:20:41 -07002269 video_send_stream_->SetSource(nullptr,
2270 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002271 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002272
2273 // Test if the input and output frames are the same. render_time_ms and
2274 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002275 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002276
eladalon413ee9a2017-08-22 04:02:52 -07002277 task_queue_.SendTask([this]() {
2278 DestroyStreams();
2279 DestroyCalls();
2280 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002281}
2282
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002283void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2284 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002285 EXPECT_EQ(frames1.size(), frames2.size());
2286 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002287 // Compare frame buffers, since we don't care about differing timestamps.
2288 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2289 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002290}
2291
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002292VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002293 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002294 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002295 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002296 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002297 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002298 // Use data as a ms timestamp.
2299 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002300 return frame;
2301}
2302
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002303TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2304 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2305 public:
eladalon413ee9a2017-08-22 04:02:52 -07002306 explicit EncoderStateObserver(
2307 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002308 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002309 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002310 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002311 initialized_(false),
2312 callback_registered_(false),
2313 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002314 released_(false),
2315 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002316
2317 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002318 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002319 return released_;
2320 }
2321
2322 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002323 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002324 return initialized_ && callback_registered_;
2325 }
2326
2327 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002328 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002329 return num_releases_;
2330 }
2331
2332 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002333 int32_t InitEncode(const VideoCodec* codecSettings,
2334 int32_t numberOfCores,
2335 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002336 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002337 EXPECT_FALSE(initialized_);
2338 initialized_ = true;
2339 released_ = false;
2340 return 0;
2341 }
2342
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002343 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002344 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002345 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002346 EXPECT_TRUE(IsReadyForEncode());
2347
Peter Boström5811a392015-12-10 13:02:50 +01002348 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002349 return 0;
2350 }
2351
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002352 int32_t RegisterEncodeCompleteCallback(
2353 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002354 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002355 EXPECT_TRUE(initialized_);
2356 callback_registered_ = true;
2357 return 0;
2358 }
2359
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002360 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002361 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002362 EXPECT_TRUE(IsReadyForEncode());
2363 EXPECT_FALSE(released_);
2364 initialized_ = false;
2365 callback_registered_ = false;
2366 released_ = true;
2367 ++num_releases_;
2368 return 0;
2369 }
2370
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002371 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002372 EXPECT_TRUE(IsReadyForEncode());
2373 return 0;
2374 }
2375
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002376 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002377 EXPECT_TRUE(IsReadyForEncode());
2378 return 0;
2379 }
2380
stefanff483612015-12-21 03:14:00 -08002381 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002382 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002383 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002384 stream_ = send_stream;
2385 }
2386
stefanff483612015-12-21 03:14:00 -08002387 void ModifyVideoConfigs(
2388 VideoSendStream::Config* send_config,
2389 std::vector<VideoReceiveStream::Config>* receive_configs,
2390 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002391 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002392 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002393 }
2394
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002395 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002396 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002397
2398 task_queue_->SendTask([this]() {
2399 EXPECT_EQ(0u, num_releases());
2400 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2401 EXPECT_EQ(0u, num_releases());
2402 stream_->Stop();
2403 // Encoder should not be released before destroying the VideoSendStream.
2404 EXPECT_FALSE(IsReleased());
2405 EXPECT_TRUE(IsReadyForEncode());
2406 stream_->Start();
2407 });
2408
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002409 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002410 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002411 }
2412
eladalon413ee9a2017-08-22 04:02:52 -07002413 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002414 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002415 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002416 bool initialized_ RTC_GUARDED_BY(crit_);
2417 bool callback_registered_ RTC_GUARDED_BY(crit_);
2418 size_t num_releases_ RTC_GUARDED_BY(crit_);
2419 bool released_ RTC_GUARDED_BY(crit_);
Niels Möller4db138e2018-04-19 09:04:13 +02002420 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002421 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002422 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002423
stefane74eef12016-01-08 06:47:13 -08002424 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002425
2426 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002427 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002428}
2429
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002430TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2431 class VideoCodecConfigObserver : public test::SendTest,
2432 public test::FakeEncoder {
2433 public:
2434 VideoCodecConfigObserver()
2435 : SendTest(kDefaultTimeoutMs),
2436 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002437 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002438 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002439 stream_(nullptr),
2440 encoder_factory_(this) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002441
2442 private:
stefanff483612015-12-21 03:14:00 -08002443 void ModifyVideoConfigs(
2444 VideoSendStream::Config* send_config,
2445 std::vector<VideoReceiveStream::Config>* receive_configs,
2446 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002447 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprangf24a0642017-02-28 13:23:26 -08002448 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002449 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002450 }
2451
stefanff483612015-12-21 03:14:00 -08002452 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002453 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002454 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002455 stream_ = send_stream;
2456 }
2457
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002458 int32_t InitEncode(const VideoCodec* config,
2459 int32_t number_of_cores,
2460 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002461 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002462 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002463 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002464 } else {
2465 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002466 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002467 }
2468 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002469 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002470 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2471 }
2472
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002473 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002474 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002475 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002476
sprangf24a0642017-02-28 13:23:26 -08002477 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002478 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002479 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002480 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002481 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2482 "new encoder settings.";
2483 }
2484
sprangf24a0642017-02-28 13:23:26 -08002485 const uint32_t kFirstMaxBitrateBps = 1000000;
2486 const uint32_t kSecondMaxBitrateBps = 2000000;
2487
pbos14fe7082016-04-20 06:35:56 -07002488 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002489 size_t num_initializations_;
2490 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002491 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002492 VideoEncoderConfig encoder_config_;
2493 } test;
2494
stefane74eef12016-01-08 06:47:13 -08002495 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002496}
2497
Sergey Silkin571e6c92018-04-03 10:03:31 +02002498static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002499template <typename T>
2500class VideoCodecConfigObserver : public test::SendTest,
2501 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002502 public:
2503 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2504 const char* codec_name)
2505 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2506 FakeEncoder(Clock::GetRealTimeClock()),
2507 video_codec_type_(video_codec_type),
2508 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002509 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002510 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002511 stream_(nullptr),
2512 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002513 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002514 }
2515
2516 private:
perkjfa10b552016-10-02 23:45:26 -07002517 class VideoStreamFactory
2518 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2519 public:
2520 VideoStreamFactory() {}
2521
2522 private:
2523 std::vector<VideoStream> CreateEncoderStreams(
2524 int width,
2525 int height,
2526 const VideoEncoderConfig& encoder_config) override {
2527 std::vector<VideoStream> streams =
2528 test::CreateVideoStreams(width, height, encoder_config);
2529 for (size_t i = 0; i < streams.size(); ++i) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002530 streams[i].num_temporal_layers =
2531 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkjfa10b552016-10-02 23:45:26 -07002532 }
2533 return streams;
2534 }
2535 };
2536
stefanff483612015-12-21 03:14:00 -08002537 void ModifyVideoConfigs(
2538 VideoSendStream::Config* send_config,
2539 std::vector<VideoReceiveStream::Config>* receive_configs,
2540 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002541 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002542 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002543
Niels Möller259a4972018-04-05 15:36:51 +02002544 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002545 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002546 encoder_config->video_stream_factory =
2547 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002548 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002549 }
2550
stefanff483612015-12-21 03:14:00 -08002551 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002552 VideoSendStream* send_stream,
2553 const std::vector<VideoReceiveStream*>& receive_streams) override {
2554 stream_ = send_stream;
2555 }
2556
2557 int32_t InitEncode(const VideoCodec* config,
2558 int32_t number_of_cores,
2559 size_t max_payload_size) override {
2560 EXPECT_EQ(video_codec_type_, config->codecType);
2561 VerifyCodecSpecifics(*config);
2562 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002563 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002564 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2565 }
2566
Sergey Silkin86684962018-03-28 19:32:37 +02002567 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002568 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002569 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2570 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002571
2572 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002573 EXPECT_TRUE(
2574 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002575 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002576
Sergey Silkin86684962018-03-28 19:32:37 +02002577 // Change encoder settings to actually trigger reconfiguration.
2578 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002579 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002580 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002581 ASSERT_TRUE(
2582 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002583 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002584 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2585 "new encoder settings.";
2586 }
2587
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002588 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002589 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002590 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002591 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2592 return 0;
2593 }
2594
2595 T encoder_settings_;
2596 const VideoCodecType video_codec_type_;
2597 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002598 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002599 size_t num_initializations_;
2600 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002601 test::EncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002602 VideoEncoderConfig encoder_config_;
2603};
2604
2605template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002606void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2607 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2608}
2609
2610template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002611void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2612 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002613 EXPECT_EQ(
2614 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002615}
kthelgason29a44e32016-09-27 03:52:02 -07002616
2617template <>
2618rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2619VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2620 return new rtc::RefCountedObject<
2621 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2622}
2623
Peter Boström53eda3d2015-03-27 15:53:18 +01002624template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002625void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2626 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2627}
2628
2629template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002630void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2631 const VideoCodec& config) const {
2632 // Check that the number of temporal layers has propagated properly to
2633 // VideoCodec.
2634 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002635 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002636
2637 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2638 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2639 config.simulcastStream[i].numberOfTemporalLayers);
2640 }
2641
2642 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002643 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002644 VideoCodecVP8 encoder_settings = encoder_settings_;
2645 encoder_settings.numberOfTemporalLayers =
2646 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002647 EXPECT_EQ(
2648 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002649}
kthelgason29a44e32016-09-27 03:52:02 -07002650
2651template <>
2652rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2653VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2654 return new rtc::RefCountedObject<
2655 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2656}
2657
Peter Boström53eda3d2015-03-27 15:53:18 +01002658template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002659void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2660 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2661}
2662
2663template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002664void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2665 const VideoCodec& config) const {
2666 // Check that the number of temporal layers has propagated properly to
2667 // VideoCodec.
2668 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002669 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002670
2671 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2672 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2673 config.simulcastStream[i].numberOfTemporalLayers);
2674 }
2675
2676 // Set expected temporal layers as they should have been set when
2677 // reconfiguring the encoder and not match the set config.
2678 VideoCodecVP9 encoder_settings = encoder_settings_;
2679 encoder_settings.numberOfTemporalLayers =
2680 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002681 EXPECT_EQ(
2682 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002683}
2684
kthelgason29a44e32016-09-27 03:52:02 -07002685template <>
2686rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2687VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2688 return new rtc::RefCountedObject<
2689 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2690}
2691
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002692TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002693 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002694 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002695}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002696
Peter Boström53eda3d2015-03-27 15:53:18 +01002697TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2698 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002699 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002700}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002701
Peter Boström53eda3d2015-03-27 15:53:18 +01002702TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2703 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002704 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002705}
2706
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002707TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002708 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002709 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002710 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2711 rtp_packets_sent_(0),
2712 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002713
2714 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002715 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002716 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002717 RTPHeader header;
2718 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002719 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002720 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2721 return SEND_PACKET;
2722 }
2723
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002724 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002725 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002726 test::RtcpPacketParser parser;
2727 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002728
danilchap3dc929e2016-11-02 08:21:59 -07002729 if (parser.sender_report()->num_packets() > 0) {
2730 // Only compare sent media bytes if SenderPacketCount matches the
2731 // number of sent rtp packets (a new rtp packet could be sent before
2732 // the rtcp packet).
2733 if (parser.sender_report()->sender_octet_count() > 0 &&
2734 parser.sender_report()->sender_packet_count() ==
2735 rtp_packets_sent_) {
2736 EXPECT_EQ(media_bytes_sent_,
2737 parser.sender_report()->sender_octet_count());
2738 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002739 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002740 }
2741
2742 return SEND_PACKET;
2743 }
2744
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002745 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002746 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002747 }
2748
stefan4b569042015-11-11 06:39:57 -08002749 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002750 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2751 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002752 } test;
2753
stefane74eef12016-01-08 06:47:13 -08002754 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002755}
2756
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002757TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002758 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002759
2760 class VideoStreamFactory
2761 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2762 public:
2763 VideoStreamFactory() {}
2764
2765 private:
2766 std::vector<VideoStream> CreateEncoderStreams(
2767 int width,
2768 int height,
2769 const VideoEncoderConfig& encoder_config) override {
2770 std::vector<VideoStream> streams =
2771 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002772 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
2773 streams[0].num_temporal_layers = 2;
2774 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2775 kScreencastMaxTargetBitrateDeltaKbps);
2776 streams[0].target_bitrate_bps =
2777 streams[0].max_bitrate_bps -
2778 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002779 return streams;
2780 }
2781 };
2782
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002783 class ScreencastTargetBitrateTest : public test::SendTest,
2784 public test::FakeEncoder {
2785 public:
2786 ScreencastTargetBitrateTest()
2787 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002788 test::FakeEncoder(Clock::GetRealTimeClock()),
2789 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002790
2791 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002792 int32_t InitEncode(const VideoCodec* config,
2793 int32_t number_of_cores,
2794 size_t max_payload_size) override {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002795 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
2796 config->maxBitrate - config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002797 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002798 return test::FakeEncoder::InitEncode(
2799 config, number_of_cores, max_payload_size);
2800 }
stefanff483612015-12-21 03:14:00 -08002801 void ModifyVideoConfigs(
2802 VideoSendStream::Config* send_config,
2803 std::vector<VideoReceiveStream::Config>* receive_configs,
2804 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002805 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002806 EXPECT_EQ(1u, encoder_config->number_of_streams);
2807 encoder_config->video_stream_factory =
2808 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002809 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002810 }
2811
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002812 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002813 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002814 << "Timed out while waiting for the encoder to be initialized.";
2815 }
Niels Möller4db138e2018-04-19 09:04:13 +02002816 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002817 } test;
2818
stefane74eef12016-01-08 06:47:13 -08002819 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002820}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002821
philipelc6957c72016-04-28 15:52:49 +02002822TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002823 // These are chosen to be "kind of odd" to not be accidentally checked against
2824 // default values.
2825 static const int kMinBitrateKbps = 137;
2826 static const int kStartBitrateKbps = 345;
2827 static const int kLowerMaxBitrateKbps = 312;
2828 static const int kMaxBitrateKbps = 413;
2829 static const int kIncreasedStartBitrateKbps = 451;
2830 static const int kIncreasedMaxBitrateKbps = 597;
2831 class EncoderBitrateThresholdObserver : public test::SendTest,
2832 public test::FakeEncoder {
2833 public:
eladalon413ee9a2017-08-22 04:02:52 -07002834 explicit EncoderBitrateThresholdObserver(
2835 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002836 : SendTest(kDefaultTimeoutMs),
2837 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002838 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002839 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002840 bitrate_changed_event_(false, false),
2841 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002842 num_initializations_(0),
2843 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002844 send_stream_(nullptr),
2845 encoder_factory_(this) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002846
2847 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002848 int32_t InitEncode(const VideoCodec* codecSettings,
2849 int32_t numberOfCores,
2850 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002851 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2852 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002853 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002854 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2855 codecSettings->minBitrate);
2856 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2857 codecSettings->startBitrate);
2858 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2859 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002860 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002861 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002862 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2863 codecSettings->maxBitrate);
2864 // The start bitrate should be kept (-1) and capped to the max bitrate.
2865 // Since this is not an end-to-end call no receiver should have been
2866 // returning a REMB that could lower this estimate.
2867 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002868 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002869 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2870 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002871 // The start bitrate will be whatever the rate BitRateController
2872 // has currently configured but in the span of the set max and min
2873 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002874 }
2875 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002876 init_encode_event_.Set();
2877
pbos@webrtc.org00873182014-11-25 14:03:34 +00002878 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2879 maxPayloadSize);
2880 }
2881
Erik Språng566124a2018-04-23 12:32:22 +02002882 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Erik Språng08127a92016-11-16 16:41:30 +01002883 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002884 {
2885 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002886 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2887 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002888 }
Erik Språng08127a92016-11-16 16:41:30 +01002889 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002890 }
2891 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002892 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002893 }
2894
2895 void WaitForSetRates(uint32_t expected_bitrate) {
2896 EXPECT_TRUE(
2897 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2898 << "Timed out while waiting encoder rate to be set.";
2899 rtc::CritScope lock(&crit_);
2900 EXPECT_EQ(expected_bitrate, target_bitrate_);
2901 }
2902
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002903 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002904 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002905 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2906 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2907 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002908 return config;
2909 }
2910
perkjfa10b552016-10-02 23:45:26 -07002911 class VideoStreamFactory
2912 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2913 public:
2914 explicit VideoStreamFactory(int min_bitrate_bps)
2915 : min_bitrate_bps_(min_bitrate_bps) {}
2916
2917 private:
2918 std::vector<VideoStream> CreateEncoderStreams(
2919 int width,
2920 int height,
2921 const VideoEncoderConfig& encoder_config) override {
2922 std::vector<VideoStream> streams =
2923 test::CreateVideoStreams(width, height, encoder_config);
2924 streams[0].min_bitrate_bps = min_bitrate_bps_;
2925 return streams;
2926 }
2927
2928 const int min_bitrate_bps_;
2929 };
2930
stefanff483612015-12-21 03:14:00 -08002931 void ModifyVideoConfigs(
2932 VideoSendStream::Config* send_config,
2933 std::vector<VideoReceiveStream::Config>* receive_configs,
2934 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002935 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002936 // Set bitrates lower/higher than min/max to make sure they are properly
2937 // capped.
perkjfa10b552016-10-02 23:45:26 -07002938 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2939 // Create a new StreamFactory to be able to set
2940 // |VideoStream.min_bitrate_bps|.
2941 encoder_config->video_stream_factory =
2942 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002943 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002944 }
2945
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002946 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002947 call_ = sender_call;
2948 }
2949
stefanff483612015-12-21 03:14:00 -08002950 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002951 VideoSendStream* send_stream,
2952 const std::vector<VideoReceiveStream*>& receive_streams) override {
2953 send_stream_ = send_stream;
2954 }
2955
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002956 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002957 ASSERT_TRUE(
2958 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002959 << "Timed out while waiting for encoder to be configured.";
2960 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002961 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002962 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2963 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002964 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002965 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2966 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002967 });
perkj26091b12016-09-01 01:17:40 -07002968 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2969 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002970 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002971 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002972 ASSERT_TRUE(
2973 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002974 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002975 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002976 WaitForSetRates(kLowerMaxBitrateKbps);
2977
2978 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2979 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2980 ASSERT_TRUE(
2981 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002982 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002983 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002984 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002985 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002986 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002987 }
2988
eladalon413ee9a2017-08-22 04:02:52 -07002989 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002990 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002991 rtc::Event bitrate_changed_event_;
2992 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002993 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002994
pbos@webrtc.org00873182014-11-25 14:03:34 +00002995 int num_initializations_;
2996 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002997 webrtc::VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002998 test::EncoderProxyFactory encoder_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002999 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07003000 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003001
stefane74eef12016-01-08 06:47:13 -08003002 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003003}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003004
3005TEST_F(VideoSendStreamTest, ReportsSentResolution) {
3006 static const size_t kNumStreams = 3;
3007 // Unusual resolutions to make sure that they are the ones being reported.
3008 static const struct {
3009 int width;
3010 int height;
3011 } kEncodedResolution[kNumStreams] = {
3012 {241, 181}, {300, 121}, {121, 221}};
3013 class ScreencastTargetBitrateTest : public test::SendTest,
3014 public test::FakeEncoder {
3015 public:
3016 ScreencastTargetBitrateTest()
3017 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02003018 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02003019 send_stream_(nullptr),
3020 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003021
3022 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003023 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003024 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07003025 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003026 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003027 specifics.codecType = kVideoCodecGeneric;
3028
3029 uint8_t buffer[16] = {0};
3030 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
3031 encoded._timeStamp = input_image.timestamp();
3032 encoded.capture_time_ms_ = input_image.render_time_ms();
3033
3034 for (size_t i = 0; i < kNumStreams; ++i) {
3035 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
3036 encoded._frameType = (*frame_types)[i];
3037 encoded._encodedWidth = kEncodedResolution[i].width;
3038 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08003039 EncodedImageCallback* callback;
3040 {
3041 rtc::CritScope cs(&crit_sect_);
3042 callback = callback_;
3043 }
3044 RTC_DCHECK(callback);
3045 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003046 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003047 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003048 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003049 }
3050
Peter Boström5811a392015-12-10 13:02:50 +01003051 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003052 return 0;
3053 }
stefanff483612015-12-21 03:14:00 -08003054 void ModifyVideoConfigs(
3055 VideoSendStream::Config* send_config,
3056 std::vector<VideoReceiveStream::Config>* receive_configs,
3057 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003058 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003059 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003060 }
3061
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003062 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003063
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003064 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003065 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003066 << "Timed out while waiting for the encoder to send one frame.";
3067 VideoSendStream::Stats stats = send_stream_->GetStats();
3068
3069 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003070 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003071 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003072 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003073 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003074 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003075 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003076 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3077 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003078 }
3079 }
3080
stefanff483612015-12-21 03:14:00 -08003081 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003082 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003083 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003084 send_stream_ = send_stream;
3085 }
3086
3087 VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02003088 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003089 } test;
3090
stefane74eef12016-01-08 06:47:13 -08003091 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003092}
philipel0f9af012015-09-01 07:01:51 -07003093
Peter Boström12996152016-05-14 02:03:18 +02003094#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003095class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003096 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003097 Vp9HeaderObserver()
3098 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003099 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003100 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3101 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003102 frames_sent_(0),
3103 expected_width_(0),
3104 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003105
stefanff483612015-12-21 03:14:00 -08003106 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003107 VideoSendStream::Config* send_config,
3108 std::vector<VideoReceiveStream::Config>* receive_configs,
3109 VideoEncoderConfig* encoder_config) {}
3110
Åsa Perssonff24c042015-12-04 10:58:08 +01003111 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003112
3113 private:
minyue20c84cc2017-04-10 16:57:57 -07003114 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003115
perkjfa10b552016-10-02 23:45:26 -07003116 class VideoStreamFactory
3117 : public VideoEncoderConfig::VideoStreamFactoryInterface {
3118 public:
3119 explicit VideoStreamFactory(size_t number_of_temporal_layers)
3120 : number_of_temporal_layers_(number_of_temporal_layers) {}
3121
3122 private:
3123 std::vector<VideoStream> CreateEncoderStreams(
3124 int width,
3125 int height,
3126 const VideoEncoderConfig& encoder_config) override {
3127 std::vector<VideoStream> streams =
3128 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01003129 streams.back().num_temporal_layers = number_of_temporal_layers_;
perkjfa10b552016-10-02 23:45:26 -07003130 return streams;
3131 }
3132
3133 const size_t number_of_temporal_layers_;
3134 };
3135
stefanff483612015-12-21 03:14:00 -08003136 void ModifyVideoConfigs(
3137 VideoSendStream::Config* send_config,
3138 std::vector<VideoReceiveStream::Config>* receive_configs,
3139 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003140 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003141 send_config->rtp.payload_name = "VP9";
3142 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003143 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003144 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
3145 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003146 EXPECT_EQ(1u, encoder_config->number_of_streams);
3147 encoder_config->video_stream_factory =
3148 new rtc::RefCountedObject<VideoStreamFactory>(
3149 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07003150 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003151 }
3152
perkjfa10b552016-10-02 23:45:26 -07003153 void ModifyVideoCaptureStartResolution(int* width,
3154 int* height,
3155 int* frame_rate) override {
3156 expected_width_ = *width;
3157 expected_height_ = *height;
3158 }
3159
philipel0f9af012015-09-01 07:01:51 -07003160 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003161 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3162 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003163 }
3164
3165 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3166 RTPHeader header;
3167 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3168
Åsa Perssonff24c042015-12-04 10:58:08 +01003169 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3170 const uint8_t* payload = packet + header.headerLength;
3171 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003172
Åsa Perssonff24c042015-12-04 10:58:08 +01003173 bool new_packet = packets_sent_ == 0 ||
3174 IsNewerSequenceNumber(header.sequenceNumber,
3175 last_header_.sequenceNumber);
3176 if (payload_length > 0 && new_packet) {
3177 RtpDepacketizer::ParsedPayload parsed;
3178 RtpDepacketizerVp9 depacketizer;
3179 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
3180 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
3181 // Verify common fields for all configurations.
3182 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
3183 CompareConsecutiveFrames(header, parsed.type.Video);
3184 // Verify configuration specific settings.
3185 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07003186
Åsa Perssonff24c042015-12-04 10:58:08 +01003187 ++packets_sent_;
3188 if (header.markerBit) {
3189 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003190 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003191 last_header_ = header;
3192 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07003193 }
philipel0f9af012015-09-01 07:01:51 -07003194 return SEND_PACKET;
3195 }
3196
philipel7fabd462015-09-03 04:42:32 -07003197 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003198 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3199 if (last_vp9_.picture_id > vp9.picture_id) {
3200 return vp9.picture_id == 0; // Wrap.
3201 } else {
3202 return vp9.picture_id == last_vp9_.picture_id + 1;
3203 }
3204 }
3205
3206 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003207 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3208 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3209 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3210 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3211 vp9.spatial_idx);
3212 }
3213
3214 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3215 uint8_t num_layers) const {
3216 switch (num_layers) {
3217 case 0:
3218 VerifyTemporalLayerStructure0(vp9);
3219 break;
3220 case 1:
3221 VerifyTemporalLayerStructure1(vp9);
3222 break;
3223 case 2:
3224 VerifyTemporalLayerStructure2(vp9);
3225 break;
3226 case 3:
3227 VerifyTemporalLayerStructure3(vp9);
3228 break;
3229 default:
3230 RTC_NOTREACHED();
3231 }
3232 }
3233
3234 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3235 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3236 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3237 EXPECT_FALSE(vp9.temporal_up_switch);
3238 }
3239
3240 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3241 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3242 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3243 EXPECT_FALSE(vp9.temporal_up_switch);
3244 }
3245
3246 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3247 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3248 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3249 EXPECT_LE(vp9.temporal_idx, 1);
3250 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3251 if (IsNewPictureId(vp9)) {
3252 uint8_t expected_tid =
3253 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3254 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3255 }
3256 }
3257
3258 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3259 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3260 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3261 EXPECT_LE(vp9.temporal_idx, 2);
3262 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3263 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3264 switch (vp9.temporal_idx) {
3265 case 0:
3266 EXPECT_EQ(2, last_vp9_.temporal_idx);
3267 EXPECT_FALSE(vp9.temporal_up_switch);
3268 break;
3269 case 1:
3270 EXPECT_EQ(2, last_vp9_.temporal_idx);
3271 EXPECT_TRUE(vp9.temporal_up_switch);
3272 break;
3273 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003274 EXPECT_LT(last_vp9_.temporal_idx, 2);
3275 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003276 break;
3277 }
3278 }
3279 }
3280
3281 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3282 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3283 return;
3284
3285 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3286 if (vp9.temporal_idx == 0)
3287 ++expected_tl0_idx;
3288 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3289 }
3290
3291 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3292 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3293 }
3294
3295 // Flexible mode (F=1): Non-flexible mode (F=0):
3296 //
3297 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3298 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3299 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3300 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3301 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3302 // M: | EXTENDED PID | M: | EXTENDED PID |
3303 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3304 // L: | T |U| S |D| L: | T |U| S |D|
3305 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3306 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3307 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3308 // X: |EXTENDED P_DIFF| V: | SS .. |
3309 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3310 // V: | SS .. |
3311 // +-+-+-+-+-+-+-+-+
3312 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3313 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3314 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3315 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003316
3317 if (vp9_settings_.numberOfSpatialLayers > 1) {
3318 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3319 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3320 EXPECT_EQ(vp9.spatial_idx, 0);
3321 } else {
3322 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3323 }
3324
3325 if (vp9_settings_.numberOfTemporalLayers > 1) {
3326 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3327 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3328 EXPECT_EQ(vp9.temporal_idx, 0);
3329 } else {
3330 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3331 }
3332
Åsa Perssonff24c042015-12-04 10:58:08 +01003333 if (vp9.ss_data_available) // V
3334 VerifySsData(vp9);
3335
3336 if (frames_sent_ == 0)
3337 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3338
3339 if (!vp9.inter_pic_predicted) {
3340 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3341 EXPECT_FALSE(vp9.temporal_up_switch);
3342 }
3343 }
3344
3345 // Scalability structure (SS).
3346 //
3347 // +-+-+-+-+-+-+-+-+
3348 // V: | N_S |Y|G|-|-|-|
3349 // +-+-+-+-+-+-+-+-+
3350 // Y: | WIDTH | N_S + 1 times
3351 // +-+-+-+-+-+-+-+-+
3352 // | HEIGHT |
3353 // +-+-+-+-+-+-+-+-+
3354 // G: | N_G |
3355 // +-+-+-+-+-+-+-+-+
3356 // N_G: | T |U| R |-|-| N_G times
3357 // +-+-+-+-+-+-+-+-+
3358 // | P_DIFF | R times
3359 // +-+-+-+-+-+-+-+-+
3360 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3361 EXPECT_TRUE(vp9.ss_data_available); // V
3362 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3363 vp9.num_spatial_layers);
3364 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003365 int expected_width = expected_width_;
3366 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003367 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003368 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3369 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3370 expected_width /= 2;
3371 expected_height /= 2;
3372 }
3373 }
3374
3375 void CompareConsecutiveFrames(const RTPHeader& header,
3376 const RTPVideoHeader& video) const {
3377 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3378
3379 bool new_frame = packets_sent_ == 0 ||
3380 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003381 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003382 if (!new_frame) {
3383 EXPECT_FALSE(last_header_.markerBit);
3384 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3385 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3386 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3387 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3388 VerifySpatialIdxWithinFrame(vp9);
3389 return;
3390 }
3391 // New frame.
3392 EXPECT_TRUE(vp9.beginning_of_frame);
3393
3394 // Compare with last packet in previous frame.
3395 if (frames_sent_ == 0)
3396 return;
3397 EXPECT_TRUE(last_vp9_.end_of_frame);
3398 EXPECT_TRUE(last_header_.markerBit);
3399 EXPECT_TRUE(ContinuousPictureId(vp9));
3400 VerifyTl0Idx(vp9);
3401 }
3402
Niels Möller4db138e2018-04-19 09:04:13 +02003403 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003404 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003405 webrtc::VideoEncoderConfig encoder_config_;
3406 RTPHeader last_header_;
3407 RTPVideoHeaderVP9 last_vp9_;
3408 size_t packets_sent_;
3409 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003410 int expected_width_;
3411 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003412};
3413
Åsa Perssonff24c042015-12-04 10:58:08 +01003414TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3415 const uint8_t kNumTemporalLayers = 1;
3416 const uint8_t kNumSpatialLayers = 1;
3417 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3418}
3419
3420TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3421 const uint8_t kNumTemporalLayers = 2;
3422 const uint8_t kNumSpatialLayers = 1;
3423 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3424}
3425
3426TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3427 const uint8_t kNumTemporalLayers = 3;
3428 const uint8_t kNumSpatialLayers = 1;
3429 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3430}
3431
3432TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3433 const uint8_t kNumTemporalLayers = 1;
3434 const uint8_t kNumSpatialLayers = 2;
3435 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3436}
3437
3438TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3439 const uint8_t kNumTemporalLayers = 2;
3440 const uint8_t kNumSpatialLayers = 2;
3441 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3442}
3443
3444TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3445 const uint8_t kNumTemporalLayers = 3;
3446 const uint8_t kNumSpatialLayers = 2;
3447 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3448}
3449
3450void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3451 uint8_t num_spatial_layers) {
3452 static const size_t kNumFramesToSend = 100;
3453 // Set to < kNumFramesToSend and coprime to length of temporal layer
3454 // structures to verify temporal id reset on key frame.
3455 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003456
3457 static const int kWidth = kMinVp9SpatialLayerWidth;
3458 static const int kHeight = kMinVp9SpatialLayerHeight;
3459 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003460 class NonFlexibleMode : public Vp9HeaderObserver {
3461 public:
3462 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3463 : num_temporal_layers_(num_temporal_layers),
3464 num_spatial_layers_(num_spatial_layers),
3465 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003466
stefanff483612015-12-21 03:14:00 -08003467 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003468 VideoSendStream::Config* send_config,
3469 std::vector<VideoReceiveStream::Config>* receive_configs,
3470 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003471 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003472 int bitrate_bps = 0;
3473 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3474 const int width = kWidth << sl_idx;
3475 const int height = kHeight << sl_idx;
3476 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3477 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3478 }
3479 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3480
Åsa Perssonff24c042015-12-04 10:58:08 +01003481 vp9_settings_.flexibleMode = false;
3482 vp9_settings_.frameDroppingOn = false;
3483 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3484 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3485 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003486 }
3487
Sergey Silkin86684962018-03-28 19:32:37 +02003488 void ModifyVideoCaptureStartResolution(int* width,
3489 int* height,
3490 int* frame_rate) override {
3491 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3492 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3493 *width = expected_width_;
3494 *height = expected_height_;
3495 }
3496
Åsa Perssonff24c042015-12-04 10:58:08 +01003497 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003498 bool ss_data_expected =
3499 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3500 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003501 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003502 if (num_spatial_layers_ > 1) {
3503 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3504 } else {
3505 EXPECT_FALSE(vp9.inter_layer_predicted);
3506 }
3507
asapersson38bb8ad2015-12-14 01:41:19 -08003508 EXPECT_EQ(!vp9.inter_pic_predicted,
3509 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003510
3511 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003512 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3513 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3514 } else {
3515 EXPECT_EQ(0, vp9.spatial_idx);
3516 }
3517 if (num_spatial_layers_ > 1)
3518 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003519 }
3520
3521 VerifyFixedTemporalLayerStructure(vp9,
3522 l_field_ ? num_temporal_layers_ : 0);
3523
3524 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003525 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003526 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003527 const uint8_t num_temporal_layers_;
3528 const uint8_t num_spatial_layers_;
3529 const bool l_field_;
3530 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003531
stefane74eef12016-01-08 06:47:13 -08003532 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003533}
3534
asaperssond9f641e2016-01-21 01:11:35 -08003535TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3536 static const size_t kNumFramesToSend = 50;
3537 static const int kWidth = 4;
3538 static const int kHeight = 4;
3539 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3540 void ModifyVideoConfigsHook(
3541 VideoSendStream::Config* send_config,
3542 std::vector<VideoReceiveStream::Config>* receive_configs,
3543 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003544 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003545 vp9_settings_.flexibleMode = false;
3546 vp9_settings_.numberOfTemporalLayers = 1;
3547 vp9_settings_.numberOfSpatialLayers = 1;
3548
perkjfa10b552016-10-02 23:45:26 -07003549 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003550 }
3551
3552 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3553 if (frames_sent_ > kNumFramesToSend)
3554 observation_complete_.Set();
3555 }
perkjfa10b552016-10-02 23:45:26 -07003556
3557 void ModifyVideoCaptureStartResolution(int* width,
3558 int* height,
3559 int* frame_rate) override {
3560 expected_width_ = kWidth;
3561 expected_height_ = kHeight;
3562 *width = kWidth;
3563 *height = kHeight;
3564 }
asaperssond9f641e2016-01-21 01:11:35 -08003565 } test;
3566
3567 RunBaseTest(&test);
3568}
3569
kjellanderf9e2a362017-03-24 12:17:33 -07003570#if defined(WEBRTC_ANDROID)
3571// Crashes on Android; bugs.webrtc.org/7401
3572#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3573#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003574// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3575// the test after webrtc:9270 is implemented.
3576#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3577// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003578#endif
3579TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003580 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003581 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003582 VideoSendStream::Config* send_config,
3583 std::vector<VideoReceiveStream::Config>* receive_configs,
3584 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003585 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003586 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003587 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003588 vp9_settings_.numberOfTemporalLayers = 1;
3589 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003590 }
3591
Åsa Perssonff24c042015-12-04 10:58:08 +01003592 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3593 EXPECT_TRUE(vp9_header.flexible_mode);
3594 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3595 if (vp9_header.inter_pic_predicted) {
3596 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003597 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003598 }
3599 }
3600 } test;
3601
stefane74eef12016-01-08 06:47:13 -08003602 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003603}
Peter Boström12996152016-05-14 02:03:18 +02003604#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003605
perkj803d97f2016-11-01 11:45:46 -07003606void VideoSendStreamTest::TestRequestSourceRotateVideo(
3607 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003608 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003609
3610 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003611 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003612 video_send_config_.rtp.extensions.clear();
3613 if (support_orientation_ext) {
3614 video_send_config_.rtp.extensions.push_back(
3615 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3616 }
3617
3618 CreateVideoStreams();
3619 test::FrameForwarder forwarder;
Taylor Brandstetter49fcc102018-05-16 14:20:41 -07003620 video_send_stream_->SetSource(&forwarder,
3621 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003622
3623 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3624 support_orientation_ext);
3625
3626 DestroyStreams();
3627}
3628
3629TEST_F(VideoSendStreamTest,
3630 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3631 TestRequestSourceRotateVideo(false);
3632}
3633
3634TEST_F(VideoSendStreamTest,
3635 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3636 TestRequestSourceRotateVideo(true);
3637}
3638
michaelta3328772016-11-29 09:25:03 -08003639// This test verifies that overhead is removed from the bandwidth estimate by
3640// testing that the maximum possible target payload rate is smaller than the
3641// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003642TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003643 test::ScopedFieldTrials override_field_trials(
3644 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3645 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3646 public test::FakeEncoder {
3647 public:
eladalon413ee9a2017-08-22 04:02:52 -07003648 explicit RemoveOverheadFromBandwidthTest(
3649 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003650 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3651 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003652 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003653 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003654 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003655 max_bitrate_bps_(0),
3656 first_packet_sent_(false),
3657 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003658
Erik Språng566124a2018-04-23 12:32:22 +02003659 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
michaelta3328772016-11-29 09:25:03 -08003660 uint32_t frameRate) override {
3661 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003662 // Wait for the first sent packet so that videosendstream knows
3663 // rtp_overhead.
3664 if (first_packet_sent_) {
3665 max_bitrate_bps_ = bitrate.get_sum_bps();
3666 bitrate_changed_event_.Set();
3667 }
michaelta3328772016-11-29 09:25:03 -08003668 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3669 }
3670
3671 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3672 call_ = sender_call;
3673 }
3674
3675 void ModifyVideoConfigs(
3676 VideoSendStream::Config* send_config,
3677 std::vector<VideoReceiveStream::Config>* receive_configs,
3678 VideoEncoderConfig* encoder_config) override {
3679 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003680 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003681 EXPECT_FALSE(send_config->rtp.extensions.empty());
3682 }
3683
michaelt192132e2017-01-26 09:05:27 -08003684 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3685 rtc::CritScope lock(&crit_);
3686 first_packet_sent_ = true;
3687 return SEND_PACKET;
3688 }
3689
michaelta3328772016-11-29 09:25:03 -08003690 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003691 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003692 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003693 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003694 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003695 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3696 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003697 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003698 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003699 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3700 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07003701 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3702 });
michaelta3328772016-11-29 09:25:03 -08003703
3704 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003705 // overhead of 40B per packet video produces 2240bps overhead.
3706 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003707 EXPECT_TRUE(
3708 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003709 {
3710 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003711 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003712 }
3713 }
3714
3715 private:
eladalon413ee9a2017-08-22 04:02:52 -07003716 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möller4db138e2018-04-19 09:04:13 +02003717 test::EncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003718 Call* call_;
3719 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003720 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3721 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003722 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003723 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003724 RunBaseTest(&test);
3725}
3726
sprang168794c2017-07-06 04:38:06 -07003727TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3728 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003729
3730 class KeepaliveObserver : public test::SendTest {
3731 public:
3732 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3733
sprangdb2a9fc2017-08-09 06:42:32 -07003734 void OnRtpTransportControllerSendCreated(
3735 RtpTransportControllerSend* controller) override {
3736 RtpKeepAliveConfig config;
3737 config.timeout_interval_ms = kTimeoutMs;
3738 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3739 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003740 }
3741
sprang168794c2017-07-06 04:38:06 -07003742 private:
3743 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3744 RTPHeader header;
3745 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3746
sprangd2702ef2017-07-10 08:41:10 -07003747 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003748 // The video stream has started. Stop it now.
3749 if (capturer_)
3750 capturer_->Stop();
3751 } else {
3752 observation_complete_.Set();
3753 }
3754
3755 return SEND_PACKET;
3756 }
3757
sprang168794c2017-07-06 04:38:06 -07003758 void PerformTest() override {
3759 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3760 }
3761
3762 void OnFrameGeneratorCapturerCreated(
3763 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3764 capturer_ = frame_generator_capturer;
3765 }
3766
3767 test::FrameGeneratorCapturer* capturer_ = nullptr;
3768 } test;
3769
3770 RunBaseTest(&test);
3771}
3772
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003773class PacingFactorObserver : public test::SendTest {
3774 public:
3775 PacingFactorObserver(bool configure_send_side,
3776 rtc::Optional<float> expected_pacing_factor)
3777 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3778 configure_send_side_(configure_send_side),
3779 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003780
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003781 void ModifyVideoConfigs(
3782 VideoSendStream::Config* send_config,
3783 std::vector<VideoReceiveStream::Config>* receive_configs,
3784 VideoEncoderConfig* encoder_config) override {
3785 // Check if send-side bwe extension is already present, and remove it if
3786 // it is not desired.
3787 bool has_send_side = false;
3788 for (auto it = send_config->rtp.extensions.begin();
3789 it != send_config->rtp.extensions.end(); ++it) {
3790 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3791 if (configure_send_side_) {
3792 has_send_side = true;
3793 } else {
3794 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003795 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003796 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003797 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003798 }
3799
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003800 if (configure_send_side_ && !has_send_side) {
3801 // Want send side, not present by default, so add it.
3802 send_config->rtp.extensions.emplace_back(
3803 RtpExtension::kTransportSequenceNumberUri,
3804 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003805 }
3806
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003807 // ALR only enabled for screenshare.
3808 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3809 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003810
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003811 void OnVideoStreamsCreated(
3812 VideoSendStream* send_stream,
3813 const std::vector<VideoReceiveStream*>& receive_streams) override {
3814 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3815 // Video streams created, check that pacing factor is correctly configured.
3816 EXPECT_EQ(expected_pacing_factor_,
3817 internal_send_peer.GetPacingFactorOverride());
3818 observation_complete_.Set();
3819 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003820
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003821 void PerformTest() override {
3822 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3823 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003824
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003825 private:
3826 const bool configure_send_side_;
3827 const rtc::Optional<float> expected_pacing_factor_;
3828};
3829
3830std::string GetAlrProbingExperimentString() {
3831 return std::string(
3832 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3833 "/1.0,2875,80,40,-60,3/";
3834}
3835const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3836
3837TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
3838 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003839 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003840 PacingFactorObserver test_with_send_side(true,
3841 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003842 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003843}
Erik Språng7c8cca32017-10-24 17:05:18 +02003844
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003845TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
3846 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3847 // Send-side bwe off, use configuration should not be overridden.
3848 PacingFactorObserver test_without_send_side(false, rtc::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003849 RunBaseTest(&test_without_send_side);
3850}
3851
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003852// Test class takes as argument a function pointer to reset the send
3853// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3854// change the content type of a VideoSendStream, you need to recreate it.
3855// Stopping and recreating the stream can only be done on the main thread and in
3856// the context of VideoSendStreamTest (not BaseTest). The test switches from
3857// realtime to screenshare and back.
3858template <typename T>
3859class ContentSwitchTest : public test::SendTest {
3860 public:
3861 enum class StreamState {
3862 kBeforeSwitch = 0,
3863 kInScreenshare = 1,
3864 kAfterSwitchBack = 2,
3865 };
3866 static const uint32_t kMinPacketsToSend = 50;
3867
3868 explicit ContentSwitchTest(T* stream_reset_fun)
3869 : SendTest(test::CallTest::kDefaultTimeoutMs),
3870 content_switch_event_(false, false),
3871 call_(nullptr),
3872 state_(StreamState::kBeforeSwitch),
3873 send_stream_(nullptr),
3874 send_stream_config_(nullptr),
3875 packets_sent_(0),
3876 stream_resetter_(stream_reset_fun) {
3877 RTC_DCHECK(stream_resetter_);
3878 }
3879
3880 void OnVideoStreamsCreated(
3881 VideoSendStream* send_stream,
3882 const std::vector<VideoReceiveStream*>& receive_streams) override {
3883 rtc::CritScope lock(&crit_);
3884 send_stream_ = send_stream;
3885 }
3886
3887 void ModifyVideoConfigs(
3888 VideoSendStream::Config* send_config,
3889 std::vector<VideoReceiveStream::Config>* receive_configs,
3890 VideoEncoderConfig* encoder_config) override {
3891 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3892 encoder_config->min_transmit_bitrate_bps = 0;
3893 encoder_config->content_type =
3894 VideoEncoderConfig::ContentType::kRealtimeVideo;
3895 send_stream_config_ = send_config->Copy();
3896 encoder_config_ = encoder_config->Copy();
3897 }
3898
3899 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3900 call_ = sender_call;
3901 }
3902
3903 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3904 rtc::CritScope lock(&crit_);
3905
3906 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3907 float pacing_factor =
3908 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3909 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3910 if (send_stream_->GetStats().content_type ==
3911 webrtc::VideoContentType::SCREENSHARE) {
3912 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3913 }
3914
3915 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3916
3917 // Wait until at least kMinPacketsToSend packets to be sent, so that
3918 // some frames would be encoded.
3919 if (++packets_sent_ < kMinPacketsToSend)
3920 return SEND_PACKET;
3921
3922 if (state_ != StreamState::kAfterSwitchBack) {
3923 // We've sent kMinPacketsToSend packets, switch the content type and move
3924 // move to the next state.
3925 // Note that we need to recreate the stream if changing content type.
3926 packets_sent_ = 0;
3927 if (encoder_config_.content_type ==
3928 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3929 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3930 } else {
3931 encoder_config_.content_type =
3932 VideoEncoderConfig::ContentType::kRealtimeVideo;
3933 }
3934 switch (state_) {
3935 case StreamState::kBeforeSwitch:
3936 state_ = StreamState::kInScreenshare;
3937 break;
3938 case StreamState::kInScreenshare:
3939 state_ = StreamState::kAfterSwitchBack;
3940 break;
3941 case StreamState::kAfterSwitchBack:
3942 RTC_NOTREACHED();
3943 break;
3944 }
3945 content_switch_event_.Set();
3946 return SEND_PACKET;
3947 }
3948
3949 observation_complete_.Set();
3950 return SEND_PACKET;
3951 }
3952
3953 void PerformTest() override {
3954 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3955 ASSERT_TRUE(
3956 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3957 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3958 }
3959
3960 ASSERT_TRUE(Wait())
3961 << "Timed out waiting for a frame sent after switch back";
3962 }
3963
3964 private:
3965 StreamState GetStreamState() {
3966 rtc::CritScope lock(&crit_);
3967 return state_;
3968 }
3969
3970 rtc::CriticalSection crit_;
3971 rtc::Event content_switch_event_;
3972 Call* call_;
3973 StreamState state_ RTC_GUARDED_BY(crit_);
3974 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3975 VideoSendStream::Config send_stream_config_;
3976 VideoEncoderConfig encoder_config_;
3977 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3978 T* stream_resetter_;
3979};
3980
3981TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
3982 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3983 const VideoEncoderConfig& encoder_config,
3984 test::BaseTest* test) {
3985 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3986 Stop();
3987 sender_call_->DestroyVideoSendStream(video_send_stream_);
3988 video_send_config_ = send_stream_config.Copy();
3989 video_encoder_config_ = encoder_config.Copy();
3990 video_send_stream_ = sender_call_->CreateVideoSendStream(
3991 video_send_config_.Copy(), video_encoder_config_.Copy());
Taylor Brandstetter49fcc102018-05-16 14:20:41 -07003992 video_send_stream_->SetSource(frame_generator_capturer_.get(),
3993 DegradationPreference::MAINTAIN_RESOLUTION);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003994 test->OnVideoStreamsCreated(video_send_stream_, video_receive_streams_);
3995 Start();
3996 });
3997 };
3998 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3999 RunBaseTest(&test);
4000}
4001
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00004002} // namespace webrtc