blob: 33f9898e713d32c5d8294cb4e29eb88bf97d19ad [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
Steve Antonbd631a02019-03-28 10:51:27 -070014#include "absl/algorithm/container.h"
Steve Anton40d55332019-01-07 10:21:47 -080015#include "absl/memory/memory.h"
Danil Chapovalov22ed3662019-03-19 19:39:49 +010016#include "api/task_queue/default_task_queue_factory.h"
Artem Titov46c4e602018-08-17 14:26:54 +020017#include "api/test/simulated_network.h"
Sergey Silkin5ee69672019-07-02 14:18:34 +020018#include "api/video/builtin_video_bitrate_allocator_factory.h"
Niels Möller4dc66c52018-10-05 14:17:58 +020019#include "api/video/encoded_image.h"
Erik Språngf93eda12019-01-16 17:10:57 +010020#include "api/video/video_bitrate_allocation.h"
Elad Alon370f93a2019-06-11 14:57:57 +020021#include "api/video_codecs/video_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "call/call.h"
Artem Titov4e199e92018-08-20 13:30:39 +020023#include "call/fake_network_pipe.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "call/rtp_transport_controller_send.h"
Artem Titov4e199e92018-08-20 13:30:39 +020025#include "call/simulated_network.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020026#include "call/video_send_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/rtp_rtcp/include/rtp_rtcp.h"
28#include "modules/rtp_rtcp/source/rtcp_sender.h"
29#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
30#include "modules/video_coding/codecs/vp8/include/vp8.h"
31#include "modules/video_coding/codecs/vp9/include/vp9.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "rtc_base/critical_section.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/event.h"
Sebastian Janssoncabe3832018-01-12 10:54:18 +010035#include "rtc_base/experiments/alr_experiment.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "rtc_base/logging.h"
37#include "rtc_base/platform_thread.h"
38#include "rtc_base/rate_limiter.h"
Tommi31d1bce2019-08-27 11:34:20 +020039#include "rtc_base/synchronization/sequence_checker.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "rtc_base/time_utils.h"
Elad Alon157540a2019-02-08 23:37:52 +010041#include "rtc_base/unique_id_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020042#include "system_wrappers/include/sleep.h"
43#include "test/call_test.h"
44#include "test/configurable_frame_size_encoder.h"
Niels Möller4db138e2018-04-19 09:04:13 +020045#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020046#include "test/fake_texture_frame.h"
47#include "test/field_trial.h"
48#include "test/frame_generator.h"
49#include "test/frame_generator_capturer.h"
50#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010051#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020052#include "test/gtest.h"
53#include "test/null_transport.h"
54#include "test/rtcp_packet_parser.h"
Tommi25eb47c2019-08-29 16:39:05 +020055#include "test/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020056#include "test/testsupport/perf_test.h"
Niels Möllercbcbc222018-09-28 09:07:24 +020057#include "test/video_encoder_proxy_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "video/send_statistics_proxy.h"
59#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010060#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000061
62namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010063namespace test {
64class VideoSendStreamPeer {
65 public:
66 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
67 : internal_stream_(
68 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020069 absl::optional<float> GetPacingFactorOverride() const {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010070 return internal_stream_->GetPacingFactorOverride();
71 }
72
73 private:
74 internal::VideoSendStream const* const internal_stream_;
75};
76} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000077
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080078namespace {
Elad Alond8d32482019-02-18 23:45:57 +010079enum : int { // The first valid value is 1.
80 kAbsSendTimeExtensionId = 1,
81 kTimestampOffsetExtensionId,
82 kTransportSequenceNumberExtensionId,
83 kVideoContentTypeExtensionId,
84 kVideoRotationExtensionId,
85 kVideoTimingExtensionId,
86};
87
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080088constexpr int64_t kRtcpIntervalMs = 1000;
89
Yves Gerey665174f2018-06-19 15:03:05 +020090enum VideoFormat {
91 kGeneric,
92 kVP8,
93};
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080094} // namespace
sprang@webrtc.org346094c2014-02-18 08:40:33 +000095
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070096VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000097
Sebastian Jansson63470292019-02-01 10:13:43 +010098class VideoSendStreamTest : public test::CallTest {
Elad Alond8d32482019-02-18 23:45:57 +010099 public:
100 VideoSendStreamTest() {
101 RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
102 kTransportSequenceNumberExtensionId));
103 }
104
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000105 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000106 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000107 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000108 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +0100109
110 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
111 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -0700112
113 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000114};
115
Sebastian Jansson63470292019-02-01 10:13:43 +0100116TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700117 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200118 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000119
eladalon413ee9a2017-08-22 04:02:52 -0700120 test::NullTransport transport;
121 CreateSendConfig(1, 0, 0, &transport);
122 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200123 GetVideoSendStream()->Start();
124 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700125 DestroyStreams();
126 DestroyCalls();
127 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000128}
129
Sebastian Jansson63470292019-02-01 10:13:43 +0100130TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700131 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200132 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000133
eladalon413ee9a2017-08-22 04:02:52 -0700134 test::NullTransport transport;
135 CreateSendConfig(1, 0, 0, &transport);
136 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200137 GetVideoSendStream()->Stop();
138 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700139 DestroyStreams();
140 DestroyCalls();
141 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000142}
143
Sebastian Jansson63470292019-02-01 10:13:43 +0100144TEST_F(VideoSendStreamTest, SupportsCName) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000145 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000146 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000147 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000148 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000149
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000150 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000151 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700152 test::RtcpPacketParser parser;
153 EXPECT_TRUE(parser.Parse(packet, length));
154 if (parser.sdes()->num_packets() > 0) {
155 EXPECT_EQ(1u, parser.sdes()->chunks().size());
156 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000157
danilchap3dc929e2016-11-02 08:21:59 -0700158 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000159 }
160
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000161 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000162 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000163
stefanff483612015-12-21 03:14:00 -0800164 void ModifyVideoConfigs(
165 VideoSendStream::Config* send_config,
166 std::vector<VideoReceiveStream::Config>* receive_configs,
167 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000168 send_config->rtp.c_name = kCName;
169 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000170
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000171 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100172 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 }
174 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000175
stefane74eef12016-01-08 06:47:13 -0800176 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000177}
178
Sebastian Jansson63470292019-02-01 10:13:43 +0100179TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000180 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000181 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000182 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000183 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100184 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000185 }
186
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000187 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000188 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000189 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000190
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000191 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
192 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
193 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700194 if (header.extension.absoluteSendTime != 0) {
195 // Wait for at least one packet with a non-zero send time. The send time
196 // is a 16-bit value derived from the system clock, and it is valid
197 // for a packet to have a zero send time. To tell that from an
198 // unpopulated value we'll wait for a packet with non-zero send time.
199 observation_complete_.Set();
200 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100201 RTC_LOG(LS_WARNING)
202 << "Got a packet with zero absoluteSendTime, waiting"
203 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700204 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000205
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000206 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000207 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000208
stefanff483612015-12-21 03:14:00 -0800209 void ModifyVideoConfigs(
210 VideoSendStream::Config* send_config,
211 std::vector<VideoReceiveStream::Config>* receive_configs,
212 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200213 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100214 send_config->rtp.extensions.push_back(
215 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000216 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000217
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000218 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100219 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000220 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000221 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000222
stefane74eef12016-01-08 06:47:13 -0800223 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000224}
225
Sebastian Jansson63470292019-02-01 10:13:43 +0100226TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000227 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000228 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000229 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000230 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200231 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200232 return absl::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200233 Clock::GetRealTimeClock(), kEncodeDelayMs);
234 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000235 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100236 kRtpExtensionTransmissionTimeOffset, kTimestampOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000237 }
238
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000239 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000240 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000241 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000242 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000243
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000244 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
245 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000246 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000247 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100248 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000249
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000250 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000251 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000252
stefanff483612015-12-21 03:14:00 -0800253 void ModifyVideoConfigs(
254 VideoSendStream::Config* send_config,
255 std::vector<VideoReceiveStream::Config>* receive_configs,
256 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200257 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100258 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700259 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100260 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000261 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000262
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000263 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100264 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000265 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000266
Niels Möller4db138e2018-04-19 09:04:13 +0200267 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000268 } test;
269
stefane74eef12016-01-08 06:47:13 -0800270 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000271}
272
Sebastian Jansson63470292019-02-01 10:13:43 +0100273TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
Elad Alond8d32482019-02-18 23:45:57 +0100274 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700275 class TransportWideSequenceNumberObserver : public test::SendTest {
276 public:
277 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200278 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200279 return absl::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200280 Clock::GetRealTimeClock());
281 }) {
sprang867fb522015-08-03 04:38:41 -0700282 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
283 kRtpExtensionTransportSequenceNumber, kExtensionId));
284 }
285
286 private:
287 Action OnSendRtp(const uint8_t* packet, size_t length) override {
288 RTPHeader header;
289 EXPECT_TRUE(parser_->Parse(packet, length, &header));
290
291 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
292 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
293 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
294
Peter Boström5811a392015-12-10 13:02:50 +0100295 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700296
297 return SEND_PACKET;
298 }
299
stefanff483612015-12-21 03:14:00 -0800300 void ModifyVideoConfigs(
301 VideoSendStream::Config* send_config,
302 std::vector<VideoReceiveStream::Config>* receive_configs,
303 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200304 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700305 }
306
307 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100308 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700309 }
310
Niels Möller4db138e2018-04-19 09:04:13 +0200311 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700312 } test;
313
stefane74eef12016-01-08 06:47:13 -0800314 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700315}
316
Sebastian Jansson63470292019-02-01 10:13:43 +0100317TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
perkj803d97f2016-11-01 11:45:46 -0700318 class VideoRotationObserver : public test::SendTest {
319 public:
320 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
321 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100322 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700323 }
324
325 Action OnSendRtp(const uint8_t* packet, size_t length) override {
326 RTPHeader header;
327 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700328 // Only the last packet of the frame is required to have the extension.
329 if (!header.markerBit)
330 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700331 EXPECT_TRUE(header.extension.hasVideoRotation);
332 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
333 observation_complete_.Set();
334 return SEND_PACKET;
335 }
336
337 void ModifyVideoConfigs(
338 VideoSendStream::Config* send_config,
339 std::vector<VideoReceiveStream::Config>* receive_configs,
340 VideoEncoderConfig* encoder_config) override {
341 send_config->rtp.extensions.clear();
342 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100343 RtpExtension::kVideoRotationUri, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700344 }
345
346 void OnFrameGeneratorCapturerCreated(
347 test::FrameGeneratorCapturer* frame_generator_capturer) override {
348 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
349 }
350
351 void PerformTest() override {
352 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
353 }
354 } test;
355
356 RunBaseTest(&test);
357}
358
Sebastian Jansson63470292019-02-01 10:13:43 +0100359TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700360 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700361 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100362 VideoContentTypeObserver()
363 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700364 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100365 kRtpExtensionVideoContentType, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700366 }
367
368 Action OnSendRtp(const uint8_t* packet, size_t length) override {
369 RTPHeader header;
370 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100371 // Only the last packet of the key-frame must have extension.
372 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700373 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100374 // First marker bit seen means that the first frame is sent.
375 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700376 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700377 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
378 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700379 observation_complete_.Set();
380 return SEND_PACKET;
381 }
382
383 void ModifyVideoConfigs(
384 VideoSendStream::Config* send_config,
385 std::vector<VideoReceiveStream::Config>* receive_configs,
386 VideoEncoderConfig* encoder_config) override {
387 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100388 send_config->rtp.extensions.push_back(RtpExtension(
389 RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700390 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
391 }
392
393 void PerformTest() override {
394 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
395 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100396
397 private:
398 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700399 } test;
400
401 RunBaseTest(&test);
402}
403
Sebastian Jansson63470292019-02-01 10:13:43 +0100404TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700405 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700406 public:
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100407 VideoTimingObserver()
408 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
Elad Alond8d32482019-02-18 23:45:57 +0100409 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
410 kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700411 }
412
413 Action OnSendRtp(const uint8_t* packet, size_t length) override {
414 RTPHeader header;
415 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700416 // Only the last packet of the frame must have extension.
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100417 // Also don't check packets of the second frame if they happen to get
418 // through before the test terminates.
419 if (!header.markerBit || first_frame_sent_)
ilnik10894992017-06-21 08:23:19 -0700420 return SEND_PACKET;
421 EXPECT_TRUE(header.extension.has_video_timing);
422 observation_complete_.Set();
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100423 first_frame_sent_ = true;
ilnik04f4d122017-06-19 07:18:55 -0700424 return SEND_PACKET;
425 }
426
427 void ModifyVideoConfigs(
428 VideoSendStream::Config* send_config,
429 std::vector<VideoReceiveStream::Config>* receive_configs,
430 VideoEncoderConfig* encoder_config) override {
431 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100432 send_config->rtp.extensions.push_back(
433 RtpExtension(RtpExtension::kVideoTimingUri, kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700434 }
435
436 void PerformTest() override {
437 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
438 }
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100439
440 private:
441 bool first_frame_sent_;
ilnik04f4d122017-06-19 07:18:55 -0700442 } test;
443
444 RunBaseTest(&test);
445}
446
danilchap901b2df2017-07-28 08:56:04 -0700447class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000448 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000449 FakeReceiveStatistics(uint32_t send_ssrc,
450 uint32_t last_sequence_number,
451 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700452 uint8_t fraction_lost) {
453 stat_.SetMediaSsrc(send_ssrc);
454 stat_.SetExtHighestSeqNum(last_sequence_number);
455 stat_.SetCumulativeLost(cumulative_lost);
456 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000457 }
458
danilchap901b2df2017-07-28 08:56:04 -0700459 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
460 EXPECT_GE(max_blocks, 1u);
461 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000462 }
463
464 private:
danilchap901b2df2017-07-28 08:56:04 -0700465 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000466};
467
brandtre602f0a2016-10-31 03:40:49 -0700468class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100469 public:
Danil Chapovalov65feec52019-08-14 18:58:17 +0200470 // Some of the test cases are expected to time out.
471 // Use a shorter timeout window than the default one for those.
472 static constexpr int kReducedTimeoutMs = 10000;
473
brandtre602f0a2016-10-31 03:40:49 -0700474 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800475 bool use_nack,
476 bool expect_red,
477 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800478 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200479 VideoEncoderFactory* encoder_factory)
Danil Chapovalov65feec52019-08-14 18:58:17 +0200480 : EndToEndTest(expect_ulpfec ? VideoSendStreamTest::kDefaultTimeoutMs
481 : kReducedTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200482 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100483 payload_name_(codec),
484 use_nack_(use_nack),
485 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700486 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800487 sent_media_(false),
488 sent_ulpfec_(false),
Elad Alond8d32482019-02-18 23:45:57 +0100489 header_extensions_enabled_(header_extensions_enabled) {
490 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
491 kAbsSendTimeExtensionId);
492 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
493 kTransportSequenceNumberExtensionId);
494 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100495
496 private:
497 Action OnSendRtp(const uint8_t* packet, size_t length) override {
498 RTPHeader header;
499 EXPECT_TRUE(parser_->Parse(packet, length, &header));
500
Stefan Holmer4654d202015-12-08 09:10:43 +0100501 int encapsulated_payload_type = -1;
502 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100503 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100504 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
505 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100506 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100507 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
508 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100509 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100510 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100511 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
512 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100513 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
514 length) {
515 // Not padding-only, media received outside of RED.
516 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800517 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100518 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100519 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000520
Stefan Holmer4654d202015-12-08 09:10:43 +0100521 if (header_extensions_enabled_) {
522 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
523 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
524 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
525 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
526 // 24 bits wrap.
527 EXPECT_GT(prev_header_.extension.absoluteSendTime,
528 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000529 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100530 EXPECT_GE(header.extension.absoluteSendTime,
531 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200532 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100533 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
534 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
535 prev_header_.extension.transportSequenceNumber;
536 EXPECT_EQ(1, seq_num_diff);
537 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200538
Stefan Holmer4654d202015-12-08 09:10:43 +0100539 if (encapsulated_payload_type != -1) {
540 if (encapsulated_payload_type ==
541 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700542 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800543 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100544 } else {
brandtr65a1e772016-12-12 01:54:58 -0800545 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000546 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000547 }
548
brandtr20d45472017-01-02 00:34:27 -0800549 if (sent_media_ && sent_ulpfec_) {
550 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100551 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000552
Stefan Holmer4654d202015-12-08 09:10:43 +0100553 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000554
Stefan Holmer4654d202015-12-08 09:10:43 +0100555 return SEND_PACKET;
556 }
557
eladalon413ee9a2017-08-22 04:02:52 -0700558 test::PacketTransport* CreateSendTransport(
559 test::SingleThreadedTaskQueueForTesting* task_queue,
560 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100561 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
562 // Configure some network delay.
563 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200564 BuiltInNetworkBehaviorConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800565 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100566 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700567 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700568 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200569 VideoSendStreamTest::payload_type_map_,
570 absl::make_unique<FakeNetworkPipe>(
571 Clock::GetRealTimeClock(),
572 absl::make_unique<SimulatedNetwork>(config)));
Peter Boström39593972016-02-15 11:27:15 +0100573 }
574
stefanff483612015-12-21 03:14:00 -0800575 void ModifyVideoConfigs(
576 VideoSendStream::Config* send_config,
577 std::vector<VideoReceiveStream::Config>* receive_configs,
578 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100579 if (use_nack_) {
580 send_config->rtp.nack.rtp_history_ms =
581 (*receive_configs)[0].rtp.nack.rtp_history_ms =
582 VideoSendStreamTest::kNackRtpHistoryMs;
583 }
Niels Möller4db138e2018-04-19 09:04:13 +0200584 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200585 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700586 send_config->rtp.ulpfec.red_payload_type =
587 VideoSendStreamTest::kRedPayloadType;
588 send_config->rtp.ulpfec.ulpfec_payload_type =
589 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800590 if (!header_extensions_enabled_) {
591 send_config->rtp.extensions.clear();
592 } else {
Elad Alond8d32482019-02-18 23:45:57 +0100593 send_config->rtp.extensions.push_back(
594 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100595 }
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +0200596 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
Niels Möller259a4972018-04-05 15:36:51 +0200597 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700598 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700599 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700600 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700601 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100602 }
603
604 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800605 EXPECT_EQ(expect_ulpfec_, Wait())
606 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100607 }
608
Niels Möller4db138e2018-04-19 09:04:13 +0200609 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800610 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100611 const bool use_nack_;
612 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700613 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800614 bool sent_media_;
615 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100616 bool header_extensions_enabled_;
617 RTPHeader prev_header_;
618};
619
Sebastian Jansson63470292019-02-01 10:13:43 +0100620TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200621 test::FunctionVideoEncoderFactory encoder_factory(
622 []() { return VP8Encoder::Create(); });
623 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800624 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100625}
626
Sebastian Jansson63470292019-02-01 10:13:43 +0100627TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200628 test::FunctionVideoEncoderFactory encoder_factory(
629 []() { return VP8Encoder::Create(); });
630 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100631 RunBaseTest(&test);
632}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000633
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200634class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
stefan60e10c72017-08-23 10:40:00 -0700635 protected:
636 VideoSendStreamWithoutUlpfecTest()
637 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
638
639 test::ScopedFieldTrials field_trial_;
640};
641
642TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200643 test::FunctionVideoEncoderFactory encoder_factory(
644 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200645 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700646 RunBaseTest(&test);
647}
648
Peter Boström39593972016-02-15 11:27:15 +0100649// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
650// since we'll still have to re-request FEC packets, effectively wasting
651// bandwidth since the receiver has to wait for FEC retransmissions to determine
652// that the received state is actually decodable.
Sebastian Jansson63470292019-02-01 10:13:43 +0100653TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200654 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200655 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200656 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200657 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100658 RunBaseTest(&test);
659}
660
661// Without retransmissions FEC for H264 is fine.
Sebastian Jansson63470292019-02-01 10:13:43 +0100662TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200663 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200664 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200665 });
666 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100667 RunBaseTest(&test);
668}
669
Danil Chapovalov65feec52019-08-14 18:58:17 +0200670TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200671 test::FunctionVideoEncoderFactory encoder_factory(
672 []() { return VP8Encoder::Create(); });
673 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100674 RunBaseTest(&test);
675}
676
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100677#if defined(RTC_ENABLE_VP9)
Danil Chapovalov65feec52019-08-14 18:58:17 +0200678TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200679 test::FunctionVideoEncoderFactory encoder_factory(
680 []() { return VP9Encoder::Create(); });
681 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800682 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000683}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100684#endif // defined(RTC_ENABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000685
Sebastian Jansson63470292019-02-01 10:13:43 +0100686TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100687 std::unique_ptr<TaskQueueFactory> task_queue_factory =
688 CreateDefaultTaskQueueFactory();
689 test::FunctionVideoEncoderFactory encoder_factory([&]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200690 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100691 Clock::GetRealTimeClock(), task_queue_factory.get());
Niels Möller4db138e2018-04-19 09:04:13 +0200692 });
693 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800694 RunBaseTest(&test);
695}
696
brandtr39f97292016-11-16 22:57:50 -0800697// TODO(brandtr): Move these FlexFEC tests when we have created
698// FlexfecSendStream.
699class FlexfecObserver : public test::EndToEndTest {
700 public:
701 FlexfecObserver(bool header_extensions_enabled,
702 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800703 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200704 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100705 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800706 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200707 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800708 payload_name_(codec),
709 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800710 sent_media_(false),
711 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100712 header_extensions_enabled_(header_extensions_enabled),
Elad Alond8d32482019-02-18 23:45:57 +0100713 num_video_streams_(num_video_streams) {
714 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
715 kAbsSendTimeExtensionId);
716 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
717 kTimestampOffsetExtensionId);
718 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
719 kTransportSequenceNumberExtensionId);
720 }
brandtr39f97292016-11-16 22:57:50 -0800721
722 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100723 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800724
725 private:
726 Action OnSendRtp(const uint8_t* packet, size_t length) override {
727 RTPHeader header;
728 EXPECT_TRUE(parser_->Parse(packet, length, &header));
729
brandtr39f97292016-11-16 22:57:50 -0800730 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
731 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
732 sent_flexfec_ = true;
733 } else {
734 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
735 header.payloadType);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200736 EXPECT_THAT(::testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
737 num_video_streams_),
738 ::testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800739 sent_media_ = true;
740 }
741
742 if (header_extensions_enabled_) {
743 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
744 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
745 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
746 }
747
brandtr0c5a1542016-11-23 04:42:26 -0800748 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800749 observation_complete_.Set();
750 }
751
752 return SEND_PACKET;
753 }
754
eladalon413ee9a2017-08-22 04:02:52 -0700755 test::PacketTransport* CreateSendTransport(
756 test::SingleThreadedTaskQueueForTesting* task_queue,
757 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800758 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
759 // Therefore we need some network delay.
760 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200761 BuiltInNetworkBehaviorConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800762 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800763 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700764 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700765 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200766 VideoSendStreamTest::payload_type_map_,
767 absl::make_unique<FakeNetworkPipe>(
768 Clock::GetRealTimeClock(),
769 absl::make_unique<SimulatedNetwork>(config)));
brandtr39f97292016-11-16 22:57:50 -0800770 }
771
772 void ModifyVideoConfigs(
773 VideoSendStream::Config* send_config,
774 std::vector<VideoReceiveStream::Config>* receive_configs,
775 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800776 if (use_nack_) {
777 send_config->rtp.nack.rtp_history_ms =
778 (*receive_configs)[0].rtp.nack.rtp_history_ms =
779 VideoSendStreamTest::kNackRtpHistoryMs;
780 }
Niels Möller4db138e2018-04-19 09:04:13 +0200781 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200782 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800783 if (header_extensions_enabled_) {
Elad Alond8d32482019-02-18 23:45:57 +0100784 send_config->rtp.extensions.push_back(
785 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
brandtr39f97292016-11-16 22:57:50 -0800786 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100787 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800788 } else {
789 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800790 }
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +0200791 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
Niels Möller259a4972018-04-05 15:36:51 +0200792 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800793 }
794
795 void PerformTest() override {
796 EXPECT_TRUE(Wait())
797 << "Timed out waiting for FlexFEC and/or media packets.";
798 }
799
Niels Möller4db138e2018-04-19 09:04:13 +0200800 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800801 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800802 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800803 bool sent_media_;
804 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100805 const bool header_extensions_enabled_;
806 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800807};
808
Sebastian Jansson63470292019-02-01 10:13:43 +0100809TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200810 test::FunctionVideoEncoderFactory encoder_factory(
811 []() { return VP8Encoder::Create(); });
812 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100813 RunBaseTest(&test);
814}
815
Sebastian Jansson63470292019-02-01 10:13:43 +0100816TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200817 test::FunctionVideoEncoderFactory encoder_factory(
818 []() { return VP8Encoder::Create(); });
819 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800820 RunBaseTest(&test);
821}
822
Sebastian Jansson63470292019-02-01 10:13:43 +0100823TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200824 test::FunctionVideoEncoderFactory encoder_factory(
825 []() { return VP8Encoder::Create(); });
826 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800827 RunBaseTest(&test);
828}
829
Sebastian Jansson63470292019-02-01 10:13:43 +0100830TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200831 test::FunctionVideoEncoderFactory encoder_factory(
832 []() { return VP8Encoder::Create(); });
833 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800834 RunBaseTest(&test);
835}
836
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100837#if defined(RTC_ENABLE_VP9)
Sebastian Jansson63470292019-02-01 10:13:43 +0100838TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200839 test::FunctionVideoEncoderFactory encoder_factory(
840 []() { return VP9Encoder::Create(); });
841 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800842 RunBaseTest(&test);
843}
844
Sebastian Jansson63470292019-02-01 10:13:43 +0100845TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200846 test::FunctionVideoEncoderFactory encoder_factory(
847 []() { return VP9Encoder::Create(); });
848 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800849 RunBaseTest(&test);
850}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100851#endif // defined(RTC_ENABLE_VP9)
brandtr39f97292016-11-16 22:57:50 -0800852
Sebastian Jansson63470292019-02-01 10:13:43 +0100853TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200854 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200855 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200856 });
857 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800858 RunBaseTest(&test);
859}
860
Sebastian Jansson63470292019-02-01 10:13:43 +0100861TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200862 test::FunctionVideoEncoderFactory encoder_factory([]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200863 return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200864 });
865 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800866 RunBaseTest(&test);
867}
868
Sebastian Jansson63470292019-02-01 10:13:43 +0100869TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100870 std::unique_ptr<TaskQueueFactory> task_queue_factory =
871 CreateDefaultTaskQueueFactory();
872 test::FunctionVideoEncoderFactory encoder_factory([&]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200873 return absl::make_unique<test::MultithreadedFakeH264Encoder>(
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100874 Clock::GetRealTimeClock(), task_queue_factory.get());
Niels Möller4db138e2018-04-19 09:04:13 +0200875 });
876
877 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800878 RunBaseTest(&test);
879}
880
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000881void VideoSendStreamTest::TestNackRetransmission(
882 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000883 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000884 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000885 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000886 explicit NackObserver(uint32_t retransmit_ssrc,
887 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000888 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000889 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100890 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000891 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100892 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000893
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000894 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000895 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000896 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000897 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000898
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200899 // NACK packets two times at some arbitrary points.
900 const int kNackedPacketsAtOnceCount = 3;
901 const int kRetransmitTarget = kNackedPacketsAtOnceCount * 2;
902
903 // Skip padding packets because they will never be retransmitted.
904 if (header.paddingLength + header.headerLength == length) {
905 return SEND_PACKET;
906 }
907
Sebastian Janssond3f38162018-02-28 16:14:44 +0100908 ++send_count_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200909
910 // NACK packets at arbitrary points.
Sebastian Janssond3f38162018-02-28 16:14:44 +0100911 if (send_count_ == 5 || send_count_ == 25) {
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200912 nacked_sequence_numbers_.insert(
913 nacked_sequence_numbers_.end(),
914 non_padding_sequence_numbers_.end() - kNackedPacketsAtOnceCount,
915 non_padding_sequence_numbers_.end());
Sebastian Janssond3f38162018-02-28 16:14:44 +0100916
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000917 RtpRtcp::Configuration config;
918 config.clock = Clock::GetRealTimeClock();
919 config.outgoing_transport = transport_adapter_.get();
920 config.rtcp_report_interval_ms = kRtcpIntervalMs;
921 RTCPSender rtcp_sender(config);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000922
pbosda903ea2015-10-02 02:36:56 -0700923 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100924 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000925
926 RTCPSender::FeedbackState feedback_state;
927
Sebastian Janssond3f38162018-02-28 16:14:44 +0100928 EXPECT_EQ(0, rtcp_sender.SendRTCP(
929 feedback_state, kRtcpNack,
930 static_cast<int>(nacked_sequence_numbers_.size()),
931 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000932 }
933
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000934 uint16_t sequence_number = header.sequenceNumber;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000935 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100936 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
937 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000938 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000939 const uint8_t* rtx_header = packet + header.headerLength;
940 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
941 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200942
Steve Antonbd631a02019-03-28 10:51:27 -0700943 auto found = absl::c_find(nacked_sequence_numbers_, sequence_number);
Sebastian Janssond3f38162018-02-28 16:14:44 +0100944 if (found != nacked_sequence_numbers_.end()) {
945 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000946
Sebastian Janssond3f38162018-02-28 16:14:44 +0100947 if (++retransmit_count_ == kRetransmitTarget) {
948 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
949 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
950 observation_complete_.Set();
951 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200952 } else {
953 non_padding_sequence_numbers_.push_back(sequence_number);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000954 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000955
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000956 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000957 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000958
stefanff483612015-12-21 03:14:00 -0800959 void ModifyVideoConfigs(
960 VideoSendStream::Config* send_config,
961 std::vector<VideoReceiveStream::Config>* receive_configs,
962 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700963 transport_adapter_.reset(
964 new internal::TransportAdapter(send_config->send_transport));
965 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000966 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000967 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100968 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000969 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
970 }
971
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000972 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100973 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000974 }
975
kwiberg27f982b2016-03-01 11:52:33 -0800976 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000977 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100978 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000979 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000980 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100981 std::vector<uint16_t> nacked_sequence_numbers_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200982 std::vector<uint16_t> non_padding_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000983 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000984
stefane74eef12016-01-08 06:47:13 -0800985 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000986}
987
Sebastian Jansson63470292019-02-01 10:13:43 +0100988TEST_F(VideoSendStreamTest, RetransmitsNack) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000989 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100990 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000991}
992
Sebastian Jansson63470292019-02-01 10:13:43 +0100993TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000994 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000995 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000996}
997
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000998void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
999 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001000 // Use a fake encoder to output a frame of every size in the range [90, 290],
1001 // for each size making sure that the exact number of payload bytes received
1002 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001003 static const size_t kMaxPacketSize = 128;
1004 static const size_t start = 90;
1005 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001006
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001007 // Observer that verifies that the expected number of packets and bytes
1008 // arrive for each frame size, from start_size to stop_size.
Niels Möller759f9592018-10-09 14:57:01 +02001009 class FrameFragmentationTest : public test::SendTest {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001010 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001011 FrameFragmentationTest(size_t max_packet_size,
1012 size_t start_size,
1013 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001014 bool test_generic_packetization,
1015 bool use_fec)
1016 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001017 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +02001018 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001019 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001020 stop_size_(stop_size),
1021 test_generic_packetization_(test_generic_packetization),
1022 use_fec_(use_fec),
1023 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001024 packets_lost_(0),
1025 last_packet_count_(0),
1026 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001027 accumulated_size_(0),
1028 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001029 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001030 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001031 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001032 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001033 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -07001034 RTC_DCHECK_GT(stop_size, max_packet_size);
Philip Eliassond52a1a62018-09-07 13:03:55 +00001035 if (!test_generic_packetization_)
1036 encoder_.SetCodecType(kVideoCodecVP8);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001037 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001038
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001039 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001040 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001041 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001042 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001043 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001044
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001045 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001046
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001047 if (use_fec_) {
1048 uint8_t payload_type = packet[header.headerLength];
1049 bool is_fec = header.payloadType == kRedPayloadType &&
1050 payload_type == kUlpfecPayloadType;
1051 if (is_fec) {
1052 fec_packet_received_ = true;
1053 return SEND_PACKET;
1054 }
1055 }
1056
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001057 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001058
1059 if (use_fec_)
1060 TriggerLossReport(header);
1061
1062 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +02001063 size_t overhead = header.headerLength + header.paddingLength;
1064 // Only remove payload header and RED header if the packet actually
1065 // contains payload.
1066 if (length > overhead) {
1067 overhead += (1 /* Generic header */);
1068 if (use_fec_)
1069 overhead += 1; // RED for FEC header.
1070 }
1071 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001072 accumulated_payload_ += length - overhead;
1073 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001074
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001075 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001076 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001077 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1078 // With FEC enabled, frame size is incremented asynchronously, so
1079 // "old" frames one byte too small may arrive. Accept, but don't
1080 // increase expected frame size.
1081 accumulated_size_ = 0;
1082 accumulated_payload_ = 0;
1083 return SEND_PACKET;
1084 }
1085
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001086 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001087 if (test_generic_packetization_) {
1088 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1089 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001090
1091 // Last packet of frame; reset counters.
1092 accumulated_size_ = 0;
1093 accumulated_payload_ = 0;
1094 if (current_size_rtp_ == stop_size_) {
1095 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001096 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001097 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001098 // Increase next expected frame size. If testing with FEC, make sure
1099 // a FEC packet has been received for this frame size before
1100 // proceeding, to make sure that redundancy packets don't exceed
1101 // size limit.
1102 if (!use_fec_) {
1103 ++current_size_rtp_;
1104 } else if (fec_packet_received_) {
1105 fec_packet_received_ = false;
1106 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001107
1108 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001109 ++current_size_frame_;
1110 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001111 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001112 }
1113
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001114 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001115 }
1116
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001117 void TriggerLossReport(const RTPHeader& header) {
1118 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001119 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001120 if (++packet_count_ % (100 / kLossPercent) == 0) {
1121 packets_lost_++;
1122 int loss_delta = packets_lost_ - last_packets_lost_;
1123 int packets_delta = packet_count_ - last_packet_count_;
1124 last_packet_count_ = packet_count_;
1125 last_packets_lost_ = packets_lost_;
1126 uint8_t loss_ratio =
1127 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001128 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001129 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001130 packets_lost_, // Cumulative lost.
1131 loss_ratio); // Loss percent.
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001132 RtpRtcp::Configuration config;
1133 config.clock = Clock::GetRealTimeClock();
1134 config.receive_statistics = &lossy_receive_stats;
1135 config.outgoing_transport = transport_adapter_.get();
1136 config.rtcp_report_interval_ms = kRtcpIntervalMs;
1137 RTCPSender rtcp_sender(config);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001138
pbosda903ea2015-10-02 02:36:56 -07001139 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001140 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001141
1142 RTCPSender::FeedbackState feedback_state;
1143
1144 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1145 }
1146 }
1147
Niels Möller759f9592018-10-09 14:57:01 +02001148 void UpdateConfiguration() {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001149 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001150 // Increase frame size for next encoded frame, in the context of the
1151 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001152 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001153 ++current_size_frame_;
1154 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001155 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001156 }
Niels Möllerde8e6e62018-11-13 15:10:33 +01001157 void ModifySenderBitrateConfig(
1158 BitrateConstraints* bitrate_config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001159 const int kMinBitrateBps = 30000;
Niels Möllerde8e6e62018-11-13 15:10:33 +01001160 bitrate_config->min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001161 }
1162
stefanff483612015-12-21 03:14:00 -08001163 void ModifyVideoConfigs(
1164 VideoSendStream::Config* send_config,
1165 std::vector<VideoReceiveStream::Config>* receive_configs,
1166 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001167 transport_adapter_.reset(
1168 new internal::TransportAdapter(send_config->send_transport));
1169 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001170 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001171 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1172 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001173 }
1174
1175 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001176 send_config->rtp.payload_name = "VP8";
Philip Eliassond52a1a62018-09-07 13:03:55 +00001177
Niels Möller4db138e2018-04-19 09:04:13 +02001178 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001179 send_config->rtp.max_packet_size = kMaxPacketSize;
Niels Möller759f9592018-10-09 14:57:01 +02001180 encoder_.RegisterPostEncodeCallback([this]() { UpdateConfiguration(); });
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001181
Erik Språng95261872015-04-10 11:58:49 +02001182 // Make sure there is at least one extension header, to make the RTP
1183 // header larger than the base length of 12 bytes.
1184 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001185
1186 // Setup screen content disables frame dropping which makes this easier.
Åsa Perssond34597c2018-10-22 17:34:02 +02001187 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
1188 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
sprang4847ae62017-06-27 07:06:52 -07001189 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001190 }
1191
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001192 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001193 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001194 }
1195
kwiberg27f982b2016-03-01 11:52:33 -08001196 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001197 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möllercbcbc222018-09-28 09:07:24 +02001198 test::VideoEncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001199
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001200 const size_t max_packet_size_;
1201 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001202 const bool test_generic_packetization_;
1203 const bool use_fec_;
1204
1205 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001206 uint32_t packets_lost_;
1207 uint32_t last_packet_count_;
1208 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001209 size_t accumulated_size_;
1210 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001211 bool fec_packet_received_;
1212
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001213 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001214 rtc::CriticalSection mutex_;
1215 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001216 };
1217
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001218 // Don't auto increment if FEC is used; continue sending frame size until
1219 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001220 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1221 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001222
stefane74eef12016-01-08 06:47:13 -08001223 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001224}
1225
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001226// TODO(sprang): Is there any way of speeding up these tests?
Sebastian Jansson63470292019-02-01 10:13:43 +01001227TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001228 TestPacketFragmentationSize(kGeneric, false);
1229}
1230
Sebastian Jansson63470292019-02-01 10:13:43 +01001231TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001232 TestPacketFragmentationSize(kGeneric, true);
1233}
1234
Sebastian Jansson63470292019-02-01 10:13:43 +01001235TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001236 TestPacketFragmentationSize(kVP8, false);
1237}
1238
Sebastian Jansson63470292019-02-01 10:13:43 +01001239TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001240 TestPacketFragmentationSize(kVP8, true);
1241}
1242
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001243// The test will go through a number of phases.
1244// 1. Start sending packets.
1245// 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 +00001246// suspend the stream.
1247// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001248// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001249// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001250// When the stream is detected again, and the stats show that the stream
1251// is no longer suspended, the test ends.
Sebastian Jansson63470292019-02-01 10:13:43 +01001252TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001253 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001254
Niels Möller412d1852019-01-02 09:42:54 +01001255 class RembObserver : public test::SendTest {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001256 public:
Niels Möller412d1852019-01-02 09:42:54 +01001257 class CaptureObserver : public rtc::VideoSinkInterface<VideoFrame> {
1258 public:
1259 explicit CaptureObserver(RembObserver* remb_observer)
1260 : remb_observer_(remb_observer) {}
1261
1262 void OnFrame(const VideoFrame&) {
1263 rtc::CritScope lock(&remb_observer_->crit_);
1264 if (remb_observer_->test_state_ == kDuringSuspend &&
1265 ++remb_observer_->suspended_frame_count_ > kSuspendTimeFrames) {
1266 VideoSendStream::Stats stats = remb_observer_->stream_->GetStats();
1267 EXPECT_TRUE(stats.suspended);
1268 remb_observer_->SendRtcpFeedback(remb_observer_->high_remb_bps_);
1269 remb_observer_->test_state_ = kWaitingForPacket;
1270 }
1271 }
1272
1273 private:
1274 RembObserver* const remb_observer_;
1275 };
1276
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001277 RembObserver()
1278 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001279 clock_(Clock::GetRealTimeClock()),
Niels Möller412d1852019-01-02 09:42:54 +01001280 capture_observer_(this),
Erik Språng737336d2016-07-29 12:59:36 +02001281 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001282 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001283 rtp_count_(0),
1284 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001285 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001286 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001287 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001288
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001289 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001290 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001291 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001292 ++rtp_count_;
1293 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001294 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001295 last_sequence_number_ = header.sequenceNumber;
1296
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001297 if (test_state_ == kBeforeSuspend) {
1298 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001299 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001300 test_state_ = kDuringSuspend;
1301 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001302 if (header.paddingLength == 0) {
1303 // Received non-padding packet during suspension period. Reset the
1304 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001305 suspended_frame_count_ = 0;
1306 }
stefanf116bd02015-10-27 08:29:42 -07001307 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001308 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001309 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001310 // Non-padding packet observed. Test is almost complete. Will just
1311 // have to wait for the stats to change.
1312 test_state_ = kWaitingForStats;
1313 }
stefanf116bd02015-10-27 08:29:42 -07001314 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001315 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001316 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001317 if (stats.suspended == false) {
1318 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001319 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001320 }
stefanf116bd02015-10-27 08:29:42 -07001321 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001322 }
1323
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001324 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001325 }
1326
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001327 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001328 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001329 low_remb_bps_ = value;
1330 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001331
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001332 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001333 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001334 high_remb_bps_ = value;
1335 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001336
stefanff483612015-12-21 03:14:00 -08001337 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001338 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001339 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001340 stream_ = send_stream;
1341 }
1342
Niels Möller412d1852019-01-02 09:42:54 +01001343 void OnFrameGeneratorCapturerCreated(
1344 test::FrameGeneratorCapturer* frame_generator_capturer) override {
1345 frame_generator_capturer->AddOrUpdateSink(&capture_observer_,
1346 rtc::VideoSinkWants());
1347 }
1348
stefanff483612015-12-21 03:14:00 -08001349 void ModifyVideoConfigs(
1350 VideoSendStream::Config* send_config,
1351 std::vector<VideoReceiveStream::Config>* receive_configs,
1352 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001353 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001354 transport_adapter_.reset(
1355 new internal::TransportAdapter(send_config->send_transport));
1356 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001357 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001358 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001359 int min_bitrate_bps =
1360 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001361 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001362 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001363 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001364 min_bitrate_bps + threshold_window + 5000);
1365 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1366 }
1367
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001368 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001369 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001370 }
1371
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001372 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001373 kBeforeSuspend,
1374 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001375 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001376 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001377 };
1378
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001379 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001380 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001381 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1382 last_sequence_number_, rtp_count_, 0);
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001383 RtpRtcp::Configuration config;
1384 config.clock = clock_;
1385 config.receive_statistics = &receive_stats;
1386 config.outgoing_transport = transport_adapter_.get();
1387 config.rtcp_report_interval_ms = kRtcpIntervalMs;
1388 RTCPSender rtcp_sender(config);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001389
pbosda903ea2015-10-02 02:36:56 -07001390 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001391 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001392 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001393 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001394 }
1395 RTCPSender::FeedbackState feedback_state;
1396 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1397 }
1398
kwiberg27f982b2016-03-01 11:52:33 -08001399 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001400 Clock* const clock_;
Niels Möller412d1852019-01-02 09:42:54 +01001401 CaptureObserver capture_observer_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001402 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001403
Peter Boströmf2f82832015-05-01 13:00:41 +02001404 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001405 TestState test_state_ RTC_GUARDED_BY(crit_);
1406 int rtp_count_ RTC_GUARDED_BY(crit_);
1407 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1408 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1409 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1410 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001411 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001412
stefane74eef12016-01-08 06:47:13 -08001413 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001414}
1415
perkj71ee44c2016-06-15 00:47:53 -07001416// This test that padding stops being send after a while if the Camera stops
1417// producing video frames and that padding resumes if the camera restarts.
Sebastian Jansson63470292019-02-01 10:13:43 +01001418TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001419 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001420 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001421 NoPaddingWhenVideoIsMuted()
1422 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001423 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001424 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001425 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001426
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001427 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001428 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001429 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001430 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001431
1432 RTPHeader header;
1433 parser_->Parse(packet, length, &header);
1434 const bool only_padding =
1435 header.headerLength + header.paddingLength == length;
1436
1437 if (test_state_ == kBeforeStopCapture) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001438 // Packets are flowing, stop camera.
perkj71ee44c2016-06-15 00:47:53 -07001439 capturer_->Stop();
1440 test_state_ = kWaitingForPadding;
1441 } else if (test_state_ == kWaitingForPadding && only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001442 // We're still getting padding, after stopping camera.
perkj71ee44c2016-06-15 00:47:53 -07001443 test_state_ = kWaitingForNoPackets;
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001444 } else if (test_state_ == kWaitingForMediaAfterCameraRestart &&
1445 !only_padding) {
1446 // Media packets are flowing again, stop camera a second time.
1447 capturer_->Stop();
1448 test_state_ = kWaitingForPaddingAfterCameraStopsAgain;
1449 } else if (test_state_ == kWaitingForPaddingAfterCameraStopsAgain &&
perkj71ee44c2016-06-15 00:47:53 -07001450 only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001451 // Padding is still flowing, test ok.
perkj71ee44c2016-06-15 00:47:53 -07001452 observation_complete_.Set();
1453 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001454 return SEND_PACKET;
1455 }
1456
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001457 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001458 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001459 const int kNoPacketsThresholdMs = 2000;
1460 if (test_state_ == kWaitingForNoPackets &&
1461 (last_packet_time_ms_ > 0 &&
1462 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1463 kNoPacketsThresholdMs)) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001464 // No packets seen for |kNoPacketsThresholdMs|, restart camera.
perkj71ee44c2016-06-15 00:47:53 -07001465 capturer_->Start();
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001466 test_state_ = kWaitingForMediaAfterCameraRestart;
perkj71ee44c2016-06-15 00:47:53 -07001467 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001468 return SEND_PACKET;
1469 }
1470
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001471 void ModifyVideoConfigs(
1472 VideoSendStream::Config* send_config,
1473 std::vector<VideoReceiveStream::Config>* receive_configs,
1474 VideoEncoderConfig* encoder_config) override {
1475 // Make sure padding is sent if encoder is not producing media.
1476 encoder_config->min_transmit_bitrate_bps = 50000;
1477 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001478
nisseef8b61e2016-04-29 06:09:15 -07001479 void OnFrameGeneratorCapturerCreated(
1480 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001481 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001482 capturer_ = frame_generator_capturer;
1483 }
1484
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001485 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001486 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001487 << "Timed out while waiting for RTP packets to stop being sent.";
1488 }
1489
perkj71ee44c2016-06-15 00:47:53 -07001490 enum TestState {
1491 kBeforeStopCapture,
1492 kWaitingForPadding,
1493 kWaitingForNoPackets,
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001494 kWaitingForMediaAfterCameraRestart,
1495 kWaitingForPaddingAfterCameraStopsAgain
perkj71ee44c2016-06-15 00:47:53 -07001496 };
1497
1498 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001499 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001500 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001501 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001502 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1503 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001504 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001505
stefane74eef12016-01-08 06:47:13 -08001506 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001507}
1508
Sebastian Jansson63470292019-02-01 10:13:43 +01001509TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
isheriffcc5903e2016-10-04 08:29:38 -07001510 const int kCapacityKbps = 10000; // 10 Mbps
1511 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1512 public:
1513 PaddingIsPrimarilyRetransmissions()
1514 : EndToEndTest(kDefaultTimeoutMs),
1515 clock_(Clock::GetRealTimeClock()),
1516 padding_length_(0),
1517 total_length_(0),
1518 call_(nullptr) {}
1519
1520 private:
1521 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1522 call_ = sender_call;
1523 }
1524
1525 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1526 rtc::CritScope lock(&crit_);
1527
1528 RTPHeader header;
1529 parser_->Parse(packet, length, &header);
1530 padding_length_ += header.paddingLength;
1531 total_length_ += length;
1532 return SEND_PACKET;
1533 }
1534
eladalon413ee9a2017-08-22 04:02:52 -07001535 test::PacketTransport* CreateSendTransport(
1536 test::SingleThreadedTaskQueueForTesting* task_queue,
1537 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001538 const int kNetworkDelayMs = 50;
Artem Titov75e36472018-10-08 12:28:56 +02001539 BuiltInNetworkBehaviorConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001540 config.loss_percent = 10;
1541 config.link_capacity_kbps = kCapacityKbps;
1542 config.queue_delay_ms = kNetworkDelayMs;
Artem Titov4e199e92018-08-20 13:30:39 +02001543 return new test::PacketTransport(
1544 task_queue, sender_call, this, test::PacketTransport::kSender,
1545 payload_type_map_,
1546 absl::make_unique<FakeNetworkPipe>(
1547 Clock::GetRealTimeClock(),
1548 absl::make_unique<SimulatedNetwork>(config)));
isheriffcc5903e2016-10-04 08:29:38 -07001549 }
1550
1551 void ModifyVideoConfigs(
1552 VideoSendStream::Config* send_config,
1553 std::vector<VideoReceiveStream::Config>* receive_configs,
1554 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001555 // Turn on RTX.
1556 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1557 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001558 }
1559
1560 void PerformTest() override {
1561 // TODO(isheriff): Some platforms do not ramp up as expected to full
1562 // capacity due to packet scheduling delays. Fix that before getting
1563 // rid of this.
1564 SleepMs(5000);
1565 {
1566 rtc::CritScope lock(&crit_);
1567 // Expect padding to be a small percentage of total bytes sent.
1568 EXPECT_LT(padding_length_, .1 * total_length_);
1569 }
1570 }
1571
1572 rtc::CriticalSection crit_;
1573 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001574 size_t padding_length_ RTC_GUARDED_BY(crit_);
1575 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001576 Call* call_;
1577 } test;
1578
1579 RunBaseTest(&test);
1580}
1581
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001582// This test first observes "high" bitrate use at which point it sends a REMB to
1583// indicate that it should be lowered significantly. The test then observes that
1584// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1585// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001586//
1587// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1588// bitrate since no receiver block or remb is sent in the initial phase.
Sebastian Jansson63470292019-02-01 10:13:43 +01001589TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001590 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001591 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001592 static const int kRembBitrateBps = 80000;
1593 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001594 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001595 public:
1596 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001597 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001598 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1599 stream_(nullptr),
1600 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001601
1602 private:
nisseef8b61e2016-04-29 06:09:15 -07001603 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001604 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001605 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001606
1607 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001608 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001609 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001610 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001611 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001612 if (!stats.substreams.empty()) {
1613 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001614 int total_bitrate_bps =
1615 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001616 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1617 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1618 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001619 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001620 rtp_rtcp_->SetRemb(kRembBitrateBps,
1621 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001622 rtp_rtcp_->Process();
1623 bitrate_capped_ = true;
1624 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001625 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001626 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001627 }
1628 }
stefanf116bd02015-10-27 08:29:42 -07001629 // Packets don't have to be delivered since the test is the receiver.
1630 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001631 }
1632
stefanff483612015-12-21 03:14:00 -08001633 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001634 VideoSendStream* send_stream,
1635 const std::vector<VideoReceiveStream*>& receive_streams) override {
1636 stream_ = send_stream;
1637 RtpRtcp::Configuration config;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001638 config.clock = Clock::GetRealTimeClock();
stefanf116bd02015-10-27 08:29:42 -07001639 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001640 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001641 rtp_rtcp_ = RtpRtcp::Create(config);
stefanf116bd02015-10-27 08:29:42 -07001642 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001643 }
1644
stefanff483612015-12-21 03:14:00 -08001645 void ModifyVideoConfigs(
1646 VideoSendStream::Config* send_config,
1647 std::vector<VideoReceiveStream::Config>* receive_configs,
1648 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001649 feedback_transport_.reset(
1650 new internal::TransportAdapter(send_config->send_transport));
1651 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001652 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001653 }
1654
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001655 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001656 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001657 << "Timeout while waiting for low bitrate stats after REMB.";
1658 }
1659
kwiberg27f982b2016-03-01 11:52:33 -08001660 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1661 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001662 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001663 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001664 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001665 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001666
stefane74eef12016-01-08 06:47:13 -08001667 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001668}
1669
Sebastian Jansson63470292019-02-01 10:13:43 +01001670TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001671 static const int kStartBitrateBps = 300000;
1672 static const int kNewMaxBitrateBps = 1234567;
Elad Alond8d32482019-02-18 23:45:57 +01001673 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001674 class ChangingNetworkRouteTest : public test::EndToEndTest {
1675 public:
eladalon413ee9a2017-08-22 04:02:52 -07001676 explicit ChangingNetworkRouteTest(
1677 test::SingleThreadedTaskQueueForTesting* task_queue)
1678 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1679 task_queue_(task_queue),
1680 call_(nullptr) {
Tommi31d1bce2019-08-27 11:34:20 +02001681 module_process_thread_.Detach();
1682 task_queue_thread_.Detach();
Stefan Holmer280de9e2016-09-30 10:06:51 +02001683 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1684 kRtpExtensionTransportSequenceNumber, kExtensionId));
1685 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001686
1687 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommi31d1bce2019-08-27 11:34:20 +02001688 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1689 RTC_DCHECK(!call_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001690 call_ = sender_call;
1691 }
1692
Stefan Holmer280de9e2016-09-30 10:06:51 +02001693 void ModifyVideoConfigs(
1694 VideoSendStream::Config* send_config,
1695 std::vector<VideoReceiveStream::Config>* receive_configs,
1696 VideoEncoderConfig* encoder_config) override {
Tommi31d1bce2019-08-27 11:34:20 +02001697 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Stefan Holmer280de9e2016-09-30 10:06:51 +02001698 send_config->rtp.extensions.clear();
1699 send_config->rtp.extensions.push_back(RtpExtension(
1700 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1701 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1702 (*receive_configs)[0].rtp.transport_cc = true;
1703 }
1704
1705 void ModifyAudioConfigs(
1706 AudioSendStream::Config* send_config,
1707 std::vector<AudioReceiveStream::Config>* receive_configs) override {
Tommi31d1bce2019-08-27 11:34:20 +02001708 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Stefan Holmer280de9e2016-09-30 10:06:51 +02001709 send_config->rtp.extensions.clear();
1710 send_config->rtp.extensions.push_back(RtpExtension(
1711 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1712 (*receive_configs)[0].rtp.extensions.clear();
1713 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1714 (*receive_configs)[0].rtp.transport_cc = true;
1715 }
1716
Stefan Holmerbe402962016-07-08 16:16:41 +02001717 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Tommi31d1bce2019-08-27 11:34:20 +02001718 RTC_DCHECK_RUN_ON(&module_process_thread_);
1719 task_queue_->PostTask([this]() {
1720 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1721 if (!call_)
1722 return;
1723 Call::Stats stats = call_->GetStats();
1724 if (stats.send_bandwidth_bps > kStartBitrateBps)
1725 observation_complete_.Set();
1726 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001727 return SEND_PACKET;
1728 }
1729
Tommi31d1bce2019-08-27 11:34:20 +02001730 void OnStreamsStopped() override {
1731 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1732 call_ = nullptr;
1733 }
1734
Stefan Holmerbe402962016-07-08 16:16:41 +02001735 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001736 rtc::NetworkRoute new_route;
1737 new_route.connected = true;
1738 new_route.local_network_id = 10;
1739 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001740 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001741
1742 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Tommi31d1bce2019-08-27 11:34:20 +02001743 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001744 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1745 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001746 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001747 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1748 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001749 });
1750
Stefan Holmerbe402962016-07-08 16:16:41 +02001751 EXPECT_TRUE(Wait())
1752 << "Timed out while waiting for start bitrate to be exceeded.";
1753
eladalon413ee9a2017-08-22 04:02:52 -07001754 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Tommi31d1bce2019-08-27 11:34:20 +02001755 RTC_DCHECK_RUN_ON(&task_queue_thread_);
eladalon413ee9a2017-08-22 04:02:52 -07001756 bitrate_config.start_bitrate_bps = -1;
1757 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001758 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1759 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001760 // TODO(holmer): We should set the last sent packet id here and verify
1761 // that we correctly ignore any packet loss reported prior to that id.
1762 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001763 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1764 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001765 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1766 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001767 }
1768
1769 private:
Tommi31d1bce2019-08-27 11:34:20 +02001770 webrtc::SequenceChecker module_process_thread_;
1771 webrtc::SequenceChecker task_queue_thread_;
eladalon413ee9a2017-08-22 04:02:52 -07001772 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Tommi31d1bce2019-08-27 11:34:20 +02001773 Call* call_ RTC_GUARDED_BY(task_queue_thread_);
eladalon413ee9a2017-08-22 04:02:52 -07001774 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001775
1776 RunBaseTest(&test);
1777}
1778
Sebastian Jansson63470292019-02-01 10:13:43 +01001779TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
michaelt79e05882016-11-08 02:50:09 -08001780 class ChangingTransportOverheadTest : public test::EndToEndTest {
1781 public:
eladalon413ee9a2017-08-22 04:02:52 -07001782 explicit ChangingTransportOverheadTest(
1783 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001784 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001785 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001786 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001787 packets_sent_(0),
1788 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001789
1790 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1791 call_ = sender_call;
1792 }
1793
1794 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001795 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001796 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001797 if (++packets_sent_ < 100)
1798 return SEND_PACKET;
1799 observation_complete_.Set();
1800 return SEND_PACKET;
1801 }
1802
michaelta3328772016-11-29 09:25:03 -08001803 void ModifyVideoConfigs(
1804 VideoSendStream::Config* send_config,
1805 std::vector<VideoReceiveStream::Config>* receive_configs,
1806 VideoEncoderConfig* encoder_config) override {
1807 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1808 }
1809
michaelt79e05882016-11-08 02:50:09 -08001810 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001811 task_queue_->SendTask([this]() {
1812 transport_overhead_ = 100;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001813 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1814 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001815 });
1816
michaelt79e05882016-11-08 02:50:09 -08001817 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001818
sprang21253fc2017-02-27 03:35:47 -08001819 {
1820 rtc::CritScope cs(&lock_);
1821 packets_sent_ = 0;
1822 }
eladalon413ee9a2017-08-22 04:02:52 -07001823
1824 task_queue_->SendTask([this]() {
1825 transport_overhead_ = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001826 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1827 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001828 });
1829
michaelt79e05882016-11-08 02:50:09 -08001830 EXPECT_TRUE(Wait());
1831 }
1832
1833 private:
eladalon413ee9a2017-08-22 04:02:52 -07001834 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001835 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001836 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001837 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001838 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001839 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001840 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001841
1842 RunBaseTest(&test);
1843}
1844
sprangf24a0642017-02-28 13:23:26 -08001845// Test class takes takes as argument a switch selecting if type switch should
1846// occur and a function pointer to reset the send stream. This is necessary
1847// since you cannot change the content type of a VideoSendStream, you need to
1848// recreate it. Stopping and recreating the stream can only be done on the main
1849// thread and in the context of VideoSendStreamTest (not BaseTest).
1850template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001851class MaxPaddingSetTest : public test::SendTest {
1852 public:
1853 static const uint32_t kMinTransmitBitrateBps = 400000;
1854 static const uint32_t kActualEncodeBitrateBps = 40000;
1855 static const uint32_t kMinPacketsToSend = 50;
1856
Tommiaaaf8042019-08-05 14:56:33 +02001857 MaxPaddingSetTest(bool test_switch_content_type,
1858 T* stream_reset_fun,
1859 test::SingleThreadedTaskQueueForTesting* task_queue)
sprang9c0b5512016-07-06 00:54:28 -07001860 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001861 running_without_padding_(test_switch_content_type),
Tommiaaaf8042019-08-05 14:56:33 +02001862 stream_resetter_(stream_reset_fun),
1863 task_queue_(task_queue) {
tommi39e12892017-03-13 05:15:14 -07001864 RTC_DCHECK(stream_resetter_);
Tommi31d1bce2019-08-27 11:34:20 +02001865 module_process_thread_.Detach();
1866 task_queue_thread_.Detach();
sprang9c0b5512016-07-06 00:54:28 -07001867 }
1868
1869 void ModifyVideoConfigs(
1870 VideoSendStream::Config* send_config,
1871 std::vector<VideoReceiveStream::Config>* receive_configs,
1872 VideoEncoderConfig* encoder_config) override {
Tommi31d1bce2019-08-27 11:34:20 +02001873 RTC_DCHECK_RUN_ON(&task_queue_thread_);
kwibergaf476c72016-11-28 15:21:39 -08001874 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
Tommi31d1bce2019-08-27 11:34:20 +02001875 if (running_without_padding_) {
sprang9c0b5512016-07-06 00:54:28 -07001876 encoder_config->min_transmit_bitrate_bps = 0;
1877 encoder_config->content_type =
1878 VideoEncoderConfig::ContentType::kRealtimeVideo;
1879 } else {
1880 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1881 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1882 }
sprangf24a0642017-02-28 13:23:26 -08001883 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001884 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001885 }
1886
1887 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommi31d1bce2019-08-27 11:34:20 +02001888 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1889 RTC_DCHECK(task_queue_->IsCurrent());
1890 RTC_DCHECK(!call_);
1891 RTC_DCHECK(sender_call);
sprang9c0b5512016-07-06 00:54:28 -07001892 call_ = sender_call;
1893 }
1894
Tommiaaaf8042019-08-05 14:56:33 +02001895 // Called on the pacer thread.
sprang9c0b5512016-07-06 00:54:28 -07001896 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Tommi31d1bce2019-08-27 11:34:20 +02001897 RTC_DCHECK_RUN_ON(&module_process_thread_);
Tommiaaaf8042019-08-05 14:56:33 +02001898
Tommi31d1bce2019-08-27 11:34:20 +02001899 // Check the stats on the correct thread and signal the 'complete' flag
1900 // once we detect that we're done.
Tommiaaaf8042019-08-05 14:56:33 +02001901
Tommi31d1bce2019-08-27 11:34:20 +02001902 task_queue_->PostTask([this]() {
1903 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1904 // In case we get a callback during teardown.
1905 // When this happens, OnStreamsStopped() has been called already,
1906 // |call_| is null and the streams are being torn down.
1907 if (!call_)
1908 return;
sprang9c0b5512016-07-06 00:54:28 -07001909
Tommi31d1bce2019-08-27 11:34:20 +02001910 ++packets_sent_;
sprang9c0b5512016-07-06 00:54:28 -07001911
Tommi31d1bce2019-08-27 11:34:20 +02001912 Call::Stats stats = call_->GetStats();
1913 if (running_without_padding_) {
1914 EXPECT_EQ(0, stats.max_padding_bitrate_bps);
sprang9c0b5512016-07-06 00:54:28 -07001915
Tommi31d1bce2019-08-27 11:34:20 +02001916 // Wait until at least kMinPacketsToSend frames have been encoded, so
1917 // that we have reliable data.
1918 if (packets_sent_ < kMinPacketsToSend)
1919 return;
1920
1921 // We've sent kMinPacketsToSend packets with default configuration,
1922 // switch to enabling screen content and setting min transmit bitrate.
1923 // Note that we need to recreate the stream if changing content type.
1924 packets_sent_ = 0;
1925
1926 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1927 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
1928
1929 running_without_padding_ = false;
1930 (*stream_resetter_)(send_stream_config_, encoder_config_);
1931 } else {
1932 // Make sure the pacer has been configured with a min transmit bitrate.
1933 if (stats.max_padding_bitrate_bps > 0) {
1934 observation_complete_.Set();
1935 }
1936 }
1937 });
sprang9c0b5512016-07-06 00:54:28 -07001938
1939 return SEND_PACKET;
1940 }
1941
Tommi31d1bce2019-08-27 11:34:20 +02001942 // Called on |task_queue_|
1943 void OnStreamsStopped() override {
1944 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1945 RTC_DCHECK(task_queue_->IsCurrent());
1946 call_ = nullptr;
1947 }
sprangf24a0642017-02-28 13:23:26 -08001948
Tommi31d1bce2019-08-27 11:34:20 +02001949 void PerformTest() override {
sprang9c0b5512016-07-06 00:54:28 -07001950 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1951 }
1952
1953 private:
Tommi31d1bce2019-08-27 11:34:20 +02001954 webrtc::SequenceChecker task_queue_thread_;
1955 Call* call_ RTC_GUARDED_BY(task_queue_thread_) = nullptr;
1956 VideoSendStream::Config send_stream_config_{nullptr};
sprang9c0b5512016-07-06 00:54:28 -07001957 VideoEncoderConfig encoder_config_;
Tommi31d1bce2019-08-27 11:34:20 +02001958 webrtc::SequenceChecker module_process_thread_;
1959 uint32_t packets_sent_ RTC_GUARDED_BY(task_queue_thread_) = 0;
1960 bool running_without_padding_ RTC_GUARDED_BY(task_queue_thread_);
sprangf24a0642017-02-28 13:23:26 -08001961 T* const stream_resetter_;
Tommi31d1bce2019-08-27 11:34:20 +02001962 test::SingleThreadedTaskQueueForTesting* const task_queue_;
sprang9c0b5512016-07-06 00:54:28 -07001963};
1964
Sebastian Jansson63470292019-02-01 10:13:43 +01001965TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001966 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1967 const VideoEncoderConfig& encoder_config) {};
Tommiaaaf8042019-08-05 14:56:33 +02001968 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun, &task_queue_);
sprang9c0b5512016-07-06 00:54:28 -07001969 RunBaseTest(&test);
1970}
1971
Sebastian Jansson63470292019-02-01 10:13:43 +01001972TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001973 // Function for removing and recreating the send stream with a new config.
1974 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1975 const VideoEncoderConfig& encoder_config) {
Tommi31d1bce2019-08-27 11:34:20 +02001976 RTC_DCHECK(task_queue_.IsCurrent());
1977 Stop();
1978 DestroyVideoSendStreams();
1979 SetVideoSendConfig(send_stream_config);
1980 SetVideoEncoderConfig(encoder_config);
1981 CreateVideoSendStreams();
1982 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
1983 Start();
sprangf24a0642017-02-28 13:23:26 -08001984 };
Tommiaaaf8042019-08-05 14:56:33 +02001985 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun, &task_queue_);
sprang9c0b5512016-07-06 00:54:28 -07001986 RunBaseTest(&test);
1987}
1988
perkjfa10b552016-10-02 23:45:26 -07001989// This test verifies that new frame sizes reconfigures encoders even though not
1990// (yet) sending. The purpose of this is to permit encoding as quickly as
1991// possible once we start sending. Likely the frames being input are from the
1992// same source that will be sent later, which just means that we're ready
1993// earlier.
Sebastian Jansson63470292019-02-01 10:13:43 +01001994TEST_F(VideoSendStreamTest,
perkjfa10b552016-10-02 23:45:26 -07001995 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1996 class EncoderObserver : public test::FakeEncoder {
1997 public:
1998 EncoderObserver()
1999 : FakeEncoder(Clock::GetRealTimeClock()),
perkjfa10b552016-10-02 23:45:26 -07002000 number_of_initializations_(0),
2001 last_initialized_frame_width_(0),
2002 last_initialized_frame_height_(0) {}
2003
2004 void WaitForResolution(int width, int height) {
2005 {
2006 rtc::CritScope lock(&crit_);
2007 if (last_initialized_frame_width_ == width &&
2008 last_initialized_frame_height_ == height) {
2009 return;
2010 }
2011 }
Erik Språng08127a92016-11-16 16:41:30 +01002012 EXPECT_TRUE(
2013 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07002014 {
2015 rtc::CritScope lock(&crit_);
2016 EXPECT_EQ(width, last_initialized_frame_width_);
2017 EXPECT_EQ(height, last_initialized_frame_height_);
2018 }
2019 }
2020
2021 private:
2022 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002023 const Settings& settings) override {
perkjfa10b552016-10-02 23:45:26 -07002024 rtc::CritScope lock(&crit_);
2025 last_initialized_frame_width_ = config->width;
2026 last_initialized_frame_height_ = config->height;
2027 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01002028 init_encode_called_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002029 return FakeEncoder::InitEncode(config, settings);
perkjfa10b552016-10-02 23:45:26 -07002030 }
2031
2032 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01002033 const std::vector<VideoFrameType>* frame_types) override {
perkjfa10b552016-10-02 23:45:26 -07002034 ADD_FAILURE()
2035 << "Unexpected Encode call since the send stream is not started";
2036 return 0;
2037 }
2038
2039 rtc::CriticalSection crit_;
2040 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07002041 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
2042 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
2043 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002044 };
2045
perkjfa10b552016-10-02 23:45:26 -07002046 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07002047 EncoderObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002048 test::VideoEncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07002049
Niels Möller4db138e2018-04-19 09:04:13 +02002050 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002051 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002052 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002053 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002054 CreateVideoStreams();
2055 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
2056 kDefaultHeight);
2057 frame_generator_capturer_->Start();
2058 });
perkjfa10b552016-10-02 23:45:26 -07002059
2060 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07002061
2062 task_queue_.SendTask([this]() {
2063 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
2064 kDefaultHeight * 2);
2065 });
2066
perkjfa10b552016-10-02 23:45:26 -07002067 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07002068
2069 task_queue_.SendTask([this]() {
2070 DestroyStreams();
2071 DestroyCalls();
2072 });
perkjfa10b552016-10-02 23:45:26 -07002073}
2074
Sebastian Jansson63470292019-02-01 10:13:43 +01002075TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002076 class StartBitrateObserver : public test::FakeEncoder {
2077 public:
2078 StartBitrateObserver()
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +02002079 : FakeEncoder(Clock::GetRealTimeClock()), start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002080 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002081 const Settings& settings) override {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002082 rtc::CritScope lock(&crit_);
2083 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07002084 start_bitrate_changed_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002085 return FakeEncoder::InitEncode(config, settings);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002086 }
2087
Erik Språng16cb8f52019-04-12 13:59:09 +02002088 void SetRates(const RateControlParameters& parameters) override {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002089 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002090 start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
pbos14fe7082016-04-20 06:35:56 -07002091 start_bitrate_changed_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002092 FakeEncoder::SetRates(parameters);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002093 }
2094
2095 int GetStartBitrateKbps() const {
2096 rtc::CritScope lock(&crit_);
2097 return start_bitrate_kbps_;
2098 }
2099
pbos14fe7082016-04-20 06:35:56 -07002100 bool WaitForStartBitrate() {
2101 return start_bitrate_changed_.Wait(
2102 VideoSendStreamTest::kDefaultTimeoutMs);
2103 }
2104
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002105 private:
pbos5ad935c2016-01-25 03:52:44 -08002106 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002107 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002108 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002109 };
2110
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002111 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002112
solenberg4fbae2b2015-08-28 04:07:10 -07002113 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002114 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002115
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002116 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002117 bitrate_config.start_bitrate_bps =
2118 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002119 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2120 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002121
2122 StartBitrateObserver encoder;
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002123 test::VideoEncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002124 // Since this test does not use a capturer, set |internal_source| = true.
2125 // Encoder configuration is otherwise updated on the next video frame.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002126 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002127 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002128
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002129 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002130
pbos14fe7082016-04-20 06:35:56 -07002131 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002132 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002133 encoder.GetStartBitrateKbps());
2134
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002135 GetVideoEncoderConfig()->max_bitrate_bps =
2136 2 * bitrate_config.start_bitrate_bps;
2137 GetVideoSendStream()->ReconfigureVideoEncoder(
2138 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002139
2140 // New bitrate should be reconfigured above the previous max. As there's no
2141 // network connection this shouldn't be flaky, as no bitrate should've been
2142 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002143 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002144 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2145 encoder.GetStartBitrateKbps());
2146
2147 DestroyStreams();
2148}
2149
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002150class StartStopBitrateObserver : public test::FakeEncoder {
2151 public:
Niels Möllerc572ff32018-11-07 08:43:50 +01002152 StartStopBitrateObserver() : FakeEncoder(Clock::GetRealTimeClock()) {}
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002153 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002154 const Settings& settings) override {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002155 rtc::CritScope lock(&crit_);
2156 encoder_init_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002157 return FakeEncoder::InitEncode(config, settings);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002158 }
2159
Erik Språng16cb8f52019-04-12 13:59:09 +02002160 void SetRates(const RateControlParameters& parameters) override {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002161 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002162 bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002163 bitrate_changed_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002164 FakeEncoder::SetRates(parameters);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002165 }
2166
2167 bool WaitForEncoderInit() {
2168 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2169 }
2170
2171 bool WaitBitrateChanged(bool non_zero) {
2172 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002173 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002174 {
2175 rtc::CritScope lock(&crit_);
2176 bitrate_kbps = bitrate_kbps_;
2177 }
2178 if (!bitrate_kbps)
2179 continue;
2180
2181 if ((non_zero && *bitrate_kbps > 0) ||
2182 (!non_zero && *bitrate_kbps == 0)) {
2183 return true;
2184 }
2185 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2186 return false;
2187 }
2188
2189 private:
2190 rtc::CriticalSection crit_;
2191 rtc::Event encoder_init_;
2192 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002193 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002194};
2195
perkj57c21f92016-06-17 07:27:16 -07002196// This test that if the encoder use an internal source, VideoEncoder::SetRates
2197// will be called with zero bitrate during initialization and that
2198// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2199// with zero bitrate.
Sebastian Jansson63470292019-02-01 10:13:43 +01002200TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002201 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002202 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002203 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002204 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002205 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002206
Niels Möller4db138e2018-04-19 09:04:13 +02002207 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002208 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002209 CreateSendConfig(1, 0, 0, &transport);
2210
2211 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002212 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002213
2214 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002215 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002216 GetVideoSendStream()->Start();
2217 GetVideoSendStream()->SetSource(&forwarder,
2218 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002219 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002220 });
perkj57c21f92016-06-17 07:27:16 -07002221
2222 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002223
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002224 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002225 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2226
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002227 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002228 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2229
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002230 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002231 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002232
eladalon413ee9a2017-08-22 04:02:52 -07002233 task_queue_.SendTask([this]() {
2234 DestroyStreams();
2235 DestroyCalls();
2236 });
perkj57c21f92016-06-17 07:27:16 -07002237}
2238
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002239// Tests that when the encoder uses an internal source, the VideoEncoder will
2240// be updated with a new bitrate when turning the VideoSendStream on/off with
2241// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2242// is reconfigured with new active layers.
Sebastian Jansson63470292019-02-01 10:13:43 +01002243TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002244 test::NullTransport transport;
2245 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002246 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002247 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002248 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002249
Niels Möller4db138e2018-04-19 09:04:13 +02002250 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002251 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002252 // Create two simulcast streams.
2253 CreateSendConfig(2, 0, 0, &transport);
2254
2255 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002256 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002257
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002258 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002259
2260 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002261 GetVideoSendStream()->Start();
2262 GetVideoSendStream()->SetSource(&forwarder,
2263 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002264 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002265 });
2266
2267 EXPECT_TRUE(encoder.WaitForEncoderInit());
2268
2269 // When we turn on the simulcast layers it will update the BitrateAllocator,
2270 // which in turn updates the VideoEncoder's bitrate.
2271 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002272 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002273 });
2274 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2275
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002276 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2277 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002278 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002279 GetVideoSendStream()->ReconfigureVideoEncoder(
2280 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002281 });
2282 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2283 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2284 // active. Once the change is made for a "soft" reconfiguration we can remove
2285 // the expecation for an encoder init. We can also test that bitrate changes
2286 // when just updating individual active layers, which should change the
2287 // bitrate set to the video encoder.
2288 EXPECT_TRUE(encoder.WaitForEncoderInit());
2289 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2290
2291 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002292 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2293 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002294 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002295 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002296 });
2297 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2298
2299 task_queue_.SendTask([this]() {
2300 DestroyStreams();
2301 DestroyCalls();
2302 });
2303}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002304
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002305VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002306 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002307 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002308 memset(buffer.get(), data, kSizeY);
Artem Titov1ebfb6a2019-01-03 23:49:37 +01002309 VideoFrame frame =
2310 webrtc::VideoFrame::Builder()
2311 .set_video_frame_buffer(I420Buffer::Create(width, height))
2312 .set_rotation(webrtc::kVideoRotation_0)
2313 .set_timestamp_us(data)
2314 .build();
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002315 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002316 // Use data as a ms timestamp.
2317 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002318 return frame;
2319}
2320
Sebastian Jansson63470292019-02-01 10:13:43 +01002321TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002322 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2323 public:
eladalon413ee9a2017-08-22 04:02:52 -07002324 explicit EncoderStateObserver(
2325 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002326 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002327 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002328 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002329 initialized_(false),
2330 callback_registered_(false),
2331 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002332 released_(false),
2333 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002334
2335 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002336 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002337 return released_;
2338 }
2339
2340 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002341 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002342 return initialized_ && callback_registered_;
2343 }
2344
2345 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002346 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002347 return num_releases_;
2348 }
2349
2350 private:
Elad Alon8f01c4e2019-06-28 15:19:43 +02002351 void SetFecControllerOverride(
2352 FecControllerOverride* fec_controller_override) override {
2353 // Ignored.
2354 }
2355
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002356 int32_t InitEncode(const VideoCodec* codecSettings,
Elad Alon370f93a2019-06-11 14:57:57 +02002357 const Settings& settings) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002358 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002359 EXPECT_FALSE(initialized_);
2360 initialized_ = true;
2361 released_ = false;
2362 return 0;
2363 }
2364
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002365 int32_t Encode(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +01002366 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002367 EXPECT_TRUE(IsReadyForEncode());
2368
Peter Boström5811a392015-12-10 13:02:50 +01002369 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002370 return 0;
2371 }
2372
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002373 int32_t RegisterEncodeCompleteCallback(
2374 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002375 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002376 EXPECT_TRUE(initialized_);
2377 callback_registered_ = true;
2378 return 0;
2379 }
2380
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002381 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002382 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002383 EXPECT_TRUE(IsReadyForEncode());
2384 EXPECT_FALSE(released_);
2385 initialized_ = false;
2386 callback_registered_ = false;
2387 released_ = true;
2388 ++num_releases_;
2389 return 0;
2390 }
2391
Erik Språng6f46e4a2019-04-24 18:33:27 +02002392 void SetRates(const RateControlParameters& parameters) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002393 EXPECT_TRUE(IsReadyForEncode());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002394 }
2395
stefanff483612015-12-21 03:14:00 -08002396 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002397 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002398 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002399 stream_ = send_stream;
2400 }
2401
stefanff483612015-12-21 03:14:00 -08002402 void ModifyVideoConfigs(
2403 VideoSendStream::Config* send_config,
2404 std::vector<VideoReceiveStream::Config>* receive_configs,
2405 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002406 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002407 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002408 }
2409
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002410 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002411 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002412
2413 task_queue_->SendTask([this]() {
2414 EXPECT_EQ(0u, num_releases());
2415 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2416 EXPECT_EQ(0u, num_releases());
2417 stream_->Stop();
2418 // Encoder should not be released before destroying the VideoSendStream.
2419 EXPECT_FALSE(IsReleased());
2420 EXPECT_TRUE(IsReadyForEncode());
2421 stream_->Start();
2422 });
2423
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002424 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002425 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002426 }
2427
eladalon413ee9a2017-08-22 04:02:52 -07002428 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002429 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002430 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002431 bool initialized_ RTC_GUARDED_BY(crit_);
2432 bool callback_registered_ RTC_GUARDED_BY(crit_);
2433 size_t num_releases_ RTC_GUARDED_BY(crit_);
2434 bool released_ RTC_GUARDED_BY(crit_);
Niels Möllercbcbc222018-09-28 09:07:24 +02002435 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002436 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002437 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002438
stefane74eef12016-01-08 06:47:13 -08002439 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002440
2441 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002442 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002443}
2444
Sergey Silkin571e6c92018-04-03 10:03:31 +02002445static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002446template <typename T>
2447class VideoCodecConfigObserver : public test::SendTest,
2448 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002449 public:
2450 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2451 const char* codec_name)
2452 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2453 FakeEncoder(Clock::GetRealTimeClock()),
2454 video_codec_type_(video_codec_type),
2455 codec_name_(codec_name),
Erik Språng737336d2016-07-29 12:59:36 +02002456 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002457 stream_(nullptr),
2458 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002459 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002460 }
2461
2462 private:
stefanff483612015-12-21 03:14:00 -08002463 void ModifyVideoConfigs(
2464 VideoSendStream::Config* send_config,
2465 std::vector<VideoReceiveStream::Config>* receive_configs,
2466 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002467 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002468 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002469
Niels Möller259a4972018-04-05 15:36:51 +02002470 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002471 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
Åsa Perssond34597c2018-10-22 17:34:02 +02002472 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2473 encoder_config->simulcast_layers[0].num_temporal_layers =
2474 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07002475 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002476 }
2477
stefanff483612015-12-21 03:14:00 -08002478 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002479 VideoSendStream* send_stream,
2480 const std::vector<VideoReceiveStream*>& receive_streams) override {
2481 stream_ = send_stream;
2482 }
2483
2484 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002485 const Settings& settings) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002486 EXPECT_EQ(video_codec_type_, config->codecType);
2487 VerifyCodecSpecifics(*config);
2488 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002489 init_encode_event_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002490 return FakeEncoder::InitEncode(config, settings);
Peter Boström53eda3d2015-03-27 15:53:18 +01002491 }
2492
Sergey Silkin86684962018-03-28 19:32:37 +02002493 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002494 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002495 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2496 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002497
2498 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002499 EXPECT_TRUE(
2500 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002501 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002502
Sergey Silkin86684962018-03-28 19:32:37 +02002503 // Change encoder settings to actually trigger reconfiguration.
2504 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002505 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002506 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002507 ASSERT_TRUE(
2508 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002509 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002510 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2511 "new encoder settings.";
2512 }
2513
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002514 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01002515 const std::vector<VideoFrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002516 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2517 return 0;
2518 }
2519
2520 T encoder_settings_;
2521 const VideoCodecType video_codec_type_;
2522 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002523 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002524 size_t num_initializations_;
2525 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002526 test::VideoEncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002527 VideoEncoderConfig encoder_config_;
2528};
2529
2530template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002531void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2532 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2533}
2534
2535template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002536void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2537 const VideoCodec& config) const {
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002538 // Check that the number of temporal layers has propagated properly to
2539 // VideoCodec.
2540 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2541 config.H264().numberOfTemporalLayers);
2542
2543 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2544 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2545 config.simulcastStream[i].numberOfTemporalLayers);
2546 }
2547
2548 // Set expected temporal layers as they should have been set when
2549 // reconfiguring the encoder and not match the set config.
2550 VideoCodecH264 encoder_settings = encoder_settings_;
2551 encoder_settings.numberOfTemporalLayers =
2552 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002553 EXPECT_EQ(
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002554 0, memcmp(&config.H264(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002555}
kthelgason29a44e32016-09-27 03:52:02 -07002556
2557template <>
2558rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2559VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2560 return new rtc::RefCountedObject<
2561 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2562}
2563
Peter Boström53eda3d2015-03-27 15:53:18 +01002564template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002565void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2566 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2567}
2568
2569template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002570void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2571 const VideoCodec& config) const {
2572 // Check that the number of temporal layers has propagated properly to
2573 // VideoCodec.
2574 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002575 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002576
2577 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2578 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2579 config.simulcastStream[i].numberOfTemporalLayers);
2580 }
2581
2582 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002583 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002584 VideoCodecVP8 encoder_settings = encoder_settings_;
2585 encoder_settings.numberOfTemporalLayers =
2586 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002587 EXPECT_EQ(
2588 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002589}
kthelgason29a44e32016-09-27 03:52:02 -07002590
2591template <>
2592rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2593VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2594 return new rtc::RefCountedObject<
2595 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2596}
2597
Peter Boström53eda3d2015-03-27 15:53:18 +01002598template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002599void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2600 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2601}
2602
2603template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002604void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2605 const VideoCodec& config) const {
2606 // Check that the number of temporal layers has propagated properly to
2607 // VideoCodec.
2608 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002609 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002610
2611 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2612 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2613 config.simulcastStream[i].numberOfTemporalLayers);
2614 }
2615
2616 // Set expected temporal layers as they should have been set when
2617 // reconfiguring the encoder and not match the set config.
2618 VideoCodecVP9 encoder_settings = encoder_settings_;
2619 encoder_settings.numberOfTemporalLayers =
2620 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002621 EXPECT_EQ(
2622 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002623}
2624
kthelgason29a44e32016-09-27 03:52:02 -07002625template <>
2626rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2627VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2628 return new rtc::RefCountedObject<
2629 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2630}
2631
Sebastian Jansson63470292019-02-01 10:13:43 +01002632TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002633 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002634 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002635}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002636
Sebastian Jansson63470292019-02-01 10:13:43 +01002637TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002638 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002639 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002640}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002641
Sebastian Jansson63470292019-02-01 10:13:43 +01002642TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002643 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002644 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002645}
2646
Sebastian Jansson63470292019-02-01 10:13:43 +01002647TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002648 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002649 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002650 RtcpSenderReportTest()
2651 : SendTest(kDefaultTimeoutMs),
2652 rtp_packets_sent_(0),
2653 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002654
2655 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002656 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002657 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002658 RTPHeader header;
2659 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002660 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002661 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2662 return SEND_PACKET;
2663 }
2664
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002665 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002666 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002667 test::RtcpPacketParser parser;
2668 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002669
danilchap3dc929e2016-11-02 08:21:59 -07002670 if (parser.sender_report()->num_packets() > 0) {
2671 // Only compare sent media bytes if SenderPacketCount matches the
2672 // number of sent rtp packets (a new rtp packet could be sent before
2673 // the rtcp packet).
2674 if (parser.sender_report()->sender_octet_count() > 0 &&
2675 parser.sender_report()->sender_packet_count() ==
2676 rtp_packets_sent_) {
2677 EXPECT_EQ(media_bytes_sent_,
2678 parser.sender_report()->sender_octet_count());
2679 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002680 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002681 }
2682
2683 return SEND_PACKET;
2684 }
2685
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002686 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002687 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002688 }
2689
stefan4b569042015-11-11 06:39:57 -08002690 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002691 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2692 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002693 } test;
2694
stefane74eef12016-01-08 06:47:13 -08002695 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002696}
2697
Sebastian Jansson63470292019-02-01 10:13:43 +01002698TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002699 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002700
2701 class VideoStreamFactory
2702 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2703 public:
2704 VideoStreamFactory() {}
2705
2706 private:
2707 std::vector<VideoStream> CreateEncoderStreams(
2708 int width,
2709 int height,
2710 const VideoEncoderConfig& encoder_config) override {
2711 std::vector<VideoStream> streams =
2712 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002713 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2714 kScreencastMaxTargetBitrateDeltaKbps);
2715 streams[0].target_bitrate_bps =
2716 streams[0].max_bitrate_bps -
2717 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002718 return streams;
2719 }
2720 };
2721
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002722 class ScreencastTargetBitrateTest : public test::SendTest,
2723 public test::FakeEncoder {
2724 public:
2725 ScreencastTargetBitrateTest()
2726 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002727 test::FakeEncoder(Clock::GetRealTimeClock()),
2728 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002729
2730 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002731 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002732 const Settings& settings) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002733 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002734 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002735 config->simulcastStream[0].maxBitrate -
2736 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002737 observation_complete_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002738 return test::FakeEncoder::InitEncode(config, settings);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002739 }
Elad Alon370f93a2019-06-11 14:57:57 +02002740
stefanff483612015-12-21 03:14:00 -08002741 void ModifyVideoConfigs(
2742 VideoSendStream::Config* send_config,
2743 std::vector<VideoReceiveStream::Config>* receive_configs,
2744 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002745 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002746 EXPECT_EQ(1u, encoder_config->number_of_streams);
2747 encoder_config->video_stream_factory =
2748 new rtc::RefCountedObject<VideoStreamFactory>();
Åsa Perssond34597c2018-10-22 17:34:02 +02002749 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2750 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
Erik Språng143cec12015-04-28 10:01:41 +02002751 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002752 }
2753
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002754 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002755 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002756 << "Timed out while waiting for the encoder to be initialized.";
2757 }
Niels Möllercbcbc222018-09-28 09:07:24 +02002758 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002759 } test;
2760
stefane74eef12016-01-08 06:47:13 -08002761 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002762}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002763
Sebastian Jansson63470292019-02-01 10:13:43 +01002764TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002765 // These are chosen to be "kind of odd" to not be accidentally checked against
2766 // default values.
2767 static const int kMinBitrateKbps = 137;
2768 static const int kStartBitrateKbps = 345;
2769 static const int kLowerMaxBitrateKbps = 312;
2770 static const int kMaxBitrateKbps = 413;
2771 static const int kIncreasedStartBitrateKbps = 451;
2772 static const int kIncreasedMaxBitrateKbps = 597;
Erik Språng7ca375c2019-02-06 16:20:17 +01002773 // If these fields trial are on, we get lower bitrates than expected by this
2774 // test, due to the packetization overhead and encoder pushback.
Niels Möller6613f8e2019-01-10 10:30:21 +01002775 webrtc::test::ScopedFieldTrials field_trials(
2776 std::string(field_trial::GetFieldTrialString()) +
Erik Språng7ca375c2019-02-06 16:20:17 +01002777 "WebRTC-SubtractPacketizationOverhead/Disabled/"
2778 "WebRTC-VideoRateControl/bitrate_adjuster:false/");
Niels Möller6613f8e2019-01-10 10:30:21 +01002779
pbos@webrtc.org00873182014-11-25 14:03:34 +00002780 class EncoderBitrateThresholdObserver : public test::SendTest,
Sergey Silkin5ee69672019-07-02 14:18:34 +02002781 public VideoBitrateAllocatorFactory,
pbos@webrtc.org00873182014-11-25 14:03:34 +00002782 public test::FakeEncoder {
2783 public:
eladalon413ee9a2017-08-22 04:02:52 -07002784 explicit EncoderBitrateThresholdObserver(
2785 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002786 : SendTest(kDefaultTimeoutMs),
2787 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002788 task_queue_(task_queue),
perkj26091b12016-09-01 01:17:40 -07002789 target_bitrate_(0),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002790 num_rate_allocator_creations_(0),
2791 num_encoder_initializations_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002792 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002793 send_stream_(nullptr),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002794 encoder_factory_(this),
2795 bitrate_allocator_factory_(
2796 CreateBuiltinVideoBitrateAllocatorFactory()) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002797
2798 private:
Sergey Silkin5ee69672019-07-02 14:18:34 +02002799 std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
2800 const VideoCodec& codec) override {
2801 EXPECT_GE(codec.startBitrate, codec.minBitrate);
2802 EXPECT_LE(codec.startBitrate, codec.maxBitrate);
2803 if (num_rate_allocator_creations_ == 0) {
2804 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps), codec.minBitrate);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002805 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002806 codec.startBitrate);
2807 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps), codec.maxBitrate);
2808 } else if (num_rate_allocator_creations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002809 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002810 codec.maxBitrate);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002811 // The start bitrate should be kept (-1) and capped to the max bitrate.
2812 // Since this is not an end-to-end call no receiver should have been
2813 // returning a REMB that could lower this estimate.
Sergey Silkin5ee69672019-07-02 14:18:34 +02002814 EXPECT_EQ(codec.startBitrate, codec.maxBitrate);
2815 } else if (num_rate_allocator_creations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002816 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002817 codec.maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002818 // The start bitrate will be whatever the rate BitRateController
2819 // has currently configured but in the span of the set max and min
2820 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002821 }
Sergey Silkin5ee69672019-07-02 14:18:34 +02002822 ++num_rate_allocator_creations_;
2823 create_rate_allocator_event_.Set();
2824
2825 return bitrate_allocator_factory_->CreateVideoBitrateAllocator(codec);
2826 }
2827
2828 int32_t InitEncode(const VideoCodec* codecSettings,
2829 const Settings& settings) override {
2830 EXPECT_EQ(0, num_encoder_initializations_);
2831 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2832 codecSettings->minBitrate);
2833 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2834 codecSettings->startBitrate);
2835 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2836 codecSettings->maxBitrate);
2837
2838 ++num_encoder_initializations_;
2839
2840 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002841 init_encode_event_.Set();
2842
Elad Alon370f93a2019-06-11 14:57:57 +02002843 return FakeEncoder::InitEncode(codecSettings, settings);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002844 }
2845
Erik Språng16cb8f52019-04-12 13:59:09 +02002846 void SetRates(const RateControlParameters& parameters) override {
perkj26091b12016-09-01 01:17:40 -07002847 {
2848 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002849 if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) {
2850 FakeEncoder::SetRates(parameters);
2851 return;
perkjfa10b552016-10-02 23:45:26 -07002852 }
Erik Språng16cb8f52019-04-12 13:59:09 +02002853 target_bitrate_ = parameters.bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002854 }
2855 bitrate_changed_event_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002856 FakeEncoder::SetRates(parameters);
perkj26091b12016-09-01 01:17:40 -07002857 }
2858
2859 void WaitForSetRates(uint32_t expected_bitrate) {
Niels Möller6bb5ab92019-01-11 11:11:10 +01002860 // Wait for the expected rate to be set. In some cases there can be
2861 // more than one update pending, in which case we keep waiting
2862 // until the correct value has been observed.
2863 const int64_t start_time = rtc::TimeMillis();
2864 do {
2865 rtc::CritScope lock(&crit_);
2866 if (target_bitrate_ == expected_bitrate) {
2867 return;
2868 }
2869 } while (bitrate_changed_event_.Wait(
2870 std::max(int64_t{1}, VideoSendStreamTest::kDefaultTimeoutMs -
2871 (rtc::TimeMillis() - start_time))));
Niels Möller6613f8e2019-01-10 10:30:21 +01002872 rtc::CritScope lock(&crit_);
Niels Möller6bb5ab92019-01-11 11:11:10 +01002873 EXPECT_EQ(target_bitrate_, expected_bitrate)
2874 << "Timed out while waiting encoder rate to be set.";
perkj26091b12016-09-01 01:17:40 -07002875 }
2876
Niels Möllerde8e6e62018-11-13 15:10:33 +01002877 void ModifySenderBitrateConfig(
2878 BitrateConstraints* bitrate_config) override {
2879 bitrate_config->min_bitrate_bps = kMinBitrateKbps * 1000;
2880 bitrate_config->start_bitrate_bps = kStartBitrateKbps * 1000;
2881 bitrate_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002882 }
2883
stefanff483612015-12-21 03:14:00 -08002884 void ModifyVideoConfigs(
2885 VideoSendStream::Config* send_config,
2886 std::vector<VideoReceiveStream::Config>* receive_configs,
2887 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002888 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002889 send_config->encoder_settings.bitrate_allocator_factory = this;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002890 // Set bitrates lower/higher than min/max to make sure they are properly
2891 // capped.
perkjfa10b552016-10-02 23:45:26 -07002892 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
Åsa Persson21740532019-04-15 14:00:30 +02002893 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2894 encoder_config->simulcast_layers[0].min_bitrate_bps =
2895 kMinBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002896 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002897 }
2898
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002899 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002900 call_ = sender_call;
2901 }
2902
stefanff483612015-12-21 03:14:00 -08002903 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002904 VideoSendStream* send_stream,
2905 const std::vector<VideoReceiveStream*>& receive_streams) override {
2906 send_stream_ = send_stream;
2907 }
2908
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002909 void PerformTest() override {
Sergey Silkin5ee69672019-07-02 14:18:34 +02002910 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2911 VideoSendStreamTest::kDefaultTimeoutMs))
2912 << "Timed out while waiting for rate allocator to be created.";
pbos14fe7082016-04-20 06:35:56 -07002913 ASSERT_TRUE(
2914 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002915 << "Timed out while waiting for encoder to be configured.";
2916 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002917 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002918 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2919 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002920 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002921 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2922 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002923 });
perkj26091b12016-09-01 01:17:40 -07002924 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2925 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002926 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002927 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Sergey Silkin5ee69672019-07-02 14:18:34 +02002928 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2929 VideoSendStreamTest::kDefaultTimeoutMs));
2930 EXPECT_EQ(2, num_rate_allocator_creations_)
2931 << "Rate allocator should have been recreated.";
2932
perkjfa10b552016-10-02 23:45:26 -07002933 WaitForSetRates(kLowerMaxBitrateKbps);
Sergey Silkin5ee69672019-07-02 14:18:34 +02002934 EXPECT_EQ(1, num_encoder_initializations_);
perkjfa10b552016-10-02 23:45:26 -07002935
2936 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2937 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Sergey Silkin5ee69672019-07-02 14:18:34 +02002938 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2939 VideoSendStreamTest::kDefaultTimeoutMs));
2940 EXPECT_EQ(3, num_rate_allocator_creations_)
2941 << "Rate allocator should have been recreated.";
2942
perkj26091b12016-09-01 01:17:40 -07002943 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002944 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002945 WaitForSetRates(kIncreasedStartBitrateKbps);
Sergey Silkin5ee69672019-07-02 14:18:34 +02002946 EXPECT_EQ(1, num_encoder_initializations_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002947 }
2948
eladalon413ee9a2017-08-22 04:02:52 -07002949 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002950 rtc::Event create_rate_allocator_event_;
pbos14fe7082016-04-20 06:35:56 -07002951 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002952 rtc::Event bitrate_changed_event_;
2953 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002954 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002955
Sergey Silkin5ee69672019-07-02 14:18:34 +02002956 int num_rate_allocator_creations_;
2957 int num_encoder_initializations_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002958 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002959 webrtc::VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002960 test::VideoEncoderProxyFactory encoder_factory_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002961 std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002962 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002963 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002964
stefane74eef12016-01-08 06:47:13 -08002965 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002966}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002967
Sebastian Jansson63470292019-02-01 10:13:43 +01002968TEST_F(VideoSendStreamTest, ReportsSentResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002969 static const size_t kNumStreams = 3;
2970 // Unusual resolutions to make sure that they are the ones being reported.
2971 static const struct {
2972 int width;
2973 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02002974 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002975 class ScreencastTargetBitrateTest : public test::SendTest,
2976 public test::FakeEncoder {
2977 public:
2978 ScreencastTargetBitrateTest()
2979 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002980 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02002981 send_stream_(nullptr),
2982 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002983
2984 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002985 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01002986 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002987 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002988 specifics.codecType = kVideoCodecGeneric;
2989
2990 uint8_t buffer[16] = {0};
2991 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
Niels Möller23775882018-08-16 10:24:12 +02002992 encoded.SetTimestamp(input_image.timestamp());
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002993 encoded.capture_time_ms_ = input_image.render_time_ms();
2994
2995 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002996 encoded._frameType = (*frame_types)[i];
2997 encoded._encodedWidth = kEncodedResolution[i].width;
2998 encoded._encodedHeight = kEncodedResolution[i].height;
Niels Möllerd3b8c632018-08-27 15:33:42 +02002999 encoded.SetSpatialIndex(i);
brandtre78d2662017-01-16 05:57:16 -08003000 EncodedImageCallback* callback;
3001 {
3002 rtc::CritScope cs(&crit_sect_);
3003 callback = callback_;
3004 }
3005 RTC_DCHECK(callback);
3006 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003007 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003008 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003009 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003010 }
3011
Peter Boström5811a392015-12-10 13:02:50 +01003012 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003013 return 0;
3014 }
stefanff483612015-12-21 03:14:00 -08003015 void ModifyVideoConfigs(
3016 VideoSendStream::Config* send_config,
3017 std::vector<VideoReceiveStream::Config>* receive_configs,
3018 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003019 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003020 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003021 }
3022
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003023 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003024
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003025 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003026 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003027 << "Timed out while waiting for the encoder to send one frame.";
3028 VideoSendStream::Stats stats = send_stream_->GetStats();
3029
3030 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003031 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003032 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003033 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003034 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003035 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003036 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003037 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3038 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003039 }
3040 }
3041
stefanff483612015-12-21 03:14:00 -08003042 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003043 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003044 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003045 send_stream_ = send_stream;
3046 }
3047
3048 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003049 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003050 } test;
3051
stefane74eef12016-01-08 06:47:13 -08003052 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003053}
philipel0f9af012015-09-01 07:01:51 -07003054
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003055#if defined(RTC_ENABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003056class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003057 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003058 Vp9HeaderObserver()
3059 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003060 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003061 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3062 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003063 frames_sent_(0),
3064 expected_width_(0),
3065 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003066
stefanff483612015-12-21 03:14:00 -08003067 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003068 VideoSendStream::Config* send_config,
3069 std::vector<VideoReceiveStream::Config>* receive_configs,
3070 VideoEncoderConfig* encoder_config) {}
3071
Åsa Perssonff24c042015-12-04 10:58:08 +01003072 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003073
3074 private:
minyue20c84cc2017-04-10 16:57:57 -07003075 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003076
stefanff483612015-12-21 03:14:00 -08003077 void ModifyVideoConfigs(
3078 VideoSendStream::Config* send_config,
3079 std::vector<VideoReceiveStream::Config>* receive_configs,
3080 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003081 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003082 send_config->rtp.payload_name = "VP9";
3083 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003084 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003085 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003086 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003087 EXPECT_EQ(1u, encoder_config->number_of_streams);
Åsa Perssond34597c2018-10-22 17:34:02 +02003088 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
3089 encoder_config->simulcast_layers[0].num_temporal_layers =
3090 vp9_settings_.numberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07003091 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003092 }
3093
perkjfa10b552016-10-02 23:45:26 -07003094 void ModifyVideoCaptureStartResolution(int* width,
3095 int* height,
3096 int* frame_rate) override {
3097 expected_width_ = *width;
3098 expected_height_ = *height;
3099 }
3100
philipel0f9af012015-09-01 07:01:51 -07003101 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003102 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3103 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003104 }
3105
3106 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3107 RTPHeader header;
3108 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3109
Åsa Perssonff24c042015-12-04 10:58:08 +01003110 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3111 const uint8_t* payload = packet + header.headerLength;
3112 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003113
Åsa Perssonff24c042015-12-04 10:58:08 +01003114 bool new_packet = packets_sent_ == 0 ||
3115 IsNewerSequenceNumber(header.sequenceNumber,
3116 last_header_.sequenceNumber);
3117 if (payload_length > 0 && new_packet) {
3118 RtpDepacketizer::ParsedPayload parsed;
3119 RtpDepacketizerVp9 depacketizer;
3120 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003121 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003122 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003123 const auto& vp9_header =
3124 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3125 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003126 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003127 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003128 InspectHeader(vp9_header);
philipel0f9af012015-09-01 07:01:51 -07003129
Åsa Perssonff24c042015-12-04 10:58:08 +01003130 ++packets_sent_;
3131 if (header.markerBit) {
3132 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003133 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003134 last_header_ = header;
philipel29d88462018-08-08 14:26:00 +02003135 last_vp9_ = vp9_header;
philipel0f9af012015-09-01 07:01:51 -07003136 }
philipel0f9af012015-09-01 07:01:51 -07003137 return SEND_PACKET;
3138 }
3139
philipel7fabd462015-09-03 04:42:32 -07003140 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003141 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3142 if (last_vp9_.picture_id > vp9.picture_id) {
3143 return vp9.picture_id == 0; // Wrap.
3144 } else {
3145 return vp9.picture_id == last_vp9_.picture_id + 1;
3146 }
3147 }
3148
3149 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003150 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3151 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3152 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3153 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3154 vp9.spatial_idx);
3155 }
3156
3157 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3158 uint8_t num_layers) const {
3159 switch (num_layers) {
3160 case 0:
3161 VerifyTemporalLayerStructure0(vp9);
3162 break;
3163 case 1:
3164 VerifyTemporalLayerStructure1(vp9);
3165 break;
3166 case 2:
3167 VerifyTemporalLayerStructure2(vp9);
3168 break;
3169 case 3:
3170 VerifyTemporalLayerStructure3(vp9);
3171 break;
3172 default:
3173 RTC_NOTREACHED();
3174 }
3175 }
3176
3177 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3178 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3179 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3180 EXPECT_FALSE(vp9.temporal_up_switch);
3181 }
3182
3183 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3184 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3185 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3186 EXPECT_FALSE(vp9.temporal_up_switch);
3187 }
3188
3189 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3190 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3191 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3192 EXPECT_LE(vp9.temporal_idx, 1);
3193 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3194 if (IsNewPictureId(vp9)) {
3195 uint8_t expected_tid =
3196 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3197 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3198 }
3199 }
3200
3201 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3202 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3203 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3204 EXPECT_LE(vp9.temporal_idx, 2);
3205 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3206 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3207 switch (vp9.temporal_idx) {
3208 case 0:
3209 EXPECT_EQ(2, last_vp9_.temporal_idx);
3210 EXPECT_FALSE(vp9.temporal_up_switch);
3211 break;
3212 case 1:
3213 EXPECT_EQ(2, last_vp9_.temporal_idx);
3214 EXPECT_TRUE(vp9.temporal_up_switch);
3215 break;
3216 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003217 EXPECT_LT(last_vp9_.temporal_idx, 2);
3218 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003219 break;
3220 }
3221 }
3222 }
3223
3224 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3225 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3226 return;
3227
3228 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3229 if (vp9.temporal_idx == 0)
3230 ++expected_tl0_idx;
3231 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3232 }
3233
3234 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3235 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3236 }
3237
3238 // Flexible mode (F=1): Non-flexible mode (F=0):
3239 //
3240 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3241 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3242 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3243 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3244 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3245 // M: | EXTENDED PID | M: | EXTENDED PID |
3246 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3247 // L: | T |U| S |D| L: | T |U| S |D|
3248 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3249 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3250 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3251 // X: |EXTENDED P_DIFF| V: | SS .. |
3252 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3253 // V: | SS .. |
3254 // +-+-+-+-+-+-+-+-+
3255 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3256 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3257 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3258 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003259
3260 if (vp9_settings_.numberOfSpatialLayers > 1) {
3261 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3262 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3263 EXPECT_EQ(vp9.spatial_idx, 0);
3264 } else {
3265 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3266 }
3267
3268 if (vp9_settings_.numberOfTemporalLayers > 1) {
3269 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3270 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3271 EXPECT_EQ(vp9.temporal_idx, 0);
3272 } else {
3273 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3274 }
3275
Åsa Perssonff24c042015-12-04 10:58:08 +01003276 if (vp9.ss_data_available) // V
3277 VerifySsData(vp9);
3278
3279 if (frames_sent_ == 0)
3280 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3281
3282 if (!vp9.inter_pic_predicted) {
3283 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3284 EXPECT_FALSE(vp9.temporal_up_switch);
3285 }
3286 }
3287
3288 // Scalability structure (SS).
3289 //
3290 // +-+-+-+-+-+-+-+-+
3291 // V: | N_S |Y|G|-|-|-|
3292 // +-+-+-+-+-+-+-+-+
3293 // Y: | WIDTH | N_S + 1 times
3294 // +-+-+-+-+-+-+-+-+
3295 // | HEIGHT |
3296 // +-+-+-+-+-+-+-+-+
3297 // G: | N_G |
3298 // +-+-+-+-+-+-+-+-+
3299 // N_G: | T |U| R |-|-| N_G times
3300 // +-+-+-+-+-+-+-+-+
3301 // | P_DIFF | R times
3302 // +-+-+-+-+-+-+-+-+
3303 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3304 EXPECT_TRUE(vp9.ss_data_available); // V
3305 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3306 vp9.num_spatial_layers);
3307 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003308 int expected_width = expected_width_;
3309 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003310 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003311 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3312 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3313 expected_width /= 2;
3314 expected_height /= 2;
3315 }
3316 }
3317
3318 void CompareConsecutiveFrames(const RTPHeader& header,
3319 const RTPVideoHeader& video) const {
philipel29d88462018-08-08 14:26:00 +02003320 const auto& vp9_header =
3321 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003322
3323 bool new_frame = packets_sent_ == 0 ||
3324 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003325 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003326 if (!new_frame) {
3327 EXPECT_FALSE(last_header_.markerBit);
3328 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003329 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3330 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3331 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3332 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003333 return;
3334 }
3335 // New frame.
philipel29d88462018-08-08 14:26:00 +02003336 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003337
3338 // Compare with last packet in previous frame.
3339 if (frames_sent_ == 0)
3340 return;
3341 EXPECT_TRUE(last_vp9_.end_of_frame);
3342 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003343 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3344 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003345 }
3346
Niels Möller4db138e2018-04-19 09:04:13 +02003347 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003348 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003349 webrtc::VideoEncoderConfig encoder_config_;
3350 RTPHeader last_header_;
3351 RTPVideoHeaderVP9 last_vp9_;
3352 size_t packets_sent_;
3353 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003354 int expected_width_;
3355 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003356};
3357
Sebastian Jansson63470292019-02-01 10:13:43 +01003358TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003359 const uint8_t kNumTemporalLayers = 1;
3360 const uint8_t kNumSpatialLayers = 1;
3361 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3362}
3363
Sebastian Jansson63470292019-02-01 10:13:43 +01003364TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003365 const uint8_t kNumTemporalLayers = 2;
3366 const uint8_t kNumSpatialLayers = 1;
3367 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3368}
3369
Sebastian Jansson63470292019-02-01 10:13:43 +01003370TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003371 const uint8_t kNumTemporalLayers = 3;
3372 const uint8_t kNumSpatialLayers = 1;
3373 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3374}
3375
Sebastian Jansson63470292019-02-01 10:13:43 +01003376TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003377 const uint8_t kNumTemporalLayers = 1;
3378 const uint8_t kNumSpatialLayers = 2;
3379 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3380}
3381
Sebastian Jansson63470292019-02-01 10:13:43 +01003382TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003383 const uint8_t kNumTemporalLayers = 2;
3384 const uint8_t kNumSpatialLayers = 2;
3385 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3386}
3387
Sebastian Jansson63470292019-02-01 10:13:43 +01003388TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003389 const uint8_t kNumTemporalLayers = 3;
3390 const uint8_t kNumSpatialLayers = 2;
3391 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3392}
3393
3394void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3395 uint8_t num_spatial_layers) {
3396 static const size_t kNumFramesToSend = 100;
3397 // Set to < kNumFramesToSend and coprime to length of temporal layer
3398 // structures to verify temporal id reset on key frame.
3399 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003400
3401 static const int kWidth = kMinVp9SpatialLayerWidth;
3402 static const int kHeight = kMinVp9SpatialLayerHeight;
3403 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003404 class NonFlexibleMode : public Vp9HeaderObserver {
3405 public:
3406 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3407 : num_temporal_layers_(num_temporal_layers),
3408 num_spatial_layers_(num_spatial_layers),
3409 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003410
stefanff483612015-12-21 03:14:00 -08003411 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003412 VideoSendStream::Config* send_config,
3413 std::vector<VideoReceiveStream::Config>* receive_configs,
3414 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003415 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003416 int bitrate_bps = 0;
3417 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3418 const int width = kWidth << sl_idx;
3419 const int height = kHeight << sl_idx;
3420 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3421 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3422 }
3423 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3424
Åsa Perssonff24c042015-12-04 10:58:08 +01003425 vp9_settings_.flexibleMode = false;
3426 vp9_settings_.frameDroppingOn = false;
3427 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3428 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3429 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003430 }
3431
Sergey Silkin86684962018-03-28 19:32:37 +02003432 void ModifyVideoCaptureStartResolution(int* width,
3433 int* height,
3434 int* frame_rate) override {
3435 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3436 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3437 *width = expected_width_;
3438 *height = expected_height_;
3439 }
3440
Åsa Perssonff24c042015-12-04 10:58:08 +01003441 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003442 bool ss_data_expected =
3443 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3444 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003445 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003446 if (num_spatial_layers_ > 1) {
3447 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3448 } else {
3449 EXPECT_FALSE(vp9.inter_layer_predicted);
3450 }
3451
asapersson38bb8ad2015-12-14 01:41:19 -08003452 EXPECT_EQ(!vp9.inter_pic_predicted,
3453 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003454
3455 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003456 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3457 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3458 } else {
3459 EXPECT_EQ(0, vp9.spatial_idx);
3460 }
3461 if (num_spatial_layers_ > 1)
3462 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003463 }
3464
3465 VerifyFixedTemporalLayerStructure(vp9,
3466 l_field_ ? num_temporal_layers_ : 0);
3467
3468 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003469 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003470 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003471 const uint8_t num_temporal_layers_;
3472 const uint8_t num_spatial_layers_;
3473 const bool l_field_;
3474 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003475
stefane74eef12016-01-08 06:47:13 -08003476 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003477}
3478
Sebastian Jansson63470292019-02-01 10:13:43 +01003479TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
asaperssond9f641e2016-01-21 01:11:35 -08003480 static const size_t kNumFramesToSend = 50;
3481 static const int kWidth = 4;
3482 static const int kHeight = 4;
3483 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3484 void ModifyVideoConfigsHook(
3485 VideoSendStream::Config* send_config,
3486 std::vector<VideoReceiveStream::Config>* receive_configs,
3487 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003488 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003489 vp9_settings_.flexibleMode = false;
3490 vp9_settings_.numberOfTemporalLayers = 1;
3491 vp9_settings_.numberOfSpatialLayers = 1;
3492
perkjfa10b552016-10-02 23:45:26 -07003493 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003494 }
3495
3496 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3497 if (frames_sent_ > kNumFramesToSend)
3498 observation_complete_.Set();
3499 }
perkjfa10b552016-10-02 23:45:26 -07003500
3501 void ModifyVideoCaptureStartResolution(int* width,
3502 int* height,
3503 int* frame_rate) override {
3504 expected_width_ = kWidth;
3505 expected_height_ = kHeight;
3506 *width = kWidth;
3507 *height = kHeight;
3508 }
asaperssond9f641e2016-01-21 01:11:35 -08003509 } test;
3510
3511 RunBaseTest(&test);
3512}
3513
kjellanderf9e2a362017-03-24 12:17:33 -07003514#if defined(WEBRTC_ANDROID)
3515// Crashes on Android; bugs.webrtc.org/7401
3516#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3517#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003518// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3519// the test after webrtc:9270 is implemented.
3520#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3521// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003522#endif
Sebastian Jansson63470292019-02-01 10:13:43 +01003523TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003524 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003525 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003526 VideoSendStream::Config* send_config,
3527 std::vector<VideoReceiveStream::Config>* receive_configs,
3528 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003529 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003530 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003531 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003532 vp9_settings_.numberOfTemporalLayers = 1;
3533 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003534 }
3535
Åsa Perssonff24c042015-12-04 10:58:08 +01003536 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3537 EXPECT_TRUE(vp9_header.flexible_mode);
3538 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3539 if (vp9_header.inter_pic_predicted) {
3540 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003541 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003542 }
3543 }
3544 } test;
3545
stefane74eef12016-01-08 06:47:13 -08003546 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003547}
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003548#endif // defined(RTC_ENABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003549
perkj803d97f2016-11-01 11:45:46 -07003550void VideoSendStreamTest::TestRequestSourceRotateVideo(
3551 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003552 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003553
3554 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003555 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003556 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003557 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003558 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003559 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3560 }
3561
3562 CreateVideoStreams();
3563 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003564 GetVideoSendStream()->SetSource(&forwarder,
3565 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003566
3567 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3568 support_orientation_ext);
3569
3570 DestroyStreams();
3571}
3572
Sebastian Jansson63470292019-02-01 10:13:43 +01003573TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003574 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3575 TestRequestSourceRotateVideo(false);
3576}
3577
Sebastian Jansson63470292019-02-01 10:13:43 +01003578TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003579 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3580 TestRequestSourceRotateVideo(true);
3581}
3582
Sebastian Jansson63470292019-02-01 10:13:43 +01003583TEST_F(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) {
Åsa Perssonf06bacc2018-10-12 11:07:20 +02003584 static const int kMaxFps = 22;
3585 class FpsObserver : public test::SendTest,
3586 public test::FrameGeneratorCapturer::SinkWantsObserver {
3587 public:
3588 FpsObserver() : SendTest(kDefaultTimeoutMs) {}
3589
3590 void OnFrameGeneratorCapturerCreated(
3591 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3592 frame_generator_capturer->SetSinkWantsObserver(this);
3593 }
3594
3595 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
3596 const rtc::VideoSinkWants& wants) override {
3597 if (wants.max_framerate_fps == kMaxFps)
3598 observation_complete_.Set();
3599 }
3600
3601 void ModifyVideoConfigs(
3602 VideoSendStream::Config* send_config,
3603 std::vector<VideoReceiveStream::Config>* receive_configs,
3604 VideoEncoderConfig* encoder_config) override {
3605 encoder_config->simulcast_layers[0].max_framerate = kMaxFps;
3606 }
3607
3608 void PerformTest() override {
3609 EXPECT_TRUE(Wait()) << "Timed out while waiting for fps to be reported.";
3610 }
3611 } test;
3612
3613 RunBaseTest(&test);
3614}
3615
michaelta3328772016-11-29 09:25:03 -08003616// This test verifies that overhead is removed from the bandwidth estimate by
3617// testing that the maximum possible target payload rate is smaller than the
3618// maximum bandwidth estimate by the overhead rate.
Sebastian Jansson63470292019-02-01 10:13:43 +01003619TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003620 test::ScopedFieldTrials override_field_trials(
3621 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3622 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3623 public test::FakeEncoder {
3624 public:
eladalon413ee9a2017-08-22 04:02:52 -07003625 explicit RemoveOverheadFromBandwidthTest(
3626 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003627 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3628 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003629 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003630 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003631 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003632 max_bitrate_bps_(0),
Niels Möllerc572ff32018-11-07 08:43:50 +01003633 first_packet_sent_(false) {}
michaelta3328772016-11-29 09:25:03 -08003634
Erik Språng16cb8f52019-04-12 13:59:09 +02003635 void SetRates(const RateControlParameters& parameters) override {
michaelta3328772016-11-29 09:25:03 -08003636 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003637 // Wait for the first sent packet so that videosendstream knows
3638 // rtp_overhead.
3639 if (first_packet_sent_) {
Erik Språng16cb8f52019-04-12 13:59:09 +02003640 max_bitrate_bps_ = parameters.bitrate.get_sum_bps();
michaelt192132e2017-01-26 09:05:27 -08003641 bitrate_changed_event_.Set();
3642 }
Erik Språng16cb8f52019-04-12 13:59:09 +02003643 return FakeEncoder::SetRates(parameters);
michaelta3328772016-11-29 09:25:03 -08003644 }
3645
3646 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3647 call_ = sender_call;
3648 }
3649
3650 void ModifyVideoConfigs(
3651 VideoSendStream::Config* send_config,
3652 std::vector<VideoReceiveStream::Config>* receive_configs,
3653 VideoEncoderConfig* encoder_config) override {
3654 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003655 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003656 EXPECT_FALSE(send_config->rtp.extensions.empty());
3657 }
3658
michaelt192132e2017-01-26 09:05:27 -08003659 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3660 rtc::CritScope lock(&crit_);
3661 first_packet_sent_ = true;
3662 return SEND_PACKET;
3663 }
3664
michaelta3328772016-11-29 09:25:03 -08003665 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003666 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003667 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003668 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003669 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003670 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3671 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003672 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003673 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003674 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3675 bitrate_config);
Stefan Holmer64be7fa2018-10-04 15:21:55 +02003676 call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
eladalon413ee9a2017-08-22 04:02:52 -07003677 });
michaelta3328772016-11-29 09:25:03 -08003678
3679 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003680 // overhead of 40B per packet video produces 2240bps overhead.
3681 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003682 EXPECT_TRUE(
3683 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003684 {
3685 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003686 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003687 }
3688 }
3689
3690 private:
eladalon413ee9a2017-08-22 04:02:52 -07003691 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003692 test::VideoEncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003693 Call* call_;
3694 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003695 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3696 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003697 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003698 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003699 RunBaseTest(&test);
3700}
3701
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003702class PacingFactorObserver : public test::SendTest {
3703 public:
3704 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003705 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003706 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3707 configure_send_side_(configure_send_side),
3708 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003709
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003710 void ModifyVideoConfigs(
3711 VideoSendStream::Config* send_config,
3712 std::vector<VideoReceiveStream::Config>* receive_configs,
3713 VideoEncoderConfig* encoder_config) override {
3714 // Check if send-side bwe extension is already present, and remove it if
3715 // it is not desired.
3716 bool has_send_side = false;
3717 for (auto it = send_config->rtp.extensions.begin();
3718 it != send_config->rtp.extensions.end(); ++it) {
3719 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3720 if (configure_send_side_) {
3721 has_send_side = true;
3722 } else {
3723 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003724 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003725 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003726 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003727 }
3728
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003729 if (configure_send_side_ && !has_send_side) {
Elad Alon157540a2019-02-08 23:37:52 +01003730 rtc::UniqueNumberGenerator<int> unique_id_generator;
3731 unique_id_generator.AddKnownId(0); // First valid RTP extension ID is 1.
3732 for (const RtpExtension& extension : send_config->rtp.extensions) {
3733 unique_id_generator.AddKnownId(extension.id);
3734 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003735 // Want send side, not present by default, so add it.
3736 send_config->rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +01003737 RtpExtension::kTransportSequenceNumberUri, unique_id_generator());
Erik Språng7c8cca32017-10-24 17:05:18 +02003738 }
3739
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003740 // ALR only enabled for screenshare.
3741 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3742 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003743
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003744 void OnVideoStreamsCreated(
3745 VideoSendStream* send_stream,
3746 const std::vector<VideoReceiveStream*>& receive_streams) override {
3747 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3748 // Video streams created, check that pacing factor is correctly configured.
3749 EXPECT_EQ(expected_pacing_factor_,
3750 internal_send_peer.GetPacingFactorOverride());
3751 observation_complete_.Set();
3752 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003753
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003754 void PerformTest() override {
3755 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3756 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003757
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003758 private:
3759 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003760 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003761};
3762
3763std::string GetAlrProbingExperimentString() {
3764 return std::string(
3765 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3766 "/1.0,2875,80,40,-60,3/";
3767}
3768const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3769
Sebastian Jansson63470292019-02-01 10:13:43 +01003770TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003771 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003772 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003773 PacingFactorObserver test_with_send_side(true,
3774 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003775 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003776}
Erik Språng7c8cca32017-10-24 17:05:18 +02003777
Sebastian Jansson63470292019-02-01 10:13:43 +01003778TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003779 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3780 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003781 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003782 RunBaseTest(&test_without_send_side);
3783}
3784
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003785// Test class takes as argument a function pointer to reset the send
3786// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3787// change the content type of a VideoSendStream, you need to recreate it.
3788// Stopping and recreating the stream can only be done on the main thread and in
3789// the context of VideoSendStreamTest (not BaseTest). The test switches from
3790// realtime to screenshare and back.
3791template <typename T>
3792class ContentSwitchTest : public test::SendTest {
3793 public:
3794 enum class StreamState {
3795 kBeforeSwitch = 0,
3796 kInScreenshare = 1,
3797 kAfterSwitchBack = 2,
3798 };
3799 static const uint32_t kMinPacketsToSend = 50;
3800
3801 explicit ContentSwitchTest(T* stream_reset_fun)
3802 : SendTest(test::CallTest::kDefaultTimeoutMs),
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003803 call_(nullptr),
3804 state_(StreamState::kBeforeSwitch),
3805 send_stream_(nullptr),
3806 send_stream_config_(nullptr),
3807 packets_sent_(0),
3808 stream_resetter_(stream_reset_fun) {
3809 RTC_DCHECK(stream_resetter_);
3810 }
3811
3812 void OnVideoStreamsCreated(
3813 VideoSendStream* send_stream,
3814 const std::vector<VideoReceiveStream*>& receive_streams) override {
3815 rtc::CritScope lock(&crit_);
3816 send_stream_ = send_stream;
3817 }
3818
3819 void ModifyVideoConfigs(
3820 VideoSendStream::Config* send_config,
3821 std::vector<VideoReceiveStream::Config>* receive_configs,
3822 VideoEncoderConfig* encoder_config) override {
3823 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3824 encoder_config->min_transmit_bitrate_bps = 0;
3825 encoder_config->content_type =
3826 VideoEncoderConfig::ContentType::kRealtimeVideo;
3827 send_stream_config_ = send_config->Copy();
3828 encoder_config_ = encoder_config->Copy();
3829 }
3830
3831 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3832 call_ = sender_call;
3833 }
3834
3835 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3836 rtc::CritScope lock(&crit_);
3837
3838 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3839 float pacing_factor =
3840 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3841 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3842 if (send_stream_->GetStats().content_type ==
3843 webrtc::VideoContentType::SCREENSHARE) {
3844 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3845 }
3846
3847 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3848
3849 // Wait until at least kMinPacketsToSend packets to be sent, so that
3850 // some frames would be encoded.
3851 if (++packets_sent_ < kMinPacketsToSend)
3852 return SEND_PACKET;
3853
3854 if (state_ != StreamState::kAfterSwitchBack) {
3855 // We've sent kMinPacketsToSend packets, switch the content type and move
3856 // move to the next state.
3857 // Note that we need to recreate the stream if changing content type.
3858 packets_sent_ = 0;
3859 if (encoder_config_.content_type ==
3860 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3861 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3862 } else {
3863 encoder_config_.content_type =
3864 VideoEncoderConfig::ContentType::kRealtimeVideo;
3865 }
3866 switch (state_) {
3867 case StreamState::kBeforeSwitch:
3868 state_ = StreamState::kInScreenshare;
3869 break;
3870 case StreamState::kInScreenshare:
3871 state_ = StreamState::kAfterSwitchBack;
3872 break;
3873 case StreamState::kAfterSwitchBack:
3874 RTC_NOTREACHED();
3875 break;
3876 }
3877 content_switch_event_.Set();
3878 return SEND_PACKET;
3879 }
3880
3881 observation_complete_.Set();
3882 return SEND_PACKET;
3883 }
3884
3885 void PerformTest() override {
3886 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3887 ASSERT_TRUE(
3888 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3889 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3890 }
3891
3892 ASSERT_TRUE(Wait())
3893 << "Timed out waiting for a frame sent after switch back";
3894 }
3895
3896 private:
3897 StreamState GetStreamState() {
3898 rtc::CritScope lock(&crit_);
3899 return state_;
3900 }
3901
3902 rtc::CriticalSection crit_;
3903 rtc::Event content_switch_event_;
3904 Call* call_;
3905 StreamState state_ RTC_GUARDED_BY(crit_);
3906 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3907 VideoSendStream::Config send_stream_config_;
3908 VideoEncoderConfig encoder_config_;
3909 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3910 T* stream_resetter_;
3911};
3912
Sebastian Jansson63470292019-02-01 10:13:43 +01003913TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003914 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3915 const VideoEncoderConfig& encoder_config,
3916 test::BaseTest* test) {
3917 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3918 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003919 DestroyVideoSendStreams();
3920 SetVideoSendConfig(send_stream_config);
3921 SetVideoEncoderConfig(encoder_config);
3922 CreateVideoSendStreams();
3923 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3924 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003925 Start();
3926 });
3927 };
3928 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3929 RunBaseTest(&test);
3930}
3931
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003932} // namespace webrtc