blob: f5ceccef41a810d54bf31ef9de883742aa99e50a [file] [log] [blame]
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000010#include <algorithm> // max
kwiberg27f982b2016-03-01 11:52:33 -080011#include <memory>
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +000012#include <vector>
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "call/call.h"
15#include "call/rtp_transport_controller_send.h"
16#include "common_video/include/frame_callback.h"
17#include "common_video/include/video_frame.h"
18#include "modules/rtp_rtcp/include/rtp_header_parser.h"
19#include "modules/rtp_rtcp/include/rtp_rtcp.h"
20#include "modules/rtp_rtcp/source/rtcp_sender.h"
21#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
22#include "modules/video_coding/codecs/vp8/include/vp8.h"
23#include "modules/video_coding/codecs/vp9/include/vp9.h"
24#include "rtc_base/bind.h"
25#include "rtc_base/checks.h"
26#include "rtc_base/criticalsection.h"
27#include "rtc_base/event.h"
Sebastian Janssoncabe3832018-01-12 10:54:18 +010028#include "rtc_base/experiments/alr_experiment.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/logging.h"
30#include "rtc_base/platform_thread.h"
31#include "rtc_base/rate_limiter.h"
32#include "rtc_base/timeutils.h"
33#include "system_wrappers/include/sleep.h"
34#include "test/call_test.h"
35#include "test/configurable_frame_size_encoder.h"
Niels Möller4db138e2018-04-19 09:04:13 +020036#include "test/encoder_proxy_factory.h"
37#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "test/fake_texture_frame.h"
39#include "test/field_trial.h"
40#include "test/frame_generator.h"
41#include "test/frame_generator_capturer.h"
42#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010043#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020044#include "test/gtest.h"
45#include "test/null_transport.h"
46#include "test/rtcp_packet_parser.h"
47#include "test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070048
Sebastian Janssona45c8da2018-01-16 10:55:29 +010049#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020050#include "video/send_statistics_proxy.h"
51#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010052#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000053
54namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010055namespace test {
56class VideoSendStreamPeer {
57 public:
58 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
59 : internal_stream_(
60 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020061 absl::optional<float> GetPacingFactorOverride() const {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010062 return internal_stream_->GetPacingFactorOverride();
63 }
64
65 private:
66 internal::VideoSendStream const* const internal_stream_;
67};
68} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000069
Yves Gerey665174f2018-06-19 15:03:05 +020070enum VideoFormat {
71 kGeneric,
72 kVP8,
73};
sprang@webrtc.org346094c2014-02-18 08:40:33 +000074
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070075void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
76 const std::vector<VideoFrame>& frames2);
77VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000078
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000079class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000080 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000081 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000082 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000083 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010084
85 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
86 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070087
88 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000089};
90
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000091TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070092 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +020093 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000094
eladalon413ee9a2017-08-22 04:02:52 -070095 test::NullTransport transport;
96 CreateSendConfig(1, 0, 0, &transport);
97 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +020098 GetVideoSendStream()->Start();
99 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700100 DestroyStreams();
101 DestroyCalls();
102 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000103}
104
105TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700106 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200107 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000108
eladalon413ee9a2017-08-22 04:02:52 -0700109 test::NullTransport transport;
110 CreateSendConfig(1, 0, 0, &transport);
111 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200112 GetVideoSendStream()->Stop();
113 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700114 DestroyStreams();
115 DestroyCalls();
116 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000117}
118
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000119TEST_F(VideoSendStreamTest, SupportsCName) {
120 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000121 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000122 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000123 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000124
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000125 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000126 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700127 test::RtcpPacketParser parser;
128 EXPECT_TRUE(parser.Parse(packet, length));
129 if (parser.sdes()->num_packets() > 0) {
130 EXPECT_EQ(1u, parser.sdes()->chunks().size());
131 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000132
danilchap3dc929e2016-11-02 08:21:59 -0700133 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000134 }
135
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000136 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000137 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000138
stefanff483612015-12-21 03:14:00 -0800139 void ModifyVideoConfigs(
140 VideoSendStream::Config* send_config,
141 std::vector<VideoReceiveStream::Config>* receive_configs,
142 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000143 send_config->rtp.c_name = kCName;
144 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000145
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000146 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100147 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000148 }
149 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000150
stefane74eef12016-01-08 06:47:13 -0800151 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000152}
153
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000154TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000155 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000156 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000157 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000158 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100159 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000160 }
161
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000162 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000163 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000164 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000165
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000166 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
167 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
168 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700169 if (header.extension.absoluteSendTime != 0) {
170 // Wait for at least one packet with a non-zero send time. The send time
171 // is a 16-bit value derived from the system clock, and it is valid
172 // for a packet to have a zero send time. To tell that from an
173 // unpopulated value we'll wait for a packet with non-zero send time.
174 observation_complete_.Set();
175 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100176 RTC_LOG(LS_WARNING)
177 << "Got a packet with zero absoluteSendTime, waiting"
178 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700179 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000180
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000181 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000182 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000183
stefanff483612015-12-21 03:14:00 -0800184 void ModifyVideoConfigs(
185 VideoSendStream::Config* send_config,
186 std::vector<VideoReceiveStream::Config>* receive_configs,
187 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200188 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100189 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700190 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000191 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000192
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000193 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100194 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000195 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000196 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000197
stefane74eef12016-01-08 06:47:13 -0800198 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000199}
200
pbos@webrtc.org29023282013-09-11 10:14:56 +0000201TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000202 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000203 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000204 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000205 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200206 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200207 return absl::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200208 Clock::GetRealTimeClock(), kEncodeDelayMs);
209 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000210 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100211 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000212 }
213
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000214 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000215 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000216 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000217 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000218
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000219 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
220 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000221 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000222 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100223 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000224
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000225 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000226 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000227
stefanff483612015-12-21 03:14:00 -0800228 void ModifyVideoConfigs(
229 VideoSendStream::Config* send_config,
230 std::vector<VideoReceiveStream::Config>* receive_configs,
231 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200232 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100233 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700234 send_config->rtp.extensions.push_back(RtpExtension(
235 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000236 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000237
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000238 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100239 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000240 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000241
Niels Möller4db138e2018-04-19 09:04:13 +0200242 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000243 } test;
244
stefane74eef12016-01-08 06:47:13 -0800245 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000246}
247
sprang867fb522015-08-03 04:38:41 -0700248TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700249 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700250 class TransportWideSequenceNumberObserver : public test::SendTest {
251 public:
252 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200253 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200254 return absl::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200255 Clock::GetRealTimeClock());
256 }) {
sprang867fb522015-08-03 04:38:41 -0700257 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
258 kRtpExtensionTransportSequenceNumber, kExtensionId));
259 }
260
261 private:
262 Action OnSendRtp(const uint8_t* packet, size_t length) override {
263 RTPHeader header;
264 EXPECT_TRUE(parser_->Parse(packet, length, &header));
265
266 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
267 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
268 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
269
Peter Boström5811a392015-12-10 13:02:50 +0100270 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700271
272 return SEND_PACKET;
273 }
274
stefanff483612015-12-21 03:14:00 -0800275 void ModifyVideoConfigs(
276 VideoSendStream::Config* send_config,
277 std::vector<VideoReceiveStream::Config>* receive_configs,
278 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200279 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700280 }
281
282 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100283 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700284 }
285
Niels Möller4db138e2018-04-19 09:04:13 +0200286 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700287 } test;
288
stefane74eef12016-01-08 06:47:13 -0800289 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700290}
291
perkj803d97f2016-11-01 11:45:46 -0700292TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
293 class VideoRotationObserver : public test::SendTest {
294 public:
295 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
296 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
297 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
298 }
299
300 Action OnSendRtp(const uint8_t* packet, size_t length) override {
301 RTPHeader header;
302 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700303 // Only the last packet of the frame is required to have the extension.
304 if (!header.markerBit)
305 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700306 EXPECT_TRUE(header.extension.hasVideoRotation);
307 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
308 observation_complete_.Set();
309 return SEND_PACKET;
310 }
311
312 void ModifyVideoConfigs(
313 VideoSendStream::Config* send_config,
314 std::vector<VideoReceiveStream::Config>* receive_configs,
315 VideoEncoderConfig* encoder_config) override {
316 send_config->rtp.extensions.clear();
317 send_config->rtp.extensions.push_back(RtpExtension(
318 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
319 }
320
321 void OnFrameGeneratorCapturerCreated(
322 test::FrameGeneratorCapturer* frame_generator_capturer) override {
323 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
324 }
325
326 void PerformTest() override {
327 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
328 }
329 } test;
330
331 RunBaseTest(&test);
332}
333
ilnik00d802b2017-04-11 10:34:31 -0700334TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700335 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700336 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100337 VideoContentTypeObserver()
338 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700339 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
340 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
341 }
342
343 Action OnSendRtp(const uint8_t* packet, size_t length) override {
344 RTPHeader header;
345 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100346 // Only the last packet of the key-frame must have extension.
347 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700348 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100349 // First marker bit seen means that the first frame is sent.
350 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700351 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700352 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
353 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700354 observation_complete_.Set();
355 return SEND_PACKET;
356 }
357
358 void ModifyVideoConfigs(
359 VideoSendStream::Config* send_config,
360 std::vector<VideoReceiveStream::Config>* receive_configs,
361 VideoEncoderConfig* encoder_config) override {
362 send_config->rtp.extensions.clear();
363 send_config->rtp.extensions.push_back(
364 RtpExtension(RtpExtension::kVideoContentTypeUri,
365 test::kVideoContentTypeExtensionId));
366 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
367 }
368
369 void PerformTest() override {
370 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
371 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100372
373 private:
374 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700375 } test;
376
377 RunBaseTest(&test);
378}
379
ilnik04f4d122017-06-19 07:18:55 -0700380TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700381 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700382 public:
ilnik10894992017-06-21 08:23:19 -0700383 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700384 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
385 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
386 }
387
388 Action OnSendRtp(const uint8_t* packet, size_t length) override {
389 RTPHeader header;
390 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700391 // Only the last packet of the frame must have extension.
392 if (!header.markerBit)
393 return SEND_PACKET;
394 EXPECT_TRUE(header.extension.has_video_timing);
395 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700396 return SEND_PACKET;
397 }
398
399 void ModifyVideoConfigs(
400 VideoSendStream::Config* send_config,
401 std::vector<VideoReceiveStream::Config>* receive_configs,
402 VideoEncoderConfig* encoder_config) override {
403 send_config->rtp.extensions.clear();
404 send_config->rtp.extensions.push_back(RtpExtension(
405 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
406 }
407
408 void PerformTest() override {
409 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
410 }
411 } test;
412
413 RunBaseTest(&test);
414}
415
danilchap901b2df2017-07-28 08:56:04 -0700416class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000417 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000418 FakeReceiveStatistics(uint32_t send_ssrc,
419 uint32_t last_sequence_number,
420 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700421 uint8_t fraction_lost) {
422 stat_.SetMediaSsrc(send_ssrc);
423 stat_.SetExtHighestSeqNum(last_sequence_number);
424 stat_.SetCumulativeLost(cumulative_lost);
425 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000426 }
427
danilchap901b2df2017-07-28 08:56:04 -0700428 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
429 EXPECT_GE(max_blocks, 1u);
430 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000431 }
432
433 private:
danilchap901b2df2017-07-28 08:56:04 -0700434 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000435};
436
brandtre602f0a2016-10-31 03:40:49 -0700437class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100438 public:
brandtre602f0a2016-10-31 03:40:49 -0700439 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800440 bool use_nack,
441 bool expect_red,
442 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800443 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200444 VideoEncoderFactory* encoder_factory)
brandtr20d45472017-01-02 00:34:27 -0800445 : EndToEndTest(kTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200446 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100447 payload_name_(codec),
448 use_nack_(use_nack),
449 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700450 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800451 sent_media_(false),
452 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800453 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100454
brandtr20d45472017-01-02 00:34:27 -0800455 // Some of the test cases are expected to time out and thus we are using
456 // a shorter timeout window than the default here.
457 static constexpr size_t kTimeoutMs = 10000;
458
Stefan Holmer4654d202015-12-08 09:10:43 +0100459 private:
460 Action OnSendRtp(const uint8_t* packet, size_t length) override {
461 RTPHeader header;
462 EXPECT_TRUE(parser_->Parse(packet, length, &header));
463
Stefan Holmer4654d202015-12-08 09:10:43 +0100464 int encapsulated_payload_type = -1;
465 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100466 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100467 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
468 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100469 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100470 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
471 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100472 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100473 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100474 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
475 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100476 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
477 length) {
478 // Not padding-only, media received outside of RED.
479 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800480 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100481 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100482 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000483
Stefan Holmer4654d202015-12-08 09:10:43 +0100484 if (header_extensions_enabled_) {
485 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
486 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
487 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
488 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
489 // 24 bits wrap.
490 EXPECT_GT(prev_header_.extension.absoluteSendTime,
491 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000492 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100493 EXPECT_GE(header.extension.absoluteSendTime,
494 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200495 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100496 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
497 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
498 prev_header_.extension.transportSequenceNumber;
499 EXPECT_EQ(1, seq_num_diff);
500 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200501
Stefan Holmer4654d202015-12-08 09:10:43 +0100502 if (encapsulated_payload_type != -1) {
503 if (encapsulated_payload_type ==
504 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700505 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800506 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100507 } else {
brandtr65a1e772016-12-12 01:54:58 -0800508 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000509 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000510 }
511
brandtr20d45472017-01-02 00:34:27 -0800512 if (sent_media_ && sent_ulpfec_) {
513 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100514 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000515
Stefan Holmer4654d202015-12-08 09:10:43 +0100516 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000517
Stefan Holmer4654d202015-12-08 09:10:43 +0100518 return SEND_PACKET;
519 }
520
eladalon413ee9a2017-08-22 04:02:52 -0700521 test::PacketTransport* CreateSendTransport(
522 test::SingleThreadedTaskQueueForTesting* task_queue,
523 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100524 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
525 // Configure some network delay.
526 const int kNetworkDelayMs = 100;
527 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800528 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100529 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700530 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700531 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700532 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100533 }
534
stefanff483612015-12-21 03:14:00 -0800535 void ModifyVideoConfigs(
536 VideoSendStream::Config* send_config,
537 std::vector<VideoReceiveStream::Config>* receive_configs,
538 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100539 if (use_nack_) {
540 send_config->rtp.nack.rtp_history_ms =
541 (*receive_configs)[0].rtp.nack.rtp_history_ms =
542 VideoSendStreamTest::kNackRtpHistoryMs;
543 }
Niels Möller4db138e2018-04-19 09:04:13 +0200544 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200545 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700546 send_config->rtp.ulpfec.red_payload_type =
547 VideoSendStreamTest::kRedPayloadType;
548 send_config->rtp.ulpfec.ulpfec_payload_type =
549 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800550 EXPECT_FALSE(send_config->rtp.extensions.empty());
551 if (!header_extensions_enabled_) {
552 send_config->rtp.extensions.clear();
553 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100554 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700555 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100556 }
Niels Möller259a4972018-04-05 15:36:51 +0200557 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700558 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700559 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700560 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700561 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100562 }
563
564 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800565 EXPECT_EQ(expect_ulpfec_, Wait())
566 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100567 }
568
Niels Möller4db138e2018-04-19 09:04:13 +0200569 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800570 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100571 const bool use_nack_;
572 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700573 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800574 bool sent_media_;
575 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100576 bool header_extensions_enabled_;
577 RTPHeader prev_header_;
578};
579
brandtre602f0a2016-10-31 03:40:49 -0700580TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200581 test::FunctionVideoEncoderFactory encoder_factory(
582 []() { return VP8Encoder::Create(); });
583 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800584 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100585}
586
brandtre602f0a2016-10-31 03:40:49 -0700587TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200588 test::FunctionVideoEncoderFactory encoder_factory(
589 []() { return VP8Encoder::Create(); });
590 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100591 RunBaseTest(&test);
592}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000593
stefan60e10c72017-08-23 10:40:00 -0700594class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
595 protected:
596 VideoSendStreamWithoutUlpfecTest()
597 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
598
599 test::ScopedFieldTrials field_trial_;
600};
601
602TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200603 test::FunctionVideoEncoderFactory encoder_factory(
604 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200605 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700606 RunBaseTest(&test);
607}
608
Peter Boström39593972016-02-15 11:27:15 +0100609// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
610// since we'll still have to re-request FEC packets, effectively wasting
611// bandwidth since the receiver has to wait for FEC retransmissions to determine
612// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700613TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200614 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200615 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200616 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200617 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100618 RunBaseTest(&test);
619}
620
621// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800622TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200623 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200624 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200625 });
626 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100627 RunBaseTest(&test);
628}
629
danilchap9f5b6222017-03-02 06:22:21 -0800630// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
631TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200632 test::FunctionVideoEncoderFactory encoder_factory(
633 []() { return VP8Encoder::Create(); });
634 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100635 RunBaseTest(&test);
636}
637
Peter Boström12996152016-05-14 02:03:18 +0200638#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800639// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
640TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200641 test::FunctionVideoEncoderFactory encoder_factory(
642 []() { return VP9Encoder::Create(); });
643 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800644 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000645}
Peter Boström12996152016-05-14 02:03:18 +0200646#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000647
brandtre78d2662017-01-16 05:57:16 -0800648TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200649 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200650 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200651 Clock::GetRealTimeClock());
652 });
653 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800654 RunBaseTest(&test);
655}
656
brandtr39f97292016-11-16 22:57:50 -0800657// TODO(brandtr): Move these FlexFEC tests when we have created
658// FlexfecSendStream.
659class FlexfecObserver : public test::EndToEndTest {
660 public:
661 FlexfecObserver(bool header_extensions_enabled,
662 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800663 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200664 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100665 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800666 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200667 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800668 payload_name_(codec),
669 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800670 sent_media_(false),
671 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100672 header_extensions_enabled_(header_extensions_enabled),
673 num_video_streams_(num_video_streams) {}
brandtr39f97292016-11-16 22:57:50 -0800674
675 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100676 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800677
678 private:
679 Action OnSendRtp(const uint8_t* packet, size_t length) override {
680 RTPHeader header;
681 EXPECT_TRUE(parser_->Parse(packet, length, &header));
682
brandtr39f97292016-11-16 22:57:50 -0800683 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
684 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
685 sent_flexfec_ = true;
686 } else {
687 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
688 header.payloadType);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100689 EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
690 num_video_streams_),
691 testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800692 sent_media_ = true;
693 }
694
695 if (header_extensions_enabled_) {
696 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
697 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
698 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
699 }
700
brandtr0c5a1542016-11-23 04:42:26 -0800701 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800702 observation_complete_.Set();
703 }
704
705 return SEND_PACKET;
706 }
707
eladalon413ee9a2017-08-22 04:02:52 -0700708 test::PacketTransport* CreateSendTransport(
709 test::SingleThreadedTaskQueueForTesting* task_queue,
710 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800711 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
712 // Therefore we need some network delay.
713 const int kNetworkDelayMs = 100;
714 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800715 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800716 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700717 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700718 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700719 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800720 }
721
722 void ModifyVideoConfigs(
723 VideoSendStream::Config* send_config,
724 std::vector<VideoReceiveStream::Config>* receive_configs,
725 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800726 if (use_nack_) {
727 send_config->rtp.nack.rtp_history_ms =
728 (*receive_configs)[0].rtp.nack.rtp_history_ms =
729 VideoSendStreamTest::kNackRtpHistoryMs;
730 }
Niels Möller4db138e2018-04-19 09:04:13 +0200731 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200732 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800733 if (header_extensions_enabled_) {
734 send_config->rtp.extensions.push_back(RtpExtension(
735 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
736 send_config->rtp.extensions.push_back(RtpExtension(
737 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800738 } else {
739 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800740 }
Niels Möller259a4972018-04-05 15:36:51 +0200741 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800742 }
743
744 void PerformTest() override {
745 EXPECT_TRUE(Wait())
746 << "Timed out waiting for FlexFEC and/or media packets.";
747 }
748
Niels Möller4db138e2018-04-19 09:04:13 +0200749 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800750 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800751 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800752 bool sent_media_;
753 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100754 const bool header_extensions_enabled_;
755 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800756};
757
brandtrd654a9b2016-12-05 05:38:19 -0800758TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200759 test::FunctionVideoEncoderFactory encoder_factory(
760 []() { return VP8Encoder::Create(); });
761 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100762 RunBaseTest(&test);
763}
764
765TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200766 test::FunctionVideoEncoderFactory encoder_factory(
767 []() { return VP8Encoder::Create(); });
768 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800769 RunBaseTest(&test);
770}
771
772TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200773 test::FunctionVideoEncoderFactory encoder_factory(
774 []() { return VP8Encoder::Create(); });
775 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800776 RunBaseTest(&test);
777}
778
brandtr39f97292016-11-16 22:57:50 -0800779TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200780 test::FunctionVideoEncoderFactory encoder_factory(
781 []() { return VP8Encoder::Create(); });
782 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800783 RunBaseTest(&test);
784}
785
brandtr39f97292016-11-16 22:57:50 -0800786#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800787TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200788 test::FunctionVideoEncoderFactory encoder_factory(
789 []() { return VP9Encoder::Create(); });
790 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800791 RunBaseTest(&test);
792}
793
brandtrd654a9b2016-12-05 05:38:19 -0800794TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200795 test::FunctionVideoEncoderFactory encoder_factory(
796 []() { return VP9Encoder::Create(); });
797 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800798 RunBaseTest(&test);
799}
800#endif // defined(RTC_DISABLE_VP9)
801
brandtrd654a9b2016-12-05 05:38:19 -0800802TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200803 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200804 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200805 });
806 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800807 RunBaseTest(&test);
808}
809
brandtrd654a9b2016-12-05 05:38:19 -0800810TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200811 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200812 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200813 });
814 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800815 RunBaseTest(&test);
816}
817
brandtre78d2662017-01-16 05:57:16 -0800818TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200819 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200820 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200821 Clock::GetRealTimeClock());
822 });
823
824 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800825 RunBaseTest(&test);
826}
827
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000828void VideoSendStreamTest::TestNackRetransmission(
829 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000830 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000831 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000832 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000833 explicit NackObserver(uint32_t retransmit_ssrc,
834 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000835 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000836 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100837 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000838 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100839 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000840
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000841 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000842 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000843 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000844 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000845
Sebastian Janssond3f38162018-02-28 16:14:44 +0100846 int kRetransmitTarget = 6;
847 ++send_count_;
848 if (send_count_ == 5 || send_count_ == 25) {
849 nacked_sequence_numbers_.push_back(
850 static_cast<uint16_t>(header.sequenceNumber - 3));
851 nacked_sequence_numbers_.push_back(
852 static_cast<uint16_t>(header.sequenceNumber - 2));
853 nacked_sequence_numbers_.push_back(
854 static_cast<uint16_t>(header.sequenceNumber - 1));
855
danilchap8a1d2a32017-08-01 03:21:37 -0700856 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -0800857 nullptr, nullptr, transport_adapter_.get(),
858 RtcpIntervalConfig{});
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000859
pbosda903ea2015-10-02 02:36:56 -0700860 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100861 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000862
863 RTCPSender::FeedbackState feedback_state;
864
Sebastian Janssond3f38162018-02-28 16:14:44 +0100865 EXPECT_EQ(0, rtcp_sender.SendRTCP(
866 feedback_state, kRtcpNack,
867 static_cast<int>(nacked_sequence_numbers_.size()),
868 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000869 }
870
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000871 uint16_t sequence_number = header.sequenceNumber;
872
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000873 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100874 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
875 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000876 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000877 const uint8_t* rtx_header = packet + header.headerLength;
878 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
879 }
Sebastian Janssond3f38162018-02-28 16:14:44 +0100880 auto found = std::find(nacked_sequence_numbers_.begin(),
881 nacked_sequence_numbers_.end(), sequence_number);
882 if (found != nacked_sequence_numbers_.end()) {
883 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000884
Sebastian Janssond3f38162018-02-28 16:14:44 +0100885 if (++retransmit_count_ == kRetransmitTarget) {
886 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
887 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
888 observation_complete_.Set();
889 }
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000890 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000891
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000892 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000893 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000894
stefanff483612015-12-21 03:14:00 -0800895 void ModifyVideoConfigs(
896 VideoSendStream::Config* send_config,
897 std::vector<VideoReceiveStream::Config>* receive_configs,
898 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700899 transport_adapter_.reset(
900 new internal::TransportAdapter(send_config->send_transport));
901 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000902 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000903 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100904 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000905 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
906 }
907
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000908 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100909 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000910 }
911
kwiberg27f982b2016-03-01 11:52:33 -0800912 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000913 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100914 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000915 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000916 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100917 std::vector<uint16_t> nacked_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000918 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000919
stefane74eef12016-01-08 06:47:13 -0800920 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000921}
922
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000923TEST_F(VideoSendStreamTest, RetransmitsNack) {
924 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100925 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000926}
927
928TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
929 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000930 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000931}
932
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000933void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
934 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000935 // Use a fake encoder to output a frame of every size in the range [90, 290],
936 // for each size making sure that the exact number of payload bytes received
937 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000938 static const size_t kMaxPacketSize = 128;
939 static const size_t start = 90;
940 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000941
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000942 // Observer that verifies that the expected number of packets and bytes
943 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000944 class FrameFragmentationTest : public test::SendTest,
945 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000946 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000947 FrameFragmentationTest(size_t max_packet_size,
948 size_t start_size,
949 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000950 bool test_generic_packetization,
951 bool use_fec)
952 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000953 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +0200954 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000955 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000956 stop_size_(stop_size),
957 test_generic_packetization_(test_generic_packetization),
958 use_fec_(use_fec),
959 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +0100960 packets_lost_(0),
961 last_packet_count_(0),
962 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000963 accumulated_size_(0),
964 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000965 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000966 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700967 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000968 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000969 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700970 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000971 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000972
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000973 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000974 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000975 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000976 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000977 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000978
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000979 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000980
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000981 if (use_fec_) {
982 uint8_t payload_type = packet[header.headerLength];
983 bool is_fec = header.payloadType == kRedPayloadType &&
984 payload_type == kUlpfecPayloadType;
985 if (is_fec) {
986 fec_packet_received_ = true;
987 return SEND_PACKET;
988 }
989 }
990
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000991 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000992
993 if (use_fec_)
994 TriggerLossReport(header);
995
996 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200997 size_t overhead = header.headerLength + header.paddingLength;
998 // Only remove payload header and RED header if the packet actually
999 // contains payload.
1000 if (length > overhead) {
1001 overhead += (1 /* Generic header */);
1002 if (use_fec_)
1003 overhead += 1; // RED for FEC header.
1004 }
1005 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001006 accumulated_payload_ += length - overhead;
1007 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001008
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001009 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001010 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001011 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1012 // With FEC enabled, frame size is incremented asynchronously, so
1013 // "old" frames one byte too small may arrive. Accept, but don't
1014 // increase expected frame size.
1015 accumulated_size_ = 0;
1016 accumulated_payload_ = 0;
1017 return SEND_PACKET;
1018 }
1019
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001020 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001021 if (test_generic_packetization_) {
1022 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1023 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001024
1025 // Last packet of frame; reset counters.
1026 accumulated_size_ = 0;
1027 accumulated_payload_ = 0;
1028 if (current_size_rtp_ == stop_size_) {
1029 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001030 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001031 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001032 // Increase next expected frame size. If testing with FEC, make sure
1033 // a FEC packet has been received for this frame size before
1034 // proceeding, to make sure that redundancy packets don't exceed
1035 // size limit.
1036 if (!use_fec_) {
1037 ++current_size_rtp_;
1038 } else if (fec_packet_received_) {
1039 fec_packet_received_ = false;
1040 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001041
1042 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001043 ++current_size_frame_;
1044 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001045 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001046 }
1047
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001048 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001049 }
1050
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001051 void TriggerLossReport(const RTPHeader& header) {
1052 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001053 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001054 if (++packet_count_ % (100 / kLossPercent) == 0) {
1055 packets_lost_++;
1056 int loss_delta = packets_lost_ - last_packets_lost_;
1057 int packets_delta = packet_count_ - last_packet_count_;
1058 last_packet_count_ = packet_count_;
1059 last_packets_lost_ = packets_lost_;
1060 uint8_t loss_ratio =
1061 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001062 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001063 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001064 packets_lost_, // Cumulative lost.
1065 loss_ratio); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +02001066 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -08001067 &lossy_receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001068 transport_adapter_.get(), RtcpIntervalConfig{});
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001069
pbosda903ea2015-10-02 02:36:56 -07001070 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001071 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001072
1073 RTCPSender::FeedbackState feedback_state;
1074
1075 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1076 }
1077 }
1078
nisseef8b61e2016-04-29 06:09:15 -07001079 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001080 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001081 // Increase frame size for next encoded frame, in the context of the
1082 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001083 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001084 ++current_size_frame_;
1085 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001086 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001087 }
Sebastian Jansson72582242018-07-13 13:19:42 +02001088 void ModifySenderCallConfig(Call::Config* config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001089 const int kMinBitrateBps = 30000;
Sebastian Jansson72582242018-07-13 13:19:42 +02001090 config->bitrate_config.min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001091 }
1092
stefanff483612015-12-21 03:14:00 -08001093 void ModifyVideoConfigs(
1094 VideoSendStream::Config* send_config,
1095 std::vector<VideoReceiveStream::Config>* receive_configs,
1096 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001097 transport_adapter_.reset(
1098 new internal::TransportAdapter(send_config->send_transport));
1099 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001100 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001101 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1102 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001103 }
1104
1105 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001106 send_config->rtp.payload_name = "VP8";
Niels Möller4db138e2018-04-19 09:04:13 +02001107 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001108 send_config->rtp.max_packet_size = kMaxPacketSize;
1109 send_config->post_encode_callback = this;
1110
Erik Språng95261872015-04-10 11:58:49 +02001111 // Make sure there is at least one extension header, to make the RTP
1112 // header larger than the base length of 12 bytes.
1113 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001114
1115 // Setup screen content disables frame dropping which makes this easier.
1116 class VideoStreamFactory
1117 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1118 public:
1119 explicit VideoStreamFactory(size_t num_temporal_layers)
1120 : num_temporal_layers_(num_temporal_layers) {
1121 EXPECT_GT(num_temporal_layers, 0u);
1122 }
1123
1124 private:
1125 std::vector<VideoStream> CreateEncoderStreams(
1126 int width,
1127 int height,
1128 const VideoEncoderConfig& encoder_config) override {
1129 std::vector<VideoStream> streams =
1130 test::CreateVideoStreams(width, height, encoder_config);
1131 for (VideoStream& stream : streams) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01001132 stream.num_temporal_layers = num_temporal_layers_;
sprang4847ae62017-06-27 07:06:52 -07001133 }
1134 return streams;
1135 }
1136 const size_t num_temporal_layers_;
1137 };
1138
1139 encoder_config->video_stream_factory =
1140 new rtc::RefCountedObject<VideoStreamFactory>(2);
1141 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001142 }
1143
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001144 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001145 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001146 }
1147
kwiberg27f982b2016-03-01 11:52:33 -08001148 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001149 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möller4db138e2018-04-19 09:04:13 +02001150 test::EncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001151
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001152 const size_t max_packet_size_;
1153 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001154 const bool test_generic_packetization_;
1155 const bool use_fec_;
1156
1157 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001158 uint32_t packets_lost_;
1159 uint32_t last_packet_count_;
1160 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001161 size_t accumulated_size_;
1162 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001163 bool fec_packet_received_;
1164
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001165 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001166 rtc::CriticalSection mutex_;
1167 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001168 };
1169
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001170 // Don't auto increment if FEC is used; continue sending frame size until
1171 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001172 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1173 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001174
stefane74eef12016-01-08 06:47:13 -08001175 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001176}
1177
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001178// TODO(sprang): Is there any way of speeding up these tests?
1179TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1180 TestPacketFragmentationSize(kGeneric, false);
1181}
1182
1183TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1184 TestPacketFragmentationSize(kGeneric, true);
1185}
1186
1187TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1188 TestPacketFragmentationSize(kVP8, false);
1189}
1190
1191TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1192 TestPacketFragmentationSize(kVP8, true);
1193}
1194
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001195// The test will go through a number of phases.
1196// 1. Start sending packets.
1197// 2. As soon as the RTP stream has been detected, signal a low REMB value to
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001198// suspend the stream.
1199// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001200// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001201// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001202// When the stream is detected again, and the stats show that the stream
1203// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001204TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1205 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001206
nissed30a1112016-04-18 05:15:22 -07001207 class RembObserver : public test::SendTest,
1208 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001209 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001210 RembObserver()
1211 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001212 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001213 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001214 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001215 rtp_count_(0),
1216 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001217 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001218 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001219 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001220
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001221 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001222 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001223 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001224 ++rtp_count_;
1225 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001226 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001227 last_sequence_number_ = header.sequenceNumber;
1228
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001229 if (test_state_ == kBeforeSuspend) {
1230 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001231 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001232 test_state_ = kDuringSuspend;
1233 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001234 if (header.paddingLength == 0) {
1235 // Received non-padding packet during suspension period. Reset the
1236 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001237 suspended_frame_count_ = 0;
1238 }
stefanf116bd02015-10-27 08:29:42 -07001239 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001240 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001241 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001242 // Non-padding packet observed. Test is almost complete. Will just
1243 // have to wait for the stats to change.
1244 test_state_ = kWaitingForStats;
1245 }
stefanf116bd02015-10-27 08:29:42 -07001246 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001247 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001248 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001249 if (stats.suspended == false) {
1250 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001251 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001252 }
stefanf116bd02015-10-27 08:29:42 -07001253 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001254 }
1255
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001256 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001257 }
1258
perkj26091b12016-09-01 01:17:40 -07001259 // This method implements the rtc::VideoSinkInterface. This is called when
1260 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001261 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001262 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001263 if (test_state_ == kDuringSuspend &&
1264 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001265 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001266 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001267 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001268 test_state_ = kWaitingForPacket;
1269 }
1270 }
1271
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001272 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001273 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001274 low_remb_bps_ = value;
1275 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001276
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001277 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001278 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001279 high_remb_bps_ = value;
1280 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001281
stefanff483612015-12-21 03:14:00 -08001282 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001283 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001284 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001285 stream_ = send_stream;
1286 }
1287
stefanff483612015-12-21 03:14:00 -08001288 void ModifyVideoConfigs(
1289 VideoSendStream::Config* send_config,
1290 std::vector<VideoReceiveStream::Config>* receive_configs,
1291 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001292 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001293 transport_adapter_.reset(
1294 new internal::TransportAdapter(send_config->send_transport));
1295 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001296 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001297 send_config->pre_encode_callback = this;
1298 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001299 int min_bitrate_bps =
1300 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001301 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001302 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001303 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001304 min_bitrate_bps + threshold_window + 5000);
1305 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1306 }
1307
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001308 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001309 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001310 }
1311
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001312 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001313 kBeforeSuspend,
1314 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001315 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001316 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001317 };
1318
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001319 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001320 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001321 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1322 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001323 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
Jiawei Ou3587b832018-01-31 22:08:26 -08001324 transport_adapter_.get(), RtcpIntervalConfig{});
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001325
pbosda903ea2015-10-02 02:36:56 -07001326 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001327 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001328 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001329 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001330 }
1331 RTCPSender::FeedbackState feedback_state;
1332 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1333 }
1334
kwiberg27f982b2016-03-01 11:52:33 -08001335 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001336 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001337 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001338
Peter Boströmf2f82832015-05-01 13:00:41 +02001339 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001340 TestState test_state_ RTC_GUARDED_BY(crit_);
1341 int rtp_count_ RTC_GUARDED_BY(crit_);
1342 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1343 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1344 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1345 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001346 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001347
stefane74eef12016-01-08 06:47:13 -08001348 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001349}
1350
perkj71ee44c2016-06-15 00:47:53 -07001351// This test that padding stops being send after a while if the Camera stops
1352// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001353TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001354 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001355 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001356 NoPaddingWhenVideoIsMuted()
1357 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001358 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001359 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001360 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001361
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001362 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001363 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001364 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001365 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001366
1367 RTPHeader header;
1368 parser_->Parse(packet, length, &header);
1369 const bool only_padding =
1370 header.headerLength + header.paddingLength == length;
1371
1372 if (test_state_ == kBeforeStopCapture) {
1373 capturer_->Stop();
1374 test_state_ = kWaitingForPadding;
1375 } else if (test_state_ == kWaitingForPadding && only_padding) {
1376 test_state_ = kWaitingForNoPackets;
1377 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1378 only_padding) {
1379 observation_complete_.Set();
1380 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001381 return SEND_PACKET;
1382 }
1383
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001384 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001385 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001386 const int kNoPacketsThresholdMs = 2000;
1387 if (test_state_ == kWaitingForNoPackets &&
1388 (last_packet_time_ms_ > 0 &&
1389 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1390 kNoPacketsThresholdMs)) {
1391 capturer_->Start();
1392 test_state_ = kWaitingForPaddingAfterCameraRestart;
1393 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001394 return SEND_PACKET;
1395 }
1396
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001397 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001398
nisseef8b61e2016-04-29 06:09:15 -07001399 void OnFrameGeneratorCapturerCreated(
1400 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001401 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001402 capturer_ = frame_generator_capturer;
1403 }
1404
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001405 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001406 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001407 << "Timed out while waiting for RTP packets to stop being sent.";
1408 }
1409
perkj71ee44c2016-06-15 00:47:53 -07001410 enum TestState {
1411 kBeforeStopCapture,
1412 kWaitingForPadding,
1413 kWaitingForNoPackets,
1414 kWaitingForPaddingAfterCameraRestart
1415 };
1416
1417 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001418 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001419 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001420 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001421 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1422 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001423 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001424
stefane74eef12016-01-08 06:47:13 -08001425 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001426}
1427
isheriffcc5903e2016-10-04 08:29:38 -07001428TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1429 const int kCapacityKbps = 10000; // 10 Mbps
1430 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1431 public:
1432 PaddingIsPrimarilyRetransmissions()
1433 : EndToEndTest(kDefaultTimeoutMs),
1434 clock_(Clock::GetRealTimeClock()),
1435 padding_length_(0),
1436 total_length_(0),
1437 call_(nullptr) {}
1438
1439 private:
1440 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1441 call_ = sender_call;
1442 }
1443
1444 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1445 rtc::CritScope lock(&crit_);
1446
1447 RTPHeader header;
1448 parser_->Parse(packet, length, &header);
1449 padding_length_ += header.paddingLength;
1450 total_length_ += length;
1451 return SEND_PACKET;
1452 }
1453
eladalon413ee9a2017-08-22 04:02:52 -07001454 test::PacketTransport* CreateSendTransport(
1455 test::SingleThreadedTaskQueueForTesting* task_queue,
1456 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001457 const int kNetworkDelayMs = 50;
1458 FakeNetworkPipe::Config config;
1459 config.loss_percent = 10;
1460 config.link_capacity_kbps = kCapacityKbps;
1461 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001462 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001463 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001464 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001465 }
1466
1467 void ModifyVideoConfigs(
1468 VideoSendStream::Config* send_config,
1469 std::vector<VideoReceiveStream::Config>* receive_configs,
1470 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001471 // Turn on RTX.
1472 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1473 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001474 }
1475
1476 void PerformTest() override {
1477 // TODO(isheriff): Some platforms do not ramp up as expected to full
1478 // capacity due to packet scheduling delays. Fix that before getting
1479 // rid of this.
1480 SleepMs(5000);
1481 {
1482 rtc::CritScope lock(&crit_);
1483 // Expect padding to be a small percentage of total bytes sent.
1484 EXPECT_LT(padding_length_, .1 * total_length_);
1485 }
1486 }
1487
1488 rtc::CriticalSection crit_;
1489 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001490 size_t padding_length_ RTC_GUARDED_BY(crit_);
1491 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001492 Call* call_;
1493 } test;
1494
1495 RunBaseTest(&test);
1496}
1497
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001498// This test first observes "high" bitrate use at which point it sends a REMB to
1499// indicate that it should be lowered significantly. The test then observes that
1500// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1501// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001502//
1503// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1504// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001505TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1506 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001507 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001508 static const int kRembBitrateBps = 80000;
1509 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001510 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001511 public:
1512 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001513 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001514 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1515 stream_(nullptr),
1516 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001517
1518 private:
nisseef8b61e2016-04-29 06:09:15 -07001519 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001520 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001521 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001522
1523 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001524 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001525 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001526 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001527 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001528 if (!stats.substreams.empty()) {
1529 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001530 int total_bitrate_bps =
1531 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001532 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1533 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1534 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001535 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001536 rtp_rtcp_->SetRemb(kRembBitrateBps,
1537 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001538 rtp_rtcp_->Process();
1539 bitrate_capped_ = true;
1540 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001541 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001542 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001543 }
1544 }
stefanf116bd02015-10-27 08:29:42 -07001545 // Packets don't have to be delivered since the test is the receiver.
1546 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001547 }
1548
stefanff483612015-12-21 03:14:00 -08001549 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001550 VideoSendStream* send_stream,
1551 const std::vector<VideoReceiveStream*>& receive_streams) override {
1552 stream_ = send_stream;
1553 RtpRtcp::Configuration config;
1554 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001555 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001556 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001557 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001558 }
1559
stefanff483612015-12-21 03:14:00 -08001560 void ModifyVideoConfigs(
1561 VideoSendStream::Config* send_config,
1562 std::vector<VideoReceiveStream::Config>* receive_configs,
1563 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001564 feedback_transport_.reset(
1565 new internal::TransportAdapter(send_config->send_transport));
1566 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001567 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001568 }
1569
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001570 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001571 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001572 << "Timeout while waiting for low bitrate stats after REMB.";
1573 }
1574
kwiberg27f982b2016-03-01 11:52:33 -08001575 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1576 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001577 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001578 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001579 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001580 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001581
stefane74eef12016-01-08 06:47:13 -08001582 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001583}
1584
Stefan Holmer280de9e2016-09-30 10:06:51 +02001585TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1586 static const int kStartBitrateBps = 300000;
1587 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001588 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001589 class ChangingNetworkRouteTest : public test::EndToEndTest {
1590 public:
eladalon413ee9a2017-08-22 04:02:52 -07001591 explicit ChangingNetworkRouteTest(
1592 test::SingleThreadedTaskQueueForTesting* task_queue)
1593 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1594 task_queue_(task_queue),
1595 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001596 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1597 kRtpExtensionTransportSequenceNumber, kExtensionId));
1598 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001599
1600 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1601 call_ = sender_call;
1602 }
1603
Stefan Holmer280de9e2016-09-30 10:06:51 +02001604 void ModifyVideoConfigs(
1605 VideoSendStream::Config* send_config,
1606 std::vector<VideoReceiveStream::Config>* receive_configs,
1607 VideoEncoderConfig* encoder_config) override {
1608 send_config->rtp.extensions.clear();
1609 send_config->rtp.extensions.push_back(RtpExtension(
1610 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1611 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1612 (*receive_configs)[0].rtp.transport_cc = true;
1613 }
1614
1615 void ModifyAudioConfigs(
1616 AudioSendStream::Config* send_config,
1617 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1618 send_config->rtp.extensions.clear();
1619 send_config->rtp.extensions.push_back(RtpExtension(
1620 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1621 (*receive_configs)[0].rtp.extensions.clear();
1622 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1623 (*receive_configs)[0].rtp.transport_cc = true;
1624 }
1625
Stefan Holmerbe402962016-07-08 16:16:41 +02001626 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1627 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1628 observation_complete_.Set();
1629 }
1630
1631 return SEND_PACKET;
1632 }
1633
1634 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001635 rtc::NetworkRoute new_route;
1636 new_route.connected = true;
1637 new_route.local_network_id = 10;
1638 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001639 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001640
1641 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001642 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1643 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001644 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001645 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1646 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001647 });
1648
Stefan Holmerbe402962016-07-08 16:16:41 +02001649 EXPECT_TRUE(Wait())
1650 << "Timed out while waiting for start bitrate to be exceeded.";
1651
eladalon413ee9a2017-08-22 04:02:52 -07001652 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1653 bitrate_config.start_bitrate_bps = -1;
1654 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001655 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1656 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001657 // TODO(holmer): We should set the last sent packet id here and verify
1658 // that we correctly ignore any packet loss reported prior to that id.
1659 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001660 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1661 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001662 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1663 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001664 }
1665
1666 private:
eladalon413ee9a2017-08-22 04:02:52 -07001667 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001668 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001669 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001670
1671 RunBaseTest(&test);
1672}
1673
michaelt79e05882016-11-08 02:50:09 -08001674TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1675 class ChangingTransportOverheadTest : public test::EndToEndTest {
1676 public:
eladalon413ee9a2017-08-22 04:02:52 -07001677 explicit ChangingTransportOverheadTest(
1678 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001679 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001680 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001681 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001682 packets_sent_(0),
1683 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001684
1685 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1686 call_ = sender_call;
1687 }
1688
1689 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001690 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001691 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001692 if (++packets_sent_ < 100)
1693 return SEND_PACKET;
1694 observation_complete_.Set();
1695 return SEND_PACKET;
1696 }
1697
michaelta3328772016-11-29 09:25:03 -08001698 void ModifyVideoConfigs(
1699 VideoSendStream::Config* send_config,
1700 std::vector<VideoReceiveStream::Config>* receive_configs,
1701 VideoEncoderConfig* encoder_config) override {
1702 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1703 }
1704
michaelt79e05882016-11-08 02:50:09 -08001705 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001706 task_queue_->SendTask([this]() {
1707 transport_overhead_ = 100;
1708 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1709 transport_overhead_);
1710 });
1711
michaelt79e05882016-11-08 02:50:09 -08001712 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001713
sprang21253fc2017-02-27 03:35:47 -08001714 {
1715 rtc::CritScope cs(&lock_);
1716 packets_sent_ = 0;
1717 }
eladalon413ee9a2017-08-22 04:02:52 -07001718
1719 task_queue_->SendTask([this]() {
1720 transport_overhead_ = 500;
1721 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1722 transport_overhead_);
1723 });
1724
michaelt79e05882016-11-08 02:50:09 -08001725 EXPECT_TRUE(Wait());
1726 }
1727
1728 private:
eladalon413ee9a2017-08-22 04:02:52 -07001729 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001730 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001731 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001732 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001733 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001734 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001735 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001736
1737 RunBaseTest(&test);
1738}
1739
sprangf24a0642017-02-28 13:23:26 -08001740// Test class takes takes as argument a switch selecting if type switch should
1741// occur and a function pointer to reset the send stream. This is necessary
1742// since you cannot change the content type of a VideoSendStream, you need to
1743// recreate it. Stopping and recreating the stream can only be done on the main
1744// thread and in the context of VideoSendStreamTest (not BaseTest).
1745template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001746class MaxPaddingSetTest : public test::SendTest {
1747 public:
1748 static const uint32_t kMinTransmitBitrateBps = 400000;
1749 static const uint32_t kActualEncodeBitrateBps = 40000;
1750 static const uint32_t kMinPacketsToSend = 50;
1751
sprangf24a0642017-02-28 13:23:26 -08001752 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001753 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001754 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001755 call_(nullptr),
1756 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001757 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001758 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001759 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001760 stream_resetter_(stream_reset_fun) {
1761 RTC_DCHECK(stream_resetter_);
1762 }
sprang9c0b5512016-07-06 00:54:28 -07001763
1764 void OnVideoStreamsCreated(
1765 VideoSendStream* send_stream,
1766 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001767 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001768 send_stream_ = send_stream;
1769 }
1770
1771 void ModifyVideoConfigs(
1772 VideoSendStream::Config* send_config,
1773 std::vector<VideoReceiveStream::Config>* receive_configs,
1774 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001775 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001776 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001777 encoder_config->min_transmit_bitrate_bps = 0;
1778 encoder_config->content_type =
1779 VideoEncoderConfig::ContentType::kRealtimeVideo;
1780 } else {
1781 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1782 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1783 }
sprangf24a0642017-02-28 13:23:26 -08001784 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001785 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001786 }
1787
1788 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1789 call_ = sender_call;
1790 }
1791
1792 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1793 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001794 if (running_without_padding_)
1795 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1796
1797 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1798 // we have reliable data.
1799 if (++packets_sent_ < kMinPacketsToSend)
1800 return SEND_PACKET;
1801
1802 if (running_without_padding_) {
1803 // We've sent kMinPacketsToSend packets with default configuration, switch
1804 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001805 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001806 packets_sent_ = 0;
1807 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1808 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001809 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001810 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001811 return SEND_PACKET;
1812 }
1813
1814 // Make sure the pacer has been configured with a min transmit bitrate.
1815 if (call_->GetStats().max_padding_bitrate_bps > 0)
1816 observation_complete_.Set();
1817
1818 return SEND_PACKET;
1819 }
1820
1821 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001822 if (RunningWithoutPadding()) {
1823 ASSERT_TRUE(
1824 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001825 (*stream_resetter_)(send_stream_config_, encoder_config_);
1826 }
1827
sprang9c0b5512016-07-06 00:54:28 -07001828 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1829 }
1830
1831 private:
sprangf24a0642017-02-28 13:23:26 -08001832 bool RunningWithoutPadding() const {
1833 rtc::CritScope lock(&crit_);
1834 return running_without_padding_;
1835 }
1836
sprang9c0b5512016-07-06 00:54:28 -07001837 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001838 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001839 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001840 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001841 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001842 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001843 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001844 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001845 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001846};
1847
1848TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001849 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1850 const VideoEncoderConfig& encoder_config) {};
1851 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001852 RunBaseTest(&test);
1853}
1854
1855TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001856 // Function for removing and recreating the send stream with a new config.
1857 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1858 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001859 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1860 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001861 DestroyVideoSendStreams();
1862 SetVideoSendConfig(send_stream_config);
1863 SetVideoEncoderConfig(encoder_config);
1864 CreateVideoSendStreams();
1865 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
eladalon413ee9a2017-08-22 04:02:52 -07001866 Start();
1867 });
sprangf24a0642017-02-28 13:23:26 -08001868 };
1869 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001870 RunBaseTest(&test);
1871}
1872
perkjfa10b552016-10-02 23:45:26 -07001873// This test verifies that new frame sizes reconfigures encoders even though not
1874// (yet) sending. The purpose of this is to permit encoding as quickly as
1875// possible once we start sending. Likely the frames being input are from the
1876// same source that will be sent later, which just means that we're ready
1877// earlier.
1878TEST_F(VideoSendStreamTest,
1879 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1880 class EncoderObserver : public test::FakeEncoder {
1881 public:
1882 EncoderObserver()
1883 : FakeEncoder(Clock::GetRealTimeClock()),
1884 init_encode_called_(false, false),
1885 number_of_initializations_(0),
1886 last_initialized_frame_width_(0),
1887 last_initialized_frame_height_(0) {}
1888
1889 void WaitForResolution(int width, int height) {
1890 {
1891 rtc::CritScope lock(&crit_);
1892 if (last_initialized_frame_width_ == width &&
1893 last_initialized_frame_height_ == height) {
1894 return;
1895 }
1896 }
Erik Språng08127a92016-11-16 16:41:30 +01001897 EXPECT_TRUE(
1898 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001899 {
1900 rtc::CritScope lock(&crit_);
1901 EXPECT_EQ(width, last_initialized_frame_width_);
1902 EXPECT_EQ(height, last_initialized_frame_height_);
1903 }
1904 }
1905
1906 private:
1907 int32_t InitEncode(const VideoCodec* config,
1908 int32_t number_of_cores,
1909 size_t max_payload_size) override {
1910 rtc::CritScope lock(&crit_);
1911 last_initialized_frame_width_ = config->width;
1912 last_initialized_frame_height_ = config->height;
1913 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001914 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001915 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1916 }
1917
1918 int32_t Encode(const VideoFrame& input_image,
1919 const CodecSpecificInfo* codec_specific_info,
1920 const std::vector<FrameType>* frame_types) override {
1921 ADD_FAILURE()
1922 << "Unexpected Encode call since the send stream is not started";
1923 return 0;
1924 }
1925
1926 rtc::CriticalSection crit_;
1927 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001928 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1929 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1930 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001931 };
1932
perkjfa10b552016-10-02 23:45:26 -07001933 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001934 EncoderObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02001935 test::EncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07001936
Niels Möller4db138e2018-04-19 09:04:13 +02001937 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02001938 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07001939 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02001940 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07001941 CreateVideoStreams();
1942 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1943 kDefaultHeight);
1944 frame_generator_capturer_->Start();
1945 });
perkjfa10b552016-10-02 23:45:26 -07001946
1947 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001948
1949 task_queue_.SendTask([this]() {
1950 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1951 kDefaultHeight * 2);
1952 });
1953
perkjfa10b552016-10-02 23:45:26 -07001954 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001955
1956 task_queue_.SendTask([this]() {
1957 DestroyStreams();
1958 DestroyCalls();
1959 });
perkjfa10b552016-10-02 23:45:26 -07001960}
1961
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001962TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1963 class StartBitrateObserver : public test::FakeEncoder {
1964 public:
1965 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001966 : FakeEncoder(Clock::GetRealTimeClock()),
1967 start_bitrate_changed_(false, false),
1968 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001969 int32_t InitEncode(const VideoCodec* config,
1970 int32_t number_of_cores,
1971 size_t max_payload_size) override {
1972 rtc::CritScope lock(&crit_);
1973 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001974 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001975 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1976 }
1977
1978 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1979 rtc::CritScope lock(&crit_);
1980 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001981 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001982 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1983 }
1984
1985 int GetStartBitrateKbps() const {
1986 rtc::CritScope lock(&crit_);
1987 return start_bitrate_kbps_;
1988 }
1989
pbos14fe7082016-04-20 06:35:56 -07001990 bool WaitForStartBitrate() {
1991 return start_bitrate_changed_.Wait(
1992 VideoSendStreamTest::kDefaultTimeoutMs);
1993 }
1994
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001995 private:
pbos5ad935c2016-01-25 03:52:44 -08001996 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001997 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001998 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001999 };
2000
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002001 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002002
solenberg4fbae2b2015-08-28 04:07:10 -07002003 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002004 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002005
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002006 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002007 bitrate_config.start_bitrate_bps =
2008 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002009 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2010 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002011
2012 StartBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002013 test::EncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002014 // Since this test does not use a capturer, set |internal_source| = true.
2015 // Encoder configuration is otherwise updated on the next video frame.
Niels Möller4db138e2018-04-19 09:04:13 +02002016 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002017 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002018
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002019 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002020
pbos14fe7082016-04-20 06:35:56 -07002021 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002022 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002023 encoder.GetStartBitrateKbps());
2024
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002025 GetVideoEncoderConfig()->max_bitrate_bps =
2026 2 * bitrate_config.start_bitrate_bps;
2027 GetVideoSendStream()->ReconfigureVideoEncoder(
2028 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002029
2030 // New bitrate should be reconfigured above the previous max. As there's no
2031 // network connection this shouldn't be flaky, as no bitrate should've been
2032 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002033 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002034 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2035 encoder.GetStartBitrateKbps());
2036
2037 DestroyStreams();
2038}
2039
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002040class StartStopBitrateObserver : public test::FakeEncoder {
2041 public:
2042 StartStopBitrateObserver()
2043 : FakeEncoder(Clock::GetRealTimeClock()),
2044 encoder_init_(false, false),
2045 bitrate_changed_(false, false) {}
2046 int32_t InitEncode(const VideoCodec* config,
2047 int32_t number_of_cores,
2048 size_t max_payload_size) override {
2049 rtc::CritScope lock(&crit_);
2050 encoder_init_.Set();
2051 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2052 }
2053
Erik Språng566124a2018-04-23 12:32:22 +02002054 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002055 uint32_t framerate) override {
2056 rtc::CritScope lock(&crit_);
2057 bitrate_kbps_ = bitrate.get_sum_kbps();
2058 bitrate_changed_.Set();
2059 return FakeEncoder::SetRateAllocation(bitrate, framerate);
2060 }
2061
2062 bool WaitForEncoderInit() {
2063 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2064 }
2065
2066 bool WaitBitrateChanged(bool non_zero) {
2067 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002068 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002069 {
2070 rtc::CritScope lock(&crit_);
2071 bitrate_kbps = bitrate_kbps_;
2072 }
2073 if (!bitrate_kbps)
2074 continue;
2075
2076 if ((non_zero && *bitrate_kbps > 0) ||
2077 (!non_zero && *bitrate_kbps == 0)) {
2078 return true;
2079 }
2080 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2081 return false;
2082 }
2083
2084 private:
2085 rtc::CriticalSection crit_;
2086 rtc::Event encoder_init_;
2087 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002088 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002089};
2090
perkj57c21f92016-06-17 07:27:16 -07002091// This test that if the encoder use an internal source, VideoEncoder::SetRates
2092// will be called with zero bitrate during initialization and that
2093// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2094// with zero bitrate.
2095TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002096 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002097 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002098 test::EncoderProxyFactory encoder_factory(&encoder);
2099 encoder_factory.SetHasInternalSource(true);
2100 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002101
Niels Möller4db138e2018-04-19 09:04:13 +02002102 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002103 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002104 CreateSendConfig(1, 0, 0, &transport);
2105
2106 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002107 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002108
2109 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002110 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002111 GetVideoSendStream()->Start();
2112 GetVideoSendStream()->SetSource(&forwarder,
2113 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002114 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002115 });
perkj57c21f92016-06-17 07:27:16 -07002116
2117 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002118
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002119 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002120 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2121
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002122 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002123 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2124
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002125 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002126 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002127
eladalon413ee9a2017-08-22 04:02:52 -07002128 task_queue_.SendTask([this]() {
2129 DestroyStreams();
2130 DestroyCalls();
2131 });
perkj57c21f92016-06-17 07:27:16 -07002132}
2133
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002134// Tests that when the encoder uses an internal source, the VideoEncoder will
2135// be updated with a new bitrate when turning the VideoSendStream on/off with
2136// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2137// is reconfigured with new active layers.
2138TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
2139 test::NullTransport transport;
2140 StartStopBitrateObserver encoder;
Niels Möller4db138e2018-04-19 09:04:13 +02002141 test::EncoderProxyFactory encoder_factory(&encoder);
2142 encoder_factory.SetHasInternalSource(true);
2143 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002144
Niels Möller4db138e2018-04-19 09:04:13 +02002145 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002146 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002147 // Create two simulcast streams.
2148 CreateSendConfig(2, 0, 0, &transport);
2149
2150 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002151 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002152
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002153 GetVideoSendConfig()->rtp.payload_name = "VP8";
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002154
2155 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002156
2157 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002158 GetVideoSendStream()->Start();
2159 GetVideoSendStream()->SetSource(&forwarder,
2160 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002161 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002162 });
2163
2164 EXPECT_TRUE(encoder.WaitForEncoderInit());
2165
2166 // When we turn on the simulcast layers it will update the BitrateAllocator,
2167 // which in turn updates the VideoEncoder's bitrate.
2168 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002169 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002170 });
2171 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2172
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002173 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2174 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002175 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002176 GetVideoSendStream()->ReconfigureVideoEncoder(
2177 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002178 });
2179 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2180 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2181 // active. Once the change is made for a "soft" reconfiguration we can remove
2182 // the expecation for an encoder init. We can also test that bitrate changes
2183 // when just updating individual active layers, which should change the
2184 // bitrate set to the video encoder.
2185 EXPECT_TRUE(encoder.WaitForEncoderInit());
2186 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2187
2188 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002189 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2190 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002191 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002192 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002193 });
2194 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2195
2196 task_queue_.SendTask([this]() {
2197 DestroyStreams();
2198 DestroyCalls();
2199 });
2200}
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002201TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002202 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002203 public:
Peter Boström5811a392015-12-10 13:02:50 +01002204 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002205
nissed30a1112016-04-18 05:15:22 -07002206 void OnFrame(const VideoFrame& video_frame) override {
2207 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002208 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002209 }
2210
2211 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002212 const int kWaitFrameTimeoutMs = 3000;
2213 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002214 << "Timeout while waiting for output frames.";
2215 }
2216
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002217 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002218 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002219 }
2220
2221 private:
2222 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002223 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002224
2225 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002226 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002227 };
2228
solenberg4fbae2b2015-08-28 04:07:10 -07002229 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002230 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002231 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002232
eladalon413ee9a2017-08-22 04:02:52 -07002233 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2234 // Initialize send stream.
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002235 CreateSenderCall();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002236
eladalon413ee9a2017-08-22 04:02:52 -07002237 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002238 GetVideoSendConfig()->pre_encode_callback = &observer;
eladalon413ee9a2017-08-22 04:02:52 -07002239 CreateVideoStreams();
2240
2241 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2242 // alternatively.
2243 int width = 168;
2244 int height = 132;
2245
2246 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2247 width, height, 1, 1, kVideoRotation_0));
2248 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2249 width, height, 2, 2, kVideoRotation_0));
2250 input_frames.push_back(CreateVideoFrame(width, height, 3));
2251 input_frames.push_back(CreateVideoFrame(width, height, 4));
2252 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2253 width, height, 5, 5, kVideoRotation_0));
2254
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002255 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -07002256 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002257 GetVideoSendStream()->SetSource(&forwarder,
2258 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002259 for (size_t i = 0; i < input_frames.size(); i++) {
2260 forwarder.IncomingCapturedFrame(input_frames[i]);
2261 // Wait until the output frame is received before sending the next input
2262 // frame. Or the previous input frame may be replaced without delivering.
2263 observer.WaitOutputFrame();
2264 }
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002265 GetVideoSendStream()->Stop();
2266 GetVideoSendStream()->SetSource(nullptr,
2267 DegradationPreference::MAINTAIN_FRAMERATE);
eladalon413ee9a2017-08-22 04:02:52 -07002268 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002269
2270 // Test if the input and output frames are the same. render_time_ms and
2271 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002272 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002273
eladalon413ee9a2017-08-22 04:02:52 -07002274 task_queue_.SendTask([this]() {
2275 DestroyStreams();
2276 DestroyCalls();
2277 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002278}
2279
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002280void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2281 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002282 EXPECT_EQ(frames1.size(), frames2.size());
2283 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002284 // Compare frame buffers, since we don't care about differing timestamps.
2285 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2286 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002287}
2288
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002289VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002290 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002291 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002292 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002293 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002294 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002295 // Use data as a ms timestamp.
2296 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002297 return frame;
2298}
2299
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002300TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2301 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2302 public:
eladalon413ee9a2017-08-22 04:02:52 -07002303 explicit EncoderStateObserver(
2304 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002305 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002306 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002307 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002308 initialized_(false),
2309 callback_registered_(false),
2310 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002311 released_(false),
2312 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002313
2314 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002315 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002316 return released_;
2317 }
2318
2319 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002320 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002321 return initialized_ && callback_registered_;
2322 }
2323
2324 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002325 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002326 return num_releases_;
2327 }
2328
2329 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002330 int32_t InitEncode(const VideoCodec* codecSettings,
2331 int32_t numberOfCores,
2332 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002333 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002334 EXPECT_FALSE(initialized_);
2335 initialized_ = true;
2336 released_ = false;
2337 return 0;
2338 }
2339
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002340 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002341 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002342 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002343 EXPECT_TRUE(IsReadyForEncode());
2344
Peter Boström5811a392015-12-10 13:02:50 +01002345 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002346 return 0;
2347 }
2348
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002349 int32_t RegisterEncodeCompleteCallback(
2350 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002351 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002352 EXPECT_TRUE(initialized_);
2353 callback_registered_ = true;
2354 return 0;
2355 }
2356
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002357 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002358 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002359 EXPECT_TRUE(IsReadyForEncode());
2360 EXPECT_FALSE(released_);
2361 initialized_ = false;
2362 callback_registered_ = false;
2363 released_ = true;
2364 ++num_releases_;
2365 return 0;
2366 }
2367
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002368 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002369 EXPECT_TRUE(IsReadyForEncode());
2370 return 0;
2371 }
2372
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002373 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002374 EXPECT_TRUE(IsReadyForEncode());
2375 return 0;
2376 }
2377
stefanff483612015-12-21 03:14:00 -08002378 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002379 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002380 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002381 stream_ = send_stream;
2382 }
2383
stefanff483612015-12-21 03:14:00 -08002384 void ModifyVideoConfigs(
2385 VideoSendStream::Config* send_config,
2386 std::vector<VideoReceiveStream::Config>* receive_configs,
2387 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002388 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002389 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002390 }
2391
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002392 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002393 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002394
2395 task_queue_->SendTask([this]() {
2396 EXPECT_EQ(0u, num_releases());
2397 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2398 EXPECT_EQ(0u, num_releases());
2399 stream_->Stop();
2400 // Encoder should not be released before destroying the VideoSendStream.
2401 EXPECT_FALSE(IsReleased());
2402 EXPECT_TRUE(IsReadyForEncode());
2403 stream_->Start();
2404 });
2405
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002406 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002407 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002408 }
2409
eladalon413ee9a2017-08-22 04:02:52 -07002410 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002411 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002412 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002413 bool initialized_ RTC_GUARDED_BY(crit_);
2414 bool callback_registered_ RTC_GUARDED_BY(crit_);
2415 size_t num_releases_ RTC_GUARDED_BY(crit_);
2416 bool released_ RTC_GUARDED_BY(crit_);
Niels Möller4db138e2018-04-19 09:04:13 +02002417 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002418 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002419 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002420
stefane74eef12016-01-08 06:47:13 -08002421 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002422
2423 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002424 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002425}
2426
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002427TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2428 class VideoCodecConfigObserver : public test::SendTest,
2429 public test::FakeEncoder {
2430 public:
2431 VideoCodecConfigObserver()
2432 : SendTest(kDefaultTimeoutMs),
2433 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002434 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002435 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002436 stream_(nullptr),
2437 encoder_factory_(this) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002438
2439 private:
stefanff483612015-12-21 03:14:00 -08002440 void ModifyVideoConfigs(
2441 VideoSendStream::Config* send_config,
2442 std::vector<VideoReceiveStream::Config>* receive_configs,
2443 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002444 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprangf24a0642017-02-28 13:23:26 -08002445 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002446 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002447 }
2448
stefanff483612015-12-21 03:14:00 -08002449 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002450 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002451 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002452 stream_ = send_stream;
2453 }
2454
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002455 int32_t InitEncode(const VideoCodec* config,
2456 int32_t number_of_cores,
2457 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002458 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002459 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002460 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002461 } else {
2462 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002463 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002464 }
2465 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002466 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002467 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2468 }
2469
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002470 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002471 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002472 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002473
sprangf24a0642017-02-28 13:23:26 -08002474 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002475 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002476 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002477 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002478 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2479 "new encoder settings.";
2480 }
2481
sprangf24a0642017-02-28 13:23:26 -08002482 const uint32_t kFirstMaxBitrateBps = 1000000;
2483 const uint32_t kSecondMaxBitrateBps = 2000000;
2484
pbos14fe7082016-04-20 06:35:56 -07002485 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002486 size_t num_initializations_;
2487 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002488 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002489 VideoEncoderConfig encoder_config_;
2490 } test;
2491
stefane74eef12016-01-08 06:47:13 -08002492 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002493}
2494
Sergey Silkin571e6c92018-04-03 10:03:31 +02002495static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002496template <typename T>
2497class VideoCodecConfigObserver : public test::SendTest,
2498 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002499 public:
2500 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2501 const char* codec_name)
2502 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2503 FakeEncoder(Clock::GetRealTimeClock()),
2504 video_codec_type_(video_codec_type),
2505 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002506 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002507 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002508 stream_(nullptr),
2509 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002510 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002511 }
2512
2513 private:
perkjfa10b552016-10-02 23:45:26 -07002514 class VideoStreamFactory
2515 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2516 public:
2517 VideoStreamFactory() {}
2518
2519 private:
2520 std::vector<VideoStream> CreateEncoderStreams(
2521 int width,
2522 int height,
2523 const VideoEncoderConfig& encoder_config) override {
2524 std::vector<VideoStream> streams =
2525 test::CreateVideoStreams(width, height, encoder_config);
2526 for (size_t i = 0; i < streams.size(); ++i) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002527 streams[i].num_temporal_layers =
2528 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkjfa10b552016-10-02 23:45:26 -07002529 }
2530 return streams;
2531 }
2532 };
2533
stefanff483612015-12-21 03:14:00 -08002534 void ModifyVideoConfigs(
2535 VideoSendStream::Config* send_config,
2536 std::vector<VideoReceiveStream::Config>* receive_configs,
2537 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002538 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002539 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002540
Niels Möller259a4972018-04-05 15:36:51 +02002541 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002542 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002543 encoder_config->video_stream_factory =
2544 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002545 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002546 }
2547
stefanff483612015-12-21 03:14:00 -08002548 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002549 VideoSendStream* send_stream,
2550 const std::vector<VideoReceiveStream*>& receive_streams) override {
2551 stream_ = send_stream;
2552 }
2553
2554 int32_t InitEncode(const VideoCodec* config,
2555 int32_t number_of_cores,
2556 size_t max_payload_size) override {
2557 EXPECT_EQ(video_codec_type_, config->codecType);
2558 VerifyCodecSpecifics(*config);
2559 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002560 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002561 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2562 }
2563
Sergey Silkin86684962018-03-28 19:32:37 +02002564 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002565 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002566 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2567 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002568
2569 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002570 EXPECT_TRUE(
2571 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002572 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002573
Sergey Silkin86684962018-03-28 19:32:37 +02002574 // Change encoder settings to actually trigger reconfiguration.
2575 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002576 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002577 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002578 ASSERT_TRUE(
2579 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002580 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002581 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2582 "new encoder settings.";
2583 }
2584
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002585 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002586 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002587 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002588 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2589 return 0;
2590 }
2591
2592 T encoder_settings_;
2593 const VideoCodecType video_codec_type_;
2594 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002595 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002596 size_t num_initializations_;
2597 VideoSendStream* stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002598 test::EncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002599 VideoEncoderConfig encoder_config_;
2600};
2601
2602template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002603void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2604 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2605}
2606
2607template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002608void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2609 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002610 EXPECT_EQ(
2611 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002612}
kthelgason29a44e32016-09-27 03:52:02 -07002613
2614template <>
2615rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2616VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2617 return new rtc::RefCountedObject<
2618 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2619}
2620
Peter Boström53eda3d2015-03-27 15:53:18 +01002621template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002622void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2623 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2624}
2625
2626template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002627void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2628 const VideoCodec& config) const {
2629 // Check that the number of temporal layers has propagated properly to
2630 // VideoCodec.
2631 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002632 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002633
2634 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2635 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2636 config.simulcastStream[i].numberOfTemporalLayers);
2637 }
2638
2639 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002640 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002641 VideoCodecVP8 encoder_settings = encoder_settings_;
2642 encoder_settings.numberOfTemporalLayers =
2643 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002644 EXPECT_EQ(
2645 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002646}
kthelgason29a44e32016-09-27 03:52:02 -07002647
2648template <>
2649rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2650VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2651 return new rtc::RefCountedObject<
2652 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2653}
2654
Peter Boström53eda3d2015-03-27 15:53:18 +01002655template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002656void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2657 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2658}
2659
2660template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002661void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2662 const VideoCodec& config) const {
2663 // Check that the number of temporal layers has propagated properly to
2664 // VideoCodec.
2665 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002666 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002667
2668 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2669 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2670 config.simulcastStream[i].numberOfTemporalLayers);
2671 }
2672
2673 // Set expected temporal layers as they should have been set when
2674 // reconfiguring the encoder and not match the set config.
2675 VideoCodecVP9 encoder_settings = encoder_settings_;
2676 encoder_settings.numberOfTemporalLayers =
2677 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002678 EXPECT_EQ(
2679 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002680}
2681
kthelgason29a44e32016-09-27 03:52:02 -07002682template <>
2683rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2684VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2685 return new rtc::RefCountedObject<
2686 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2687}
2688
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002689TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002690 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002691 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002692}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002693
Peter Boström53eda3d2015-03-27 15:53:18 +01002694TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2695 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002696 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002697}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002698
Peter Boström53eda3d2015-03-27 15:53:18 +01002699TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2700 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002701 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002702}
2703
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002704TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002705 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002706 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002707 RtcpSenderReportTest()
2708 : SendTest(kDefaultTimeoutMs),
2709 rtp_packets_sent_(0),
2710 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002711
2712 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002713 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002714 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002715 RTPHeader header;
2716 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002717 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002718 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2719 return SEND_PACKET;
2720 }
2721
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002722 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002723 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002724 test::RtcpPacketParser parser;
2725 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002726
danilchap3dc929e2016-11-02 08:21:59 -07002727 if (parser.sender_report()->num_packets() > 0) {
2728 // Only compare sent media bytes if SenderPacketCount matches the
2729 // number of sent rtp packets (a new rtp packet could be sent before
2730 // the rtcp packet).
2731 if (parser.sender_report()->sender_octet_count() > 0 &&
2732 parser.sender_report()->sender_packet_count() ==
2733 rtp_packets_sent_) {
2734 EXPECT_EQ(media_bytes_sent_,
2735 parser.sender_report()->sender_octet_count());
2736 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002737 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002738 }
2739
2740 return SEND_PACKET;
2741 }
2742
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002743 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002744 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002745 }
2746
stefan4b569042015-11-11 06:39:57 -08002747 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002748 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2749 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002750 } test;
2751
stefane74eef12016-01-08 06:47:13 -08002752 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002753}
2754
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002755TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002756 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002757
2758 class VideoStreamFactory
2759 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2760 public:
2761 VideoStreamFactory() {}
2762
2763 private:
2764 std::vector<VideoStream> CreateEncoderStreams(
2765 int width,
2766 int height,
2767 const VideoEncoderConfig& encoder_config) override {
2768 std::vector<VideoStream> streams =
2769 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002770 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
2771 streams[0].num_temporal_layers = 2;
2772 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2773 kScreencastMaxTargetBitrateDeltaKbps);
2774 streams[0].target_bitrate_bps =
2775 streams[0].max_bitrate_bps -
2776 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002777 return streams;
2778 }
2779 };
2780
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002781 class ScreencastTargetBitrateTest : public test::SendTest,
2782 public test::FakeEncoder {
2783 public:
2784 ScreencastTargetBitrateTest()
2785 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002786 test::FakeEncoder(Clock::GetRealTimeClock()),
2787 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002788
2789 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002790 int32_t InitEncode(const VideoCodec* config,
2791 int32_t number_of_cores,
2792 size_t max_payload_size) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002793 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002794 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002795 config->simulcastStream[0].maxBitrate -
2796 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002797 observation_complete_.Set();
Yves Gerey665174f2018-06-19 15:03:05 +02002798 return test::FakeEncoder::InitEncode(config, number_of_cores,
2799 max_payload_size);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002800 }
stefanff483612015-12-21 03:14:00 -08002801 void ModifyVideoConfigs(
2802 VideoSendStream::Config* send_config,
2803 std::vector<VideoReceiveStream::Config>* receive_configs,
2804 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002805 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002806 EXPECT_EQ(1u, encoder_config->number_of_streams);
2807 encoder_config->video_stream_factory =
2808 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002809 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002810 }
2811
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002812 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002813 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002814 << "Timed out while waiting for the encoder to be initialized.";
2815 }
Niels Möller4db138e2018-04-19 09:04:13 +02002816 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002817 } test;
2818
stefane74eef12016-01-08 06:47:13 -08002819 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002820}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002821
philipelc6957c72016-04-28 15:52:49 +02002822TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002823 // These are chosen to be "kind of odd" to not be accidentally checked against
2824 // default values.
2825 static const int kMinBitrateKbps = 137;
2826 static const int kStartBitrateKbps = 345;
2827 static const int kLowerMaxBitrateKbps = 312;
2828 static const int kMaxBitrateKbps = 413;
2829 static const int kIncreasedStartBitrateKbps = 451;
2830 static const int kIncreasedMaxBitrateKbps = 597;
2831 class EncoderBitrateThresholdObserver : public test::SendTest,
2832 public test::FakeEncoder {
2833 public:
eladalon413ee9a2017-08-22 04:02:52 -07002834 explicit EncoderBitrateThresholdObserver(
2835 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002836 : SendTest(kDefaultTimeoutMs),
2837 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002838 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002839 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002840 bitrate_changed_event_(false, false),
2841 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002842 num_initializations_(0),
2843 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002844 send_stream_(nullptr),
2845 encoder_factory_(this) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002846
2847 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002848 int32_t InitEncode(const VideoCodec* codecSettings,
2849 int32_t numberOfCores,
2850 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002851 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2852 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002853 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002854 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2855 codecSettings->minBitrate);
2856 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2857 codecSettings->startBitrate);
2858 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2859 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002860 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002861 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002862 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2863 codecSettings->maxBitrate);
2864 // The start bitrate should be kept (-1) and capped to the max bitrate.
2865 // Since this is not an end-to-end call no receiver should have been
2866 // returning a REMB that could lower this estimate.
2867 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002868 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002869 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2870 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002871 // The start bitrate will be whatever the rate BitRateController
2872 // has currently configured but in the span of the set max and min
2873 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002874 }
2875 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002876 init_encode_event_.Set();
2877
pbos@webrtc.org00873182014-11-25 14:03:34 +00002878 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2879 maxPayloadSize);
2880 }
2881
Erik Språng566124a2018-04-23 12:32:22 +02002882 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
Erik Språng08127a92016-11-16 16:41:30 +01002883 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002884 {
2885 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002886 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2887 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002888 }
Erik Språng08127a92016-11-16 16:41:30 +01002889 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002890 }
2891 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002892 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002893 }
2894
2895 void WaitForSetRates(uint32_t expected_bitrate) {
2896 EXPECT_TRUE(
2897 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2898 << "Timed out while waiting encoder rate to be set.";
2899 rtc::CritScope lock(&crit_);
2900 EXPECT_EQ(expected_bitrate, target_bitrate_);
2901 }
2902
Sebastian Jansson72582242018-07-13 13:19:42 +02002903 void ModifySenderCallConfig(Call::Config* config) override {
2904 config->bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2905 config->bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2906 config->bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002907 }
2908
perkjfa10b552016-10-02 23:45:26 -07002909 class VideoStreamFactory
2910 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2911 public:
2912 explicit VideoStreamFactory(int min_bitrate_bps)
2913 : min_bitrate_bps_(min_bitrate_bps) {}
2914
2915 private:
2916 std::vector<VideoStream> CreateEncoderStreams(
2917 int width,
2918 int height,
2919 const VideoEncoderConfig& encoder_config) override {
2920 std::vector<VideoStream> streams =
2921 test::CreateVideoStreams(width, height, encoder_config);
2922 streams[0].min_bitrate_bps = min_bitrate_bps_;
2923 return streams;
2924 }
2925
2926 const int min_bitrate_bps_;
2927 };
2928
stefanff483612015-12-21 03:14:00 -08002929 void ModifyVideoConfigs(
2930 VideoSendStream::Config* send_config,
2931 std::vector<VideoReceiveStream::Config>* receive_configs,
2932 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002933 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002934 // Set bitrates lower/higher than min/max to make sure they are properly
2935 // capped.
perkjfa10b552016-10-02 23:45:26 -07002936 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2937 // Create a new StreamFactory to be able to set
2938 // |VideoStream.min_bitrate_bps|.
2939 encoder_config->video_stream_factory =
2940 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002941 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002942 }
2943
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002944 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002945 call_ = sender_call;
2946 }
2947
stefanff483612015-12-21 03:14:00 -08002948 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002949 VideoSendStream* send_stream,
2950 const std::vector<VideoReceiveStream*>& receive_streams) override {
2951 send_stream_ = send_stream;
2952 }
2953
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002954 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002955 ASSERT_TRUE(
2956 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002957 << "Timed out while waiting for encoder to be configured.";
2958 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002959 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002960 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2961 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002962 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002963 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2964 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002965 });
perkj26091b12016-09-01 01:17:40 -07002966 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2967 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002968 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002969 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002970 ASSERT_TRUE(
2971 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002972 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002973 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002974 WaitForSetRates(kLowerMaxBitrateKbps);
2975
2976 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2977 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2978 ASSERT_TRUE(
2979 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002980 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002981 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002982 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002983 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002984 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002985 }
2986
eladalon413ee9a2017-08-22 04:02:52 -07002987 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002988 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002989 rtc::Event bitrate_changed_event_;
2990 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002991 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002992
pbos@webrtc.org00873182014-11-25 14:03:34 +00002993 int num_initializations_;
2994 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002995 webrtc::VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02002996 test::EncoderProxyFactory encoder_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002997 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002998 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002999
stefane74eef12016-01-08 06:47:13 -08003000 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003001}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003002
3003TEST_F(VideoSendStreamTest, ReportsSentResolution) {
3004 static const size_t kNumStreams = 3;
3005 // Unusual resolutions to make sure that they are the ones being reported.
3006 static const struct {
3007 int width;
3008 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02003009 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003010 class ScreencastTargetBitrateTest : public test::SendTest,
3011 public test::FakeEncoder {
3012 public:
3013 ScreencastTargetBitrateTest()
3014 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02003015 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02003016 send_stream_(nullptr),
3017 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003018
3019 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003020 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003021 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07003022 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003023 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003024 specifics.codecType = kVideoCodecGeneric;
3025
3026 uint8_t buffer[16] = {0};
3027 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
3028 encoded._timeStamp = input_image.timestamp();
3029 encoded.capture_time_ms_ = input_image.render_time_ms();
3030
3031 for (size_t i = 0; i < kNumStreams; ++i) {
3032 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
3033 encoded._frameType = (*frame_types)[i];
3034 encoded._encodedWidth = kEncodedResolution[i].width;
3035 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08003036 EncodedImageCallback* callback;
3037 {
3038 rtc::CritScope cs(&crit_sect_);
3039 callback = callback_;
3040 }
3041 RTC_DCHECK(callback);
3042 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003043 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003044 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003045 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003046 }
3047
Peter Boström5811a392015-12-10 13:02:50 +01003048 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003049 return 0;
3050 }
stefanff483612015-12-21 03:14:00 -08003051 void ModifyVideoConfigs(
3052 VideoSendStream::Config* send_config,
3053 std::vector<VideoReceiveStream::Config>* receive_configs,
3054 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003055 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003056 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003057 }
3058
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003059 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003060
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003061 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003062 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003063 << "Timed out while waiting for the encoder to send one frame.";
3064 VideoSendStream::Stats stats = send_stream_->GetStats();
3065
3066 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003067 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003068 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003069 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003070 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003071 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003072 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003073 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3074 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003075 }
3076 }
3077
stefanff483612015-12-21 03:14:00 -08003078 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003079 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003080 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003081 send_stream_ = send_stream;
3082 }
3083
3084 VideoSendStream* send_stream_;
Niels Möller4db138e2018-04-19 09:04:13 +02003085 test::EncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003086 } test;
3087
stefane74eef12016-01-08 06:47:13 -08003088 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003089}
philipel0f9af012015-09-01 07:01:51 -07003090
Peter Boström12996152016-05-14 02:03:18 +02003091#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003092class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003093 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003094 Vp9HeaderObserver()
3095 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003096 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003097 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3098 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003099 frames_sent_(0),
3100 expected_width_(0),
3101 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003102
stefanff483612015-12-21 03:14:00 -08003103 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003104 VideoSendStream::Config* send_config,
3105 std::vector<VideoReceiveStream::Config>* receive_configs,
3106 VideoEncoderConfig* encoder_config) {}
3107
Åsa Perssonff24c042015-12-04 10:58:08 +01003108 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003109
3110 private:
minyue20c84cc2017-04-10 16:57:57 -07003111 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003112
perkjfa10b552016-10-02 23:45:26 -07003113 class VideoStreamFactory
3114 : public VideoEncoderConfig::VideoStreamFactoryInterface {
3115 public:
3116 explicit VideoStreamFactory(size_t number_of_temporal_layers)
3117 : number_of_temporal_layers_(number_of_temporal_layers) {}
3118
3119 private:
3120 std::vector<VideoStream> CreateEncoderStreams(
3121 int width,
3122 int height,
3123 const VideoEncoderConfig& encoder_config) override {
3124 std::vector<VideoStream> streams =
3125 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01003126 streams.back().num_temporal_layers = number_of_temporal_layers_;
perkjfa10b552016-10-02 23:45:26 -07003127 return streams;
3128 }
3129
3130 const size_t number_of_temporal_layers_;
3131 };
3132
stefanff483612015-12-21 03:14:00 -08003133 void ModifyVideoConfigs(
3134 VideoSendStream::Config* send_config,
3135 std::vector<VideoReceiveStream::Config>* receive_configs,
3136 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003137 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003138 send_config->rtp.payload_name = "VP9";
3139 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003140 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003141 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003142 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003143 EXPECT_EQ(1u, encoder_config->number_of_streams);
3144 encoder_config->video_stream_factory =
3145 new rtc::RefCountedObject<VideoStreamFactory>(
3146 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07003147 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003148 }
3149
perkjfa10b552016-10-02 23:45:26 -07003150 void ModifyVideoCaptureStartResolution(int* width,
3151 int* height,
3152 int* frame_rate) override {
3153 expected_width_ = *width;
3154 expected_height_ = *height;
3155 }
3156
philipel0f9af012015-09-01 07:01:51 -07003157 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003158 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3159 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003160 }
3161
3162 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3163 RTPHeader header;
3164 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3165
Åsa Perssonff24c042015-12-04 10:58:08 +01003166 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3167 const uint8_t* payload = packet + header.headerLength;
3168 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003169
Åsa Perssonff24c042015-12-04 10:58:08 +01003170 bool new_packet = packets_sent_ == 0 ||
3171 IsNewerSequenceNumber(header.sequenceNumber,
3172 last_header_.sequenceNumber);
3173 if (payload_length > 0 && new_packet) {
3174 RtpDepacketizer::ParsedPayload parsed;
3175 RtpDepacketizerVp9 depacketizer;
3176 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003177 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003178 // Verify common fields for all configurations.
philipel5ab67a52018-07-05 12:27:04 +02003179 VerifyCommonHeader(parsed.video_header().vp9());
philipelcb96ad82018-07-02 14:41:58 +02003180 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003181 // Verify configuration specific settings.
philipel5ab67a52018-07-05 12:27:04 +02003182 InspectHeader(parsed.video_header().vp9());
philipel0f9af012015-09-01 07:01:51 -07003183
Åsa Perssonff24c042015-12-04 10:58:08 +01003184 ++packets_sent_;
3185 if (header.markerBit) {
3186 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003187 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003188 last_header_ = header;
philipel5ab67a52018-07-05 12:27:04 +02003189 last_vp9_ = parsed.video_header().vp9();
philipel0f9af012015-09-01 07:01:51 -07003190 }
philipel0f9af012015-09-01 07:01:51 -07003191 return SEND_PACKET;
3192 }
3193
philipel7fabd462015-09-03 04:42:32 -07003194 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003195 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3196 if (last_vp9_.picture_id > vp9.picture_id) {
3197 return vp9.picture_id == 0; // Wrap.
3198 } else {
3199 return vp9.picture_id == last_vp9_.picture_id + 1;
3200 }
3201 }
3202
3203 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003204 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3205 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3206 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3207 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3208 vp9.spatial_idx);
3209 }
3210
3211 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3212 uint8_t num_layers) const {
3213 switch (num_layers) {
3214 case 0:
3215 VerifyTemporalLayerStructure0(vp9);
3216 break;
3217 case 1:
3218 VerifyTemporalLayerStructure1(vp9);
3219 break;
3220 case 2:
3221 VerifyTemporalLayerStructure2(vp9);
3222 break;
3223 case 3:
3224 VerifyTemporalLayerStructure3(vp9);
3225 break;
3226 default:
3227 RTC_NOTREACHED();
3228 }
3229 }
3230
3231 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3232 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3233 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3234 EXPECT_FALSE(vp9.temporal_up_switch);
3235 }
3236
3237 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3238 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3239 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3240 EXPECT_FALSE(vp9.temporal_up_switch);
3241 }
3242
3243 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3244 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3245 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3246 EXPECT_LE(vp9.temporal_idx, 1);
3247 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3248 if (IsNewPictureId(vp9)) {
3249 uint8_t expected_tid =
3250 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3251 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3252 }
3253 }
3254
3255 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3256 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3257 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3258 EXPECT_LE(vp9.temporal_idx, 2);
3259 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3260 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3261 switch (vp9.temporal_idx) {
3262 case 0:
3263 EXPECT_EQ(2, last_vp9_.temporal_idx);
3264 EXPECT_FALSE(vp9.temporal_up_switch);
3265 break;
3266 case 1:
3267 EXPECT_EQ(2, last_vp9_.temporal_idx);
3268 EXPECT_TRUE(vp9.temporal_up_switch);
3269 break;
3270 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003271 EXPECT_LT(last_vp9_.temporal_idx, 2);
3272 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003273 break;
3274 }
3275 }
3276 }
3277
3278 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3279 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3280 return;
3281
3282 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3283 if (vp9.temporal_idx == 0)
3284 ++expected_tl0_idx;
3285 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3286 }
3287
3288 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3289 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3290 }
3291
3292 // Flexible mode (F=1): Non-flexible mode (F=0):
3293 //
3294 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3295 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3296 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3297 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3298 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3299 // M: | EXTENDED PID | M: | EXTENDED PID |
3300 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3301 // L: | T |U| S |D| L: | T |U| S |D|
3302 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3303 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3304 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3305 // X: |EXTENDED P_DIFF| V: | SS .. |
3306 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3307 // V: | SS .. |
3308 // +-+-+-+-+-+-+-+-+
3309 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3310 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3311 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3312 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003313
3314 if (vp9_settings_.numberOfSpatialLayers > 1) {
3315 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3316 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3317 EXPECT_EQ(vp9.spatial_idx, 0);
3318 } else {
3319 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3320 }
3321
3322 if (vp9_settings_.numberOfTemporalLayers > 1) {
3323 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3324 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3325 EXPECT_EQ(vp9.temporal_idx, 0);
3326 } else {
3327 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3328 }
3329
Åsa Perssonff24c042015-12-04 10:58:08 +01003330 if (vp9.ss_data_available) // V
3331 VerifySsData(vp9);
3332
3333 if (frames_sent_ == 0)
3334 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3335
3336 if (!vp9.inter_pic_predicted) {
3337 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3338 EXPECT_FALSE(vp9.temporal_up_switch);
3339 }
3340 }
3341
3342 // Scalability structure (SS).
3343 //
3344 // +-+-+-+-+-+-+-+-+
3345 // V: | N_S |Y|G|-|-|-|
3346 // +-+-+-+-+-+-+-+-+
3347 // Y: | WIDTH | N_S + 1 times
3348 // +-+-+-+-+-+-+-+-+
3349 // | HEIGHT |
3350 // +-+-+-+-+-+-+-+-+
3351 // G: | N_G |
3352 // +-+-+-+-+-+-+-+-+
3353 // N_G: | T |U| R |-|-| N_G times
3354 // +-+-+-+-+-+-+-+-+
3355 // | P_DIFF | R times
3356 // +-+-+-+-+-+-+-+-+
3357 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3358 EXPECT_TRUE(vp9.ss_data_available); // V
3359 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3360 vp9.num_spatial_layers);
3361 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003362 int expected_width = expected_width_;
3363 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003364 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003365 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3366 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3367 expected_width /= 2;
3368 expected_height /= 2;
3369 }
3370 }
3371
3372 void CompareConsecutiveFrames(const RTPHeader& header,
3373 const RTPVideoHeader& video) const {
philipel5ab67a52018-07-05 12:27:04 +02003374 const RTPVideoHeaderVP9& vp9 = video.vp9();
Åsa Perssonff24c042015-12-04 10:58:08 +01003375
3376 bool new_frame = packets_sent_ == 0 ||
3377 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003378 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003379 if (!new_frame) {
3380 EXPECT_FALSE(last_header_.markerBit);
3381 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3382 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3383 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3384 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3385 VerifySpatialIdxWithinFrame(vp9);
3386 return;
3387 }
3388 // New frame.
3389 EXPECT_TRUE(vp9.beginning_of_frame);
3390
3391 // Compare with last packet in previous frame.
3392 if (frames_sent_ == 0)
3393 return;
3394 EXPECT_TRUE(last_vp9_.end_of_frame);
3395 EXPECT_TRUE(last_header_.markerBit);
3396 EXPECT_TRUE(ContinuousPictureId(vp9));
3397 VerifyTl0Idx(vp9);
3398 }
3399
Niels Möller4db138e2018-04-19 09:04:13 +02003400 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003401 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003402 webrtc::VideoEncoderConfig encoder_config_;
3403 RTPHeader last_header_;
3404 RTPVideoHeaderVP9 last_vp9_;
3405 size_t packets_sent_;
3406 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003407 int expected_width_;
3408 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003409};
3410
Åsa Perssonff24c042015-12-04 10:58:08 +01003411TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3412 const uint8_t kNumTemporalLayers = 1;
3413 const uint8_t kNumSpatialLayers = 1;
3414 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3415}
3416
3417TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3418 const uint8_t kNumTemporalLayers = 2;
3419 const uint8_t kNumSpatialLayers = 1;
3420 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3421}
3422
3423TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3424 const uint8_t kNumTemporalLayers = 3;
3425 const uint8_t kNumSpatialLayers = 1;
3426 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3427}
3428
3429TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3430 const uint8_t kNumTemporalLayers = 1;
3431 const uint8_t kNumSpatialLayers = 2;
3432 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3433}
3434
3435TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3436 const uint8_t kNumTemporalLayers = 2;
3437 const uint8_t kNumSpatialLayers = 2;
3438 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3439}
3440
3441TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3442 const uint8_t kNumTemporalLayers = 3;
3443 const uint8_t kNumSpatialLayers = 2;
3444 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3445}
3446
3447void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3448 uint8_t num_spatial_layers) {
3449 static const size_t kNumFramesToSend = 100;
3450 // Set to < kNumFramesToSend and coprime to length of temporal layer
3451 // structures to verify temporal id reset on key frame.
3452 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003453
3454 static const int kWidth = kMinVp9SpatialLayerWidth;
3455 static const int kHeight = kMinVp9SpatialLayerHeight;
3456 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003457 class NonFlexibleMode : public Vp9HeaderObserver {
3458 public:
3459 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3460 : num_temporal_layers_(num_temporal_layers),
3461 num_spatial_layers_(num_spatial_layers),
3462 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003463
stefanff483612015-12-21 03:14:00 -08003464 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003465 VideoSendStream::Config* send_config,
3466 std::vector<VideoReceiveStream::Config>* receive_configs,
3467 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003468 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003469 int bitrate_bps = 0;
3470 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3471 const int width = kWidth << sl_idx;
3472 const int height = kHeight << sl_idx;
3473 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3474 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3475 }
3476 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3477
Åsa Perssonff24c042015-12-04 10:58:08 +01003478 vp9_settings_.flexibleMode = false;
3479 vp9_settings_.frameDroppingOn = false;
3480 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3481 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3482 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003483 }
3484
Sergey Silkin86684962018-03-28 19:32:37 +02003485 void ModifyVideoCaptureStartResolution(int* width,
3486 int* height,
3487 int* frame_rate) override {
3488 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3489 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3490 *width = expected_width_;
3491 *height = expected_height_;
3492 }
3493
Åsa Perssonff24c042015-12-04 10:58:08 +01003494 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003495 bool ss_data_expected =
3496 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3497 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003498 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003499 if (num_spatial_layers_ > 1) {
3500 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3501 } else {
3502 EXPECT_FALSE(vp9.inter_layer_predicted);
3503 }
3504
asapersson38bb8ad2015-12-14 01:41:19 -08003505 EXPECT_EQ(!vp9.inter_pic_predicted,
3506 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003507
3508 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003509 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3510 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3511 } else {
3512 EXPECT_EQ(0, vp9.spatial_idx);
3513 }
3514 if (num_spatial_layers_ > 1)
3515 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003516 }
3517
3518 VerifyFixedTemporalLayerStructure(vp9,
3519 l_field_ ? num_temporal_layers_ : 0);
3520
3521 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003522 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003523 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003524 const uint8_t num_temporal_layers_;
3525 const uint8_t num_spatial_layers_;
3526 const bool l_field_;
3527 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003528
stefane74eef12016-01-08 06:47:13 -08003529 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003530}
3531
asaperssond9f641e2016-01-21 01:11:35 -08003532TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3533 static const size_t kNumFramesToSend = 50;
3534 static const int kWidth = 4;
3535 static const int kHeight = 4;
3536 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3537 void ModifyVideoConfigsHook(
3538 VideoSendStream::Config* send_config,
3539 std::vector<VideoReceiveStream::Config>* receive_configs,
3540 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003541 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003542 vp9_settings_.flexibleMode = false;
3543 vp9_settings_.numberOfTemporalLayers = 1;
3544 vp9_settings_.numberOfSpatialLayers = 1;
3545
perkjfa10b552016-10-02 23:45:26 -07003546 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003547 }
3548
3549 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3550 if (frames_sent_ > kNumFramesToSend)
3551 observation_complete_.Set();
3552 }
perkjfa10b552016-10-02 23:45:26 -07003553
3554 void ModifyVideoCaptureStartResolution(int* width,
3555 int* height,
3556 int* frame_rate) override {
3557 expected_width_ = kWidth;
3558 expected_height_ = kHeight;
3559 *width = kWidth;
3560 *height = kHeight;
3561 }
asaperssond9f641e2016-01-21 01:11:35 -08003562 } test;
3563
3564 RunBaseTest(&test);
3565}
3566
kjellanderf9e2a362017-03-24 12:17:33 -07003567#if defined(WEBRTC_ANDROID)
3568// Crashes on Android; bugs.webrtc.org/7401
3569#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3570#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003571// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3572// the test after webrtc:9270 is implemented.
3573#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3574// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003575#endif
3576TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003577 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003578 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003579 VideoSendStream::Config* send_config,
3580 std::vector<VideoReceiveStream::Config>* receive_configs,
3581 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003582 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003583 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003584 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003585 vp9_settings_.numberOfTemporalLayers = 1;
3586 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003587 }
3588
Åsa Perssonff24c042015-12-04 10:58:08 +01003589 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3590 EXPECT_TRUE(vp9_header.flexible_mode);
3591 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3592 if (vp9_header.inter_pic_predicted) {
3593 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003594 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003595 }
3596 }
3597 } test;
3598
stefane74eef12016-01-08 06:47:13 -08003599 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003600}
Peter Boström12996152016-05-14 02:03:18 +02003601#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003602
perkj803d97f2016-11-01 11:45:46 -07003603void VideoSendStreamTest::TestRequestSourceRotateVideo(
3604 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003605 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003606
3607 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003608 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003609 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003610 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003611 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003612 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3613 }
3614
3615 CreateVideoStreams();
3616 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003617 GetVideoSendStream()->SetSource(&forwarder,
3618 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003619
3620 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3621 support_orientation_ext);
3622
3623 DestroyStreams();
3624}
3625
3626TEST_F(VideoSendStreamTest,
3627 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3628 TestRequestSourceRotateVideo(false);
3629}
3630
3631TEST_F(VideoSendStreamTest,
3632 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3633 TestRequestSourceRotateVideo(true);
3634}
3635
michaelta3328772016-11-29 09:25:03 -08003636// This test verifies that overhead is removed from the bandwidth estimate by
3637// testing that the maximum possible target payload rate is smaller than the
3638// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003639TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003640 test::ScopedFieldTrials override_field_trials(
3641 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3642 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3643 public test::FakeEncoder {
3644 public:
eladalon413ee9a2017-08-22 04:02:52 -07003645 explicit RemoveOverheadFromBandwidthTest(
3646 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003647 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3648 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003649 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003650 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003651 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003652 max_bitrate_bps_(0),
3653 first_packet_sent_(false),
3654 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003655
Erik Språng566124a2018-04-23 12:32:22 +02003656 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
michaelta3328772016-11-29 09:25:03 -08003657 uint32_t frameRate) override {
3658 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003659 // Wait for the first sent packet so that videosendstream knows
3660 // rtp_overhead.
3661 if (first_packet_sent_) {
3662 max_bitrate_bps_ = bitrate.get_sum_bps();
3663 bitrate_changed_event_.Set();
3664 }
michaelta3328772016-11-29 09:25:03 -08003665 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3666 }
3667
3668 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3669 call_ = sender_call;
3670 }
3671
3672 void ModifyVideoConfigs(
3673 VideoSendStream::Config* send_config,
3674 std::vector<VideoReceiveStream::Config>* receive_configs,
3675 VideoEncoderConfig* encoder_config) override {
3676 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003677 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003678 EXPECT_FALSE(send_config->rtp.extensions.empty());
3679 }
3680
michaelt192132e2017-01-26 09:05:27 -08003681 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3682 rtc::CritScope lock(&crit_);
3683 first_packet_sent_ = true;
3684 return SEND_PACKET;
3685 }
3686
michaelta3328772016-11-29 09:25:03 -08003687 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003688 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003689 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003690 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003691 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003692 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3693 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003694 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003695 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003696 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3697 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07003698 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3699 });
michaelta3328772016-11-29 09:25:03 -08003700
3701 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003702 // overhead of 40B per packet video produces 2240bps overhead.
3703 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003704 EXPECT_TRUE(
3705 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003706 {
3707 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003708 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003709 }
3710 }
3711
3712 private:
eladalon413ee9a2017-08-22 04:02:52 -07003713 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möller4db138e2018-04-19 09:04:13 +02003714 test::EncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003715 Call* call_;
3716 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003717 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3718 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003719 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003720 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003721 RunBaseTest(&test);
3722}
3723
sprang168794c2017-07-06 04:38:06 -07003724TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3725 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003726
3727 class KeepaliveObserver : public test::SendTest {
3728 public:
3729 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3730
sprangdb2a9fc2017-08-09 06:42:32 -07003731 void OnRtpTransportControllerSendCreated(
3732 RtpTransportControllerSend* controller) override {
3733 RtpKeepAliveConfig config;
3734 config.timeout_interval_ms = kTimeoutMs;
3735 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3736 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003737 }
3738
sprang168794c2017-07-06 04:38:06 -07003739 private:
3740 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3741 RTPHeader header;
3742 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3743
sprangd2702ef2017-07-10 08:41:10 -07003744 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003745 // The video stream has started. Stop it now.
3746 if (capturer_)
3747 capturer_->Stop();
3748 } else {
3749 observation_complete_.Set();
3750 }
3751
3752 return SEND_PACKET;
3753 }
3754
sprang168794c2017-07-06 04:38:06 -07003755 void PerformTest() override {
3756 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3757 }
3758
3759 void OnFrameGeneratorCapturerCreated(
3760 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3761 capturer_ = frame_generator_capturer;
3762 }
3763
3764 test::FrameGeneratorCapturer* capturer_ = nullptr;
3765 } test;
3766
3767 RunBaseTest(&test);
3768}
3769
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003770class PacingFactorObserver : public test::SendTest {
3771 public:
3772 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003773 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003774 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3775 configure_send_side_(configure_send_side),
3776 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003777
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003778 void ModifyVideoConfigs(
3779 VideoSendStream::Config* send_config,
3780 std::vector<VideoReceiveStream::Config>* receive_configs,
3781 VideoEncoderConfig* encoder_config) override {
3782 // Check if send-side bwe extension is already present, and remove it if
3783 // it is not desired.
3784 bool has_send_side = false;
3785 for (auto it = send_config->rtp.extensions.begin();
3786 it != send_config->rtp.extensions.end(); ++it) {
3787 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3788 if (configure_send_side_) {
3789 has_send_side = true;
3790 } else {
3791 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003792 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003793 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003794 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003795 }
3796
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003797 if (configure_send_side_ && !has_send_side) {
3798 // Want send side, not present by default, so add it.
3799 send_config->rtp.extensions.emplace_back(
3800 RtpExtension::kTransportSequenceNumberUri,
3801 RtpExtension::kTransportSequenceNumberDefaultId);
Erik Språng7c8cca32017-10-24 17:05:18 +02003802 }
3803
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003804 // ALR only enabled for screenshare.
3805 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3806 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003807
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003808 void OnVideoStreamsCreated(
3809 VideoSendStream* send_stream,
3810 const std::vector<VideoReceiveStream*>& receive_streams) override {
3811 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3812 // Video streams created, check that pacing factor is correctly configured.
3813 EXPECT_EQ(expected_pacing_factor_,
3814 internal_send_peer.GetPacingFactorOverride());
3815 observation_complete_.Set();
3816 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003817
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003818 void PerformTest() override {
3819 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3820 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003821
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003822 private:
3823 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003824 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003825};
3826
3827std::string GetAlrProbingExperimentString() {
3828 return std::string(
3829 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3830 "/1.0,2875,80,40,-60,3/";
3831}
3832const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3833
3834TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
3835 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003836 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003837 PacingFactorObserver test_with_send_side(true,
3838 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003839 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003840}
Erik Språng7c8cca32017-10-24 17:05:18 +02003841
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003842TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
3843 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3844 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003845 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003846 RunBaseTest(&test_without_send_side);
3847}
3848
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003849// Test class takes as argument a function pointer to reset the send
3850// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3851// change the content type of a VideoSendStream, you need to recreate it.
3852// Stopping and recreating the stream can only be done on the main thread and in
3853// the context of VideoSendStreamTest (not BaseTest). The test switches from
3854// realtime to screenshare and back.
3855template <typename T>
3856class ContentSwitchTest : public test::SendTest {
3857 public:
3858 enum class StreamState {
3859 kBeforeSwitch = 0,
3860 kInScreenshare = 1,
3861 kAfterSwitchBack = 2,
3862 };
3863 static const uint32_t kMinPacketsToSend = 50;
3864
3865 explicit ContentSwitchTest(T* stream_reset_fun)
3866 : SendTest(test::CallTest::kDefaultTimeoutMs),
3867 content_switch_event_(false, false),
3868 call_(nullptr),
3869 state_(StreamState::kBeforeSwitch),
3870 send_stream_(nullptr),
3871 send_stream_config_(nullptr),
3872 packets_sent_(0),
3873 stream_resetter_(stream_reset_fun) {
3874 RTC_DCHECK(stream_resetter_);
3875 }
3876
3877 void OnVideoStreamsCreated(
3878 VideoSendStream* send_stream,
3879 const std::vector<VideoReceiveStream*>& receive_streams) override {
3880 rtc::CritScope lock(&crit_);
3881 send_stream_ = send_stream;
3882 }
3883
3884 void ModifyVideoConfigs(
3885 VideoSendStream::Config* send_config,
3886 std::vector<VideoReceiveStream::Config>* receive_configs,
3887 VideoEncoderConfig* encoder_config) override {
3888 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3889 encoder_config->min_transmit_bitrate_bps = 0;
3890 encoder_config->content_type =
3891 VideoEncoderConfig::ContentType::kRealtimeVideo;
3892 send_stream_config_ = send_config->Copy();
3893 encoder_config_ = encoder_config->Copy();
3894 }
3895
3896 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3897 call_ = sender_call;
3898 }
3899
3900 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3901 rtc::CritScope lock(&crit_);
3902
3903 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3904 float pacing_factor =
3905 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3906 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3907 if (send_stream_->GetStats().content_type ==
3908 webrtc::VideoContentType::SCREENSHARE) {
3909 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3910 }
3911
3912 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3913
3914 // Wait until at least kMinPacketsToSend packets to be sent, so that
3915 // some frames would be encoded.
3916 if (++packets_sent_ < kMinPacketsToSend)
3917 return SEND_PACKET;
3918
3919 if (state_ != StreamState::kAfterSwitchBack) {
3920 // We've sent kMinPacketsToSend packets, switch the content type and move
3921 // move to the next state.
3922 // Note that we need to recreate the stream if changing content type.
3923 packets_sent_ = 0;
3924 if (encoder_config_.content_type ==
3925 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3926 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3927 } else {
3928 encoder_config_.content_type =
3929 VideoEncoderConfig::ContentType::kRealtimeVideo;
3930 }
3931 switch (state_) {
3932 case StreamState::kBeforeSwitch:
3933 state_ = StreamState::kInScreenshare;
3934 break;
3935 case StreamState::kInScreenshare:
3936 state_ = StreamState::kAfterSwitchBack;
3937 break;
3938 case StreamState::kAfterSwitchBack:
3939 RTC_NOTREACHED();
3940 break;
3941 }
3942 content_switch_event_.Set();
3943 return SEND_PACKET;
3944 }
3945
3946 observation_complete_.Set();
3947 return SEND_PACKET;
3948 }
3949
3950 void PerformTest() override {
3951 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3952 ASSERT_TRUE(
3953 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3954 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3955 }
3956
3957 ASSERT_TRUE(Wait())
3958 << "Timed out waiting for a frame sent after switch back";
3959 }
3960
3961 private:
3962 StreamState GetStreamState() {
3963 rtc::CritScope lock(&crit_);
3964 return state_;
3965 }
3966
3967 rtc::CriticalSection crit_;
3968 rtc::Event content_switch_event_;
3969 Call* call_;
3970 StreamState state_ RTC_GUARDED_BY(crit_);
3971 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3972 VideoSendStream::Config send_stream_config_;
3973 VideoEncoderConfig encoder_config_;
3974 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3975 T* stream_resetter_;
3976};
3977
3978TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
3979 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3980 const VideoEncoderConfig& encoder_config,
3981 test::BaseTest* test) {
3982 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3983 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003984 DestroyVideoSendStreams();
3985 SetVideoSendConfig(send_stream_config);
3986 SetVideoEncoderConfig(encoder_config);
3987 CreateVideoSendStreams();
3988 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3989 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003990 Start();
3991 });
3992 };
3993 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3994 RunBaseTest(&test);
3995}
3996
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003997} // namespace webrtc