blob: 7a2ded0e152900c81ce946208c70e0eda5326008 [file] [log] [blame]
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000010#include <algorithm> // max
kwiberg27f982b2016-03-01 11:52:33 -080011#include <memory>
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +000012#include <vector>
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000013
Artem Titov46c4e602018-08-17 14:26:54 +020014#include "api/test/simulated_network.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "call/call.h"
16#include "call/rtp_transport_controller_send.h"
17#include "common_video/include/frame_callback.h"
18#include "common_video/include/video_frame.h"
19#include "modules/rtp_rtcp/include/rtp_header_parser.h"
20#include "modules/rtp_rtcp/include/rtp_rtcp.h"
21#include "modules/rtp_rtcp/source/rtcp_sender.h"
22#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
23#include "modules/video_coding/codecs/vp8/include/vp8.h"
24#include "modules/video_coding/codecs/vp9/include/vp9.h"
25#include "rtc_base/bind.h"
26#include "rtc_base/checks.h"
27#include "rtc_base/criticalsection.h"
28#include "rtc_base/event.h"
Sebastian Janssoncabe3832018-01-12 10:54:18 +010029#include "rtc_base/experiments/alr_experiment.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "rtc_base/logging.h"
31#include "rtc_base/platform_thread.h"
32#include "rtc_base/rate_limiter.h"
33#include "rtc_base/timeutils.h"
34#include "system_wrappers/include/sleep.h"
35#include "test/call_test.h"
36#include "test/configurable_frame_size_encoder.h"
Niels Möller4db138e2018-04-19 09:04:13 +020037#include "test/encoder_proxy_factory.h"
38#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020039#include "test/fake_texture_frame.h"
40#include "test/field_trial.h"
41#include "test/frame_generator.h"
42#include "test/frame_generator_capturer.h"
43#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010044#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020045#include "test/gtest.h"
46#include "test/null_transport.h"
47#include "test/rtcp_packet_parser.h"
48#include "test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070049
Sebastian Janssona45c8da2018-01-16 10:55:29 +010050#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020051#include "video/send_statistics_proxy.h"
52#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010053#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000054
55namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010056namespace test {
57class VideoSendStreamPeer {
58 public:
59 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
60 : internal_stream_(
61 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020062 absl::optional<float> GetPacingFactorOverride() const {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010063 return internal_stream_->GetPacingFactorOverride();
64 }
65
66 private:
67 internal::VideoSendStream const* const internal_stream_;
68};
69} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000070
Yves Gerey665174f2018-06-19 15:03:05 +020071enum VideoFormat {
72 kGeneric,
73 kVP8,
74};
sprang@webrtc.org346094c2014-02-18 08:40:33 +000075
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070076void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
77 const std::vector<VideoFrame>& frames2);
78VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000079
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000080class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000081 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000082 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000083 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000084 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010085
86 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
87 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070088
89 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000090};
91
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000092TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070093 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +020094 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000095
eladalon413ee9a2017-08-22 04:02:52 -070096 test::NullTransport transport;
97 CreateSendConfig(1, 0, 0, &transport);
98 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +020099 GetVideoSendStream()->Start();
100 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700101 DestroyStreams();
102 DestroyCalls();
103 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000104}
105
106TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700107 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200108 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000109
eladalon413ee9a2017-08-22 04:02:52 -0700110 test::NullTransport transport;
111 CreateSendConfig(1, 0, 0, &transport);
112 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200113 GetVideoSendStream()->Stop();
114 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700115 DestroyStreams();
116 DestroyCalls();
117 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000118}
119
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000120TEST_F(VideoSendStreamTest, SupportsCName) {
121 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000122 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000123 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000124 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000125
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000127 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700128 test::RtcpPacketParser parser;
129 EXPECT_TRUE(parser.Parse(packet, length));
130 if (parser.sdes()->num_packets() > 0) {
131 EXPECT_EQ(1u, parser.sdes()->chunks().size());
132 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000133
danilchap3dc929e2016-11-02 08:21:59 -0700134 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000135 }
136
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000137 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000138 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000139
stefanff483612015-12-21 03:14:00 -0800140 void ModifyVideoConfigs(
141 VideoSendStream::Config* send_config,
142 std::vector<VideoReceiveStream::Config>* receive_configs,
143 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000144 send_config->rtp.c_name = kCName;
145 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000146
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000147 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100148 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000149 }
150 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000151
stefane74eef12016-01-08 06:47:13 -0800152 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000153}
154
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000155TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000156 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000157 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000158 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000159 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100160 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000161 }
162
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000163 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000164 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000165 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000166
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000167 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
168 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
169 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700170 if (header.extension.absoluteSendTime != 0) {
171 // Wait for at least one packet with a non-zero send time. The send time
172 // is a 16-bit value derived from the system clock, and it is valid
173 // for a packet to have a zero send time. To tell that from an
174 // unpopulated value we'll wait for a packet with non-zero send time.
175 observation_complete_.Set();
176 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100177 RTC_LOG(LS_WARNING)
178 << "Got a packet with zero absoluteSendTime, waiting"
179 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700180 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000181
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000182 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000183 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000184
stefanff483612015-12-21 03:14:00 -0800185 void ModifyVideoConfigs(
186 VideoSendStream::Config* send_config,
187 std::vector<VideoReceiveStream::Config>* receive_configs,
188 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200189 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100190 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700191 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000192 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000193
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000194 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100195 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000196 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000197 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000198
stefane74eef12016-01-08 06:47:13 -0800199 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000200}
201
pbos@webrtc.org29023282013-09-11 10:14:56 +0000202TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000203 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000204 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000205 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000206 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200207 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200208 return absl::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200209 Clock::GetRealTimeClock(), kEncodeDelayMs);
210 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000211 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100212 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000213 }
214
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000215 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000216 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000217 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000218 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000219
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000220 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
221 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000222 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000223 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100224 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000225
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000226 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000227 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000228
stefanff483612015-12-21 03:14:00 -0800229 void ModifyVideoConfigs(
230 VideoSendStream::Config* send_config,
231 std::vector<VideoReceiveStream::Config>* receive_configs,
232 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200233 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100234 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700235 send_config->rtp.extensions.push_back(RtpExtension(
236 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000237 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000238
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000239 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100240 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000241 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000242
Niels Möller4db138e2018-04-19 09:04:13 +0200243 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000244 } test;
245
stefane74eef12016-01-08 06:47:13 -0800246 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000247}
248
sprang867fb522015-08-03 04:38:41 -0700249TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700250 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700251 class TransportWideSequenceNumberObserver : public test::SendTest {
252 public:
253 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200254 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200255 return absl::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200256 Clock::GetRealTimeClock());
257 }) {
sprang867fb522015-08-03 04:38:41 -0700258 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
259 kRtpExtensionTransportSequenceNumber, kExtensionId));
260 }
261
262 private:
263 Action OnSendRtp(const uint8_t* packet, size_t length) override {
264 RTPHeader header;
265 EXPECT_TRUE(parser_->Parse(packet, length, &header));
266
267 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
268 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
269 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
270
Peter Boström5811a392015-12-10 13:02:50 +0100271 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700272
273 return SEND_PACKET;
274 }
275
stefanff483612015-12-21 03:14:00 -0800276 void ModifyVideoConfigs(
277 VideoSendStream::Config* send_config,
278 std::vector<VideoReceiveStream::Config>* receive_configs,
279 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200280 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700281 }
282
283 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100284 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700285 }
286
Niels Möller4db138e2018-04-19 09:04:13 +0200287 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700288 } test;
289
stefane74eef12016-01-08 06:47:13 -0800290 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700291}
292
perkj803d97f2016-11-01 11:45:46 -0700293TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
294 class VideoRotationObserver : public test::SendTest {
295 public:
296 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
297 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
298 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
299 }
300
301 Action OnSendRtp(const uint8_t* packet, size_t length) override {
302 RTPHeader header;
303 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700304 // Only the last packet of the frame is required to have the extension.
305 if (!header.markerBit)
306 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700307 EXPECT_TRUE(header.extension.hasVideoRotation);
308 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
309 observation_complete_.Set();
310 return SEND_PACKET;
311 }
312
313 void ModifyVideoConfigs(
314 VideoSendStream::Config* send_config,
315 std::vector<VideoReceiveStream::Config>* receive_configs,
316 VideoEncoderConfig* encoder_config) override {
317 send_config->rtp.extensions.clear();
318 send_config->rtp.extensions.push_back(RtpExtension(
319 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
320 }
321
322 void OnFrameGeneratorCapturerCreated(
323 test::FrameGeneratorCapturer* frame_generator_capturer) override {
324 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
325 }
326
327 void PerformTest() override {
328 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
329 }
330 } test;
331
332 RunBaseTest(&test);
333}
334
ilnik00d802b2017-04-11 10:34:31 -0700335TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700336 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700337 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100338 VideoContentTypeObserver()
339 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700340 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
341 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
342 }
343
344 Action OnSendRtp(const uint8_t* packet, size_t length) override {
345 RTPHeader header;
346 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100347 // Only the last packet of the key-frame must have extension.
348 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700349 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100350 // First marker bit seen means that the first frame is sent.
351 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700352 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700353 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
354 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700355 observation_complete_.Set();
356 return SEND_PACKET;
357 }
358
359 void ModifyVideoConfigs(
360 VideoSendStream::Config* send_config,
361 std::vector<VideoReceiveStream::Config>* receive_configs,
362 VideoEncoderConfig* encoder_config) override {
363 send_config->rtp.extensions.clear();
364 send_config->rtp.extensions.push_back(
365 RtpExtension(RtpExtension::kVideoContentTypeUri,
366 test::kVideoContentTypeExtensionId));
367 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
368 }
369
370 void PerformTest() override {
371 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
372 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100373
374 private:
375 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700376 } test;
377
378 RunBaseTest(&test);
379}
380
ilnik04f4d122017-06-19 07:18:55 -0700381TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700382 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700383 public:
ilnik10894992017-06-21 08:23:19 -0700384 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700385 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
386 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
387 }
388
389 Action OnSendRtp(const uint8_t* packet, size_t length) override {
390 RTPHeader header;
391 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700392 // Only the last packet of the frame must have extension.
393 if (!header.markerBit)
394 return SEND_PACKET;
395 EXPECT_TRUE(header.extension.has_video_timing);
396 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700397 return SEND_PACKET;
398 }
399
400 void ModifyVideoConfigs(
401 VideoSendStream::Config* send_config,
402 std::vector<VideoReceiveStream::Config>* receive_configs,
403 VideoEncoderConfig* encoder_config) override {
404 send_config->rtp.extensions.clear();
405 send_config->rtp.extensions.push_back(RtpExtension(
406 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
407 }
408
409 void PerformTest() override {
410 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
411 }
412 } test;
413
414 RunBaseTest(&test);
415}
416
danilchap901b2df2017-07-28 08:56:04 -0700417class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000418 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000419 FakeReceiveStatistics(uint32_t send_ssrc,
420 uint32_t last_sequence_number,
421 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700422 uint8_t fraction_lost) {
423 stat_.SetMediaSsrc(send_ssrc);
424 stat_.SetExtHighestSeqNum(last_sequence_number);
425 stat_.SetCumulativeLost(cumulative_lost);
426 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000427 }
428
danilchap901b2df2017-07-28 08:56:04 -0700429 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
430 EXPECT_GE(max_blocks, 1u);
431 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000432 }
433
434 private:
danilchap901b2df2017-07-28 08:56:04 -0700435 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000436};
437
brandtre602f0a2016-10-31 03:40:49 -0700438class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100439 public:
brandtre602f0a2016-10-31 03:40:49 -0700440 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800441 bool use_nack,
442 bool expect_red,
443 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800444 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200445 VideoEncoderFactory* encoder_factory)
brandtr20d45472017-01-02 00:34:27 -0800446 : EndToEndTest(kTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200447 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100448 payload_name_(codec),
449 use_nack_(use_nack),
450 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700451 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800452 sent_media_(false),
453 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800454 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100455
brandtr20d45472017-01-02 00:34:27 -0800456 // Some of the test cases are expected to time out and thus we are using
457 // a shorter timeout window than the default here.
458 static constexpr size_t kTimeoutMs = 10000;
459
Stefan Holmer4654d202015-12-08 09:10:43 +0100460 private:
461 Action OnSendRtp(const uint8_t* packet, size_t length) override {
462 RTPHeader header;
463 EXPECT_TRUE(parser_->Parse(packet, length, &header));
464
Stefan Holmer4654d202015-12-08 09:10:43 +0100465 int encapsulated_payload_type = -1;
466 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100467 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100468 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
469 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100470 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100471 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
472 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100473 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100474 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100475 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
476 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100477 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
478 length) {
479 // Not padding-only, media received outside of RED.
480 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800481 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100482 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100483 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000484
Stefan Holmer4654d202015-12-08 09:10:43 +0100485 if (header_extensions_enabled_) {
486 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
487 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
488 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
489 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
490 // 24 bits wrap.
491 EXPECT_GT(prev_header_.extension.absoluteSendTime,
492 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000493 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100494 EXPECT_GE(header.extension.absoluteSendTime,
495 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200496 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100497 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
498 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
499 prev_header_.extension.transportSequenceNumber;
500 EXPECT_EQ(1, seq_num_diff);
501 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200502
Stefan Holmer4654d202015-12-08 09:10:43 +0100503 if (encapsulated_payload_type != -1) {
504 if (encapsulated_payload_type ==
505 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700506 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800507 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100508 } else {
brandtr65a1e772016-12-12 01:54:58 -0800509 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000510 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000511 }
512
brandtr20d45472017-01-02 00:34:27 -0800513 if (sent_media_ && sent_ulpfec_) {
514 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100515 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000516
Stefan Holmer4654d202015-12-08 09:10:43 +0100517 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000518
Stefan Holmer4654d202015-12-08 09:10:43 +0100519 return SEND_PACKET;
520 }
521
eladalon413ee9a2017-08-22 04:02:52 -0700522 test::PacketTransport* CreateSendTransport(
523 test::SingleThreadedTaskQueueForTesting* task_queue,
524 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100525 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
526 // Configure some network delay.
527 const int kNetworkDelayMs = 100;
Artem Titov46c4e602018-08-17 14:26:54 +0200528 DefaultNetworkSimulationConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800529 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100530 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700531 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700532 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700533 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100534 }
535
stefanff483612015-12-21 03:14:00 -0800536 void ModifyVideoConfigs(
537 VideoSendStream::Config* send_config,
538 std::vector<VideoReceiveStream::Config>* receive_configs,
539 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100540 if (use_nack_) {
541 send_config->rtp.nack.rtp_history_ms =
542 (*receive_configs)[0].rtp.nack.rtp_history_ms =
543 VideoSendStreamTest::kNackRtpHistoryMs;
544 }
Niels Möller4db138e2018-04-19 09:04:13 +0200545 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200546 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700547 send_config->rtp.ulpfec.red_payload_type =
548 VideoSendStreamTest::kRedPayloadType;
549 send_config->rtp.ulpfec.ulpfec_payload_type =
550 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800551 EXPECT_FALSE(send_config->rtp.extensions.empty());
552 if (!header_extensions_enabled_) {
553 send_config->rtp.extensions.clear();
554 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100555 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700556 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100557 }
Niels Möller259a4972018-04-05 15:36:51 +0200558 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700559 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700560 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700561 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700562 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100563 }
564
565 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800566 EXPECT_EQ(expect_ulpfec_, Wait())
567 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100568 }
569
Niels Möller4db138e2018-04-19 09:04:13 +0200570 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800571 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100572 const bool use_nack_;
573 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700574 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800575 bool sent_media_;
576 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100577 bool header_extensions_enabled_;
578 RTPHeader prev_header_;
579};
580
brandtre602f0a2016-10-31 03:40:49 -0700581TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200582 test::FunctionVideoEncoderFactory encoder_factory(
583 []() { return VP8Encoder::Create(); });
584 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800585 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100586}
587
brandtre602f0a2016-10-31 03:40:49 -0700588TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200589 test::FunctionVideoEncoderFactory encoder_factory(
590 []() { return VP8Encoder::Create(); });
591 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100592 RunBaseTest(&test);
593}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000594
stefan60e10c72017-08-23 10:40:00 -0700595class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
596 protected:
597 VideoSendStreamWithoutUlpfecTest()
598 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
599
600 test::ScopedFieldTrials field_trial_;
601};
602
603TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200604 test::FunctionVideoEncoderFactory encoder_factory(
605 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200606 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700607 RunBaseTest(&test);
608}
609
Peter Boström39593972016-02-15 11:27:15 +0100610// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
611// since we'll still have to re-request FEC packets, effectively wasting
612// bandwidth since the receiver has to wait for FEC retransmissions to determine
613// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700614TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200615 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200616 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200617 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200618 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100619 RunBaseTest(&test);
620}
621
622// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800623TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200624 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200625 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200626 });
627 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100628 RunBaseTest(&test);
629}
630
danilchap9f5b6222017-03-02 06:22:21 -0800631// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
632TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200633 test::FunctionVideoEncoderFactory encoder_factory(
634 []() { return VP8Encoder::Create(); });
635 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100636 RunBaseTest(&test);
637}
638
Peter Boström12996152016-05-14 02:03:18 +0200639#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800640// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
641TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200642 test::FunctionVideoEncoderFactory encoder_factory(
643 []() { return VP9Encoder::Create(); });
644 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800645 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000646}
Peter Boström12996152016-05-14 02:03:18 +0200647#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000648
brandtre78d2662017-01-16 05:57:16 -0800649TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200650 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200651 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200652 Clock::GetRealTimeClock());
653 });
654 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800655 RunBaseTest(&test);
656}
657
brandtr39f97292016-11-16 22:57:50 -0800658// TODO(brandtr): Move these FlexFEC tests when we have created
659// FlexfecSendStream.
660class FlexfecObserver : public test::EndToEndTest {
661 public:
662 FlexfecObserver(bool header_extensions_enabled,
663 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800664 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200665 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100666 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800667 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200668 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800669 payload_name_(codec),
670 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800671 sent_media_(false),
672 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100673 header_extensions_enabled_(header_extensions_enabled),
674 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800675
676 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100677 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800678
679 private:
680 Action OnSendRtp(const uint8_t* packet, size_t length) override {
681 RTPHeader header;
682 EXPECT_TRUE(parser_->Parse(packet, length, &header));
683
brandtr39f97292016-11-16 22:57:50 -0800684 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
685 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
686 sent_flexfec_ = true;
687 } else {
688 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
689 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100690 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
691 num_video_streams_),
692 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800693 sent_media_ = true;
694 }
695
696 if (header_extensions_enabled_) {
697 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
698 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
699 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
700 }
701
brandtr0c5a1542016-11-23 04:42:26 -0800702 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800703 observation_complete_.Set();
704 }
705
706 return SEND_PACKET;
707 }
708
eladalon413ee9a2017-08-22 04:02:52 -0700709 test::PacketTransport* CreateSendTransport(
710 test::SingleThreadedTaskQueueForTesting* task_queue,
711 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800712 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
713 // Therefore we need some network delay.
714 const int kNetworkDelayMs = 100;
Artem Titov46c4e602018-08-17 14:26:54 +0200715 DefaultNetworkSimulationConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800716 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800717 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700718 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700719 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700720 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800721 }
722
723 void ModifyVideoConfigs(
724 VideoSendStream::Config* send_config,
725 std::vector<VideoReceiveStream::Config>* receive_configs,
726 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800727 if (use_nack_) {
728 send_config->rtp.nack.rtp_history_ms =
729 (*receive_configs)[0].rtp.nack.rtp_history_ms =
730 VideoSendStreamTest::kNackRtpHistoryMs;
731 }
Niels Möller4db138e2018-04-19 09:04:13 +0200732 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200733 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800734 if (header_extensions_enabled_) {
735 send_config->rtp.extensions.push_back(RtpExtension(
736 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
737 send_config->rtp.extensions.push_back(RtpExtension(
738 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800739 } else {
740 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800741 }
Niels Möller259a4972018-04-05 15:36:51 +0200742 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800743 }
744
745 void PerformTest() override {
746 EXPECT_TRUE(Wait())
747 << "Timed out waiting for FlexFEC and/or media packets.";
748 }
749
Niels Möller4db138e2018-04-19 09:04:13 +0200750 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800751 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800752 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800753 bool sent_media_;
754 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100755 const bool header_extensions_enabled_;
756 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800757};
758
brandtrd654a9b2016-12-05 05:38:19 -0800759TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200760 test::FunctionVideoEncoderFactory encoder_factory(
761 []() { return VP8Encoder::Create(); });
762 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100763 RunBaseTest(&test);
764}
765
766TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200767 test::FunctionVideoEncoderFactory encoder_factory(
768 []() { return VP8Encoder::Create(); });
769 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800770 RunBaseTest(&test);
771}
772
773TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200774 test::FunctionVideoEncoderFactory encoder_factory(
775 []() { return VP8Encoder::Create(); });
776 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800777 RunBaseTest(&test);
778}
779
brandtr39f97292016-11-16 22:57:50 -0800780TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200781 test::FunctionVideoEncoderFactory encoder_factory(
782 []() { return VP8Encoder::Create(); });
783 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800784 RunBaseTest(&test);
785}
786
brandtr39f97292016-11-16 22:57:50 -0800787#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800788TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200789 test::FunctionVideoEncoderFactory encoder_factory(
790 []() { return VP9Encoder::Create(); });
791 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800792 RunBaseTest(&test);
793}
794
brandtrd654a9b2016-12-05 05:38:19 -0800795TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200796 test::FunctionVideoEncoderFactory encoder_factory(
797 []() { return VP9Encoder::Create(); });
798 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800799 RunBaseTest(&test);
800}
801#endif // defined(RTC_DISABLE_VP9)
802
brandtrd654a9b2016-12-05 05:38:19 -0800803TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200804 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200805 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200806 });
807 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800808 RunBaseTest(&test);
809}
810
brandtrd654a9b2016-12-05 05:38:19 -0800811TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200812 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200813 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200814 });
815 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800816 RunBaseTest(&test);
817}
818
brandtre78d2662017-01-16 05:57:16 -0800819TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200820 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200821 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200822 Clock::GetRealTimeClock());
823 });
824
825 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800826 RunBaseTest(&test);
827}
828
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000829void VideoSendStreamTest::TestNackRetransmission(
830 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000831 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000832 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000833 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000834 explicit NackObserver(uint32_t retransmit_ssrc,
835 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000836 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000837 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100838 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000839 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100840 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000841
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000842 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000843 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000844 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000845 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000846
Sebastian Janssond3f38162018-02-28 16:14:44 +0100847 int kRetransmitTarget = 6;
848 ++send_count_;
849 if (send_count_ == 5 || send_count_ == 25) {
850 nacked_sequence_numbers_.push_back(
851 static_cast<uint16_t>(header.sequenceNumber - 3));
852 nacked_sequence_numbers_.push_back(
853 static_cast<uint16_t>(header.sequenceNumber - 2));
854 nacked_sequence_numbers_.push_back(
855 static_cast<uint16_t>(header.sequenceNumber - 1));
856
danilchap8a1d2a32017-08-01 03:21:37 -0700857 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800858 nullptr, nullptr, transport_adapter_.get(),
859 RtcpIntervalConfig{});
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000860
pbosda903ea2015-10-02 02:36:56 -0700861 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100862 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000863
864 RTCPSender::FeedbackState feedback_state;
865
Sebastian Janssond3f38162018-02-28 16:14:44 +0100866 EXPECT_EQ(0, rtcp_sender.SendRTCP(
867 feedback_state, kRtcpNack,
868 static_cast<int>(nacked_sequence_numbers_.size()),
869 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000870 }
871
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000872 uint16_t sequence_number = header.sequenceNumber;
873
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000874 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100875 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
876 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000877 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000878 const uint8_t* rtx_header = packet + header.headerLength;
879 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
880 }
Sebastian Janssond3f38162018-02-28 16:14:44 +0100881 auto found = std::find(nacked_sequence_numbers_.begin(),
882 nacked_sequence_numbers_.end(), sequence_number);
883 if (found != nacked_sequence_numbers_.end()) {
884 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000885
Sebastian Janssond3f38162018-02-28 16:14:44 +0100886 if (++retransmit_count_ == kRetransmitTarget) {
887 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
888 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
889 observation_complete_.Set();
890 }
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000891 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000892
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000893 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000894 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000895
stefanff483612015-12-21 03:14:00 -0800896 void ModifyVideoConfigs(
897 VideoSendStream::Config* send_config,
898 std::vector<VideoReceiveStream::Config>* receive_configs,
899 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700900 transport_adapter_.reset(
901 new internal::TransportAdapter(send_config->send_transport));
902 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000903 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000904 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100905 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000906 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
907 }
908
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000909 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100910 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000911 }
912
kwiberg27f982b2016-03-01 11:52:33 -0800913 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000914 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100915 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000916 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000917 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100918 std::vector<uint16_t> nacked_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000919 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000920
stefane74eef12016-01-08 06:47:13 -0800921 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000922}
923
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000924TEST_F(VideoSendStreamTest, RetransmitsNack) {
925 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100926 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000927}
928
929TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
930 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000931 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000932}
933
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000934void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
935 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000936 // Use a fake encoder to output a frame of every size in the range [90, 290],
937 // for each size making sure that the exact number of payload bytes received
938 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000939 static const size_t kMaxPacketSize = 128;
940 static const size_t start = 90;
941 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000942
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000943 // Observer that verifies that the expected number of packets and bytes
944 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000945 class FrameFragmentationTest : public test::SendTest,
946 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000947 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000948 FrameFragmentationTest(size_t max_packet_size,
949 size_t start_size,
950 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000951 bool test_generic_packetization,
952 bool use_fec)
953 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000954 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +0200955 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000956 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000957 stop_size_(stop_size),
958 test_generic_packetization_(test_generic_packetization),
959 use_fec_(use_fec),
960 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100961 packets_lost_(0),
962 last_packet_count_(0),
963 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000964 accumulated_size_(0),
965 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000966 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000967 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700968 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000969 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000970 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700971 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000972 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000973
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000974 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000975 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000976 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000977 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000978 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000979
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000980 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000981
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000982 if (use_fec_) {
983 uint8_t payload_type = packet[header.headerLength];
984 bool is_fec = header.payloadType == kRedPayloadType &&
985 payload_type == kUlpfecPayloadType;
986 if (is_fec) {
987 fec_packet_received_ = true;
988 return SEND_PACKET;
989 }
990 }
991
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000992 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000993
994 if (use_fec_)
995 TriggerLossReport(header);
996
997 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200998 size_t overhead = header.headerLength + header.paddingLength;
999 // Only remove payload header and RED header if the packet actually
1000 // contains payload.
1001 if (length > overhead) {
1002 overhead += (1 /* Generic header */);
1003 if (use_fec_)
1004 overhead += 1; // RED for FEC header.
1005 }
1006 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001007 accumulated_payload_ += length - overhead;
1008 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001009
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001010 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001011 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001012 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1013 // With FEC enabled, frame size is incremented asynchronously, so
1014 // "old" frames one byte too small may arrive. Accept, but don't
1015 // increase expected frame size.
1016 accumulated_size_ = 0;
1017 accumulated_payload_ = 0;
1018 return SEND_PACKET;
1019 }
1020
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001021 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001022 if (test_generic_packetization_) {
1023 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1024 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001025
1026 // Last packet of frame; reset counters.
1027 accumulated_size_ = 0;
1028 accumulated_payload_ = 0;
1029 if (current_size_rtp_ == stop_size_) {
1030 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001031 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001032 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001033 // Increase next expected frame size. If testing with FEC, make sure
1034 // a FEC packet has been received for this frame size before
1035 // proceeding, to make sure that redundancy packets don't exceed
1036 // size limit.
1037 if (!use_fec_) {
1038 ++current_size_rtp_;
1039 } else if (fec_packet_received_) {
1040 fec_packet_received_ = false;
1041 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001042
1043 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001044 ++current_size_frame_;
1045 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001046 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001047 }
1048
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001049 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001050 }
1051
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001052 void TriggerLossReport(const RTPHeader& header) {
1053 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001054 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001055 if (++packet_count_ % (100 / kLossPercent) == 0) {
1056 packets_lost_++;
1057 int loss_delta = packets_lost_ - last_packets_lost_;
1058 int packets_delta = packet_count_ - last_packet_count_;
1059 last_packet_count_ = packet_count_;
1060 last_packets_lost_ = packets_lost_;
1061 uint8_t loss_ratio =
1062 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001063 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001064 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001065 packets_lost_, // Cumulative lost.
1066 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001067 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001068 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001069 transport_adapter_.get(), RtcpIntervalConfig{});
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001070
pbosda903ea2015-10-02 02:36:56 -07001071 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001072 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001073
1074 RTCPSender::FeedbackState feedback_state;
1075
1076 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1077 }
1078 }
1079
nisseef8b61e2016-04-29 06:09:15 -07001080 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001081 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001082 // Increase frame size for next encoded frame, in the context of the
1083 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001084 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001085 ++current_size_frame_;
1086 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001087 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001088 }
Sebastian Jansson72582242018-07-13 13:19:42 +02001089 void ModifySenderCallConfig(Call::Config* config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001090 const int kMinBitrateBps = 30000;
Sebastian Jansson72582242018-07-13 13:19:42 +02001091 config->bitrate_config.min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001092 }
1093
stefanff483612015-12-21 03:14:00 -08001094 void ModifyVideoConfigs(
1095 VideoSendStream::Config* send_config,
1096 std::vector<VideoReceiveStream::Config>* receive_configs,
1097 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001098 transport_adapter_.reset(
1099 new internal::TransportAdapter(send_config->send_transport));
1100 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001101 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001102 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1103 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001104 }
1105
1106 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001107 send_config->rtp.payload_name = "VP8";
Niels Möller4db138e2018-04-19 09:04:13 +02001108 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001109 send_config->rtp.max_packet_size = kMaxPacketSize;
1110 send_config->post_encode_callback = this;
1111
Erik Språng95261872015-04-10 11:58:49 +02001112 // Make sure there is at least one extension header, to make the RTP
1113 // header larger than the base length of 12 bytes.
1114 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001115
1116 // Setup screen content disables frame dropping which makes this easier.
1117 class VideoStreamFactory
1118 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1119 public:
1120 explicit VideoStreamFactory(size_t num_temporal_layers)
1121 : num_temporal_layers_(num_temporal_layers) {
1122 EXPECT_GT(num_temporal_layers, 0u);
1123 }
1124
1125 private:
1126 std::vector<VideoStream> CreateEncoderStreams(
1127 int width,
1128 int height,
1129 const VideoEncoderConfig& encoder_config) override {
1130 std::vector<VideoStream> streams =
1131 test::CreateVideoStreams(width, height, encoder_config);
1132 for (VideoStream& stream : streams) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01001133 stream.num_temporal_layers = num_temporal_layers_;
sprang4847ae62017-06-27 07:06:52 -07001134 }
1135 return streams;
1136 }
1137 const size_t num_temporal_layers_;
1138 };
1139
1140 encoder_config->video_stream_factory =
1141 new rtc::RefCountedObject<VideoStreamFactory>(2);
1142 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001143 }
1144
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001145 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001146 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001147 }
1148
kwiberg27f982b2016-03-01 11:52:33 -08001149 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001150 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möller4db138e2018-04-19 09:04:13 +02001151 test::EncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001152
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001153 const size_t max_packet_size_;
1154 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001155 const bool test_generic_packetization_;
1156 const bool use_fec_;
1157
1158 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001159 uint32_t packets_lost_;
1160 uint32_t last_packet_count_;
1161 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001162 size_t accumulated_size_;
1163 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001164 bool fec_packet_received_;
1165
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001166 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001167 rtc::CriticalSection mutex_;
1168 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001169 };
1170
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001171 // Don't auto increment if FEC is used; continue sending frame size until
1172 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001173 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1174 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001175
stefane74eef12016-01-08 06:47:13 -08001176 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001177}
1178
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001179// TODO(sprang): Is there any way of speeding up these tests?
1180TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1181 TestPacketFragmentationSize(kGeneric, false);
1182}
1183
1184TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1185 TestPacketFragmentationSize(kGeneric, true);
1186}
1187
1188TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1189 TestPacketFragmentationSize(kVP8, false);
1190}
1191
1192TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1193 TestPacketFragmentationSize(kVP8, true);
1194}
1195
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001196// The test will go through a number of phases.
1197// 1. Start sending packets.
1198// 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 +00001199// suspend the stream.
1200// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001201// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001202// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001203// When the stream is detected again, and the stats show that the stream
1204// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001205TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1206 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001207
nissed30a1112016-04-18 05:15:22 -07001208 class RembObserver : public test::SendTest,
1209 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001210 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001211 RembObserver()
1212 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001213 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001214 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001215 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001216 rtp_count_(0),
1217 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001218 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001219 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001220 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001221
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001222 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001223 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001224 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001225 ++rtp_count_;
1226 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001227 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001228 last_sequence_number_ = header.sequenceNumber;
1229
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001230 if (test_state_ == kBeforeSuspend) {
1231 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001232 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001233 test_state_ = kDuringSuspend;
1234 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001235 if (header.paddingLength == 0) {
1236 // Received non-padding packet during suspension period. Reset the
1237 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001238 suspended_frame_count_ = 0;
1239 }
stefanf116bd02015-10-27 08:29:42 -07001240 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001241 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001242 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001243 // Non-padding packet observed. Test is almost complete. Will just
1244 // have to wait for the stats to change.
1245 test_state_ = kWaitingForStats;
1246 }
stefanf116bd02015-10-27 08:29:42 -07001247 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001248 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001249 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001250 if (stats.suspended == false) {
1251 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001252 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001253 }
stefanf116bd02015-10-27 08:29:42 -07001254 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001255 }
1256
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001257 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001258 }
1259
perkj26091b12016-09-01 01:17:40 -07001260 // This method implements the rtc::VideoSinkInterface. This is called when
1261 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001262 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001263 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001264 if (test_state_ == kDuringSuspend &&
1265 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001266 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001267 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001268 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001269 test_state_ = kWaitingForPacket;
1270 }
1271 }
1272
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001273 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001274 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001275 low_remb_bps_ = value;
1276 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001277
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001278 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001279 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001280 high_remb_bps_ = value;
1281 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001282
stefanff483612015-12-21 03:14:00 -08001283 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001284 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001285 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001286 stream_ = send_stream;
1287 }
1288
stefanff483612015-12-21 03:14:00 -08001289 void ModifyVideoConfigs(
1290 VideoSendStream::Config* send_config,
1291 std::vector<VideoReceiveStream::Config>* receive_configs,
1292 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001293 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001294 transport_adapter_.reset(
1295 new internal::TransportAdapter(send_config->send_transport));
1296 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001297 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001298 send_config->pre_encode_callback = this;
1299 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001300 int min_bitrate_bps =
1301 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001302 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001303 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001304 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001305 min_bitrate_bps + threshold_window + 5000);
1306 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1307 }
1308
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001309 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001310 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001311 }
1312
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001313 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001314 kBeforeSuspend,
1315 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001316 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001317 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001318 };
1319
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001320 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001321 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001322 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1323 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001324 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001325 transport_adapter_.get(), RtcpIntervalConfig{});
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001326
pbosda903ea2015-10-02 02:36:56 -07001327 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001328 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001329 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001330 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001331 }
1332 RTCPSender::FeedbackState feedback_state;
1333 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1334 }
1335
kwiberg27f982b2016-03-01 11:52:33 -08001336 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001337 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001338 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001339
Peter Boströmf2f82832015-05-01 13:00:41 +02001340 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001341 TestState test_state_ RTC_GUARDED_BY(crit_);
1342 int rtp_count_ RTC_GUARDED_BY(crit_);
1343 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1344 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1345 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1346 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001347 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001348
stefane74eef12016-01-08 06:47:13 -08001349 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001350}
1351
perkj71ee44c2016-06-15 00:47:53 -07001352// This test that padding stops being send after a while if the Camera stops
1353// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001354TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001355 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001356 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001357 NoPaddingWhenVideoIsMuted()
1358 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001359 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001360 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001361 capturer_(nullptr) {}
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;
Artem Titov46c4e602018-08-17 14:26:54 +02001459 DefaultNetworkSimulationConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001460 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;
Yves Gerey665174f2018-06-19 15:03:05 +02001533 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1534 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1535 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001536 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001537 rtp_rtcp_->SetRemb(kRembBitrateBps,
1538 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001539 rtp_rtcp_->Process();
1540 bitrate_capped_ = true;
1541 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001542 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001543 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001544 }
1545 }
stefanf116bd02015-10-27 08:29:42 -07001546 // Packets don't have to be delivered since the test is the receiver.
1547 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001548 }
1549
stefanff483612015-12-21 03:14:00 -08001550 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001551 VideoSendStream* send_stream,
1552 const std::vector<VideoReceiveStream*>& receive_streams) override {
1553 stream_ = send_stream;
1554 RtpRtcp::Configuration config;
1555 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001556 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001557 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001558 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001559 }
1560
stefanff483612015-12-21 03:14:00 -08001561 void ModifyVideoConfigs(
1562 VideoSendStream::Config* send_config,
1563 std::vector<VideoReceiveStream::Config>* receive_configs,
1564 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001565 feedback_transport_.reset(
1566 new internal::TransportAdapter(send_config->send_transport));
1567 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001568 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001569 }
1570
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001571 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001572 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001573 << "Timeout while waiting for low bitrate stats after REMB.";
1574 }
1575
kwiberg27f982b2016-03-01 11:52:33 -08001576 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1577 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001578 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001579 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001580 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001581 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001582
stefane74eef12016-01-08 06:47:13 -08001583 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001584}
1585
Stefan Holmer280de9e2016-09-30 10:06:51 +02001586TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1587 static const int kStartBitrateBps = 300000;
1588 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001589 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001590 class ChangingNetworkRouteTest : public test::EndToEndTest {
1591 public:
eladalon413ee9a2017-08-22 04:02:52 -07001592 explicit ChangingNetworkRouteTest(
1593 test::SingleThreadedTaskQueueForTesting* task_queue)
1594 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1595 task_queue_(task_queue),
1596 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001597 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1598 kRtpExtensionTransportSequenceNumber, kExtensionId));
1599 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001600
1601 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1602 call_ = sender_call;
1603 }
1604
Stefan Holmer280de9e2016-09-30 10:06:51 +02001605 void ModifyVideoConfigs(
1606 VideoSendStream::Config* send_config,
1607 std::vector<VideoReceiveStream::Config>* receive_configs,
1608 VideoEncoderConfig* encoder_config) override {
1609 send_config->rtp.extensions.clear();
1610 send_config->rtp.extensions.push_back(RtpExtension(
1611 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1612 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1613 (*receive_configs)[0].rtp.transport_cc = true;
1614 }
1615
1616 void ModifyAudioConfigs(
1617 AudioSendStream::Config* send_config,
1618 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1619 send_config->rtp.extensions.clear();
1620 send_config->rtp.extensions.push_back(RtpExtension(
1621 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1622 (*receive_configs)[0].rtp.extensions.clear();
1623 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1624 (*receive_configs)[0].rtp.transport_cc = true;
1625 }
1626
Stefan Holmerbe402962016-07-08 16:16:41 +02001627 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1628 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1629 observation_complete_.Set();
1630 }
1631
1632 return SEND_PACKET;
1633 }
1634
1635 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001636 rtc::NetworkRoute new_route;
1637 new_route.connected = true;
1638 new_route.local_network_id = 10;
1639 new_route.remote_network_id = 20;
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();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001862 DestroyVideoSendStreams();
1863 SetVideoSendConfig(send_stream_config);
1864 SetVideoEncoderConfig(encoder_config);
1865 CreateVideoSendStreams();
1866 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
eladalon413ee9a2017-08-22 04:02:52 -07001867 Start();
1868 });
sprangf24a0642017-02-28 13:23:26 -08001869 };
1870 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001871 RunBaseTest(&test);
1872}
1873
perkjfa10b552016-10-02 23:45:26 -07001874// This test verifies that new frame sizes reconfigures encoders even though not
1875// (yet) sending. The purpose of this is to permit encoding as quickly as
1876// possible once we start sending. Likely the frames being input are from the
1877// same source that will be sent later, which just means that we're ready
1878// earlier.
1879TEST_F(VideoSendStreamTest,
1880 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1881 class EncoderObserver : public test::FakeEncoder {
1882 public:
1883 EncoderObserver()
1884 : FakeEncoder(Clock::GetRealTimeClock()),
1885 init_encode_called_(false, false),
1886 number_of_initializations_(0),
1887 last_initialized_frame_width_(0),
1888 last_initialized_frame_height_(0) {}
1889
1890 void WaitForResolution(int width, int height) {
1891 {
1892 rtc::CritScope lock(&crit_);
1893 if (last_initialized_frame_width_ == width &&
1894 last_initialized_frame_height_ == height) {
1895 return;
1896 }
1897 }
Erik Språng08127a92016-11-16 16:41:30 +01001898 EXPECT_TRUE(
1899 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001900 {
1901 rtc::CritScope lock(&crit_);
1902 EXPECT_EQ(width, last_initialized_frame_width_);
1903 EXPECT_EQ(height, last_initialized_frame_height_);
1904 }
1905 }
1906
1907 private:
1908 int32_t InitEncode(const VideoCodec* config,
1909 int32_t number_of_cores,
1910 size_t max_payload_size) override {
1911 rtc::CritScope lock(&crit_);
1912 last_initialized_frame_width_ = config->width;
1913 last_initialized_frame_height_ = config->height;
1914 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001915 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001916 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1917 }
1918
1919 int32_t Encode(const VideoFrame& input_image,
1920 const CodecSpecificInfo* codec_specific_info,
1921 const std::vector<FrameType>* frame_types) override {
1922 ADD_FAILURE()
1923 << "Unexpected Encode call since the send stream is not started";
1924 return 0;
1925 }
1926
1927 rtc::CriticalSection crit_;
1928 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001929 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1930 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1931 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001932 };
1933
perkjfa10b552016-10-02 23:45:26 -07001934 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001935 EncoderObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02001936 test::EncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07001937
Niels Möller4db138e2018-04-19 09:04:13 +02001938 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02001939 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07001940 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001941 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07001942 CreateVideoStreams();
1943 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1944 kDefaultHeight);
1945 frame_generator_capturer_->Start();
1946 });
perkjfa10b552016-10-02 23:45:26 -07001947
1948 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001949
1950 task_queue_.SendTask([this]() {
1951 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1952 kDefaultHeight * 2);
1953 });
1954
perkjfa10b552016-10-02 23:45:26 -07001955 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001956
1957 task_queue_.SendTask([this]() {
1958 DestroyStreams();
1959 DestroyCalls();
1960 });
perkjfa10b552016-10-02 23:45:26 -07001961}
1962
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001963TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1964 class StartBitrateObserver : public test::FakeEncoder {
1965 public:
1966 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001967 : FakeEncoder(Clock::GetRealTimeClock()),
1968 start_bitrate_changed_(false, false),
1969 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001970 int32_t InitEncode(const VideoCodec* config,
1971 int32_t number_of_cores,
1972 size_t max_payload_size) override {
1973 rtc::CritScope lock(&crit_);
1974 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001975 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001976 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1977 }
1978
1979 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1980 rtc::CritScope lock(&crit_);
1981 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001982 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001983 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1984 }
1985
1986 int GetStartBitrateKbps() const {
1987 rtc::CritScope lock(&crit_);
1988 return start_bitrate_kbps_;
1989 }
1990
pbos14fe7082016-04-20 06:35:56 -07001991 bool WaitForStartBitrate() {
1992 return start_bitrate_changed_.Wait(
1993 VideoSendStreamTest::kDefaultTimeoutMs);
1994 }
1995
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001996 private:
pbos5ad935c2016-01-25 03:52:44 -08001997 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001998 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001999 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002000 };
2001
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002002 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002003
solenberg4fbae2b2015-08-28 04:07:10 -07002004 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002005 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002006
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002007 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002008 bitrate_config.start_bitrate_bps =
2009 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002010 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2011 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002012
2013 StartBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002014 test::EncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002015 // Since this test does not use a capturer, set |internal_source| = true.
2016 // Encoder configuration is otherwise updated on the next video frame.
Niels Möller4db138e2018-04-19 09:04:13 +02002017 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002018 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002019
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002020 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002021
pbos14fe7082016-04-20 06:35:56 -07002022 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002023 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002024 encoder.GetStartBitrateKbps());
2025
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002026 GetVideoEncoderConfig()->max_bitrate_bps =
2027 2 * bitrate_config.start_bitrate_bps;
2028 GetVideoSendStream()->ReconfigureVideoEncoder(
2029 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002030
2031 // New bitrate should be reconfigured above the previous max. As there's no
2032 // network connection this shouldn't be flaky, as no bitrate should've been
2033 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002034 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002035 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2036 encoder.GetStartBitrateKbps());
2037
2038 DestroyStreams();
2039}
2040
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002041class StartStopBitrateObserver : public test::FakeEncoder {
2042 public:
2043 StartStopBitrateObserver()
2044 : FakeEncoder(Clock::GetRealTimeClock()),
2045 encoder_init_(false, false),
2046 bitrate_changed_(false, false) {}
2047 int32_t InitEncode(const VideoCodec* config,
2048 int32_t number_of_cores,
2049 size_t max_payload_size) override {
2050 rtc::CritScope lock(&crit_);
2051 encoder_init_.Set();
2052 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2053 }
2054
Erik Språng566124a2018-04-23 12:32:22 +02002055 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002056 uint32_t framerate) override {
2057 rtc::CritScope lock(&crit_);
2058 bitrate_kbps_ = bitrate.get_sum_kbps();
2059 bitrate_changed_.Set();
2060 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2061 }
2062
2063 bool WaitForEncoderInit() {
2064 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2065 }
2066
2067 bool WaitBitrateChanged(bool non_zero) {
2068 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002069 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002070 {
2071 rtc::CritScope lock(&crit_);
2072 bitrate_kbps = bitrate_kbps_;
2073 }
2074 if (!bitrate_kbps)
2075 continue;
2076
2077 if ((non_zero && *bitrate_kbps > 0) ||
2078 (!non_zero && *bitrate_kbps == 0)) {
2079 return true;
2080 }
2081 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2082 return false;
2083 }
2084
2085 private:
2086 rtc::CriticalSection crit_;
2087 rtc::Event encoder_init_;
2088 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002089 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002090};
2091
perkj57c21f92016-06-17 07:27:16 -07002092// This test that if the encoder use an internal source, VideoEncoder::SetRates
2093// will be called with zero bitrate during initialization and that
2094// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2095// with zero bitrate.
2096TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002097 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002098 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002099 test::EncoderProxyFactory encoder_factory(&encoder);
2100 encoder_factory.SetHasInternalSource(true);
2101 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002102
Niels Möller4db138e2018-04-19 09:04:13 +02002103 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002104 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002105 CreateSendConfig(1, 0, 0, &transport);
2106
2107 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002108 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002109
2110 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002111 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002112 GetVideoSendStream()->Start();
2113 GetVideoSendStream()->SetSource(&forwarder,
2114 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002115 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002116 });
perkj57c21f92016-06-17 07:27:16 -07002117
2118 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002119
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002120 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002121 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2122
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002123 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002124 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2125
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002126 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002127 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002128
eladalon413ee9a2017-08-22 04:02:52 -07002129 task_queue_.SendTask([this]() {
2130 DestroyStreams();
2131 DestroyCalls();
2132 });
perkj57c21f92016-06-17 07:27:16 -07002133}
2134
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002135// Tests that when the encoder uses an internal source, the VideoEncoder will
2136// be updated with a new bitrate when turning the VideoSendStream on/off with
2137// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2138// is reconfigured with new active layers.
2139TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
2140 test::NullTransport transport;
2141 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002142 test::EncoderProxyFactory encoder_factory(&encoder);
2143 encoder_factory.SetHasInternalSource(true);
2144 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002145
Niels Möller4db138e2018-04-19 09:04:13 +02002146 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002147 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002148 // Create two simulcast streams.
2149 CreateSendConfig(2, 0, 0, &transport);
2150
2151 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002152 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002153
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002154 GetVideoSendConfig()->rtp.payload_name = "VP8";
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002155
2156 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002157
2158 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002159 GetVideoSendStream()->Start();
2160 GetVideoSendStream()->SetSource(&forwarder,
2161 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002162 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002163 });
2164
2165 EXPECT_TRUE(encoder.WaitForEncoderInit());
2166
2167 // When we turn on the simulcast layers it will update the BitrateAllocator,
2168 // which in turn updates the VideoEncoder's bitrate.
2169 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002170 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002171 });
2172 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2173
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002174 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2175 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002176 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002177 GetVideoSendStream()->ReconfigureVideoEncoder(
2178 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002179 });
2180 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2181 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2182 // active. Once the change is made for a "soft" reconfiguration we can remove
2183 // the expecation for an encoder init. We can also test that bitrate changes
2184 // when just updating individual active layers, which should change the
2185 // bitrate set to the video encoder.
2186 EXPECT_TRUE(encoder.WaitForEncoderInit());
2187 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2188
2189 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002190 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2191 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002192 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002193 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002194 });
2195 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2196
2197 task_queue_.SendTask([this]() {
2198 DestroyStreams();
2199 DestroyCalls();
2200 });
2201}
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002202TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002203 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002204 public:
Peter Boström5811a392015-12-10 13:02:50 +01002205 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002206
nissed30a1112016-04-18 05:15:22 -07002207 void OnFrame(const VideoFrame& video_frame) override {
2208 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002209 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002210 }
2211
2212 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002213 const int kWaitFrameTimeoutMs = 3000;
2214 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002215 << "Timeout while waiting for output frames.";
2216 }
2217
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002218 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002219 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002220 }
2221
2222 private:
2223 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002224 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002225
2226 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002227 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002228 };
2229
solenberg4fbae2b2015-08-28 04:07:10 -07002230 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002231 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002232 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002233
eladalon413ee9a2017-08-22 04:02:52 -07002234 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2235 // Initialize send stream.
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002236 CreateSenderCall();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002237
eladalon413ee9a2017-08-22 04:02:52 -07002238 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002239 GetVideoSendConfig()->pre_encode_callback = &observer;
eladalon413ee9a2017-08-22 04:02:52 -07002240 CreateVideoStreams();
2241
2242 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2243 // alternatively.
2244 int width = 168;
2245 int height = 132;
2246
2247 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2248 width, height, 1, 1, kVideoRotation_0));
2249 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2250 width, height, 2, 2, kVideoRotation_0));
2251 input_frames.push_back(CreateVideoFrame(width, height, 3));
2252 input_frames.push_back(CreateVideoFrame(width, height, 4));
2253 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2254 width, height, 5, 5, kVideoRotation_0));
2255
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002256 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -07002257 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002258 GetVideoSendStream()->SetSource(&forwarder,
2259 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002260 for (size_t i = 0; i < input_frames.size(); i++) {
2261 forwarder.IncomingCapturedFrame(input_frames[i]);
2262 // Wait until the output frame is received before sending the next input
2263 // frame. Or the previous input frame may be replaced without delivering.
2264 observer.WaitOutputFrame();
2265 }
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002266 GetVideoSendStream()->Stop();
2267 GetVideoSendStream()->SetSource(nullptr,
2268 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002269 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002270
2271 // Test if the input and output frames are the same. render_time_ms and
2272 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002273 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002274
eladalon413ee9a2017-08-22 04:02:52 -07002275 task_queue_.SendTask([this]() {
2276 DestroyStreams();
2277 DestroyCalls();
2278 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002279}
2280
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002281void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2282 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002283 EXPECT_EQ(frames1.size(), frames2.size());
2284 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002285 // Compare frame buffers, since we don't care about differing timestamps.
2286 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2287 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002288}
2289
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002290VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002291 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002292 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002293 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002294 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002295 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002296 // Use data as a ms timestamp.
2297 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002298 return frame;
2299}
2300
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002301TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2302 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2303 public:
eladalon413ee9a2017-08-22 04:02:52 -07002304 explicit EncoderStateObserver(
2305 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002306 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002307 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002308 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002309 initialized_(false),
2310 callback_registered_(false),
2311 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002312 released_(false),
2313 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002314
2315 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002316 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002317 return released_;
2318 }
2319
2320 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002321 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002322 return initialized_ && callback_registered_;
2323 }
2324
2325 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002326 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002327 return num_releases_;
2328 }
2329
2330 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002331 int32_t InitEncode(const VideoCodec* codecSettings,
2332 int32_t numberOfCores,
2333 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002334 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002335 EXPECT_FALSE(initialized_);
2336 initialized_ = true;
2337 released_ = false;
2338 return 0;
2339 }
2340
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002341 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002342 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002343 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002344 EXPECT_TRUE(IsReadyForEncode());
2345
Peter Boström5811a392015-12-10 13:02:50 +01002346 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002347 return 0;
2348 }
2349
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002350 int32_t RegisterEncodeCompleteCallback(
2351 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002352 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002353 EXPECT_TRUE(initialized_);
2354 callback_registered_ = true;
2355 return 0;
2356 }
2357
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002358 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002359 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002360 EXPECT_TRUE(IsReadyForEncode());
2361 EXPECT_FALSE(released_);
2362 initialized_ = false;
2363 callback_registered_ = false;
2364 released_ = true;
2365 ++num_releases_;
2366 return 0;
2367 }
2368
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002369 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002370 EXPECT_TRUE(IsReadyForEncode());
2371 return 0;
2372 }
2373
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002374 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002375 EXPECT_TRUE(IsReadyForEncode());
2376 return 0;
2377 }
2378
stefanff483612015-12-21 03:14:00 -08002379 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002380 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002381 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002382 stream_ = send_stream;
2383 }
2384
stefanff483612015-12-21 03:14:00 -08002385 void ModifyVideoConfigs(
2386 VideoSendStream::Config* send_config,
2387 std::vector<VideoReceiveStream::Config>* receive_configs,
2388 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002389 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002390 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002391 }
2392
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002393 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002394 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002395
2396 task_queue_->SendTask([this]() {
2397 EXPECT_EQ(0u, num_releases());
2398 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2399 EXPECT_EQ(0u, num_releases());
2400 stream_->Stop();
2401 // Encoder should not be released before destroying the VideoSendStream.
2402 EXPECT_FALSE(IsReleased());
2403 EXPECT_TRUE(IsReadyForEncode());
2404 stream_->Start();
2405 });
2406
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002407 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002408 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002409 }
2410
eladalon413ee9a2017-08-22 04:02:52 -07002411 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002412 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002413 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002414 bool initialized_ RTC_GUARDED_BY(crit_);
2415 bool callback_registered_ RTC_GUARDED_BY(crit_);
2416 size_t num_releases_ RTC_GUARDED_BY(crit_);
2417 bool released_ RTC_GUARDED_BY(crit_);
Niels Möller4db138e2018-04-19 09:04:13 +02002418 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002419 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002420 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002421
stefane74eef12016-01-08 06:47:13 -08002422 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002423
2424 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002425 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002426}
2427
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002428TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2429 class VideoCodecConfigObserver : public test::SendTest,
2430 public test::FakeEncoder {
2431 public:
2432 VideoCodecConfigObserver()
2433 : SendTest(kDefaultTimeoutMs),
2434 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002435 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002436 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002437 stream_(nullptr),
2438 encoder_factory_(this) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002439
2440 private:
stefanff483612015-12-21 03:14:00 -08002441 void ModifyVideoConfigs(
2442 VideoSendStream::Config* send_config,
2443 std::vector<VideoReceiveStream::Config>* receive_configs,
2444 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002445 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprangf24a0642017-02-28 13:23:26 -08002446 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002447 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002448 }
2449
stefanff483612015-12-21 03:14:00 -08002450 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002451 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002452 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002453 stream_ = send_stream;
2454 }
2455
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002456 int32_t InitEncode(const VideoCodec* config,
2457 int32_t number_of_cores,
2458 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002459 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002460 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002461 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002462 } else {
2463 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002464 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002465 }
2466 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002467 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002468 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2469 }
2470
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002471 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002472 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002473 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002474
sprangf24a0642017-02-28 13:23:26 -08002475 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002476 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002477 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002478 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002479 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2480 "new encoder settings.";
2481 }
2482
sprangf24a0642017-02-28 13:23:26 -08002483 const uint32_t kFirstMaxBitrateBps = 1000000;
2484 const uint32_t kSecondMaxBitrateBps = 2000000;
2485
pbos14fe7082016-04-20 06:35:56 -07002486 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002487 size_t num_initializations_;
2488 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002489 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002490 VideoEncoderConfig encoder_config_;
2491 } test;
2492
stefane74eef12016-01-08 06:47:13 -08002493 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002494}
2495
Sergey Silkin571e6c92018-04-03 10:03:31 +02002496static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002497template <typename T>
2498class VideoCodecConfigObserver : public test::SendTest,
2499 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002500 public:
2501 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2502 const char* codec_name)
2503 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2504 FakeEncoder(Clock::GetRealTimeClock()),
2505 video_codec_type_(video_codec_type),
2506 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002507 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002508 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002509 stream_(nullptr),
2510 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002511 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002512 }
2513
2514 private:
perkjfa10b552016-10-02 23:45:26 -07002515 class VideoStreamFactory
2516 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2517 public:
2518 VideoStreamFactory() {}
2519
2520 private:
2521 std::vector<VideoStream> CreateEncoderStreams(
2522 int width,
2523 int height,
2524 const VideoEncoderConfig& encoder_config) override {
2525 std::vector<VideoStream> streams =
2526 test::CreateVideoStreams(width, height, encoder_config);
2527 for (size_t i = 0; i < streams.size(); ++i) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002528 streams[i].num_temporal_layers =
2529 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkjfa10b552016-10-02 23:45:26 -07002530 }
2531 return streams;
2532 }
2533 };
2534
stefanff483612015-12-21 03:14:00 -08002535 void ModifyVideoConfigs(
2536 VideoSendStream::Config* send_config,
2537 std::vector<VideoReceiveStream::Config>* receive_configs,
2538 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002539 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002540 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002541
Niels Möller259a4972018-04-05 15:36:51 +02002542 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002543 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002544 encoder_config->video_stream_factory =
2545 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002546 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002547 }
2548
stefanff483612015-12-21 03:14:00 -08002549 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002550 VideoSendStream* send_stream,
2551 const std::vector<VideoReceiveStream*>& receive_streams) override {
2552 stream_ = send_stream;
2553 }
2554
2555 int32_t InitEncode(const VideoCodec* config,
2556 int32_t number_of_cores,
2557 size_t max_payload_size) override {
2558 EXPECT_EQ(video_codec_type_, config->codecType);
2559 VerifyCodecSpecifics(*config);
2560 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002561 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002562 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2563 }
2564
Sergey Silkin86684962018-03-28 19:32:37 +02002565 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002566 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002567 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2568 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002569
2570 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002571 EXPECT_TRUE(
2572 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002573 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002574
Sergey Silkin86684962018-03-28 19:32:37 +02002575 // Change encoder settings to actually trigger reconfiguration.
2576 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002577 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002578 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002579 ASSERT_TRUE(
2580 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002581 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002582 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2583 "new encoder settings.";
2584 }
2585
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002586 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002587 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002588 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002589 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2590 return 0;
2591 }
2592
2593 T encoder_settings_;
2594 const VideoCodecType video_codec_type_;
2595 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002596 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002597 size_t num_initializations_;
2598 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002599 test::EncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002600 VideoEncoderConfig encoder_config_;
2601};
2602
2603template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002604void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2605 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2606}
2607
2608template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002609void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2610 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002611 EXPECT_EQ(
2612 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002613}
kthelgason29a44e32016-09-27 03:52:02 -07002614
2615template <>
2616rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2617VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2618 return new rtc::RefCountedObject<
2619 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2620}
2621
Peter Boström53eda3d2015-03-27 15:53:18 +01002622template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002623void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2624 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2625}
2626
2627template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002628void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2629 const VideoCodec& config) const {
2630 // Check that the number of temporal layers has propagated properly to
2631 // VideoCodec.
2632 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002633 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002634
2635 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2636 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2637 config.simulcastStream[i].numberOfTemporalLayers);
2638 }
2639
2640 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002641 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002642 VideoCodecVP8 encoder_settings = encoder_settings_;
2643 encoder_settings.numberOfTemporalLayers =
2644 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002645 EXPECT_EQ(
2646 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002647}
kthelgason29a44e32016-09-27 03:52:02 -07002648
2649template <>
2650rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2651VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2652 return new rtc::RefCountedObject<
2653 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2654}
2655
Peter Boström53eda3d2015-03-27 15:53:18 +01002656template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002657void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2658 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2659}
2660
2661template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002662void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2663 const VideoCodec& config) const {
2664 // Check that the number of temporal layers has propagated properly to
2665 // VideoCodec.
2666 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002667 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002668
2669 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2670 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2671 config.simulcastStream[i].numberOfTemporalLayers);
2672 }
2673
2674 // Set expected temporal layers as they should have been set when
2675 // reconfiguring the encoder and not match the set config.
2676 VideoCodecVP9 encoder_settings = encoder_settings_;
2677 encoder_settings.numberOfTemporalLayers =
2678 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002679 EXPECT_EQ(
2680 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002681}
2682
kthelgason29a44e32016-09-27 03:52:02 -07002683template <>
2684rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2685VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2686 return new rtc::RefCountedObject<
2687 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2688}
2689
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002690TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002691 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002692 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002693}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002694
Peter Boström53eda3d2015-03-27 15:53:18 +01002695TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2696 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002697 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002698}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002699
Peter Boström53eda3d2015-03-27 15:53:18 +01002700TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2701 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002702 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002703}
2704
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002705TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002706 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002707 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002708 RtcpSenderReportTest()
2709 : SendTest(kDefaultTimeoutMs),
2710 rtp_packets_sent_(0),
2711 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002712
2713 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002714 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002715 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002716 RTPHeader header;
2717 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002718 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002719 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2720 return SEND_PACKET;
2721 }
2722
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002723 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002724 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002725 test::RtcpPacketParser parser;
2726 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002727
danilchap3dc929e2016-11-02 08:21:59 -07002728 if (parser.sender_report()->num_packets() > 0) {
2729 // Only compare sent media bytes if SenderPacketCount matches the
2730 // number of sent rtp packets (a new rtp packet could be sent before
2731 // the rtcp packet).
2732 if (parser.sender_report()->sender_octet_count() > 0 &&
2733 parser.sender_report()->sender_packet_count() ==
2734 rtp_packets_sent_) {
2735 EXPECT_EQ(media_bytes_sent_,
2736 parser.sender_report()->sender_octet_count());
2737 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002738 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002739 }
2740
2741 return SEND_PACKET;
2742 }
2743
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002744 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002745 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002746 }
2747
stefan4b569042015-11-11 06:39:57 -08002748 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002749 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2750 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002751 } test;
2752
stefane74eef12016-01-08 06:47:13 -08002753 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002754}
2755
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002756TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002757 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002758
2759 class VideoStreamFactory
2760 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2761 public:
2762 VideoStreamFactory() {}
2763
2764 private:
2765 std::vector<VideoStream> CreateEncoderStreams(
2766 int width,
2767 int height,
2768 const VideoEncoderConfig& encoder_config) override {
2769 std::vector<VideoStream> streams =
2770 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002771 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
2772 streams[0].num_temporal_layers = 2;
2773 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2774 kScreencastMaxTargetBitrateDeltaKbps);
2775 streams[0].target_bitrate_bps =
2776 streams[0].max_bitrate_bps -
2777 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002778 return streams;
2779 }
2780 };
2781
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002782 class ScreencastTargetBitrateTest : public test::SendTest,
2783 public test::FakeEncoder {
2784 public:
2785 ScreencastTargetBitrateTest()
2786 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002787 test::FakeEncoder(Clock::GetRealTimeClock()),
2788 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002789
2790 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002791 int32_t InitEncode(const VideoCodec* config,
2792 int32_t number_of_cores,
2793 size_t max_payload_size) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002794 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002795 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002796 config->simulcastStream[0].maxBitrate -
2797 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002798 observation_complete_.Set();
Yves Gerey665174f2018-06-19 15:03:05 +02002799 return test::FakeEncoder::InitEncode(config, number_of_cores,
2800 max_payload_size);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002801 }
stefanff483612015-12-21 03:14:00 -08002802 void ModifyVideoConfigs(
2803 VideoSendStream::Config* send_config,
2804 std::vector<VideoReceiveStream::Config>* receive_configs,
2805 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002806 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002807 EXPECT_EQ(1u, encoder_config->number_of_streams);
2808 encoder_config->video_stream_factory =
2809 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002810 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002811 }
2812
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002813 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002814 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002815 << "Timed out while waiting for the encoder to be initialized.";
2816 }
Niels Möller4db138e2018-04-19 09:04:13 +02002817 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002818 } test;
2819
stefane74eef12016-01-08 06:47:13 -08002820 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002821}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002822
philipelc6957c72016-04-28 15:52:49 +02002823TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002824 // These are chosen to be "kind of odd" to not be accidentally checked against
2825 // default values.
2826 static const int kMinBitrateKbps = 137;
2827 static const int kStartBitrateKbps = 345;
2828 static const int kLowerMaxBitrateKbps = 312;
2829 static const int kMaxBitrateKbps = 413;
2830 static const int kIncreasedStartBitrateKbps = 451;
2831 static const int kIncreasedMaxBitrateKbps = 597;
2832 class EncoderBitrateThresholdObserver : public test::SendTest,
2833 public test::FakeEncoder {
2834 public:
eladalon413ee9a2017-08-22 04:02:52 -07002835 explicit EncoderBitrateThresholdObserver(
2836 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002837 : SendTest(kDefaultTimeoutMs),
2838 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002839 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002840 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002841 bitrate_changed_event_(false, false),
2842 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002843 num_initializations_(0),
2844 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002845 send_stream_(nullptr),
2846 encoder_factory_(this) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002847
2848 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002849 int32_t InitEncode(const VideoCodec* codecSettings,
2850 int32_t numberOfCores,
2851 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002852 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2853 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002854 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002855 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2856 codecSettings->minBitrate);
2857 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2858 codecSettings->startBitrate);
2859 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2860 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002861 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002862 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002863 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2864 codecSettings->maxBitrate);
2865 // The start bitrate should be kept (-1) and capped to the max bitrate.
2866 // Since this is not an end-to-end call no receiver should have been
2867 // returning a REMB that could lower this estimate.
2868 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002869 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002870 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2871 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002872 // The start bitrate will be whatever the rate BitRateController
2873 // has currently configured but in the span of the set max and min
2874 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002875 }
2876 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002877 init_encode_event_.Set();
2878
pbos@webrtc.org00873182014-11-25 14:03:34 +00002879 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2880 maxPayloadSize);
2881 }
2882
Erik Språng566124a2018-04-23 12:32:22 +02002883 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Erik Språng08127a92016-11-16 16:41:30 +01002884 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002885 {
2886 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002887 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2888 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002889 }
Erik Språng08127a92016-11-16 16:41:30 +01002890 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002891 }
2892 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002893 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002894 }
2895
2896 void WaitForSetRates(uint32_t expected_bitrate) {
2897 EXPECT_TRUE(
2898 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2899 << "Timed out while waiting encoder rate to be set.";
2900 rtc::CritScope lock(&crit_);
2901 EXPECT_EQ(expected_bitrate, target_bitrate_);
2902 }
2903
Sebastian Jansson72582242018-07-13 13:19:42 +02002904 void ModifySenderCallConfig(Call::Config* config) override {
2905 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 }
2909
perkjfa10b552016-10-02 23:45:26 -07002910 class VideoStreamFactory
2911 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2912 public:
2913 explicit VideoStreamFactory(int min_bitrate_bps)
2914 : min_bitrate_bps_(min_bitrate_bps) {}
2915
2916 private:
2917 std::vector<VideoStream> CreateEncoderStreams(
2918 int width,
2919 int height,
2920 const VideoEncoderConfig& encoder_config) override {
2921 std::vector<VideoStream> streams =
2922 test::CreateVideoStreams(width, height, encoder_config);
2923 streams[0].min_bitrate_bps = min_bitrate_bps_;
2924 return streams;
2925 }
2926
2927 const int min_bitrate_bps_;
2928 };
2929
stefanff483612015-12-21 03:14:00 -08002930 void ModifyVideoConfigs(
2931 VideoSendStream::Config* send_config,
2932 std::vector<VideoReceiveStream::Config>* receive_configs,
2933 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002934 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002935 // Set bitrates lower/higher than min/max to make sure they are properly
2936 // capped.
perkjfa10b552016-10-02 23:45:26 -07002937 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2938 // Create a new StreamFactory to be able to set
2939 // |VideoStream.min_bitrate_bps|.
2940 encoder_config->video_stream_factory =
2941 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002942 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002943 }
2944
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002945 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002946 call_ = sender_call;
2947 }
2948
stefanff483612015-12-21 03:14:00 -08002949 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002950 VideoSendStream* send_stream,
2951 const std::vector<VideoReceiveStream*>& receive_streams) override {
2952 send_stream_ = send_stream;
2953 }
2954
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002955 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002956 ASSERT_TRUE(
2957 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002958 << "Timed out while waiting for encoder to be configured.";
2959 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002960 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002961 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2962 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002963 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002964 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2965 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002966 });
perkj26091b12016-09-01 01:17:40 -07002967 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2968 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002969 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002970 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002971 ASSERT_TRUE(
2972 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002973 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002974 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002975 WaitForSetRates(kLowerMaxBitrateKbps);
2976
2977 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2978 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2979 ASSERT_TRUE(
2980 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002981 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002982 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002983 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002984 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002985 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002986 }
2987
eladalon413ee9a2017-08-22 04:02:52 -07002988 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002989 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002990 rtc::Event bitrate_changed_event_;
2991 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002992 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002993
pbos@webrtc.org00873182014-11-25 14:03:34 +00002994 int num_initializations_;
2995 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002996 webrtc::VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002997 test::EncoderProxyFactory encoder_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002998 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002999 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003000
stefane74eef12016-01-08 06:47:13 -08003001 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003002}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003003
3004TEST_F(VideoSendStreamTest, ReportsSentResolution) {
3005 static const size_t kNumStreams = 3;
3006 // Unusual resolutions to make sure that they are the ones being reported.
3007 static const struct {
3008 int width;
3009 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02003010 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003011 class ScreencastTargetBitrateTest : public test::SendTest,
3012 public test::FakeEncoder {
3013 public:
3014 ScreencastTargetBitrateTest()
3015 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02003016 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02003017 send_stream_(nullptr),
3018 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003019
3020 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003021 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003022 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07003023 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003024 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003025 specifics.codecType = kVideoCodecGeneric;
3026
3027 uint8_t buffer[16] = {0};
3028 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
3029 encoded._timeStamp = input_image.timestamp();
3030 encoded.capture_time_ms_ = input_image.render_time_ms();
3031
3032 for (size_t i = 0; i < kNumStreams; ++i) {
3033 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
3034 encoded._frameType = (*frame_types)[i];
3035 encoded._encodedWidth = kEncodedResolution[i].width;
3036 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08003037 EncodedImageCallback* callback;
3038 {
3039 rtc::CritScope cs(&crit_sect_);
3040 callback = callback_;
3041 }
3042 RTC_DCHECK(callback);
3043 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003044 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003045 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003046 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003047 }
3048
Peter Boström5811a392015-12-10 13:02:50 +01003049 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003050 return 0;
3051 }
stefanff483612015-12-21 03:14:00 -08003052 void ModifyVideoConfigs(
3053 VideoSendStream::Config* send_config,
3054 std::vector<VideoReceiveStream::Config>* receive_configs,
3055 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003056 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003057 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003058 }
3059
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003060 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003061
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003062 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003063 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003064 << "Timed out while waiting for the encoder to send one frame.";
3065 VideoSendStream::Stats stats = send_stream_->GetStats();
3066
3067 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003068 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003069 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003070 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003071 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003072 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003073 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003074 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3075 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003076 }
3077 }
3078
stefanff483612015-12-21 03:14:00 -08003079 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003080 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003081 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003082 send_stream_ = send_stream;
3083 }
3084
3085 VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02003086 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003087 } test;
3088
stefane74eef12016-01-08 06:47:13 -08003089 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003090}
philipel0f9af012015-09-01 07:01:51 -07003091
Peter Boström12996152016-05-14 02:03:18 +02003092#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003093class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003094 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003095 Vp9HeaderObserver()
3096 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003097 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003098 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3099 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003100 frames_sent_(0),
3101 expected_width_(0),
3102 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003103
stefanff483612015-12-21 03:14:00 -08003104 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003105 VideoSendStream::Config* send_config,
3106 std::vector<VideoReceiveStream::Config>* receive_configs,
3107 VideoEncoderConfig* encoder_config) {}
3108
Åsa Perssonff24c042015-12-04 10:58:08 +01003109 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003110
3111 private:
minyue20c84cc2017-04-10 16:57:57 -07003112 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003113
perkjfa10b552016-10-02 23:45:26 -07003114 class VideoStreamFactory
3115 : public VideoEncoderConfig::VideoStreamFactoryInterface {
3116 public:
3117 explicit VideoStreamFactory(size_t number_of_temporal_layers)
3118 : number_of_temporal_layers_(number_of_temporal_layers) {}
3119
3120 private:
3121 std::vector<VideoStream> CreateEncoderStreams(
3122 int width,
3123 int height,
3124 const VideoEncoderConfig& encoder_config) override {
3125 std::vector<VideoStream> streams =
3126 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01003127 streams.back().num_temporal_layers = number_of_temporal_layers_;
perkjfa10b552016-10-02 23:45:26 -07003128 return streams;
3129 }
3130
3131 const size_t number_of_temporal_layers_;
3132 };
3133
stefanff483612015-12-21 03:14:00 -08003134 void ModifyVideoConfigs(
3135 VideoSendStream::Config* send_config,
3136 std::vector<VideoReceiveStream::Config>* receive_configs,
3137 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003138 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003139 send_config->rtp.payload_name = "VP9";
3140 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003141 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003142 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003143 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003144 EXPECT_EQ(1u, encoder_config->number_of_streams);
3145 encoder_config->video_stream_factory =
3146 new rtc::RefCountedObject<VideoStreamFactory>(
3147 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07003148 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003149 }
3150
perkjfa10b552016-10-02 23:45:26 -07003151 void ModifyVideoCaptureStartResolution(int* width,
3152 int* height,
3153 int* frame_rate) override {
3154 expected_width_ = *width;
3155 expected_height_ = *height;
3156 }
3157
philipel0f9af012015-09-01 07:01:51 -07003158 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003159 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3160 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003161 }
3162
3163 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3164 RTPHeader header;
3165 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3166
Åsa Perssonff24c042015-12-04 10:58:08 +01003167 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3168 const uint8_t* payload = packet + header.headerLength;
3169 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003170
Åsa Perssonff24c042015-12-04 10:58:08 +01003171 bool new_packet = packets_sent_ == 0 ||
3172 IsNewerSequenceNumber(header.sequenceNumber,
3173 last_header_.sequenceNumber);
3174 if (payload_length > 0 && new_packet) {
3175 RtpDepacketizer::ParsedPayload parsed;
3176 RtpDepacketizerVp9 depacketizer;
3177 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003178 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003179 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003180 const auto& vp9_header =
3181 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3182 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003183 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003184 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003185 InspectHeader(vp9_header);
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;
philipel29d88462018-08-08 14:26:00 +02003192 last_vp9_ = vp9_header;
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 {
philipel29d88462018-08-08 14:26:00 +02003377 const auto& vp9_header =
3378 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003379
3380 bool new_frame = packets_sent_ == 0 ||
3381 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003382 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003383 if (!new_frame) {
3384 EXPECT_FALSE(last_header_.markerBit);
3385 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003386 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3387 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3388 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3389 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003390 return;
3391 }
3392 // New frame.
philipel29d88462018-08-08 14:26:00 +02003393 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003394
3395 // Compare with last packet in previous frame.
3396 if (frames_sent_ == 0)
3397 return;
3398 EXPECT_TRUE(last_vp9_.end_of_frame);
3399 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003400 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3401 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003402 }
3403
Niels Möller4db138e2018-04-19 09:04:13 +02003404 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003405 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003406 webrtc::VideoEncoderConfig encoder_config_;
3407 RTPHeader last_header_;
3408 RTPVideoHeaderVP9 last_vp9_;
3409 size_t packets_sent_;
3410 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003411 int expected_width_;
3412 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003413};
3414
Åsa Perssonff24c042015-12-04 10:58:08 +01003415TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3416 const uint8_t kNumTemporalLayers = 1;
3417 const uint8_t kNumSpatialLayers = 1;
3418 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3419}
3420
3421TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3422 const uint8_t kNumTemporalLayers = 2;
3423 const uint8_t kNumSpatialLayers = 1;
3424 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3425}
3426
3427TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3428 const uint8_t kNumTemporalLayers = 3;
3429 const uint8_t kNumSpatialLayers = 1;
3430 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3431}
3432
3433TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3434 const uint8_t kNumTemporalLayers = 1;
3435 const uint8_t kNumSpatialLayers = 2;
3436 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3437}
3438
3439TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3440 const uint8_t kNumTemporalLayers = 2;
3441 const uint8_t kNumSpatialLayers = 2;
3442 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3443}
3444
3445TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3446 const uint8_t kNumTemporalLayers = 3;
3447 const uint8_t kNumSpatialLayers = 2;
3448 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3449}
3450
3451void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3452 uint8_t num_spatial_layers) {
3453 static const size_t kNumFramesToSend = 100;
3454 // Set to < kNumFramesToSend and coprime to length of temporal layer
3455 // structures to verify temporal id reset on key frame.
3456 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003457
3458 static const int kWidth = kMinVp9SpatialLayerWidth;
3459 static const int kHeight = kMinVp9SpatialLayerHeight;
3460 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003461 class NonFlexibleMode : public Vp9HeaderObserver {
3462 public:
3463 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3464 : num_temporal_layers_(num_temporal_layers),
3465 num_spatial_layers_(num_spatial_layers),
3466 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003467
stefanff483612015-12-21 03:14:00 -08003468 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003469 VideoSendStream::Config* send_config,
3470 std::vector<VideoReceiveStream::Config>* receive_configs,
3471 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003472 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003473 int bitrate_bps = 0;
3474 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3475 const int width = kWidth << sl_idx;
3476 const int height = kHeight << sl_idx;
3477 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3478 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3479 }
3480 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3481
Åsa Perssonff24c042015-12-04 10:58:08 +01003482 vp9_settings_.flexibleMode = false;
3483 vp9_settings_.frameDroppingOn = false;
3484 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3485 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3486 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003487 }
3488
Sergey Silkin86684962018-03-28 19:32:37 +02003489 void ModifyVideoCaptureStartResolution(int* width,
3490 int* height,
3491 int* frame_rate) override {
3492 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3493 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3494 *width = expected_width_;
3495 *height = expected_height_;
3496 }
3497
Åsa Perssonff24c042015-12-04 10:58:08 +01003498 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003499 bool ss_data_expected =
3500 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3501 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003502 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003503 if (num_spatial_layers_ > 1) {
3504 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3505 } else {
3506 EXPECT_FALSE(vp9.inter_layer_predicted);
3507 }
3508
asapersson38bb8ad2015-12-14 01:41:19 -08003509 EXPECT_EQ(!vp9.inter_pic_predicted,
3510 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003511
3512 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003513 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3514 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3515 } else {
3516 EXPECT_EQ(0, vp9.spatial_idx);
3517 }
3518 if (num_spatial_layers_ > 1)
3519 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003520 }
3521
3522 VerifyFixedTemporalLayerStructure(vp9,
3523 l_field_ ? num_temporal_layers_ : 0);
3524
3525 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003526 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003527 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003528 const uint8_t num_temporal_layers_;
3529 const uint8_t num_spatial_layers_;
3530 const bool l_field_;
3531 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003532
stefane74eef12016-01-08 06:47:13 -08003533 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003534}
3535
asaperssond9f641e2016-01-21 01:11:35 -08003536TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3537 static const size_t kNumFramesToSend = 50;
3538 static const int kWidth = 4;
3539 static const int kHeight = 4;
3540 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3541 void ModifyVideoConfigsHook(
3542 VideoSendStream::Config* send_config,
3543 std::vector<VideoReceiveStream::Config>* receive_configs,
3544 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003545 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003546 vp9_settings_.flexibleMode = false;
3547 vp9_settings_.numberOfTemporalLayers = 1;
3548 vp9_settings_.numberOfSpatialLayers = 1;
3549
perkjfa10b552016-10-02 23:45:26 -07003550 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003551 }
3552
3553 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3554 if (frames_sent_ > kNumFramesToSend)
3555 observation_complete_.Set();
3556 }
perkjfa10b552016-10-02 23:45:26 -07003557
3558 void ModifyVideoCaptureStartResolution(int* width,
3559 int* height,
3560 int* frame_rate) override {
3561 expected_width_ = kWidth;
3562 expected_height_ = kHeight;
3563 *width = kWidth;
3564 *height = kHeight;
3565 }
asaperssond9f641e2016-01-21 01:11:35 -08003566 } test;
3567
3568 RunBaseTest(&test);
3569}
3570
kjellanderf9e2a362017-03-24 12:17:33 -07003571#if defined(WEBRTC_ANDROID)
3572// Crashes on Android; bugs.webrtc.org/7401
3573#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3574#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003575// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3576// the test after webrtc:9270 is implemented.
3577#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3578// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003579#endif
3580TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003581 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003582 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003583 VideoSendStream::Config* send_config,
3584 std::vector<VideoReceiveStream::Config>* receive_configs,
3585 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003586 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003587 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003588 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003589 vp9_settings_.numberOfTemporalLayers = 1;
3590 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003591 }
3592
Åsa Perssonff24c042015-12-04 10:58:08 +01003593 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3594 EXPECT_TRUE(vp9_header.flexible_mode);
3595 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3596 if (vp9_header.inter_pic_predicted) {
3597 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003598 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003599 }
3600 }
3601 } test;
3602
stefane74eef12016-01-08 06:47:13 -08003603 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003604}
Peter Boström12996152016-05-14 02:03:18 +02003605#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003606
perkj803d97f2016-11-01 11:45:46 -07003607void VideoSendStreamTest::TestRequestSourceRotateVideo(
3608 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003609 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003610
3611 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003612 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003613 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003614 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003615 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003616 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3617 }
3618
3619 CreateVideoStreams();
3620 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003621 GetVideoSendStream()->SetSource(&forwarder,
3622 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003623
3624 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3625 support_orientation_ext);
3626
3627 DestroyStreams();
3628}
3629
3630TEST_F(VideoSendStreamTest,
3631 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3632 TestRequestSourceRotateVideo(false);
3633}
3634
3635TEST_F(VideoSendStreamTest,
3636 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3637 TestRequestSourceRotateVideo(true);
3638}
3639
michaelta3328772016-11-29 09:25:03 -08003640// This test verifies that overhead is removed from the bandwidth estimate by
3641// testing that the maximum possible target payload rate is smaller than the
3642// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003643TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003644 test::ScopedFieldTrials override_field_trials(
3645 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3646 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3647 public test::FakeEncoder {
3648 public:
eladalon413ee9a2017-08-22 04:02:52 -07003649 explicit RemoveOverheadFromBandwidthTest(
3650 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003651 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3652 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003653 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003654 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003655 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003656 max_bitrate_bps_(0),
3657 first_packet_sent_(false),
3658 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003659
Erik Språng566124a2018-04-23 12:32:22 +02003660 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
michaelta3328772016-11-29 09:25:03 -08003661 uint32_t frameRate) override {
3662 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003663 // Wait for the first sent packet so that videosendstream knows
3664 // rtp_overhead.
3665 if (first_packet_sent_) {
3666 max_bitrate_bps_ = bitrate.get_sum_bps();
3667 bitrate_changed_event_.Set();
3668 }
michaelta3328772016-11-29 09:25:03 -08003669 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3670 }
3671
3672 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3673 call_ = sender_call;
3674 }
3675
3676 void ModifyVideoConfigs(
3677 VideoSendStream::Config* send_config,
3678 std::vector<VideoReceiveStream::Config>* receive_configs,
3679 VideoEncoderConfig* encoder_config) override {
3680 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003681 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003682 EXPECT_FALSE(send_config->rtp.extensions.empty());
3683 }
3684
michaelt192132e2017-01-26 09:05:27 -08003685 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3686 rtc::CritScope lock(&crit_);
3687 first_packet_sent_ = true;
3688 return SEND_PACKET;
3689 }
3690
michaelta3328772016-11-29 09:25:03 -08003691 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003692 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003693 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003694 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003695 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003696 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3697 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003698 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003699 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003700 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3701 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07003702 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3703 });
michaelta3328772016-11-29 09:25:03 -08003704
3705 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003706 // overhead of 40B per packet video produces 2240bps overhead.
3707 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003708 EXPECT_TRUE(
3709 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003710 {
3711 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003712 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003713 }
3714 }
3715
3716 private:
eladalon413ee9a2017-08-22 04:02:52 -07003717 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möller4db138e2018-04-19 09:04:13 +02003718 test::EncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003719 Call* call_;
3720 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003721 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3722 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003723 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003724 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003725 RunBaseTest(&test);
3726}
3727
sprang168794c2017-07-06 04:38:06 -07003728TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3729 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003730
3731 class KeepaliveObserver : public test::SendTest {
3732 public:
3733 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3734
sprangdb2a9fc2017-08-09 06:42:32 -07003735 void OnRtpTransportControllerSendCreated(
3736 RtpTransportControllerSend* controller) override {
3737 RtpKeepAliveConfig config;
3738 config.timeout_interval_ms = kTimeoutMs;
3739 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3740 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003741 }
3742
sprang168794c2017-07-06 04:38:06 -07003743 private:
3744 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3745 RTPHeader header;
3746 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3747
sprangd2702ef2017-07-10 08:41:10 -07003748 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003749 // The video stream has started. Stop it now.
3750 if (capturer_)
3751 capturer_->Stop();
3752 } else {
3753 observation_complete_.Set();
3754 }
3755
3756 return SEND_PACKET;
3757 }
3758
sprang168794c2017-07-06 04:38:06 -07003759 void PerformTest() override {
3760 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3761 }
3762
3763 void OnFrameGeneratorCapturerCreated(
3764 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3765 capturer_ = frame_generator_capturer;
3766 }
3767
3768 test::FrameGeneratorCapturer* capturer_ = nullptr;
3769 } test;
3770
3771 RunBaseTest(&test);
3772}
3773
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003774class PacingFactorObserver : public test::SendTest {
3775 public:
3776 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003777 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003778 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3779 configure_send_side_(configure_send_side),
3780 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003781
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003782 void ModifyVideoConfigs(
3783 VideoSendStream::Config* send_config,
3784 std::vector<VideoReceiveStream::Config>* receive_configs,
3785 VideoEncoderConfig* encoder_config) override {
3786 // Check if send-side bwe extension is already present, and remove it if
3787 // it is not desired.
3788 bool has_send_side = false;
3789 for (auto it = send_config->rtp.extensions.begin();
3790 it != send_config->rtp.extensions.end(); ++it) {
3791 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3792 if (configure_send_side_) {
3793 has_send_side = true;
3794 } else {
3795 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003796 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003797 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003798 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003799 }
3800
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003801 if (configure_send_side_ && !has_send_side) {
3802 // Want send side, not present by default, so add it.
3803 send_config->rtp.extensions.emplace_back(
3804 RtpExtension::kTransportSequenceNumberUri,
3805 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003806 }
3807
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003808 // ALR only enabled for screenshare.
3809 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3810 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003811
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003812 void OnVideoStreamsCreated(
3813 VideoSendStream* send_stream,
3814 const std::vector<VideoReceiveStream*>& receive_streams) override {
3815 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3816 // Video streams created, check that pacing factor is correctly configured.
3817 EXPECT_EQ(expected_pacing_factor_,
3818 internal_send_peer.GetPacingFactorOverride());
3819 observation_complete_.Set();
3820 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003821
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003822 void PerformTest() override {
3823 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3824 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003825
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003826 private:
3827 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003828 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003829};
3830
3831std::string GetAlrProbingExperimentString() {
3832 return std::string(
3833 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3834 "/1.0,2875,80,40,-60,3/";
3835}
3836const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3837
3838TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
3839 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003840 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003841 PacingFactorObserver test_with_send_side(true,
3842 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003843 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003844}
Erik Språng7c8cca32017-10-24 17:05:18 +02003845
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003846TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
3847 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3848 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003849 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003850 RunBaseTest(&test_without_send_side);
3851}
3852
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003853// Test class takes as argument a function pointer to reset the send
3854// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3855// change the content type of a VideoSendStream, you need to recreate it.
3856// Stopping and recreating the stream can only be done on the main thread and in
3857// the context of VideoSendStreamTest (not BaseTest). The test switches from
3858// realtime to screenshare and back.
3859template <typename T>
3860class ContentSwitchTest : public test::SendTest {
3861 public:
3862 enum class StreamState {
3863 kBeforeSwitch = 0,
3864 kInScreenshare = 1,
3865 kAfterSwitchBack = 2,
3866 };
3867 static const uint32_t kMinPacketsToSend = 50;
3868
3869 explicit ContentSwitchTest(T* stream_reset_fun)
3870 : SendTest(test::CallTest::kDefaultTimeoutMs),
3871 content_switch_event_(false, false),
3872 call_(nullptr),
3873 state_(StreamState::kBeforeSwitch),
3874 send_stream_(nullptr),
3875 send_stream_config_(nullptr),
3876 packets_sent_(0),
3877 stream_resetter_(stream_reset_fun) {
3878 RTC_DCHECK(stream_resetter_);
3879 }
3880
3881 void OnVideoStreamsCreated(
3882 VideoSendStream* send_stream,
3883 const std::vector<VideoReceiveStream*>& receive_streams) override {
3884 rtc::CritScope lock(&crit_);
3885 send_stream_ = send_stream;
3886 }
3887
3888 void ModifyVideoConfigs(
3889 VideoSendStream::Config* send_config,
3890 std::vector<VideoReceiveStream::Config>* receive_configs,
3891 VideoEncoderConfig* encoder_config) override {
3892 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3893 encoder_config->min_transmit_bitrate_bps = 0;
3894 encoder_config->content_type =
3895 VideoEncoderConfig::ContentType::kRealtimeVideo;
3896 send_stream_config_ = send_config->Copy();
3897 encoder_config_ = encoder_config->Copy();
3898 }
3899
3900 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3901 call_ = sender_call;
3902 }
3903
3904 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3905 rtc::CritScope lock(&crit_);
3906
3907 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3908 float pacing_factor =
3909 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3910 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3911 if (send_stream_->GetStats().content_type ==
3912 webrtc::VideoContentType::SCREENSHARE) {
3913 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3914 }
3915
3916 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3917
3918 // Wait until at least kMinPacketsToSend packets to be sent, so that
3919 // some frames would be encoded.
3920 if (++packets_sent_ < kMinPacketsToSend)
3921 return SEND_PACKET;
3922
3923 if (state_ != StreamState::kAfterSwitchBack) {
3924 // We've sent kMinPacketsToSend packets, switch the content type and move
3925 // move to the next state.
3926 // Note that we need to recreate the stream if changing content type.
3927 packets_sent_ = 0;
3928 if (encoder_config_.content_type ==
3929 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3930 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3931 } else {
3932 encoder_config_.content_type =
3933 VideoEncoderConfig::ContentType::kRealtimeVideo;
3934 }
3935 switch (state_) {
3936 case StreamState::kBeforeSwitch:
3937 state_ = StreamState::kInScreenshare;
3938 break;
3939 case StreamState::kInScreenshare:
3940 state_ = StreamState::kAfterSwitchBack;
3941 break;
3942 case StreamState::kAfterSwitchBack:
3943 RTC_NOTREACHED();
3944 break;
3945 }
3946 content_switch_event_.Set();
3947 return SEND_PACKET;
3948 }
3949
3950 observation_complete_.Set();
3951 return SEND_PACKET;
3952 }
3953
3954 void PerformTest() override {
3955 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3956 ASSERT_TRUE(
3957 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3958 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3959 }
3960
3961 ASSERT_TRUE(Wait())
3962 << "Timed out waiting for a frame sent after switch back";
3963 }
3964
3965 private:
3966 StreamState GetStreamState() {
3967 rtc::CritScope lock(&crit_);
3968 return state_;
3969 }
3970
3971 rtc::CriticalSection crit_;
3972 rtc::Event content_switch_event_;
3973 Call* call_;
3974 StreamState state_ RTC_GUARDED_BY(crit_);
3975 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3976 VideoSendStream::Config send_stream_config_;
3977 VideoEncoderConfig encoder_config_;
3978 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3979 T* stream_resetter_;
3980};
3981
3982TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
3983 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3984 const VideoEncoderConfig& encoder_config,
3985 test::BaseTest* test) {
3986 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3987 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003988 DestroyVideoSendStreams();
3989 SetVideoSendConfig(send_stream_config);
3990 SetVideoEncoderConfig(encoder_config);
3991 CreateVideoSendStreams();
3992 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3993 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003994 Start();
3995 });
3996 };
3997 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3998 RunBaseTest(&test);
3999}
4000
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00004001} // namespace webrtc