blob: 0d51cbd00701603c609579383e247e6bf9824cf4 [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"
Danil Chapovalov22ed3662019-03-19 19:39:49 +010015#include "api/task_queue/default_task_queue_factory.h"
Danil Chapovalov44db4362019-09-30 04:16:28 +020016#include "api/task_queue/task_queue_base.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"
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +020040#include "rtc_base/task_queue_for_test.h"
Danil Chapovalov85a10002019-10-21 15:00:53 +020041#include "rtc_base/task_utils/to_queued_task.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "rtc_base/time_utils.h"
Elad Alon157540a2019-02-08 23:37:52 +010043#include "rtc_base/unique_id_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020044#include "system_wrappers/include/sleep.h"
45#include "test/call_test.h"
46#include "test/configurable_frame_size_encoder.h"
Niels Möller4db138e2018-04-19 09:04:13 +020047#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020048#include "test/fake_texture_frame.h"
49#include "test/field_trial.h"
50#include "test/frame_generator.h"
51#include "test/frame_generator_capturer.h"
52#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010053#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020054#include "test/gtest.h"
55#include "test/null_transport.h"
56#include "test/rtcp_packet_parser.h"
Tommi25eb47c2019-08-29 16:39:05 +020057#include "test/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "test/testsupport/perf_test.h"
Niels Möllercbcbc222018-09-28 09:07:24 +020059#include "test/video_encoder_proxy_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020060#include "video/send_statistics_proxy.h"
61#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010062#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000063
64namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010065namespace test {
66class VideoSendStreamPeer {
67 public:
68 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
69 : internal_stream_(
70 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020071 absl::optional<float> GetPacingFactorOverride() const {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010072 return internal_stream_->GetPacingFactorOverride();
73 }
74
75 private:
76 internal::VideoSendStream const* const internal_stream_;
77};
78} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000079
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080080namespace {
Elad Alond8d32482019-02-18 23:45:57 +010081enum : int { // The first valid value is 1.
82 kAbsSendTimeExtensionId = 1,
83 kTimestampOffsetExtensionId,
84 kTransportSequenceNumberExtensionId,
85 kVideoContentTypeExtensionId,
86 kVideoRotationExtensionId,
87 kVideoTimingExtensionId,
88};
89
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080090constexpr int64_t kRtcpIntervalMs = 1000;
91
Yves Gerey665174f2018-06-19 15:03:05 +020092enum VideoFormat {
93 kGeneric,
94 kVP8,
95};
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080096} // namespace
sprang@webrtc.org346094c2014-02-18 08:40:33 +000097
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070098VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000099
Sebastian Jansson63470292019-02-01 10:13:43 +0100100class VideoSendStreamTest : public test::CallTest {
Elad Alond8d32482019-02-18 23:45:57 +0100101 public:
102 VideoSendStreamTest() {
103 RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
104 kTransportSequenceNumberExtensionId));
105 }
106
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000107 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000108 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000109 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000110 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +0100111
112 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
113 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -0700114
115 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000116};
117
Sebastian Jansson63470292019-02-01 10:13:43 +0100118TEST_F(VideoSendStreamTest, CanStartStartedStream) {
Danil Chapovalovd15a0282019-10-22 10:48:17 +0200119 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200120 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000121
eladalon413ee9a2017-08-22 04:02:52 -0700122 test::NullTransport transport;
123 CreateSendConfig(1, 0, 0, &transport);
124 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200125 GetVideoSendStream()->Start();
126 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700127 DestroyStreams();
128 DestroyCalls();
129 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000130}
131
Sebastian Jansson63470292019-02-01 10:13:43 +0100132TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
Danil Chapovalovd15a0282019-10-22 10:48:17 +0200133 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200134 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000135
eladalon413ee9a2017-08-22 04:02:52 -0700136 test::NullTransport transport;
137 CreateSendConfig(1, 0, 0, &transport);
138 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200139 GetVideoSendStream()->Stop();
140 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700141 DestroyStreams();
142 DestroyCalls();
143 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000144}
145
Sebastian Jansson63470292019-02-01 10:13:43 +0100146TEST_F(VideoSendStreamTest, SupportsCName) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000147 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000148 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000149 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000150 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000151
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000152 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000153 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700154 test::RtcpPacketParser parser;
155 EXPECT_TRUE(parser.Parse(packet, length));
156 if (parser.sdes()->num_packets() > 0) {
157 EXPECT_EQ(1u, parser.sdes()->chunks().size());
158 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000159
danilchap3dc929e2016-11-02 08:21:59 -0700160 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000161 }
162
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000163 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000164 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000165
stefanff483612015-12-21 03:14:00 -0800166 void ModifyVideoConfigs(
167 VideoSendStream::Config* send_config,
168 std::vector<VideoReceiveStream::Config>* receive_configs,
169 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000170 send_config->rtp.c_name = kCName;
171 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000172
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000173 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100174 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000175 }
176 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000177
stefane74eef12016-01-08 06:47:13 -0800178 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000179}
180
Sebastian Jansson63470292019-02-01 10:13:43 +0100181TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000182 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000183 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000184 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000185 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100186 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000187 }
188
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000189 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000190 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000191 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000192
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000193 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
194 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
195 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700196 if (header.extension.absoluteSendTime != 0) {
197 // Wait for at least one packet with a non-zero send time. The send time
198 // is a 16-bit value derived from the system clock, and it is valid
199 // for a packet to have a zero send time. To tell that from an
200 // unpopulated value we'll wait for a packet with non-zero send time.
201 observation_complete_.Set();
202 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100203 RTC_LOG(LS_WARNING)
204 << "Got a packet with zero absoluteSendTime, waiting"
205 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700206 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000207
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000208 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000209 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000210
stefanff483612015-12-21 03:14:00 -0800211 void ModifyVideoConfigs(
212 VideoSendStream::Config* send_config,
213 std::vector<VideoReceiveStream::Config>* receive_configs,
214 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200215 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100216 send_config->rtp.extensions.push_back(
217 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000218 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000219
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000220 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100221 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000222 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000223 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000224
stefane74eef12016-01-08 06:47:13 -0800225 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000226}
227
Sebastian Jansson63470292019-02-01 10:13:43 +0100228TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000229 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000230 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000231 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000232 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200233 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200234 return std::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200235 Clock::GetRealTimeClock(), kEncodeDelayMs);
236 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000237 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100238 kRtpExtensionTransmissionTimeOffset, kTimestampOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000239 }
240
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000241 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000242 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000243 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000244 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000245
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000246 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
247 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000248 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000249 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100250 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000251
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000252 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000253 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000254
stefanff483612015-12-21 03:14:00 -0800255 void ModifyVideoConfigs(
256 VideoSendStream::Config* send_config,
257 std::vector<VideoReceiveStream::Config>* receive_configs,
258 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200259 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100260 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700261 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100262 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000263 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000264
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000265 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100266 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000267 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000268
Niels Möller4db138e2018-04-19 09:04:13 +0200269 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000270 } test;
271
stefane74eef12016-01-08 06:47:13 -0800272 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000273}
274
Sebastian Jansson63470292019-02-01 10:13:43 +0100275TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
Elad Alond8d32482019-02-18 23:45:57 +0100276 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700277 class TransportWideSequenceNumberObserver : public test::SendTest {
278 public:
279 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200280 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200281 return std::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200282 Clock::GetRealTimeClock());
283 }) {
sprang867fb522015-08-03 04:38:41 -0700284 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
285 kRtpExtensionTransportSequenceNumber, kExtensionId));
286 }
287
288 private:
289 Action OnSendRtp(const uint8_t* packet, size_t length) override {
290 RTPHeader header;
291 EXPECT_TRUE(parser_->Parse(packet, length, &header));
292
293 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
294 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
295 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
296
Peter Boström5811a392015-12-10 13:02:50 +0100297 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700298
299 return SEND_PACKET;
300 }
301
stefanff483612015-12-21 03:14:00 -0800302 void ModifyVideoConfigs(
303 VideoSendStream::Config* send_config,
304 std::vector<VideoReceiveStream::Config>* receive_configs,
305 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200306 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700307 }
308
309 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100310 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700311 }
312
Niels Möller4db138e2018-04-19 09:04:13 +0200313 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700314 } test;
315
stefane74eef12016-01-08 06:47:13 -0800316 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700317}
318
Sebastian Jansson63470292019-02-01 10:13:43 +0100319TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
perkj803d97f2016-11-01 11:45:46 -0700320 class VideoRotationObserver : public test::SendTest {
321 public:
322 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
323 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100324 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700325 }
326
327 Action OnSendRtp(const uint8_t* packet, size_t length) override {
328 RTPHeader header;
329 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700330 // Only the last packet of the frame is required to have the extension.
331 if (!header.markerBit)
332 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700333 EXPECT_TRUE(header.extension.hasVideoRotation);
334 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
335 observation_complete_.Set();
336 return SEND_PACKET;
337 }
338
339 void ModifyVideoConfigs(
340 VideoSendStream::Config* send_config,
341 std::vector<VideoReceiveStream::Config>* receive_configs,
342 VideoEncoderConfig* encoder_config) override {
343 send_config->rtp.extensions.clear();
344 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100345 RtpExtension::kVideoRotationUri, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700346 }
347
348 void OnFrameGeneratorCapturerCreated(
349 test::FrameGeneratorCapturer* frame_generator_capturer) override {
350 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
351 }
352
353 void PerformTest() override {
354 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
355 }
356 } test;
357
358 RunBaseTest(&test);
359}
360
Sebastian Jansson63470292019-02-01 10:13:43 +0100361TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700362 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700363 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100364 VideoContentTypeObserver()
365 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700366 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100367 kRtpExtensionVideoContentType, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700368 }
369
370 Action OnSendRtp(const uint8_t* packet, size_t length) override {
371 RTPHeader header;
372 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100373 // Only the last packet of the key-frame must have extension.
374 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700375 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100376 // First marker bit seen means that the first frame is sent.
377 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700378 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700379 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
380 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700381 observation_complete_.Set();
382 return SEND_PACKET;
383 }
384
385 void ModifyVideoConfigs(
386 VideoSendStream::Config* send_config,
387 std::vector<VideoReceiveStream::Config>* receive_configs,
388 VideoEncoderConfig* encoder_config) override {
389 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100390 send_config->rtp.extensions.push_back(RtpExtension(
391 RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700392 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
393 }
394
395 void PerformTest() override {
396 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
397 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100398
399 private:
400 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700401 } test;
402
403 RunBaseTest(&test);
404}
405
Sebastian Jansson63470292019-02-01 10:13:43 +0100406TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700407 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700408 public:
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100409 VideoTimingObserver()
410 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
Elad Alond8d32482019-02-18 23:45:57 +0100411 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
412 kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700413 }
414
415 Action OnSendRtp(const uint8_t* packet, size_t length) override {
416 RTPHeader header;
417 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700418 // Only the last packet of the frame must have extension.
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100419 // Also don't check packets of the second frame if they happen to get
420 // through before the test terminates.
421 if (!header.markerBit || first_frame_sent_)
ilnik10894992017-06-21 08:23:19 -0700422 return SEND_PACKET;
423 EXPECT_TRUE(header.extension.has_video_timing);
424 observation_complete_.Set();
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100425 first_frame_sent_ = true;
ilnik04f4d122017-06-19 07:18:55 -0700426 return SEND_PACKET;
427 }
428
429 void ModifyVideoConfigs(
430 VideoSendStream::Config* send_config,
431 std::vector<VideoReceiveStream::Config>* receive_configs,
432 VideoEncoderConfig* encoder_config) override {
433 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100434 send_config->rtp.extensions.push_back(
435 RtpExtension(RtpExtension::kVideoTimingUri, kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700436 }
437
438 void PerformTest() override {
439 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
440 }
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100441
442 private:
443 bool first_frame_sent_;
ilnik04f4d122017-06-19 07:18:55 -0700444 } test;
445
446 RunBaseTest(&test);
447}
448
danilchap901b2df2017-07-28 08:56:04 -0700449class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000450 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000451 FakeReceiveStatistics(uint32_t send_ssrc,
452 uint32_t last_sequence_number,
453 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700454 uint8_t fraction_lost) {
455 stat_.SetMediaSsrc(send_ssrc);
456 stat_.SetExtHighestSeqNum(last_sequence_number);
457 stat_.SetCumulativeLost(cumulative_lost);
458 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000459 }
460
danilchap901b2df2017-07-28 08:56:04 -0700461 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
462 EXPECT_GE(max_blocks, 1u);
463 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000464 }
465
466 private:
danilchap901b2df2017-07-28 08:56:04 -0700467 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000468};
469
brandtre602f0a2016-10-31 03:40:49 -0700470class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100471 public:
Danil Chapovalov65feec52019-08-14 18:58:17 +0200472 // Some of the test cases are expected to time out.
473 // Use a shorter timeout window than the default one for those.
474 static constexpr int kReducedTimeoutMs = 10000;
475
brandtre602f0a2016-10-31 03:40:49 -0700476 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800477 bool use_nack,
478 bool expect_red,
479 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800480 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200481 VideoEncoderFactory* encoder_factory)
Danil Chapovalov65feec52019-08-14 18:58:17 +0200482 : EndToEndTest(expect_ulpfec ? VideoSendStreamTest::kDefaultTimeoutMs
483 : kReducedTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200484 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100485 payload_name_(codec),
486 use_nack_(use_nack),
487 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700488 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800489 sent_media_(false),
490 sent_ulpfec_(false),
Elad Alond8d32482019-02-18 23:45:57 +0100491 header_extensions_enabled_(header_extensions_enabled) {
492 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
493 kAbsSendTimeExtensionId);
494 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
495 kTransportSequenceNumberExtensionId);
496 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100497
498 private:
499 Action OnSendRtp(const uint8_t* packet, size_t length) override {
500 RTPHeader header;
501 EXPECT_TRUE(parser_->Parse(packet, length, &header));
502
Stefan Holmer4654d202015-12-08 09:10:43 +0100503 int encapsulated_payload_type = -1;
504 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100505 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100506 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
507 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100508 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100509 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
510 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100511 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100512 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100513 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
514 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100515 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
516 length) {
517 // Not padding-only, media received outside of RED.
518 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800519 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100520 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100521 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000522
Stefan Holmer4654d202015-12-08 09:10:43 +0100523 if (header_extensions_enabled_) {
524 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
525 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
526 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
527 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
528 // 24 bits wrap.
529 EXPECT_GT(prev_header_.extension.absoluteSendTime,
530 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000531 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100532 EXPECT_GE(header.extension.absoluteSendTime,
533 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200534 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100535 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
536 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
537 prev_header_.extension.transportSequenceNumber;
538 EXPECT_EQ(1, seq_num_diff);
539 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200540
Stefan Holmer4654d202015-12-08 09:10:43 +0100541 if (encapsulated_payload_type != -1) {
542 if (encapsulated_payload_type ==
543 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700544 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800545 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100546 } else {
brandtr65a1e772016-12-12 01:54:58 -0800547 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000548 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000549 }
550
brandtr20d45472017-01-02 00:34:27 -0800551 if (sent_media_ && sent_ulpfec_) {
552 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100553 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000554
Stefan Holmer4654d202015-12-08 09:10:43 +0100555 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000556
Stefan Holmer4654d202015-12-08 09:10:43 +0100557 return SEND_PACKET;
558 }
559
Danil Chapovalov44db4362019-09-30 04:16:28 +0200560 std::unique_ptr<test::PacketTransport> CreateSendTransport(
561 TaskQueueBase* task_queue,
eladalon413ee9a2017-08-22 04:02:52 -0700562 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100563 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
564 // Configure some network delay.
565 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200566 BuiltInNetworkBehaviorConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800567 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100568 config.queue_delay_ms = kNetworkDelayMs;
Danil Chapovalov44db4362019-09-30 04:16:28 +0200569 return std::make_unique<test::PacketTransport>(
eladalon413ee9a2017-08-22 04:02:52 -0700570 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200571 VideoSendStreamTest::payload_type_map_,
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200572 std::make_unique<FakeNetworkPipe>(
Artem Titov4e199e92018-08-20 13:30:39 +0200573 Clock::GetRealTimeClock(),
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200574 std::make_unique<SimulatedNetwork>(config)));
Peter Boström39593972016-02-15 11:27:15 +0100575 }
576
stefanff483612015-12-21 03:14:00 -0800577 void ModifyVideoConfigs(
578 VideoSendStream::Config* send_config,
579 std::vector<VideoReceiveStream::Config>* receive_configs,
580 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100581 if (use_nack_) {
582 send_config->rtp.nack.rtp_history_ms =
583 (*receive_configs)[0].rtp.nack.rtp_history_ms =
584 VideoSendStreamTest::kNackRtpHistoryMs;
585 }
Niels Möller4db138e2018-04-19 09:04:13 +0200586 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200587 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700588 send_config->rtp.ulpfec.red_payload_type =
589 VideoSendStreamTest::kRedPayloadType;
590 send_config->rtp.ulpfec.ulpfec_payload_type =
591 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800592 if (!header_extensions_enabled_) {
593 send_config->rtp.extensions.clear();
594 } else {
Elad Alond8d32482019-02-18 23:45:57 +0100595 send_config->rtp.extensions.push_back(
596 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100597 }
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +0200598 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
Niels Möller259a4972018-04-05 15:36:51 +0200599 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700600 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700601 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700602 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700603 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100604 }
605
606 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800607 EXPECT_EQ(expect_ulpfec_, Wait())
608 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100609 }
610
Niels Möller4db138e2018-04-19 09:04:13 +0200611 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800612 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100613 const bool use_nack_;
614 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700615 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800616 bool sent_media_;
617 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100618 bool header_extensions_enabled_;
619 RTPHeader prev_header_;
620};
621
Sebastian Jansson63470292019-02-01 10:13:43 +0100622TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200623 test::FunctionVideoEncoderFactory encoder_factory(
624 []() { return VP8Encoder::Create(); });
625 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800626 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100627}
628
Sebastian Jansson63470292019-02-01 10:13:43 +0100629TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200630 test::FunctionVideoEncoderFactory encoder_factory(
631 []() { return VP8Encoder::Create(); });
632 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100633 RunBaseTest(&test);
634}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000635
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200636class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
stefan60e10c72017-08-23 10:40:00 -0700637 protected:
638 VideoSendStreamWithoutUlpfecTest()
639 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
640
641 test::ScopedFieldTrials field_trial_;
642};
643
644TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200645 test::FunctionVideoEncoderFactory encoder_factory(
646 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200647 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700648 RunBaseTest(&test);
649}
650
Peter Boström39593972016-02-15 11:27:15 +0100651// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
652// since we'll still have to re-request FEC packets, effectively wasting
653// bandwidth since the receiver has to wait for FEC retransmissions to determine
654// that the received state is actually decodable.
Sebastian Jansson63470292019-02-01 10:13:43 +0100655TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200656 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200657 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200658 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200659 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100660 RunBaseTest(&test);
661}
662
663// Without retransmissions FEC for H264 is fine.
Sebastian Jansson63470292019-02-01 10:13:43 +0100664TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200665 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200666 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200667 });
668 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100669 RunBaseTest(&test);
670}
671
Danil Chapovalov65feec52019-08-14 18:58:17 +0200672TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200673 test::FunctionVideoEncoderFactory encoder_factory(
674 []() { return VP8Encoder::Create(); });
675 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100676 RunBaseTest(&test);
677}
678
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100679#if defined(RTC_ENABLE_VP9)
Danil Chapovalov65feec52019-08-14 18:58:17 +0200680TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200681 test::FunctionVideoEncoderFactory encoder_factory(
682 []() { return VP9Encoder::Create(); });
683 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800684 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000685}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100686#endif // defined(RTC_ENABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000687
Sebastian Jansson63470292019-02-01 10:13:43 +0100688TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100689 std::unique_ptr<TaskQueueFactory> task_queue_factory =
690 CreateDefaultTaskQueueFactory();
691 test::FunctionVideoEncoderFactory encoder_factory([&]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200692 return std::make_unique<test::MultithreadedFakeH264Encoder>(
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100693 Clock::GetRealTimeClock(), task_queue_factory.get());
Niels Möller4db138e2018-04-19 09:04:13 +0200694 });
695 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800696 RunBaseTest(&test);
697}
698
brandtr39f97292016-11-16 22:57:50 -0800699// TODO(brandtr): Move these FlexFEC tests when we have created
700// FlexfecSendStream.
701class FlexfecObserver : public test::EndToEndTest {
702 public:
703 FlexfecObserver(bool header_extensions_enabled,
704 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800705 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200706 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100707 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800708 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200709 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800710 payload_name_(codec),
711 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800712 sent_media_(false),
713 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100714 header_extensions_enabled_(header_extensions_enabled),
Elad Alond8d32482019-02-18 23:45:57 +0100715 num_video_streams_(num_video_streams) {
716 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
717 kAbsSendTimeExtensionId);
718 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
719 kTimestampOffsetExtensionId);
720 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
721 kTransportSequenceNumberExtensionId);
722 }
brandtr39f97292016-11-16 22:57:50 -0800723
724 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100725 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800726
727 private:
728 Action OnSendRtp(const uint8_t* packet, size_t length) override {
729 RTPHeader header;
730 EXPECT_TRUE(parser_->Parse(packet, length, &header));
731
brandtr39f97292016-11-16 22:57:50 -0800732 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
733 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
734 sent_flexfec_ = true;
735 } else {
736 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
737 header.payloadType);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200738 EXPECT_THAT(::testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
739 num_video_streams_),
740 ::testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800741 sent_media_ = true;
742 }
743
744 if (header_extensions_enabled_) {
745 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
746 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
747 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
748 }
749
brandtr0c5a1542016-11-23 04:42:26 -0800750 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800751 observation_complete_.Set();
752 }
753
754 return SEND_PACKET;
755 }
756
Danil Chapovalov44db4362019-09-30 04:16:28 +0200757 std::unique_ptr<test::PacketTransport> CreateSendTransport(
758 TaskQueueBase* task_queue,
eladalon413ee9a2017-08-22 04:02:52 -0700759 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800760 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
761 // Therefore we need some network delay.
762 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200763 BuiltInNetworkBehaviorConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800764 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800765 config.queue_delay_ms = kNetworkDelayMs;
Danil Chapovalov44db4362019-09-30 04:16:28 +0200766 return std::make_unique<test::PacketTransport>(
eladalon413ee9a2017-08-22 04:02:52 -0700767 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200768 VideoSendStreamTest::payload_type_map_,
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200769 std::make_unique<FakeNetworkPipe>(
Artem Titov4e199e92018-08-20 13:30:39 +0200770 Clock::GetRealTimeClock(),
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200771 std::make_unique<SimulatedNetwork>(config)));
brandtr39f97292016-11-16 22:57:50 -0800772 }
773
Björn Terelius24d251f2019-10-02 00:37:36 +0200774 std::unique_ptr<test::PacketTransport> CreateReceiveTransport(
775 TaskQueueBase* task_queue) override {
776 // We need the RTT to be >200 ms to send FEC and the network delay for the
777 // send transport is 100 ms, so add 100 ms (but no loss) on the return link.
778 BuiltInNetworkBehaviorConfig config;
779 config.loss_percent = 0;
780 config.queue_delay_ms = 100;
781 return std::make_unique<test::PacketTransport>(
782 task_queue, nullptr, this, test::PacketTransport::kReceiver,
783 VideoSendStreamTest::payload_type_map_,
784 std::make_unique<FakeNetworkPipe>(
785 Clock::GetRealTimeClock(),
786 std::make_unique<SimulatedNetwork>(config)));
787 }
788
brandtr39f97292016-11-16 22:57:50 -0800789 void ModifyVideoConfigs(
790 VideoSendStream::Config* send_config,
791 std::vector<VideoReceiveStream::Config>* receive_configs,
792 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800793 if (use_nack_) {
794 send_config->rtp.nack.rtp_history_ms =
795 (*receive_configs)[0].rtp.nack.rtp_history_ms =
796 VideoSendStreamTest::kNackRtpHistoryMs;
797 }
Niels Möller4db138e2018-04-19 09:04:13 +0200798 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200799 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800800 if (header_extensions_enabled_) {
Elad Alond8d32482019-02-18 23:45:57 +0100801 send_config->rtp.extensions.push_back(
802 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
brandtr39f97292016-11-16 22:57:50 -0800803 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100804 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800805 } else {
806 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800807 }
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +0200808 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
Niels Möller259a4972018-04-05 15:36:51 +0200809 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800810 }
811
812 void PerformTest() override {
813 EXPECT_TRUE(Wait())
814 << "Timed out waiting for FlexFEC and/or media packets.";
815 }
816
Niels Möller4db138e2018-04-19 09:04:13 +0200817 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800818 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800819 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800820 bool sent_media_;
821 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100822 const bool header_extensions_enabled_;
823 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800824};
825
Sebastian Jansson63470292019-02-01 10:13:43 +0100826TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200827 test::FunctionVideoEncoderFactory encoder_factory(
828 []() { return VP8Encoder::Create(); });
829 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100830 RunBaseTest(&test);
831}
832
Sebastian Jansson63470292019-02-01 10:13:43 +0100833TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200834 test::FunctionVideoEncoderFactory encoder_factory(
835 []() { return VP8Encoder::Create(); });
836 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800837 RunBaseTest(&test);
838}
839
Sebastian Jansson63470292019-02-01 10:13:43 +0100840TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200841 test::FunctionVideoEncoderFactory encoder_factory(
842 []() { return VP8Encoder::Create(); });
843 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800844 RunBaseTest(&test);
845}
846
Sebastian Jansson63470292019-02-01 10:13:43 +0100847TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200848 test::FunctionVideoEncoderFactory encoder_factory(
849 []() { return VP8Encoder::Create(); });
850 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800851 RunBaseTest(&test);
852}
853
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100854#if defined(RTC_ENABLE_VP9)
Sebastian Jansson63470292019-02-01 10:13:43 +0100855TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200856 test::FunctionVideoEncoderFactory encoder_factory(
857 []() { return VP9Encoder::Create(); });
858 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800859 RunBaseTest(&test);
860}
861
Sebastian Jansson63470292019-02-01 10:13:43 +0100862TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200863 test::FunctionVideoEncoderFactory encoder_factory(
864 []() { return VP9Encoder::Create(); });
865 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800866 RunBaseTest(&test);
867}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100868#endif // defined(RTC_ENABLE_VP9)
brandtr39f97292016-11-16 22:57:50 -0800869
Sebastian Jansson63470292019-02-01 10:13:43 +0100870TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200871 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200872 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200873 });
874 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800875 RunBaseTest(&test);
876}
877
Sebastian Jansson63470292019-02-01 10:13:43 +0100878TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200879 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200880 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200881 });
882 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800883 RunBaseTest(&test);
884}
885
Sebastian Jansson63470292019-02-01 10:13:43 +0100886TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100887 std::unique_ptr<TaskQueueFactory> task_queue_factory =
888 CreateDefaultTaskQueueFactory();
889 test::FunctionVideoEncoderFactory encoder_factory([&]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200890 return std::make_unique<test::MultithreadedFakeH264Encoder>(
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100891 Clock::GetRealTimeClock(), task_queue_factory.get());
Niels Möller4db138e2018-04-19 09:04:13 +0200892 });
893
894 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800895 RunBaseTest(&test);
896}
897
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000898void VideoSendStreamTest::TestNackRetransmission(
899 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000900 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000901 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000902 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000903 explicit NackObserver(uint32_t retransmit_ssrc,
904 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000905 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000906 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100907 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000908 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100909 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000910
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000911 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000912 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000913 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000914 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000915
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200916 // NACK packets two times at some arbitrary points.
917 const int kNackedPacketsAtOnceCount = 3;
918 const int kRetransmitTarget = kNackedPacketsAtOnceCount * 2;
919
920 // Skip padding packets because they will never be retransmitted.
921 if (header.paddingLength + header.headerLength == length) {
922 return SEND_PACKET;
923 }
924
Sebastian Janssond3f38162018-02-28 16:14:44 +0100925 ++send_count_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200926
927 // NACK packets at arbitrary points.
Sebastian Janssond3f38162018-02-28 16:14:44 +0100928 if (send_count_ == 5 || send_count_ == 25) {
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200929 nacked_sequence_numbers_.insert(
930 nacked_sequence_numbers_.end(),
931 non_padding_sequence_numbers_.end() - kNackedPacketsAtOnceCount,
932 non_padding_sequence_numbers_.end());
Sebastian Janssond3f38162018-02-28 16:14:44 +0100933
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000934 RtpRtcp::Configuration config;
935 config.clock = Clock::GetRealTimeClock();
936 config.outgoing_transport = transport_adapter_.get();
937 config.rtcp_report_interval_ms = kRtcpIntervalMs;
Erik Språng6841d252019-10-15 14:29:11 +0200938 config.local_media_ssrc = kReceiverLocalVideoSsrc;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000939 RTCPSender rtcp_sender(config);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000940
pbosda903ea2015-10-02 02:36:56 -0700941 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100942 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000943
944 RTCPSender::FeedbackState feedback_state;
945
Sebastian Janssond3f38162018-02-28 16:14:44 +0100946 EXPECT_EQ(0, rtcp_sender.SendRTCP(
947 feedback_state, kRtcpNack,
948 static_cast<int>(nacked_sequence_numbers_.size()),
949 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000950 }
951
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000952 uint16_t sequence_number = header.sequenceNumber;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000953 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100954 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
955 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000956 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000957 const uint8_t* rtx_header = packet + header.headerLength;
958 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
959 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200960
Steve Antonbd631a02019-03-28 10:51:27 -0700961 auto found = absl::c_find(nacked_sequence_numbers_, sequence_number);
Sebastian Janssond3f38162018-02-28 16:14:44 +0100962 if (found != nacked_sequence_numbers_.end()) {
963 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000964
Sebastian Janssond3f38162018-02-28 16:14:44 +0100965 if (++retransmit_count_ == kRetransmitTarget) {
966 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
967 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
968 observation_complete_.Set();
969 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200970 } else {
971 non_padding_sequence_numbers_.push_back(sequence_number);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000972 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000973
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000974 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000975 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000976
stefanff483612015-12-21 03:14:00 -0800977 void ModifyVideoConfigs(
978 VideoSendStream::Config* send_config,
979 std::vector<VideoReceiveStream::Config>* receive_configs,
980 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700981 transport_adapter_.reset(
982 new internal::TransportAdapter(send_config->send_transport));
983 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000984 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000985 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100986 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000987 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
988 }
989
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000990 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100991 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000992 }
993
kwiberg27f982b2016-03-01 11:52:33 -0800994 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000995 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100996 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000997 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000998 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100999 std::vector<uint16_t> nacked_sequence_numbers_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +02001000 std::vector<uint16_t> non_padding_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001001 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +00001002
stefane74eef12016-01-08 06:47:13 -08001003 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +00001004}
1005
Sebastian Jansson63470292019-02-01 10:13:43 +01001006TEST_F(VideoSendStreamTest, RetransmitsNack) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001007 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001008 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001009}
1010
Sebastian Jansson63470292019-02-01 10:13:43 +01001011TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001012 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001013 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001014}
1015
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001016void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
1017 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001018 // Use a fake encoder to output a frame of every size in the range [90, 290],
1019 // for each size making sure that the exact number of payload bytes received
1020 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001021 static const size_t kMaxPacketSize = 128;
1022 static const size_t start = 90;
1023 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001024
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001025 // Observer that verifies that the expected number of packets and bytes
1026 // arrive for each frame size, from start_size to stop_size.
Niels Möller759f9592018-10-09 14:57:01 +02001027 class FrameFragmentationTest : public test::SendTest {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001028 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001029 FrameFragmentationTest(size_t max_packet_size,
1030 size_t start_size,
1031 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001032 bool test_generic_packetization,
1033 bool use_fec)
1034 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001035 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +02001036 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001037 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001038 stop_size_(stop_size),
1039 test_generic_packetization_(test_generic_packetization),
1040 use_fec_(use_fec),
1041 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001042 packets_lost_(0),
1043 last_packet_count_(0),
1044 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001045 accumulated_size_(0),
1046 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001047 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001048 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001049 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001050 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001051 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -07001052 RTC_DCHECK_GT(stop_size, max_packet_size);
Philip Eliassond52a1a62018-09-07 13:03:55 +00001053 if (!test_generic_packetization_)
1054 encoder_.SetCodecType(kVideoCodecVP8);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001055 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001056
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001057 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001058 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001059 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001060 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001061 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001062
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001063 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001064
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001065 if (use_fec_) {
1066 uint8_t payload_type = packet[header.headerLength];
1067 bool is_fec = header.payloadType == kRedPayloadType &&
1068 payload_type == kUlpfecPayloadType;
1069 if (is_fec) {
1070 fec_packet_received_ = true;
1071 return SEND_PACKET;
1072 }
1073 }
1074
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001075 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001076
1077 if (use_fec_)
1078 TriggerLossReport(header);
1079
1080 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +02001081 size_t overhead = header.headerLength + header.paddingLength;
1082 // Only remove payload header and RED header if the packet actually
1083 // contains payload.
1084 if (length > overhead) {
1085 overhead += (1 /* Generic header */);
1086 if (use_fec_)
1087 overhead += 1; // RED for FEC header.
1088 }
1089 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001090 accumulated_payload_ += length - overhead;
1091 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001092
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001093 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001094 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001095 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1096 // With FEC enabled, frame size is incremented asynchronously, so
1097 // "old" frames one byte too small may arrive. Accept, but don't
1098 // increase expected frame size.
1099 accumulated_size_ = 0;
1100 accumulated_payload_ = 0;
1101 return SEND_PACKET;
1102 }
1103
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001104 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001105 if (test_generic_packetization_) {
1106 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1107 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001108
1109 // Last packet of frame; reset counters.
1110 accumulated_size_ = 0;
1111 accumulated_payload_ = 0;
1112 if (current_size_rtp_ == stop_size_) {
1113 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001114 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001115 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001116 // Increase next expected frame size. If testing with FEC, make sure
1117 // a FEC packet has been received for this frame size before
1118 // proceeding, to make sure that redundancy packets don't exceed
1119 // size limit.
1120 if (!use_fec_) {
1121 ++current_size_rtp_;
1122 } else if (fec_packet_received_) {
1123 fec_packet_received_ = false;
1124 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001125
1126 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001127 ++current_size_frame_;
1128 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001129 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001130 }
1131
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001132 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001133 }
1134
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001135 void TriggerLossReport(const RTPHeader& header) {
1136 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001137 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001138 if (++packet_count_ % (100 / kLossPercent) == 0) {
1139 packets_lost_++;
1140 int loss_delta = packets_lost_ - last_packets_lost_;
1141 int packets_delta = packet_count_ - last_packet_count_;
1142 last_packet_count_ = packet_count_;
1143 last_packets_lost_ = packets_lost_;
1144 uint8_t loss_ratio =
1145 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001146 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001147 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001148 packets_lost_, // Cumulative lost.
1149 loss_ratio); // Loss percent.
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001150 RtpRtcp::Configuration config;
1151 config.clock = Clock::GetRealTimeClock();
1152 config.receive_statistics = &lossy_receive_stats;
1153 config.outgoing_transport = transport_adapter_.get();
1154 config.rtcp_report_interval_ms = kRtcpIntervalMs;
Erik Språng6841d252019-10-15 14:29:11 +02001155 config.local_media_ssrc = kVideoSendSsrcs[0];
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001156 RTCPSender rtcp_sender(config);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001157
pbosda903ea2015-10-02 02:36:56 -07001158 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001159 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001160
1161 RTCPSender::FeedbackState feedback_state;
1162
1163 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1164 }
1165 }
1166
Niels Möller759f9592018-10-09 14:57:01 +02001167 void UpdateConfiguration() {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001168 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001169 // Increase frame size for next encoded frame, in the context of the
1170 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001171 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001172 ++current_size_frame_;
1173 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001174 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001175 }
Niels Möllerde8e6e62018-11-13 15:10:33 +01001176 void ModifySenderBitrateConfig(
1177 BitrateConstraints* bitrate_config) override {
Nikita Zetilov8ae70f62019-11-12 16:13:10 +01001178 const int kMinBitrateBps = 300000;
Niels Möllerde8e6e62018-11-13 15:10:33 +01001179 bitrate_config->min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001180 }
1181
stefanff483612015-12-21 03:14:00 -08001182 void ModifyVideoConfigs(
1183 VideoSendStream::Config* send_config,
1184 std::vector<VideoReceiveStream::Config>* receive_configs,
1185 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001186 transport_adapter_.reset(
1187 new internal::TransportAdapter(send_config->send_transport));
1188 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001189 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001190 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1191 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001192 }
1193
1194 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001195 send_config->rtp.payload_name = "VP8";
Philip Eliassond52a1a62018-09-07 13:03:55 +00001196
Niels Möller4db138e2018-04-19 09:04:13 +02001197 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001198 send_config->rtp.max_packet_size = kMaxPacketSize;
Niels Möller759f9592018-10-09 14:57:01 +02001199 encoder_.RegisterPostEncodeCallback([this]() { UpdateConfiguration(); });
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001200
Erik Språng95261872015-04-10 11:58:49 +02001201 // Make sure there is at least one extension header, to make the RTP
1202 // header larger than the base length of 12 bytes.
1203 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001204
1205 // Setup screen content disables frame dropping which makes this easier.
Åsa Perssond34597c2018-10-22 17:34:02 +02001206 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
1207 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
sprang4847ae62017-06-27 07:06:52 -07001208 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001209 }
1210
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001211 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001212 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001213 }
1214
kwiberg27f982b2016-03-01 11:52:33 -08001215 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001216 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möllercbcbc222018-09-28 09:07:24 +02001217 test::VideoEncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001218
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001219 const size_t max_packet_size_;
1220 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001221 const bool test_generic_packetization_;
1222 const bool use_fec_;
1223
1224 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001225 uint32_t packets_lost_;
1226 uint32_t last_packet_count_;
1227 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001228 size_t accumulated_size_;
1229 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001230 bool fec_packet_received_;
1231
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001232 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001233 rtc::CriticalSection mutex_;
1234 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001235 };
1236
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001237 // Don't auto increment if FEC is used; continue sending frame size until
1238 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001239 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1240 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001241
stefane74eef12016-01-08 06:47:13 -08001242 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001243}
1244
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001245// TODO(sprang): Is there any way of speeding up these tests?
Sebastian Jansson63470292019-02-01 10:13:43 +01001246TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001247 TestPacketFragmentationSize(kGeneric, false);
1248}
1249
Sebastian Jansson63470292019-02-01 10:13:43 +01001250TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001251 TestPacketFragmentationSize(kGeneric, true);
1252}
1253
Sebastian Jansson63470292019-02-01 10:13:43 +01001254TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001255 TestPacketFragmentationSize(kVP8, false);
1256}
1257
Sebastian Jansson63470292019-02-01 10:13:43 +01001258TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001259 TestPacketFragmentationSize(kVP8, true);
1260}
1261
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001262// The test will go through a number of phases.
1263// 1. Start sending packets.
1264// 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 +00001265// suspend the stream.
1266// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001267// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001268// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001269// When the stream is detected again, and the stats show that the stream
1270// is no longer suspended, the test ends.
Sebastian Jansson63470292019-02-01 10:13:43 +01001271TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001272 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001273
Niels Möller412d1852019-01-02 09:42:54 +01001274 class RembObserver : public test::SendTest {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001275 public:
Niels Möller412d1852019-01-02 09:42:54 +01001276 class CaptureObserver : public rtc::VideoSinkInterface<VideoFrame> {
1277 public:
1278 explicit CaptureObserver(RembObserver* remb_observer)
1279 : remb_observer_(remb_observer) {}
1280
1281 void OnFrame(const VideoFrame&) {
1282 rtc::CritScope lock(&remb_observer_->crit_);
1283 if (remb_observer_->test_state_ == kDuringSuspend &&
1284 ++remb_observer_->suspended_frame_count_ > kSuspendTimeFrames) {
1285 VideoSendStream::Stats stats = remb_observer_->stream_->GetStats();
1286 EXPECT_TRUE(stats.suspended);
1287 remb_observer_->SendRtcpFeedback(remb_observer_->high_remb_bps_);
1288 remb_observer_->test_state_ = kWaitingForPacket;
1289 }
1290 }
1291
1292 private:
1293 RembObserver* const remb_observer_;
1294 };
1295
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001296 RembObserver()
1297 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001298 clock_(Clock::GetRealTimeClock()),
Niels Möller412d1852019-01-02 09:42:54 +01001299 capture_observer_(this),
Erik Språng737336d2016-07-29 12:59:36 +02001300 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001301 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001302 rtp_count_(0),
1303 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001304 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001305 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001306 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001307
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001308 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001309 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001310 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001311 ++rtp_count_;
1312 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001313 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001314 last_sequence_number_ = header.sequenceNumber;
1315
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001316 if (test_state_ == kBeforeSuspend) {
1317 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001318 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001319 test_state_ = kDuringSuspend;
1320 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001321 if (header.paddingLength == 0) {
1322 // Received non-padding packet during suspension period. Reset the
1323 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001324 suspended_frame_count_ = 0;
1325 }
stefanf116bd02015-10-27 08:29:42 -07001326 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001327 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001328 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001329 // Non-padding packet observed. Test is almost complete. Will just
1330 // have to wait for the stats to change.
1331 test_state_ = kWaitingForStats;
1332 }
stefanf116bd02015-10-27 08:29:42 -07001333 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001334 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001335 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001336 if (stats.suspended == false) {
1337 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001338 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001339 }
stefanf116bd02015-10-27 08:29:42 -07001340 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001341 }
1342
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001343 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001344 }
1345
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001346 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001347 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001348 low_remb_bps_ = value;
1349 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001350
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001351 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001352 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001353 high_remb_bps_ = value;
1354 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001355
stefanff483612015-12-21 03:14:00 -08001356 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001357 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001358 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001359 stream_ = send_stream;
1360 }
1361
Niels Möller412d1852019-01-02 09:42:54 +01001362 void OnFrameGeneratorCapturerCreated(
1363 test::FrameGeneratorCapturer* frame_generator_capturer) override {
1364 frame_generator_capturer->AddOrUpdateSink(&capture_observer_,
1365 rtc::VideoSinkWants());
1366 }
1367
stefanff483612015-12-21 03:14:00 -08001368 void ModifyVideoConfigs(
1369 VideoSendStream::Config* send_config,
1370 std::vector<VideoReceiveStream::Config>* receive_configs,
1371 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001372 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001373 transport_adapter_.reset(
1374 new internal::TransportAdapter(send_config->send_transport));
1375 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001376 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001377 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001378 int min_bitrate_bps =
1379 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001380 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001381 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001382 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001383 min_bitrate_bps + threshold_window + 5000);
1384 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1385 }
1386
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001387 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001388 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001389 }
1390
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001391 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001392 kBeforeSuspend,
1393 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001394 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001395 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001396 };
1397
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001398 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001399 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001400 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1401 last_sequence_number_, rtp_count_, 0);
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001402 RtpRtcp::Configuration config;
1403 config.clock = clock_;
1404 config.receive_statistics = &receive_stats;
1405 config.outgoing_transport = transport_adapter_.get();
1406 config.rtcp_report_interval_ms = kRtcpIntervalMs;
Erik Språng6841d252019-10-15 14:29:11 +02001407 config.local_media_ssrc = kVideoSendSsrcs[0];
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001408 RTCPSender rtcp_sender(config);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001409
pbosda903ea2015-10-02 02:36:56 -07001410 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001411 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001412 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001413 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001414 }
1415 RTCPSender::FeedbackState feedback_state;
1416 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1417 }
1418
kwiberg27f982b2016-03-01 11:52:33 -08001419 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001420 Clock* const clock_;
Niels Möller412d1852019-01-02 09:42:54 +01001421 CaptureObserver capture_observer_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001422 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001423
Peter Boströmf2f82832015-05-01 13:00:41 +02001424 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001425 TestState test_state_ RTC_GUARDED_BY(crit_);
1426 int rtp_count_ RTC_GUARDED_BY(crit_);
1427 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1428 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1429 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1430 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001431 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001432
stefane74eef12016-01-08 06:47:13 -08001433 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001434}
1435
perkj71ee44c2016-06-15 00:47:53 -07001436// This test that padding stops being send after a while if the Camera stops
1437// producing video frames and that padding resumes if the camera restarts.
Sebastian Jansson63470292019-02-01 10:13:43 +01001438TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001439 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001440 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001441 NoPaddingWhenVideoIsMuted()
1442 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001443 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001444 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001445 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001446
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001447 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001448 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001449 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001450 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001451
1452 RTPHeader header;
1453 parser_->Parse(packet, length, &header);
1454 const bool only_padding =
1455 header.headerLength + header.paddingLength == length;
1456
1457 if (test_state_ == kBeforeStopCapture) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001458 // Packets are flowing, stop camera.
perkj71ee44c2016-06-15 00:47:53 -07001459 capturer_->Stop();
1460 test_state_ = kWaitingForPadding;
1461 } else if (test_state_ == kWaitingForPadding && only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001462 // We're still getting padding, after stopping camera.
perkj71ee44c2016-06-15 00:47:53 -07001463 test_state_ = kWaitingForNoPackets;
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001464 } else if (test_state_ == kWaitingForMediaAfterCameraRestart &&
1465 !only_padding) {
1466 // Media packets are flowing again, stop camera a second time.
1467 capturer_->Stop();
1468 test_state_ = kWaitingForPaddingAfterCameraStopsAgain;
1469 } else if (test_state_ == kWaitingForPaddingAfterCameraStopsAgain &&
perkj71ee44c2016-06-15 00:47:53 -07001470 only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001471 // Padding is still flowing, test ok.
perkj71ee44c2016-06-15 00:47:53 -07001472 observation_complete_.Set();
1473 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001474 return SEND_PACKET;
1475 }
1476
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001477 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001478 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001479 const int kNoPacketsThresholdMs = 2000;
1480 if (test_state_ == kWaitingForNoPackets &&
1481 (last_packet_time_ms_ > 0 &&
1482 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1483 kNoPacketsThresholdMs)) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001484 // No packets seen for |kNoPacketsThresholdMs|, restart camera.
perkj71ee44c2016-06-15 00:47:53 -07001485 capturer_->Start();
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001486 test_state_ = kWaitingForMediaAfterCameraRestart;
perkj71ee44c2016-06-15 00:47:53 -07001487 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001488 return SEND_PACKET;
1489 }
1490
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001491 void ModifyVideoConfigs(
1492 VideoSendStream::Config* send_config,
1493 std::vector<VideoReceiveStream::Config>* receive_configs,
1494 VideoEncoderConfig* encoder_config) override {
1495 // Make sure padding is sent if encoder is not producing media.
1496 encoder_config->min_transmit_bitrate_bps = 50000;
1497 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001498
nisseef8b61e2016-04-29 06:09:15 -07001499 void OnFrameGeneratorCapturerCreated(
1500 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001501 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001502 capturer_ = frame_generator_capturer;
1503 }
1504
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001505 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001506 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001507 << "Timed out while waiting for RTP packets to stop being sent.";
1508 }
1509
perkj71ee44c2016-06-15 00:47:53 -07001510 enum TestState {
1511 kBeforeStopCapture,
1512 kWaitingForPadding,
1513 kWaitingForNoPackets,
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001514 kWaitingForMediaAfterCameraRestart,
1515 kWaitingForPaddingAfterCameraStopsAgain
perkj71ee44c2016-06-15 00:47:53 -07001516 };
1517
1518 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001519 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001520 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001521 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001522 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1523 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001524 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001525
stefane74eef12016-01-08 06:47:13 -08001526 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001527}
1528
Sebastian Jansson63470292019-02-01 10:13:43 +01001529TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
isheriffcc5903e2016-10-04 08:29:38 -07001530 const int kCapacityKbps = 10000; // 10 Mbps
1531 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1532 public:
1533 PaddingIsPrimarilyRetransmissions()
1534 : EndToEndTest(kDefaultTimeoutMs),
1535 clock_(Clock::GetRealTimeClock()),
1536 padding_length_(0),
1537 total_length_(0),
1538 call_(nullptr) {}
1539
1540 private:
1541 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1542 call_ = sender_call;
1543 }
1544
1545 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1546 rtc::CritScope lock(&crit_);
1547
1548 RTPHeader header;
1549 parser_->Parse(packet, length, &header);
1550 padding_length_ += header.paddingLength;
1551 total_length_ += length;
1552 return SEND_PACKET;
1553 }
1554
Danil Chapovalov44db4362019-09-30 04:16:28 +02001555 std::unique_ptr<test::PacketTransport> CreateSendTransport(
1556 TaskQueueBase* task_queue,
eladalon413ee9a2017-08-22 04:02:52 -07001557 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001558 const int kNetworkDelayMs = 50;
Artem Titov75e36472018-10-08 12:28:56 +02001559 BuiltInNetworkBehaviorConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001560 config.loss_percent = 10;
1561 config.link_capacity_kbps = kCapacityKbps;
1562 config.queue_delay_ms = kNetworkDelayMs;
Danil Chapovalov44db4362019-09-30 04:16:28 +02001563 return std::make_unique<test::PacketTransport>(
Artem Titov4e199e92018-08-20 13:30:39 +02001564 task_queue, sender_call, this, test::PacketTransport::kSender,
1565 payload_type_map_,
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001566 std::make_unique<FakeNetworkPipe>(
Artem Titov4e199e92018-08-20 13:30:39 +02001567 Clock::GetRealTimeClock(),
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001568 std::make_unique<SimulatedNetwork>(config)));
isheriffcc5903e2016-10-04 08:29:38 -07001569 }
1570
1571 void ModifyVideoConfigs(
1572 VideoSendStream::Config* send_config,
1573 std::vector<VideoReceiveStream::Config>* receive_configs,
1574 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001575 // Turn on RTX.
1576 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
Erik Språngc06aef22019-10-17 13:02:27 +02001577 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001578 }
1579
1580 void PerformTest() override {
1581 // TODO(isheriff): Some platforms do not ramp up as expected to full
1582 // capacity due to packet scheduling delays. Fix that before getting
1583 // rid of this.
1584 SleepMs(5000);
1585 {
1586 rtc::CritScope lock(&crit_);
1587 // Expect padding to be a small percentage of total bytes sent.
1588 EXPECT_LT(padding_length_, .1 * total_length_);
1589 }
1590 }
1591
1592 rtc::CriticalSection crit_;
1593 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001594 size_t padding_length_ RTC_GUARDED_BY(crit_);
1595 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001596 Call* call_;
1597 } test;
1598
1599 RunBaseTest(&test);
1600}
1601
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001602// This test first observes "high" bitrate use at which point it sends a REMB to
1603// indicate that it should be lowered significantly. The test then observes that
1604// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1605// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001606//
1607// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1608// bitrate since no receiver block or remb is sent in the initial phase.
Sebastian Jansson63470292019-02-01 10:13:43 +01001609TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001610 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001611 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001612 static const int kRembBitrateBps = 80000;
1613 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001614 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001615 public:
1616 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001617 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001618 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1619 stream_(nullptr),
1620 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001621
1622 private:
nisseef8b61e2016-04-29 06:09:15 -07001623 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001624 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001625 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001626
1627 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001628 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001629 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001630 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001631 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001632 if (!stats.substreams.empty()) {
1633 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001634 int total_bitrate_bps =
1635 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001636 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1637 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1638 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001639 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001640 rtp_rtcp_->SetRemb(kRembBitrateBps,
1641 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001642 rtp_rtcp_->Process();
1643 bitrate_capped_ = true;
1644 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001645 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001646 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001647 }
1648 }
stefanf116bd02015-10-27 08:29:42 -07001649 // Packets don't have to be delivered since the test is the receiver.
1650 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001651 }
1652
stefanff483612015-12-21 03:14:00 -08001653 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001654 VideoSendStream* send_stream,
1655 const std::vector<VideoReceiveStream*>& receive_streams) override {
1656 stream_ = send_stream;
1657 RtpRtcp::Configuration config;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001658 config.clock = Clock::GetRealTimeClock();
stefanf116bd02015-10-27 08:29:42 -07001659 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001660 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001661 rtp_rtcp_ = RtpRtcp::Create(config);
stefanf116bd02015-10-27 08:29:42 -07001662 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001663 }
1664
stefanff483612015-12-21 03:14:00 -08001665 void ModifyVideoConfigs(
1666 VideoSendStream::Config* send_config,
1667 std::vector<VideoReceiveStream::Config>* receive_configs,
1668 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001669 feedback_transport_.reset(
1670 new internal::TransportAdapter(send_config->send_transport));
1671 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001672 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001673 }
1674
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001675 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001676 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001677 << "Timeout while waiting for low bitrate stats after REMB.";
1678 }
1679
kwiberg27f982b2016-03-01 11:52:33 -08001680 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1681 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001682 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001683 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001684 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001685 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001686
stefane74eef12016-01-08 06:47:13 -08001687 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001688}
1689
Sebastian Jansson63470292019-02-01 10:13:43 +01001690TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001691 static const int kStartBitrateBps = 300000;
1692 static const int kNewMaxBitrateBps = 1234567;
Elad Alond8d32482019-02-18 23:45:57 +01001693 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001694 class ChangingNetworkRouteTest : public test::EndToEndTest {
1695 public:
Danil Chapovalov85a10002019-10-21 15:00:53 +02001696 explicit ChangingNetworkRouteTest(TaskQueueBase* task_queue)
eladalon413ee9a2017-08-22 04:02:52 -07001697 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1698 task_queue_(task_queue),
1699 call_(nullptr) {
Tommi31d1bce2019-08-27 11:34:20 +02001700 module_process_thread_.Detach();
1701 task_queue_thread_.Detach();
Stefan Holmer280de9e2016-09-30 10:06:51 +02001702 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1703 kRtpExtensionTransportSequenceNumber, kExtensionId));
1704 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001705
1706 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommi31d1bce2019-08-27 11:34:20 +02001707 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1708 RTC_DCHECK(!call_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001709 call_ = sender_call;
1710 }
1711
Stefan Holmer280de9e2016-09-30 10:06:51 +02001712 void ModifyVideoConfigs(
1713 VideoSendStream::Config* send_config,
1714 std::vector<VideoReceiveStream::Config>* receive_configs,
1715 VideoEncoderConfig* encoder_config) override {
Tommi31d1bce2019-08-27 11:34:20 +02001716 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Stefan Holmer280de9e2016-09-30 10:06:51 +02001717 send_config->rtp.extensions.clear();
1718 send_config->rtp.extensions.push_back(RtpExtension(
1719 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1720 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1721 (*receive_configs)[0].rtp.transport_cc = true;
1722 }
1723
1724 void ModifyAudioConfigs(
1725 AudioSendStream::Config* send_config,
1726 std::vector<AudioReceiveStream::Config>* receive_configs) override {
Tommi31d1bce2019-08-27 11:34:20 +02001727 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Stefan Holmer280de9e2016-09-30 10:06:51 +02001728 send_config->rtp.extensions.clear();
1729 send_config->rtp.extensions.push_back(RtpExtension(
1730 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1731 (*receive_configs)[0].rtp.extensions.clear();
1732 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1733 (*receive_configs)[0].rtp.transport_cc = true;
1734 }
1735
Stefan Holmerbe402962016-07-08 16:16:41 +02001736 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Tommi31d1bce2019-08-27 11:34:20 +02001737 RTC_DCHECK_RUN_ON(&module_process_thread_);
Danil Chapovalov85a10002019-10-21 15:00:53 +02001738 task_queue_->PostTask(ToQueuedTask([this]() {
Tommi31d1bce2019-08-27 11:34:20 +02001739 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1740 if (!call_)
1741 return;
1742 Call::Stats stats = call_->GetStats();
1743 if (stats.send_bandwidth_bps > kStartBitrateBps)
1744 observation_complete_.Set();
Danil Chapovalov85a10002019-10-21 15:00:53 +02001745 }));
Stefan Holmerbe402962016-07-08 16:16:41 +02001746 return SEND_PACKET;
1747 }
1748
Tommi31d1bce2019-08-27 11:34:20 +02001749 void OnStreamsStopped() override {
1750 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1751 call_ = nullptr;
1752 }
1753
Stefan Holmerbe402962016-07-08 16:16:41 +02001754 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001755 rtc::NetworkRoute new_route;
1756 new_route.connected = true;
1757 new_route.local_network_id = 10;
1758 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001759 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001760
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02001761 SendTask(RTC_FROM_HERE, task_queue_,
1762 [this, &new_route, &bitrate_config]() {
1763 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1764 call_->GetTransportControllerSend()->OnNetworkRouteChanged(
1765 "transport", new_route);
1766 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1767 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1768 bitrate_config);
1769 });
eladalon413ee9a2017-08-22 04:02:52 -07001770
Stefan Holmerbe402962016-07-08 16:16:41 +02001771 EXPECT_TRUE(Wait())
1772 << "Timed out while waiting for start bitrate to be exceeded.";
1773
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02001774 SendTask(
1775 RTC_FROM_HERE, task_queue_, [this, &new_route, &bitrate_config]() {
1776 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1777 bitrate_config.start_bitrate_bps = -1;
1778 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1779 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1780 bitrate_config);
1781 // TODO(holmer): We should set the last sent packet id here and
1782 // verify that we correctly ignore any packet loss reported prior to
1783 // that id.
1784 ++new_route.local_network_id;
1785 call_->GetTransportControllerSend()->OnNetworkRouteChanged(
1786 "transport", new_route);
1787 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1788 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001789 }
1790
1791 private:
Tommi31d1bce2019-08-27 11:34:20 +02001792 webrtc::SequenceChecker module_process_thread_;
1793 webrtc::SequenceChecker task_queue_thread_;
Danil Chapovalov85a10002019-10-21 15:00:53 +02001794 TaskQueueBase* const task_queue_;
Tommi31d1bce2019-08-27 11:34:20 +02001795 Call* call_ RTC_GUARDED_BY(task_queue_thread_);
Danil Chapovalovd15a0282019-10-22 10:48:17 +02001796 } test(task_queue());
Stefan Holmerbe402962016-07-08 16:16:41 +02001797
1798 RunBaseTest(&test);
1799}
1800
Sebastian Jansson63470292019-02-01 10:13:43 +01001801TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
michaelt79e05882016-11-08 02:50:09 -08001802 class ChangingTransportOverheadTest : public test::EndToEndTest {
1803 public:
Danil Chapovalov85a10002019-10-21 15:00:53 +02001804 explicit ChangingTransportOverheadTest(TaskQueueBase* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001805 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001806 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001807 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001808 packets_sent_(0),
1809 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001810
1811 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1812 call_ = sender_call;
1813 }
1814
1815 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001816 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001817 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001818 if (++packets_sent_ < 100)
1819 return SEND_PACKET;
1820 observation_complete_.Set();
1821 return SEND_PACKET;
1822 }
1823
michaelta3328772016-11-29 09:25:03 -08001824 void ModifyVideoConfigs(
1825 VideoSendStream::Config* send_config,
1826 std::vector<VideoReceiveStream::Config>* receive_configs,
1827 VideoEncoderConfig* encoder_config) override {
1828 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1829 }
1830
michaelt79e05882016-11-08 02:50:09 -08001831 void PerformTest() override {
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02001832 SendTask(RTC_FROM_HERE, task_queue_, [this]() {
eladalon413ee9a2017-08-22 04:02:52 -07001833 transport_overhead_ = 100;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001834 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1835 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001836 });
1837
michaelt79e05882016-11-08 02:50:09 -08001838 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001839
sprang21253fc2017-02-27 03:35:47 -08001840 {
1841 rtc::CritScope cs(&lock_);
1842 packets_sent_ = 0;
1843 }
eladalon413ee9a2017-08-22 04:02:52 -07001844
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02001845 SendTask(RTC_FROM_HERE, task_queue_, [this]() {
eladalon413ee9a2017-08-22 04:02:52 -07001846 transport_overhead_ = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001847 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1848 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001849 });
1850
michaelt79e05882016-11-08 02:50:09 -08001851 EXPECT_TRUE(Wait());
1852 }
1853
1854 private:
Danil Chapovalov85a10002019-10-21 15:00:53 +02001855 TaskQueueBase* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001856 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001857 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001858 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001859 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001860 const size_t kMaxRtpPacketSize = 1000;
Danil Chapovalovd15a0282019-10-22 10:48:17 +02001861 } test(task_queue());
michaelt79e05882016-11-08 02:50:09 -08001862
1863 RunBaseTest(&test);
1864}
1865
sprangf24a0642017-02-28 13:23:26 -08001866// Test class takes takes as argument a switch selecting if type switch should
1867// occur and a function pointer to reset the send stream. This is necessary
1868// since you cannot change the content type of a VideoSendStream, you need to
1869// recreate it. Stopping and recreating the stream can only be done on the main
1870// thread and in the context of VideoSendStreamTest (not BaseTest).
1871template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001872class MaxPaddingSetTest : public test::SendTest {
1873 public:
1874 static const uint32_t kMinTransmitBitrateBps = 400000;
1875 static const uint32_t kActualEncodeBitrateBps = 40000;
1876 static const uint32_t kMinPacketsToSend = 50;
1877
Danil Chapovalov85a10002019-10-21 15:00:53 +02001878 MaxPaddingSetTest(bool test_switch_content_type,
1879 T* stream_reset_fun,
1880 TaskQueueBase* task_queue)
sprang9c0b5512016-07-06 00:54:28 -07001881 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001882 running_without_padding_(test_switch_content_type),
Tommiaaaf8042019-08-05 14:56:33 +02001883 stream_resetter_(stream_reset_fun),
1884 task_queue_(task_queue) {
tommi39e12892017-03-13 05:15:14 -07001885 RTC_DCHECK(stream_resetter_);
Tommi31d1bce2019-08-27 11:34:20 +02001886 module_process_thread_.Detach();
1887 task_queue_thread_.Detach();
sprang9c0b5512016-07-06 00:54:28 -07001888 }
1889
1890 void ModifyVideoConfigs(
1891 VideoSendStream::Config* send_config,
1892 std::vector<VideoReceiveStream::Config>* receive_configs,
1893 VideoEncoderConfig* encoder_config) override {
Tommi31d1bce2019-08-27 11:34:20 +02001894 RTC_DCHECK_RUN_ON(&task_queue_thread_);
kwibergaf476c72016-11-28 15:21:39 -08001895 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
Tommi31d1bce2019-08-27 11:34:20 +02001896 if (running_without_padding_) {
sprang9c0b5512016-07-06 00:54:28 -07001897 encoder_config->min_transmit_bitrate_bps = 0;
1898 encoder_config->content_type =
1899 VideoEncoderConfig::ContentType::kRealtimeVideo;
1900 } else {
1901 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1902 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1903 }
sprangf24a0642017-02-28 13:23:26 -08001904 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001905 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001906 }
1907
1908 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommi31d1bce2019-08-27 11:34:20 +02001909 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1910 RTC_DCHECK(task_queue_->IsCurrent());
1911 RTC_DCHECK(!call_);
1912 RTC_DCHECK(sender_call);
sprang9c0b5512016-07-06 00:54:28 -07001913 call_ = sender_call;
1914 }
1915
Tommiaaaf8042019-08-05 14:56:33 +02001916 // Called on the pacer thread.
sprang9c0b5512016-07-06 00:54:28 -07001917 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Tommi31d1bce2019-08-27 11:34:20 +02001918 RTC_DCHECK_RUN_ON(&module_process_thread_);
Tommiaaaf8042019-08-05 14:56:33 +02001919
Tommi31d1bce2019-08-27 11:34:20 +02001920 // Check the stats on the correct thread and signal the 'complete' flag
1921 // once we detect that we're done.
Tommiaaaf8042019-08-05 14:56:33 +02001922
Danil Chapovalov85a10002019-10-21 15:00:53 +02001923 task_queue_->PostTask(ToQueuedTask([this]() {
Tommi31d1bce2019-08-27 11:34:20 +02001924 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1925 // In case we get a callback during teardown.
1926 // When this happens, OnStreamsStopped() has been called already,
1927 // |call_| is null and the streams are being torn down.
1928 if (!call_)
1929 return;
sprang9c0b5512016-07-06 00:54:28 -07001930
Tommi31d1bce2019-08-27 11:34:20 +02001931 ++packets_sent_;
sprang9c0b5512016-07-06 00:54:28 -07001932
Tommi31d1bce2019-08-27 11:34:20 +02001933 Call::Stats stats = call_->GetStats();
1934 if (running_without_padding_) {
1935 EXPECT_EQ(0, stats.max_padding_bitrate_bps);
sprang9c0b5512016-07-06 00:54:28 -07001936
Tommi31d1bce2019-08-27 11:34:20 +02001937 // Wait until at least kMinPacketsToSend frames have been encoded, so
1938 // that we have reliable data.
1939 if (packets_sent_ < kMinPacketsToSend)
1940 return;
1941
1942 // We've sent kMinPacketsToSend packets with default configuration,
1943 // switch to enabling screen content and setting min transmit bitrate.
1944 // Note that we need to recreate the stream if changing content type.
1945 packets_sent_ = 0;
1946
1947 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1948 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
1949
1950 running_without_padding_ = false;
1951 (*stream_resetter_)(send_stream_config_, encoder_config_);
1952 } else {
1953 // Make sure the pacer has been configured with a min transmit bitrate.
1954 if (stats.max_padding_bitrate_bps > 0) {
1955 observation_complete_.Set();
1956 }
1957 }
Danil Chapovalov85a10002019-10-21 15:00:53 +02001958 }));
sprang9c0b5512016-07-06 00:54:28 -07001959
1960 return SEND_PACKET;
1961 }
1962
Tommi31d1bce2019-08-27 11:34:20 +02001963 // Called on |task_queue_|
1964 void OnStreamsStopped() override {
1965 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1966 RTC_DCHECK(task_queue_->IsCurrent());
1967 call_ = nullptr;
1968 }
sprangf24a0642017-02-28 13:23:26 -08001969
Tommi31d1bce2019-08-27 11:34:20 +02001970 void PerformTest() override {
sprang9c0b5512016-07-06 00:54:28 -07001971 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1972 }
1973
1974 private:
Tommi31d1bce2019-08-27 11:34:20 +02001975 webrtc::SequenceChecker task_queue_thread_;
1976 Call* call_ RTC_GUARDED_BY(task_queue_thread_) = nullptr;
1977 VideoSendStream::Config send_stream_config_{nullptr};
sprang9c0b5512016-07-06 00:54:28 -07001978 VideoEncoderConfig encoder_config_;
Tommi31d1bce2019-08-27 11:34:20 +02001979 webrtc::SequenceChecker module_process_thread_;
1980 uint32_t packets_sent_ RTC_GUARDED_BY(task_queue_thread_) = 0;
1981 bool running_without_padding_ RTC_GUARDED_BY(task_queue_thread_);
sprangf24a0642017-02-28 13:23:26 -08001982 T* const stream_resetter_;
Danil Chapovalov85a10002019-10-21 15:00:53 +02001983 TaskQueueBase* const task_queue_;
sprang9c0b5512016-07-06 00:54:28 -07001984};
1985
Sebastian Jansson63470292019-02-01 10:13:43 +01001986TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001987 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1988 const VideoEncoderConfig& encoder_config) {};
Danil Chapovalovd15a0282019-10-22 10:48:17 +02001989 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun, task_queue());
sprang9c0b5512016-07-06 00:54:28 -07001990 RunBaseTest(&test);
1991}
1992
Sebastian Jansson63470292019-02-01 10:13:43 +01001993TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001994 // Function for removing and recreating the send stream with a new config.
1995 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1996 const VideoEncoderConfig& encoder_config) {
Danil Chapovalovd15a0282019-10-22 10:48:17 +02001997 RTC_DCHECK(task_queue()->IsCurrent());
Tommi31d1bce2019-08-27 11:34:20 +02001998 Stop();
1999 DestroyVideoSendStreams();
2000 SetVideoSendConfig(send_stream_config);
2001 SetVideoEncoderConfig(encoder_config);
2002 CreateVideoSendStreams();
2003 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
2004 Start();
sprangf24a0642017-02-28 13:23:26 -08002005 };
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002006 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun, task_queue());
sprang9c0b5512016-07-06 00:54:28 -07002007 RunBaseTest(&test);
2008}
2009
perkjfa10b552016-10-02 23:45:26 -07002010// This test verifies that new frame sizes reconfigures encoders even though not
2011// (yet) sending. The purpose of this is to permit encoding as quickly as
2012// possible once we start sending. Likely the frames being input are from the
2013// same source that will be sent later, which just means that we're ready
2014// earlier.
Sebastian Jansson63470292019-02-01 10:13:43 +01002015TEST_F(VideoSendStreamTest,
perkjfa10b552016-10-02 23:45:26 -07002016 EncoderReconfigureOnResolutionChangeWhenNotSending) {
2017 class EncoderObserver : public test::FakeEncoder {
2018 public:
2019 EncoderObserver()
2020 : FakeEncoder(Clock::GetRealTimeClock()),
perkjfa10b552016-10-02 23:45:26 -07002021 number_of_initializations_(0),
2022 last_initialized_frame_width_(0),
2023 last_initialized_frame_height_(0) {}
2024
2025 void WaitForResolution(int width, int height) {
2026 {
2027 rtc::CritScope lock(&crit_);
2028 if (last_initialized_frame_width_ == width &&
2029 last_initialized_frame_height_ == height) {
2030 return;
2031 }
2032 }
Erik Språng08127a92016-11-16 16:41:30 +01002033 EXPECT_TRUE(
2034 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07002035 {
2036 rtc::CritScope lock(&crit_);
2037 EXPECT_EQ(width, last_initialized_frame_width_);
2038 EXPECT_EQ(height, last_initialized_frame_height_);
2039 }
2040 }
2041
2042 private:
2043 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002044 const Settings& settings) override {
perkjfa10b552016-10-02 23:45:26 -07002045 rtc::CritScope lock(&crit_);
2046 last_initialized_frame_width_ = config->width;
2047 last_initialized_frame_height_ = config->height;
2048 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01002049 init_encode_called_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002050 return FakeEncoder::InitEncode(config, settings);
perkjfa10b552016-10-02 23:45:26 -07002051 }
2052
2053 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01002054 const std::vector<VideoFrameType>* frame_types) override {
perkjfa10b552016-10-02 23:45:26 -07002055 ADD_FAILURE()
2056 << "Unexpected Encode call since the send stream is not started";
2057 return 0;
2058 }
2059
2060 rtc::CriticalSection crit_;
2061 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07002062 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
2063 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
2064 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002065 };
2066
perkjfa10b552016-10-02 23:45:26 -07002067 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07002068 EncoderObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002069 test::VideoEncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07002070
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002071 SendTask(RTC_FROM_HERE, task_queue(), [this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002072 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002073 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002074 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002075 CreateVideoStreams();
2076 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
2077 kDefaultHeight);
2078 frame_generator_capturer_->Start();
2079 });
perkjfa10b552016-10-02 23:45:26 -07002080
2081 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07002082
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002083 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
eladalon413ee9a2017-08-22 04:02:52 -07002084 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
2085 kDefaultHeight * 2);
2086 });
2087
perkjfa10b552016-10-02 23:45:26 -07002088 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07002089
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002090 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
eladalon413ee9a2017-08-22 04:02:52 -07002091 DestroyStreams();
2092 DestroyCalls();
2093 });
perkjfa10b552016-10-02 23:45:26 -07002094}
2095
Sebastian Jansson63470292019-02-01 10:13:43 +01002096TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002097 class StartBitrateObserver : public test::FakeEncoder {
2098 public:
2099 StartBitrateObserver()
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +02002100 : FakeEncoder(Clock::GetRealTimeClock()), start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002101 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002102 const Settings& settings) override {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002103 rtc::CritScope lock(&crit_);
2104 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07002105 start_bitrate_changed_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002106 return FakeEncoder::InitEncode(config, settings);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002107 }
2108
Erik Språng16cb8f52019-04-12 13:59:09 +02002109 void SetRates(const RateControlParameters& parameters) override {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002110 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002111 start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
pbos14fe7082016-04-20 06:35:56 -07002112 start_bitrate_changed_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002113 FakeEncoder::SetRates(parameters);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002114 }
2115
2116 int GetStartBitrateKbps() const {
2117 rtc::CritScope lock(&crit_);
2118 return start_bitrate_kbps_;
2119 }
2120
pbos14fe7082016-04-20 06:35:56 -07002121 bool WaitForStartBitrate() {
2122 return start_bitrate_changed_.Wait(
2123 VideoSendStreamTest::kDefaultTimeoutMs);
2124 }
2125
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002126 private:
pbos5ad935c2016-01-25 03:52:44 -08002127 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002128 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002129 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002130 };
2131
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002132 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002133
solenberg4fbae2b2015-08-28 04:07:10 -07002134 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002135 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002136
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002137 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002138 bitrate_config.start_bitrate_bps =
2139 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002140 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2141 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002142
2143 StartBitrateObserver encoder;
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002144 test::VideoEncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002145 // Since this test does not use a capturer, set |internal_source| = true.
2146 // Encoder configuration is otherwise updated on the next video frame.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002147 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002148 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002149
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002150 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002151
pbos14fe7082016-04-20 06:35:56 -07002152 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002153 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002154 encoder.GetStartBitrateKbps());
2155
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002156 GetVideoEncoderConfig()->max_bitrate_bps =
2157 2 * bitrate_config.start_bitrate_bps;
2158 GetVideoSendStream()->ReconfigureVideoEncoder(
2159 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002160
2161 // New bitrate should be reconfigured above the previous max. As there's no
2162 // network connection this shouldn't be flaky, as no bitrate should've been
2163 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002164 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002165 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2166 encoder.GetStartBitrateKbps());
2167
2168 DestroyStreams();
2169}
2170
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002171class StartStopBitrateObserver : public test::FakeEncoder {
2172 public:
Niels Möllerc572ff32018-11-07 08:43:50 +01002173 StartStopBitrateObserver() : FakeEncoder(Clock::GetRealTimeClock()) {}
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002174 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002175 const Settings& settings) override {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002176 rtc::CritScope lock(&crit_);
2177 encoder_init_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002178 return FakeEncoder::InitEncode(config, settings);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002179 }
2180
Erik Språng16cb8f52019-04-12 13:59:09 +02002181 void SetRates(const RateControlParameters& parameters) override {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002182 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002183 bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002184 bitrate_changed_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002185 FakeEncoder::SetRates(parameters);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002186 }
2187
2188 bool WaitForEncoderInit() {
2189 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2190 }
2191
2192 bool WaitBitrateChanged(bool non_zero) {
2193 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002194 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002195 {
2196 rtc::CritScope lock(&crit_);
2197 bitrate_kbps = bitrate_kbps_;
2198 }
2199 if (!bitrate_kbps)
2200 continue;
2201
2202 if ((non_zero && *bitrate_kbps > 0) ||
2203 (!non_zero && *bitrate_kbps == 0)) {
2204 return true;
2205 }
2206 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2207 return false;
2208 }
2209
2210 private:
2211 rtc::CriticalSection crit_;
2212 rtc::Event encoder_init_;
2213 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002214 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002215};
2216
perkj57c21f92016-06-17 07:27:16 -07002217// This test that if the encoder use an internal source, VideoEncoder::SetRates
2218// will be called with zero bitrate during initialization and that
2219// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2220// with zero bitrate.
Sebastian Jansson63470292019-02-01 10:13:43 +01002221TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002222 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002223 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002224 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002225 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002226 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002227
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002228 SendTask(RTC_FROM_HERE, task_queue(),
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002229 [this, &transport, &encoder_factory, &forwarder]() {
2230 CreateSenderCall();
2231 CreateSendConfig(1, 0, 0, &transport);
eladalon413ee9a2017-08-22 04:02:52 -07002232
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002233 sender_call_->SignalChannelNetworkState(MediaType::VIDEO,
2234 kNetworkUp);
2235 GetVideoSendConfig()->encoder_settings.encoder_factory =
2236 &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002237
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002238 CreateVideoStreams();
2239 // Inject a frame, to force encoder creation.
2240 GetVideoSendStream()->Start();
2241 GetVideoSendStream()->SetSource(&forwarder,
2242 DegradationPreference::DISABLED);
2243 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
2244 });
perkj57c21f92016-06-17 07:27:16 -07002245
2246 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002247
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002248 SendTask(RTC_FROM_HERE, task_queue(),
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002249 [this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002250 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2251
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002252 SendTask(RTC_FROM_HERE, task_queue(),
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002253 [this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002254 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2255
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002256 SendTask(RTC_FROM_HERE, task_queue(),
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002257 [this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002258 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002259
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002260 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
eladalon413ee9a2017-08-22 04:02:52 -07002261 DestroyStreams();
2262 DestroyCalls();
2263 });
perkj57c21f92016-06-17 07:27:16 -07002264}
2265
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002266// Tests that when the encoder uses an internal source, the VideoEncoder will
2267// be updated with a new bitrate when turning the VideoSendStream on/off with
2268// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2269// is reconfigured with new active layers.
Sebastian Jansson63470292019-02-01 10:13:43 +01002270TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002271 test::NullTransport transport;
2272 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002273 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002274 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002275 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002276
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002277 SendTask(RTC_FROM_HERE, task_queue(),
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002278 [this, &transport, &encoder_factory, &forwarder]() {
2279 CreateSenderCall();
2280 // Create two simulcast streams.
2281 CreateSendConfig(2, 0, 0, &transport);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002282
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002283 sender_call_->SignalChannelNetworkState(MediaType::VIDEO,
2284 kNetworkUp);
2285 GetVideoSendConfig()->encoder_settings.encoder_factory =
2286 &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002287
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002288 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002289
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002290 // Inject a frame, to force encoder creation.
2291 GetVideoSendStream()->Start();
2292 GetVideoSendStream()->SetSource(&forwarder,
2293 DegradationPreference::DISABLED);
2294 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
2295 });
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002296
2297 EXPECT_TRUE(encoder.WaitForEncoderInit());
2298
2299 // When we turn on the simulcast layers it will update the BitrateAllocator,
2300 // which in turn updates the VideoEncoder's bitrate.
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002301 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002302 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002303 });
2304 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2305
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002306 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2307 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002308 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002309 GetVideoSendStream()->ReconfigureVideoEncoder(
2310 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002311 });
2312 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2313 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2314 // active. Once the change is made for a "soft" reconfiguration we can remove
2315 // the expecation for an encoder init. We can also test that bitrate changes
2316 // when just updating individual active layers, which should change the
2317 // bitrate set to the video encoder.
2318 EXPECT_TRUE(encoder.WaitForEncoderInit());
2319 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2320
2321 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002322 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2323 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002324 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002325 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002326 });
2327 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2328
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002329 SendTask(RTC_FROM_HERE, task_queue(), [this]() {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002330 DestroyStreams();
2331 DestroyCalls();
2332 });
2333}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002334
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002335VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002336 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002337 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002338 memset(buffer.get(), data, kSizeY);
Artem Titov1ebfb6a2019-01-03 23:49:37 +01002339 VideoFrame frame =
2340 webrtc::VideoFrame::Builder()
2341 .set_video_frame_buffer(I420Buffer::Create(width, height))
2342 .set_rotation(webrtc::kVideoRotation_0)
2343 .set_timestamp_us(data)
2344 .build();
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002345 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002346 // Use data as a ms timestamp.
2347 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002348 return frame;
2349}
2350
Sebastian Jansson63470292019-02-01 10:13:43 +01002351TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002352 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2353 public:
Danil Chapovalov85a10002019-10-21 15:00:53 +02002354 explicit EncoderStateObserver(TaskQueueBase* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002355 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002356 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002357 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002358 initialized_(false),
2359 callback_registered_(false),
2360 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002361 released_(false),
2362 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002363
2364 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002365 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002366 return released_;
2367 }
2368
2369 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002370 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002371 return initialized_ && callback_registered_;
2372 }
2373
2374 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002375 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002376 return num_releases_;
2377 }
2378
2379 private:
Elad Alon8f01c4e2019-06-28 15:19:43 +02002380 void SetFecControllerOverride(
2381 FecControllerOverride* fec_controller_override) override {
2382 // Ignored.
2383 }
2384
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002385 int32_t InitEncode(const VideoCodec* codecSettings,
Elad Alon370f93a2019-06-11 14:57:57 +02002386 const Settings& settings) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002387 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002388 EXPECT_FALSE(initialized_);
2389 initialized_ = true;
2390 released_ = false;
2391 return 0;
2392 }
2393
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002394 int32_t Encode(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +01002395 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002396 EXPECT_TRUE(IsReadyForEncode());
2397
Peter Boström5811a392015-12-10 13:02:50 +01002398 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002399 return 0;
2400 }
2401
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002402 int32_t RegisterEncodeCompleteCallback(
2403 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002404 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002405 EXPECT_TRUE(initialized_);
2406 callback_registered_ = true;
2407 return 0;
2408 }
2409
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002410 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002411 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002412 EXPECT_TRUE(IsReadyForEncode());
2413 EXPECT_FALSE(released_);
2414 initialized_ = false;
2415 callback_registered_ = false;
2416 released_ = true;
2417 ++num_releases_;
2418 return 0;
2419 }
2420
Erik Språng6f46e4a2019-04-24 18:33:27 +02002421 void SetRates(const RateControlParameters& parameters) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002422 EXPECT_TRUE(IsReadyForEncode());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002423 }
2424
stefanff483612015-12-21 03:14:00 -08002425 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002426 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002427 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002428 stream_ = send_stream;
2429 }
2430
stefanff483612015-12-21 03:14:00 -08002431 void ModifyVideoConfigs(
2432 VideoSendStream::Config* send_config,
2433 std::vector<VideoReceiveStream::Config>* receive_configs,
2434 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002435 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002436 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002437 }
2438
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002439 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002440 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002441
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002442 SendTask(RTC_FROM_HERE, task_queue_, [this]() {
eladalon413ee9a2017-08-22 04:02:52 -07002443 EXPECT_EQ(0u, num_releases());
2444 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2445 EXPECT_EQ(0u, num_releases());
2446 stream_->Stop();
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002447 // Encoder should not be released before destroying the
2448 // VideoSendStream.
eladalon413ee9a2017-08-22 04:02:52 -07002449 EXPECT_FALSE(IsReleased());
2450 EXPECT_TRUE(IsReadyForEncode());
2451 stream_->Start();
2452 });
2453
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002454 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002455 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002456 }
2457
Danil Chapovalov85a10002019-10-21 15:00:53 +02002458 TaskQueueBase* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002459 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002460 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002461 bool initialized_ RTC_GUARDED_BY(crit_);
2462 bool callback_registered_ RTC_GUARDED_BY(crit_);
2463 size_t num_releases_ RTC_GUARDED_BY(crit_);
2464 bool released_ RTC_GUARDED_BY(crit_);
Niels Möllercbcbc222018-09-28 09:07:24 +02002465 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002466 VideoEncoderConfig encoder_config_;
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002467 } test_encoder(task_queue());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002468
stefane74eef12016-01-08 06:47:13 -08002469 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002470
2471 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002472 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002473}
2474
Sergey Silkin571e6c92018-04-03 10:03:31 +02002475static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002476template <typename T>
2477class VideoCodecConfigObserver : public test::SendTest,
2478 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002479 public:
2480 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2481 const char* codec_name)
2482 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2483 FakeEncoder(Clock::GetRealTimeClock()),
2484 video_codec_type_(video_codec_type),
2485 codec_name_(codec_name),
Erik Språng737336d2016-07-29 12:59:36 +02002486 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002487 stream_(nullptr),
2488 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002489 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002490 }
2491
2492 private:
stefanff483612015-12-21 03:14:00 -08002493 void ModifyVideoConfigs(
2494 VideoSendStream::Config* send_config,
2495 std::vector<VideoReceiveStream::Config>* receive_configs,
2496 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002497 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002498 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002499
Niels Möller259a4972018-04-05 15:36:51 +02002500 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002501 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
Åsa Perssond34597c2018-10-22 17:34:02 +02002502 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2503 encoder_config->simulcast_layers[0].num_temporal_layers =
2504 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07002505 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002506 }
2507
stefanff483612015-12-21 03:14:00 -08002508 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002509 VideoSendStream* send_stream,
2510 const std::vector<VideoReceiveStream*>& receive_streams) override {
2511 stream_ = send_stream;
2512 }
2513
2514 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002515 const Settings& settings) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002516 EXPECT_EQ(video_codec_type_, config->codecType);
2517 VerifyCodecSpecifics(*config);
2518 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002519 init_encode_event_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002520 return FakeEncoder::InitEncode(config, settings);
Peter Boström53eda3d2015-03-27 15:53:18 +01002521 }
2522
Sergey Silkin86684962018-03-28 19:32:37 +02002523 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002524 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002525 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2526 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002527
2528 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002529 EXPECT_TRUE(
2530 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002531 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002532
Sergey Silkin86684962018-03-28 19:32:37 +02002533 // Change encoder settings to actually trigger reconfiguration.
2534 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002535 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002536 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002537 ASSERT_TRUE(
2538 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002539 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002540 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2541 "new encoder settings.";
2542 }
2543
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002544 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01002545 const std::vector<VideoFrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002546 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2547 return 0;
2548 }
2549
2550 T encoder_settings_;
2551 const VideoCodecType video_codec_type_;
2552 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002553 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002554 size_t num_initializations_;
2555 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002556 test::VideoEncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002557 VideoEncoderConfig encoder_config_;
2558};
2559
2560template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002561void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2562 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2563}
2564
2565template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002566void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2567 const VideoCodec& config) const {
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002568 // Check that the number of temporal layers has propagated properly to
2569 // VideoCodec.
2570 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2571 config.H264().numberOfTemporalLayers);
2572
2573 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2574 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2575 config.simulcastStream[i].numberOfTemporalLayers);
2576 }
2577
2578 // Set expected temporal layers as they should have been set when
2579 // reconfiguring the encoder and not match the set config.
2580 VideoCodecH264 encoder_settings = encoder_settings_;
2581 encoder_settings.numberOfTemporalLayers =
2582 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002583 EXPECT_EQ(
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002584 0, memcmp(&config.H264(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002585}
kthelgason29a44e32016-09-27 03:52:02 -07002586
2587template <>
2588rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2589VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2590 return new rtc::RefCountedObject<
2591 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2592}
2593
Peter Boström53eda3d2015-03-27 15:53:18 +01002594template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002595void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2596 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2597}
2598
2599template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002600void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2601 const VideoCodec& config) const {
2602 // Check that the number of temporal layers has propagated properly to
2603 // VideoCodec.
2604 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002605 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002606
2607 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2608 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2609 config.simulcastStream[i].numberOfTemporalLayers);
2610 }
2611
2612 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002613 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002614 VideoCodecVP8 encoder_settings = encoder_settings_;
2615 encoder_settings.numberOfTemporalLayers =
2616 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002617 EXPECT_EQ(
2618 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002619}
kthelgason29a44e32016-09-27 03:52:02 -07002620
2621template <>
2622rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2623VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2624 return new rtc::RefCountedObject<
2625 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2626}
2627
Peter Boström53eda3d2015-03-27 15:53:18 +01002628template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002629void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2630 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2631}
2632
2633template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002634void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2635 const VideoCodec& config) const {
2636 // Check that the number of temporal layers has propagated properly to
2637 // VideoCodec.
2638 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002639 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002640
2641 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2642 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2643 config.simulcastStream[i].numberOfTemporalLayers);
2644 }
2645
2646 // Set expected temporal layers as they should have been set when
2647 // reconfiguring the encoder and not match the set config.
2648 VideoCodecVP9 encoder_settings = encoder_settings_;
2649 encoder_settings.numberOfTemporalLayers =
2650 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002651 EXPECT_EQ(
2652 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002653}
2654
kthelgason29a44e32016-09-27 03:52:02 -07002655template <>
2656rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2657VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2658 return new rtc::RefCountedObject<
2659 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2660}
2661
Sebastian Jansson63470292019-02-01 10:13:43 +01002662TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002663 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002664 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002665}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002666
Sebastian Jansson63470292019-02-01 10:13:43 +01002667TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002668 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002669 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002670}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002671
Sebastian Jansson63470292019-02-01 10:13:43 +01002672TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002673 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002674 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002675}
2676
Sebastian Jansson63470292019-02-01 10:13:43 +01002677TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002678 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002679 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002680 RtcpSenderReportTest()
2681 : SendTest(kDefaultTimeoutMs),
2682 rtp_packets_sent_(0),
2683 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002684
2685 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002686 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002687 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002688 RTPHeader header;
2689 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002690 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002691 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2692 return SEND_PACKET;
2693 }
2694
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002695 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002696 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002697 test::RtcpPacketParser parser;
2698 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002699
danilchap3dc929e2016-11-02 08:21:59 -07002700 if (parser.sender_report()->num_packets() > 0) {
2701 // Only compare sent media bytes if SenderPacketCount matches the
2702 // number of sent rtp packets (a new rtp packet could be sent before
2703 // the rtcp packet).
2704 if (parser.sender_report()->sender_octet_count() > 0 &&
2705 parser.sender_report()->sender_packet_count() ==
2706 rtp_packets_sent_) {
2707 EXPECT_EQ(media_bytes_sent_,
2708 parser.sender_report()->sender_octet_count());
2709 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002710 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002711 }
2712
2713 return SEND_PACKET;
2714 }
2715
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002716 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002717 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002718 }
2719
stefan4b569042015-11-11 06:39:57 -08002720 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002721 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2722 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002723 } test;
2724
stefane74eef12016-01-08 06:47:13 -08002725 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002726}
2727
Sebastian Jansson63470292019-02-01 10:13:43 +01002728TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002729 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002730
2731 class VideoStreamFactory
2732 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2733 public:
2734 VideoStreamFactory() {}
2735
2736 private:
2737 std::vector<VideoStream> CreateEncoderStreams(
2738 int width,
2739 int height,
2740 const VideoEncoderConfig& encoder_config) override {
2741 std::vector<VideoStream> streams =
2742 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002743 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2744 kScreencastMaxTargetBitrateDeltaKbps);
2745 streams[0].target_bitrate_bps =
2746 streams[0].max_bitrate_bps -
2747 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002748 return streams;
2749 }
2750 };
2751
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002752 class ScreencastTargetBitrateTest : public test::SendTest,
2753 public test::FakeEncoder {
2754 public:
2755 ScreencastTargetBitrateTest()
2756 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002757 test::FakeEncoder(Clock::GetRealTimeClock()),
2758 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002759
2760 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002761 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002762 const Settings& settings) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002763 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002764 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002765 config->simulcastStream[0].maxBitrate -
2766 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002767 observation_complete_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002768 return test::FakeEncoder::InitEncode(config, settings);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002769 }
Elad Alon370f93a2019-06-11 14:57:57 +02002770
stefanff483612015-12-21 03:14:00 -08002771 void ModifyVideoConfigs(
2772 VideoSendStream::Config* send_config,
2773 std::vector<VideoReceiveStream::Config>* receive_configs,
2774 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002775 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002776 EXPECT_EQ(1u, encoder_config->number_of_streams);
2777 encoder_config->video_stream_factory =
2778 new rtc::RefCountedObject<VideoStreamFactory>();
Åsa Perssond34597c2018-10-22 17:34:02 +02002779 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2780 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
Erik Språng143cec12015-04-28 10:01:41 +02002781 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002782 }
2783
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002784 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002785 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002786 << "Timed out while waiting for the encoder to be initialized.";
2787 }
Niels Möllercbcbc222018-09-28 09:07:24 +02002788 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002789 } test;
2790
stefane74eef12016-01-08 06:47:13 -08002791 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002792}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002793
Sebastian Jansson63470292019-02-01 10:13:43 +01002794TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002795 // These are chosen to be "kind of odd" to not be accidentally checked against
2796 // default values.
2797 static const int kMinBitrateKbps = 137;
2798 static const int kStartBitrateKbps = 345;
2799 static const int kLowerMaxBitrateKbps = 312;
2800 static const int kMaxBitrateKbps = 413;
2801 static const int kIncreasedStartBitrateKbps = 451;
2802 static const int kIncreasedMaxBitrateKbps = 597;
Erik Språng7ca375c2019-02-06 16:20:17 +01002803 // If these fields trial are on, we get lower bitrates than expected by this
2804 // test, due to the packetization overhead and encoder pushback.
Niels Möller6613f8e2019-01-10 10:30:21 +01002805 webrtc::test::ScopedFieldTrials field_trials(
2806 std::string(field_trial::GetFieldTrialString()) +
Erik Språng7ca375c2019-02-06 16:20:17 +01002807 "WebRTC-SubtractPacketizationOverhead/Disabled/"
2808 "WebRTC-VideoRateControl/bitrate_adjuster:false/");
Niels Möller6613f8e2019-01-10 10:30:21 +01002809
pbos@webrtc.org00873182014-11-25 14:03:34 +00002810 class EncoderBitrateThresholdObserver : public test::SendTest,
Sergey Silkin5ee69672019-07-02 14:18:34 +02002811 public VideoBitrateAllocatorFactory,
pbos@webrtc.org00873182014-11-25 14:03:34 +00002812 public test::FakeEncoder {
2813 public:
Danil Chapovalov85a10002019-10-21 15:00:53 +02002814 explicit EncoderBitrateThresholdObserver(TaskQueueBase* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002815 : SendTest(kDefaultTimeoutMs),
2816 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002817 task_queue_(task_queue),
perkj26091b12016-09-01 01:17:40 -07002818 target_bitrate_(0),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002819 num_rate_allocator_creations_(0),
2820 num_encoder_initializations_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002821 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002822 send_stream_(nullptr),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002823 encoder_factory_(this),
2824 bitrate_allocator_factory_(
2825 CreateBuiltinVideoBitrateAllocatorFactory()) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002826
2827 private:
Sergey Silkin5ee69672019-07-02 14:18:34 +02002828 std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
2829 const VideoCodec& codec) override {
2830 EXPECT_GE(codec.startBitrate, codec.minBitrate);
2831 EXPECT_LE(codec.startBitrate, codec.maxBitrate);
2832 if (num_rate_allocator_creations_ == 0) {
2833 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps), codec.minBitrate);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002834 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002835 codec.startBitrate);
2836 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps), codec.maxBitrate);
2837 } else if (num_rate_allocator_creations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002838 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002839 codec.maxBitrate);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002840 // The start bitrate should be kept (-1) and capped to the max bitrate.
2841 // Since this is not an end-to-end call no receiver should have been
2842 // returning a REMB that could lower this estimate.
Sergey Silkin5ee69672019-07-02 14:18:34 +02002843 EXPECT_EQ(codec.startBitrate, codec.maxBitrate);
2844 } else if (num_rate_allocator_creations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002845 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002846 codec.maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002847 // The start bitrate will be whatever the rate BitRateController
2848 // has currently configured but in the span of the set max and min
2849 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002850 }
Sergey Silkin5ee69672019-07-02 14:18:34 +02002851 ++num_rate_allocator_creations_;
2852 create_rate_allocator_event_.Set();
2853
2854 return bitrate_allocator_factory_->CreateVideoBitrateAllocator(codec);
2855 }
2856
2857 int32_t InitEncode(const VideoCodec* codecSettings,
2858 const Settings& settings) override {
2859 EXPECT_EQ(0, num_encoder_initializations_);
2860 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2861 codecSettings->minBitrate);
2862 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2863 codecSettings->startBitrate);
2864 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2865 codecSettings->maxBitrate);
2866
2867 ++num_encoder_initializations_;
2868
2869 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002870 init_encode_event_.Set();
2871
Elad Alon370f93a2019-06-11 14:57:57 +02002872 return FakeEncoder::InitEncode(codecSettings, settings);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002873 }
2874
Erik Språng16cb8f52019-04-12 13:59:09 +02002875 void SetRates(const RateControlParameters& parameters) override {
perkj26091b12016-09-01 01:17:40 -07002876 {
2877 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002878 if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) {
2879 FakeEncoder::SetRates(parameters);
2880 return;
perkjfa10b552016-10-02 23:45:26 -07002881 }
Erik Språng16cb8f52019-04-12 13:59:09 +02002882 target_bitrate_ = parameters.bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002883 }
2884 bitrate_changed_event_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002885 FakeEncoder::SetRates(parameters);
perkj26091b12016-09-01 01:17:40 -07002886 }
2887
2888 void WaitForSetRates(uint32_t expected_bitrate) {
Niels Möller6bb5ab92019-01-11 11:11:10 +01002889 // Wait for the expected rate to be set. In some cases there can be
2890 // more than one update pending, in which case we keep waiting
2891 // until the correct value has been observed.
2892 const int64_t start_time = rtc::TimeMillis();
2893 do {
2894 rtc::CritScope lock(&crit_);
2895 if (target_bitrate_ == expected_bitrate) {
2896 return;
2897 }
2898 } while (bitrate_changed_event_.Wait(
2899 std::max(int64_t{1}, VideoSendStreamTest::kDefaultTimeoutMs -
2900 (rtc::TimeMillis() - start_time))));
Niels Möller6613f8e2019-01-10 10:30:21 +01002901 rtc::CritScope lock(&crit_);
Niels Möller6bb5ab92019-01-11 11:11:10 +01002902 EXPECT_EQ(target_bitrate_, expected_bitrate)
2903 << "Timed out while waiting encoder rate to be set.";
perkj26091b12016-09-01 01:17:40 -07002904 }
2905
Niels Möllerde8e6e62018-11-13 15:10:33 +01002906 void ModifySenderBitrateConfig(
2907 BitrateConstraints* bitrate_config) override {
2908 bitrate_config->min_bitrate_bps = kMinBitrateKbps * 1000;
2909 bitrate_config->start_bitrate_bps = kStartBitrateKbps * 1000;
2910 bitrate_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002911 }
2912
stefanff483612015-12-21 03:14:00 -08002913 void ModifyVideoConfigs(
2914 VideoSendStream::Config* send_config,
2915 std::vector<VideoReceiveStream::Config>* receive_configs,
2916 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002917 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002918 send_config->encoder_settings.bitrate_allocator_factory = this;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002919 // Set bitrates lower/higher than min/max to make sure they are properly
2920 // capped.
perkjfa10b552016-10-02 23:45:26 -07002921 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
Åsa Persson21740532019-04-15 14:00:30 +02002922 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2923 encoder_config->simulcast_layers[0].min_bitrate_bps =
2924 kMinBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002925 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002926 }
2927
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002928 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002929 call_ = sender_call;
2930 }
2931
stefanff483612015-12-21 03:14:00 -08002932 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002933 VideoSendStream* send_stream,
2934 const std::vector<VideoReceiveStream*>& receive_streams) override {
2935 send_stream_ = send_stream;
2936 }
2937
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002938 void PerformTest() override {
Sergey Silkin5ee69672019-07-02 14:18:34 +02002939 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2940 VideoSendStreamTest::kDefaultTimeoutMs))
2941 << "Timed out while waiting for rate allocator to be created.";
pbos14fe7082016-04-20 06:35:56 -07002942 ASSERT_TRUE(
2943 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002944 << "Timed out while waiting for encoder to be configured.";
2945 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002946 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002947 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2948 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02002949 SendTask(RTC_FROM_HERE, task_queue_, [this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002950 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2951 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002952 });
perkj26091b12016-09-01 01:17:40 -07002953 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2954 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002955 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002956 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Sergey Silkin5ee69672019-07-02 14:18:34 +02002957 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2958 VideoSendStreamTest::kDefaultTimeoutMs));
2959 EXPECT_EQ(2, num_rate_allocator_creations_)
2960 << "Rate allocator should have been recreated.";
2961
perkjfa10b552016-10-02 23:45:26 -07002962 WaitForSetRates(kLowerMaxBitrateKbps);
Sergey Silkin5ee69672019-07-02 14:18:34 +02002963 EXPECT_EQ(1, num_encoder_initializations_);
perkjfa10b552016-10-02 23:45:26 -07002964
2965 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2966 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Sergey Silkin5ee69672019-07-02 14:18:34 +02002967 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2968 VideoSendStreamTest::kDefaultTimeoutMs));
2969 EXPECT_EQ(3, num_rate_allocator_creations_)
2970 << "Rate allocator should have been recreated.";
2971
perkj26091b12016-09-01 01:17:40 -07002972 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002973 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002974 WaitForSetRates(kIncreasedStartBitrateKbps);
Sergey Silkin5ee69672019-07-02 14:18:34 +02002975 EXPECT_EQ(1, num_encoder_initializations_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002976 }
2977
Danil Chapovalov85a10002019-10-21 15:00:53 +02002978 TaskQueueBase* const task_queue_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002979 rtc::Event create_rate_allocator_event_;
pbos14fe7082016-04-20 06:35:56 -07002980 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002981 rtc::Event bitrate_changed_event_;
2982 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002983 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002984
Sergey Silkin5ee69672019-07-02 14:18:34 +02002985 int num_rate_allocator_creations_;
2986 int num_encoder_initializations_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002987 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002988 webrtc::VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002989 test::VideoEncoderProxyFactory encoder_factory_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002990 std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002991 webrtc::VideoEncoderConfig encoder_config_;
Danil Chapovalovd15a0282019-10-22 10:48:17 +02002992 } test(task_queue());
pbos@webrtc.org00873182014-11-25 14:03:34 +00002993
stefane74eef12016-01-08 06:47:13 -08002994 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002995}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002996
Sebastian Jansson63470292019-02-01 10:13:43 +01002997TEST_F(VideoSendStreamTest, ReportsSentResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002998 static const size_t kNumStreams = 3;
2999 // Unusual resolutions to make sure that they are the ones being reported.
3000 static const struct {
3001 int width;
3002 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02003003 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003004 class ScreencastTargetBitrateTest : public test::SendTest,
3005 public test::FakeEncoder {
3006 public:
3007 ScreencastTargetBitrateTest()
3008 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02003009 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02003010 send_stream_(nullptr),
3011 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003012
3013 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003014 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01003015 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003016 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003017 specifics.codecType = kVideoCodecGeneric;
3018
3019 uint8_t buffer[16] = {0};
3020 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
Niels Möller23775882018-08-16 10:24:12 +02003021 encoded.SetTimestamp(input_image.timestamp());
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003022 encoded.capture_time_ms_ = input_image.render_time_ms();
3023
3024 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003025 encoded._frameType = (*frame_types)[i];
3026 encoded._encodedWidth = kEncodedResolution[i].width;
3027 encoded._encodedHeight = kEncodedResolution[i].height;
Niels Möllerd3b8c632018-08-27 15:33:42 +02003028 encoded.SetSpatialIndex(i);
brandtre78d2662017-01-16 05:57:16 -08003029 EncodedImageCallback* callback;
3030 {
3031 rtc::CritScope cs(&crit_sect_);
3032 callback = callback_;
3033 }
3034 RTC_DCHECK(callback);
3035 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003036 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003037 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003038 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003039 }
3040
Peter Boström5811a392015-12-10 13:02:50 +01003041 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003042 return 0;
3043 }
stefanff483612015-12-21 03:14:00 -08003044 void ModifyVideoConfigs(
3045 VideoSendStream::Config* send_config,
3046 std::vector<VideoReceiveStream::Config>* receive_configs,
3047 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003048 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003049 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003050 }
3051
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003052 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003053
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003054 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003055 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003056 << "Timed out while waiting for the encoder to send one frame.";
3057 VideoSendStream::Stats stats = send_stream_->GetStats();
3058
3059 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003060 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003061 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003062 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003063 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003064 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003065 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003066 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3067 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003068 }
3069 }
3070
stefanff483612015-12-21 03:14:00 -08003071 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003072 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003073 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003074 send_stream_ = send_stream;
3075 }
3076
3077 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003078 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003079 } test;
3080
stefane74eef12016-01-08 06:47:13 -08003081 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003082}
philipel0f9af012015-09-01 07:01:51 -07003083
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003084#if defined(RTC_ENABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003085class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003086 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003087 Vp9HeaderObserver()
3088 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003089 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003090 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3091 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003092 frames_sent_(0),
3093 expected_width_(0),
3094 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003095
stefanff483612015-12-21 03:14:00 -08003096 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003097 VideoSendStream::Config* send_config,
3098 std::vector<VideoReceiveStream::Config>* receive_configs,
3099 VideoEncoderConfig* encoder_config) {}
3100
Åsa Perssonff24c042015-12-04 10:58:08 +01003101 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003102
3103 private:
minyue20c84cc2017-04-10 16:57:57 -07003104 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003105
stefanff483612015-12-21 03:14:00 -08003106 void ModifyVideoConfigs(
3107 VideoSendStream::Config* send_config,
3108 std::vector<VideoReceiveStream::Config>* receive_configs,
3109 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003110 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003111 send_config->rtp.payload_name = "VP9";
3112 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003113 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003114 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003115 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003116 EXPECT_EQ(1u, encoder_config->number_of_streams);
Åsa Perssond34597c2018-10-22 17:34:02 +02003117 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
3118 encoder_config->simulcast_layers[0].num_temporal_layers =
3119 vp9_settings_.numberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07003120 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003121 }
3122
perkjfa10b552016-10-02 23:45:26 -07003123 void ModifyVideoCaptureStartResolution(int* width,
3124 int* height,
3125 int* frame_rate) override {
3126 expected_width_ = *width;
3127 expected_height_ = *height;
3128 }
3129
philipel0f9af012015-09-01 07:01:51 -07003130 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003131 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3132 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003133 }
3134
3135 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3136 RTPHeader header;
3137 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3138
Åsa Perssonff24c042015-12-04 10:58:08 +01003139 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3140 const uint8_t* payload = packet + header.headerLength;
3141 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003142
Åsa Perssonff24c042015-12-04 10:58:08 +01003143 bool new_packet = packets_sent_ == 0 ||
3144 IsNewerSequenceNumber(header.sequenceNumber,
3145 last_header_.sequenceNumber);
3146 if (payload_length > 0 && new_packet) {
3147 RtpDepacketizer::ParsedPayload parsed;
3148 RtpDepacketizerVp9 depacketizer;
3149 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003150 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003151 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003152 const auto& vp9_header =
3153 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3154 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003155 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003156 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003157 InspectHeader(vp9_header);
philipel0f9af012015-09-01 07:01:51 -07003158
Åsa Perssonff24c042015-12-04 10:58:08 +01003159 ++packets_sent_;
3160 if (header.markerBit) {
3161 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003162 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003163 last_header_ = header;
philipel29d88462018-08-08 14:26:00 +02003164 last_vp9_ = vp9_header;
philipel0f9af012015-09-01 07:01:51 -07003165 }
philipel0f9af012015-09-01 07:01:51 -07003166 return SEND_PACKET;
3167 }
3168
philipel7fabd462015-09-03 04:42:32 -07003169 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003170 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3171 if (last_vp9_.picture_id > vp9.picture_id) {
3172 return vp9.picture_id == 0; // Wrap.
3173 } else {
3174 return vp9.picture_id == last_vp9_.picture_id + 1;
3175 }
3176 }
3177
3178 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003179 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3180 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3181 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3182 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3183 vp9.spatial_idx);
3184 }
3185
3186 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3187 uint8_t num_layers) const {
3188 switch (num_layers) {
3189 case 0:
3190 VerifyTemporalLayerStructure0(vp9);
3191 break;
3192 case 1:
3193 VerifyTemporalLayerStructure1(vp9);
3194 break;
3195 case 2:
3196 VerifyTemporalLayerStructure2(vp9);
3197 break;
3198 case 3:
3199 VerifyTemporalLayerStructure3(vp9);
3200 break;
3201 default:
3202 RTC_NOTREACHED();
3203 }
3204 }
3205
3206 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3207 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3208 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3209 EXPECT_FALSE(vp9.temporal_up_switch);
3210 }
3211
3212 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3213 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3214 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3215 EXPECT_FALSE(vp9.temporal_up_switch);
3216 }
3217
3218 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3219 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3220 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3221 EXPECT_LE(vp9.temporal_idx, 1);
3222 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3223 if (IsNewPictureId(vp9)) {
3224 uint8_t expected_tid =
3225 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3226 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3227 }
3228 }
3229
3230 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3231 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3232 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3233 EXPECT_LE(vp9.temporal_idx, 2);
3234 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3235 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3236 switch (vp9.temporal_idx) {
3237 case 0:
3238 EXPECT_EQ(2, last_vp9_.temporal_idx);
3239 EXPECT_FALSE(vp9.temporal_up_switch);
3240 break;
3241 case 1:
3242 EXPECT_EQ(2, last_vp9_.temporal_idx);
3243 EXPECT_TRUE(vp9.temporal_up_switch);
3244 break;
3245 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003246 EXPECT_LT(last_vp9_.temporal_idx, 2);
3247 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003248 break;
3249 }
3250 }
3251 }
3252
3253 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3254 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3255 return;
3256
3257 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3258 if (vp9.temporal_idx == 0)
3259 ++expected_tl0_idx;
3260 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3261 }
3262
3263 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3264 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3265 }
3266
3267 // Flexible mode (F=1): Non-flexible mode (F=0):
3268 //
3269 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3270 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3271 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3272 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3273 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3274 // M: | EXTENDED PID | M: | EXTENDED PID |
3275 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3276 // L: | T |U| S |D| L: | T |U| S |D|
3277 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3278 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3279 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3280 // X: |EXTENDED P_DIFF| V: | SS .. |
3281 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3282 // V: | SS .. |
3283 // +-+-+-+-+-+-+-+-+
3284 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3285 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3286 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3287 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003288
3289 if (vp9_settings_.numberOfSpatialLayers > 1) {
3290 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3291 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3292 EXPECT_EQ(vp9.spatial_idx, 0);
3293 } else {
3294 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3295 }
3296
3297 if (vp9_settings_.numberOfTemporalLayers > 1) {
3298 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3299 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3300 EXPECT_EQ(vp9.temporal_idx, 0);
3301 } else {
3302 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3303 }
3304
Åsa Perssonff24c042015-12-04 10:58:08 +01003305 if (vp9.ss_data_available) // V
3306 VerifySsData(vp9);
3307
3308 if (frames_sent_ == 0)
3309 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3310
3311 if (!vp9.inter_pic_predicted) {
3312 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3313 EXPECT_FALSE(vp9.temporal_up_switch);
3314 }
3315 }
3316
3317 // Scalability structure (SS).
3318 //
3319 // +-+-+-+-+-+-+-+-+
3320 // V: | N_S |Y|G|-|-|-|
3321 // +-+-+-+-+-+-+-+-+
3322 // Y: | WIDTH | N_S + 1 times
3323 // +-+-+-+-+-+-+-+-+
3324 // | HEIGHT |
3325 // +-+-+-+-+-+-+-+-+
3326 // G: | N_G |
3327 // +-+-+-+-+-+-+-+-+
3328 // N_G: | T |U| R |-|-| N_G times
3329 // +-+-+-+-+-+-+-+-+
3330 // | P_DIFF | R times
3331 // +-+-+-+-+-+-+-+-+
3332 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3333 EXPECT_TRUE(vp9.ss_data_available); // V
3334 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3335 vp9.num_spatial_layers);
3336 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003337 int expected_width = expected_width_;
3338 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003339 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003340 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3341 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3342 expected_width /= 2;
3343 expected_height /= 2;
3344 }
3345 }
3346
3347 void CompareConsecutiveFrames(const RTPHeader& header,
3348 const RTPVideoHeader& video) const {
philipel29d88462018-08-08 14:26:00 +02003349 const auto& vp9_header =
3350 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003351
3352 bool new_frame = packets_sent_ == 0 ||
3353 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003354 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003355 if (!new_frame) {
3356 EXPECT_FALSE(last_header_.markerBit);
3357 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003358 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3359 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3360 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3361 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003362 return;
3363 }
3364 // New frame.
philipel29d88462018-08-08 14:26:00 +02003365 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003366
3367 // Compare with last packet in previous frame.
3368 if (frames_sent_ == 0)
3369 return;
3370 EXPECT_TRUE(last_vp9_.end_of_frame);
3371 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003372 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3373 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003374 }
3375
Niels Möller4db138e2018-04-19 09:04:13 +02003376 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003377 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003378 webrtc::VideoEncoderConfig encoder_config_;
3379 RTPHeader last_header_;
3380 RTPVideoHeaderVP9 last_vp9_;
3381 size_t packets_sent_;
3382 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003383 int expected_width_;
3384 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003385};
3386
Sebastian Jansson63470292019-02-01 10:13:43 +01003387TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003388 const uint8_t kNumTemporalLayers = 1;
3389 const uint8_t kNumSpatialLayers = 1;
3390 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3391}
3392
Sebastian Jansson63470292019-02-01 10:13:43 +01003393TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003394 const uint8_t kNumTemporalLayers = 2;
3395 const uint8_t kNumSpatialLayers = 1;
3396 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3397}
3398
Sebastian Jansson63470292019-02-01 10:13:43 +01003399TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003400 const uint8_t kNumTemporalLayers = 3;
3401 const uint8_t kNumSpatialLayers = 1;
3402 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3403}
3404
Sebastian Jansson63470292019-02-01 10:13:43 +01003405TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003406 const uint8_t kNumTemporalLayers = 1;
3407 const uint8_t kNumSpatialLayers = 2;
3408 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3409}
3410
Sebastian Jansson63470292019-02-01 10:13:43 +01003411TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003412 const uint8_t kNumTemporalLayers = 2;
3413 const uint8_t kNumSpatialLayers = 2;
3414 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3415}
3416
Sebastian Jansson63470292019-02-01 10:13:43 +01003417TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003418 const uint8_t kNumTemporalLayers = 3;
3419 const uint8_t kNumSpatialLayers = 2;
3420 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3421}
3422
3423void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3424 uint8_t num_spatial_layers) {
3425 static const size_t kNumFramesToSend = 100;
3426 // Set to < kNumFramesToSend and coprime to length of temporal layer
3427 // structures to verify temporal id reset on key frame.
3428 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003429
3430 static const int kWidth = kMinVp9SpatialLayerWidth;
3431 static const int kHeight = kMinVp9SpatialLayerHeight;
3432 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003433 class NonFlexibleMode : public Vp9HeaderObserver {
3434 public:
3435 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3436 : num_temporal_layers_(num_temporal_layers),
3437 num_spatial_layers_(num_spatial_layers),
3438 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003439
stefanff483612015-12-21 03:14:00 -08003440 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003441 VideoSendStream::Config* send_config,
3442 std::vector<VideoReceiveStream::Config>* receive_configs,
3443 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003444 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003445 int bitrate_bps = 0;
3446 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3447 const int width = kWidth << sl_idx;
3448 const int height = kHeight << sl_idx;
3449 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3450 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3451 }
3452 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3453
Åsa Perssonff24c042015-12-04 10:58:08 +01003454 vp9_settings_.flexibleMode = false;
3455 vp9_settings_.frameDroppingOn = false;
3456 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3457 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3458 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003459 }
3460
Sergey Silkin86684962018-03-28 19:32:37 +02003461 void ModifyVideoCaptureStartResolution(int* width,
3462 int* height,
3463 int* frame_rate) override {
3464 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3465 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3466 *width = expected_width_;
3467 *height = expected_height_;
3468 }
3469
Åsa Perssonff24c042015-12-04 10:58:08 +01003470 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003471 bool ss_data_expected =
3472 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3473 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003474 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003475 if (num_spatial_layers_ > 1) {
3476 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3477 } else {
3478 EXPECT_FALSE(vp9.inter_layer_predicted);
3479 }
3480
asapersson38bb8ad2015-12-14 01:41:19 -08003481 EXPECT_EQ(!vp9.inter_pic_predicted,
3482 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003483
3484 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003485 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3486 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3487 } else {
3488 EXPECT_EQ(0, vp9.spatial_idx);
3489 }
3490 if (num_spatial_layers_ > 1)
3491 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003492 }
3493
3494 VerifyFixedTemporalLayerStructure(vp9,
3495 l_field_ ? num_temporal_layers_ : 0);
3496
3497 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003498 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003499 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003500 const uint8_t num_temporal_layers_;
3501 const uint8_t num_spatial_layers_;
3502 const bool l_field_;
Nikita Zetilov8ae70f62019-11-12 16:13:10 +01003503
3504 private:
3505 void ModifySenderBitrateConfig(
3506 BitrateConstraints* bitrate_config) override {
3507 const int kMinBitrateBps = 300000;
3508 bitrate_config->min_bitrate_bps = kMinBitrateBps;
3509 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003510 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003511
stefane74eef12016-01-08 06:47:13 -08003512 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003513}
3514
Sebastian Jansson63470292019-02-01 10:13:43 +01003515TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
asaperssond9f641e2016-01-21 01:11:35 -08003516 static const size_t kNumFramesToSend = 50;
3517 static const int kWidth = 4;
3518 static const int kHeight = 4;
3519 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3520 void ModifyVideoConfigsHook(
3521 VideoSendStream::Config* send_config,
3522 std::vector<VideoReceiveStream::Config>* receive_configs,
3523 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003524 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003525 vp9_settings_.flexibleMode = false;
3526 vp9_settings_.numberOfTemporalLayers = 1;
3527 vp9_settings_.numberOfSpatialLayers = 1;
3528
perkjfa10b552016-10-02 23:45:26 -07003529 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003530 }
3531
3532 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3533 if (frames_sent_ > kNumFramesToSend)
3534 observation_complete_.Set();
3535 }
perkjfa10b552016-10-02 23:45:26 -07003536
3537 void ModifyVideoCaptureStartResolution(int* width,
3538 int* height,
3539 int* frame_rate) override {
3540 expected_width_ = kWidth;
3541 expected_height_ = kHeight;
3542 *width = kWidth;
3543 *height = kHeight;
3544 }
asaperssond9f641e2016-01-21 01:11:35 -08003545 } test;
3546
3547 RunBaseTest(&test);
3548}
3549
kjellanderf9e2a362017-03-24 12:17:33 -07003550#if defined(WEBRTC_ANDROID)
3551// Crashes on Android; bugs.webrtc.org/7401
3552#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3553#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003554// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3555// the test after webrtc:9270 is implemented.
3556#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3557// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003558#endif
Sebastian Jansson63470292019-02-01 10:13:43 +01003559TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003560 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003561 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003562 VideoSendStream::Config* send_config,
3563 std::vector<VideoReceiveStream::Config>* receive_configs,
3564 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003565 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003566 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003567 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003568 vp9_settings_.numberOfTemporalLayers = 1;
3569 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003570 }
3571
Åsa Perssonff24c042015-12-04 10:58:08 +01003572 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3573 EXPECT_TRUE(vp9_header.flexible_mode);
3574 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3575 if (vp9_header.inter_pic_predicted) {
3576 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003577 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003578 }
3579 }
3580 } test;
3581
stefane74eef12016-01-08 06:47:13 -08003582 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003583}
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003584#endif // defined(RTC_ENABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003585
perkj803d97f2016-11-01 11:45:46 -07003586void VideoSendStreamTest::TestRequestSourceRotateVideo(
3587 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003588 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003589
3590 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003591 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003592 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003593 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003594 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003595 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3596 }
3597
3598 CreateVideoStreams();
3599 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003600 GetVideoSendStream()->SetSource(&forwarder,
3601 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003602
3603 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3604 support_orientation_ext);
3605
3606 DestroyStreams();
3607}
3608
Sebastian Jansson63470292019-02-01 10:13:43 +01003609TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003610 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3611 TestRequestSourceRotateVideo(false);
3612}
3613
Sebastian Jansson63470292019-02-01 10:13:43 +01003614TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003615 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3616 TestRequestSourceRotateVideo(true);
3617}
3618
Sebastian Jansson63470292019-02-01 10:13:43 +01003619TEST_F(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) {
Åsa Perssonf06bacc2018-10-12 11:07:20 +02003620 static const int kMaxFps = 22;
3621 class FpsObserver : public test::SendTest,
3622 public test::FrameGeneratorCapturer::SinkWantsObserver {
3623 public:
3624 FpsObserver() : SendTest(kDefaultTimeoutMs) {}
3625
3626 void OnFrameGeneratorCapturerCreated(
3627 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3628 frame_generator_capturer->SetSinkWantsObserver(this);
3629 }
3630
3631 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
3632 const rtc::VideoSinkWants& wants) override {
3633 if (wants.max_framerate_fps == kMaxFps)
3634 observation_complete_.Set();
3635 }
3636
3637 void ModifyVideoConfigs(
3638 VideoSendStream::Config* send_config,
3639 std::vector<VideoReceiveStream::Config>* receive_configs,
3640 VideoEncoderConfig* encoder_config) override {
3641 encoder_config->simulcast_layers[0].max_framerate = kMaxFps;
3642 }
3643
3644 void PerformTest() override {
3645 EXPECT_TRUE(Wait()) << "Timed out while waiting for fps to be reported.";
3646 }
3647 } test;
3648
3649 RunBaseTest(&test);
3650}
3651
michaelta3328772016-11-29 09:25:03 -08003652// This test verifies that overhead is removed from the bandwidth estimate by
3653// testing that the maximum possible target payload rate is smaller than the
3654// maximum bandwidth estimate by the overhead rate.
Sebastian Jansson63470292019-02-01 10:13:43 +01003655TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003656 test::ScopedFieldTrials override_field_trials(
3657 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3658 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3659 public test::FakeEncoder {
3660 public:
Danil Chapovalov85a10002019-10-21 15:00:53 +02003661 explicit RemoveOverheadFromBandwidthTest(TaskQueueBase* task_queue)
michaelta3328772016-11-29 09:25:03 -08003662 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3663 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003664 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003665 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003666 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003667 max_bitrate_bps_(0),
Niels Möllerc572ff32018-11-07 08:43:50 +01003668 first_packet_sent_(false) {}
michaelta3328772016-11-29 09:25:03 -08003669
Erik Språng16cb8f52019-04-12 13:59:09 +02003670 void SetRates(const RateControlParameters& parameters) override {
michaelta3328772016-11-29 09:25:03 -08003671 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003672 // Wait for the first sent packet so that videosendstream knows
3673 // rtp_overhead.
3674 if (first_packet_sent_) {
Erik Språng16cb8f52019-04-12 13:59:09 +02003675 max_bitrate_bps_ = parameters.bitrate.get_sum_bps();
michaelt192132e2017-01-26 09:05:27 -08003676 bitrate_changed_event_.Set();
3677 }
Erik Språng16cb8f52019-04-12 13:59:09 +02003678 return FakeEncoder::SetRates(parameters);
michaelta3328772016-11-29 09:25:03 -08003679 }
3680
3681 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3682 call_ = sender_call;
3683 }
3684
3685 void ModifyVideoConfigs(
3686 VideoSendStream::Config* send_config,
3687 std::vector<VideoReceiveStream::Config>* receive_configs,
3688 VideoEncoderConfig* encoder_config) override {
3689 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003690 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003691 EXPECT_FALSE(send_config->rtp.extensions.empty());
3692 }
3693
michaelt192132e2017-01-26 09:05:27 -08003694 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3695 rtc::CritScope lock(&crit_);
3696 first_packet_sent_ = true;
3697 return SEND_PACKET;
3698 }
3699
michaelta3328772016-11-29 09:25:03 -08003700 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003701 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003702 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003703 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003704 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003705 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3706 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003707 bitrate_config.min_bitrate_bps = kMinBitrateBps;
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02003708 SendTask(RTC_FROM_HERE, task_queue_, [this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003709 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3710 bitrate_config);
Stefan Holmer64be7fa2018-10-04 15:21:55 +02003711 call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
eladalon413ee9a2017-08-22 04:02:52 -07003712 });
michaelta3328772016-11-29 09:25:03 -08003713
3714 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003715 // overhead of 40B per packet video produces 2240bps overhead.
3716 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003717 EXPECT_TRUE(
3718 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003719 {
3720 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003721 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003722 }
3723 }
3724
3725 private:
Danil Chapovalov85a10002019-10-21 15:00:53 +02003726 TaskQueueBase* const task_queue_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003727 test::VideoEncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003728 Call* call_;
3729 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003730 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3731 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003732 rtc::Event bitrate_changed_event_;
Danil Chapovalovd15a0282019-10-22 10:48:17 +02003733 } test(task_queue());
michaelta3328772016-11-29 09:25:03 -08003734 RunBaseTest(&test);
3735}
3736
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003737class PacingFactorObserver : public test::SendTest {
3738 public:
3739 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003740 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003741 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3742 configure_send_side_(configure_send_side),
3743 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003744
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003745 void ModifyVideoConfigs(
3746 VideoSendStream::Config* send_config,
3747 std::vector<VideoReceiveStream::Config>* receive_configs,
3748 VideoEncoderConfig* encoder_config) override {
3749 // Check if send-side bwe extension is already present, and remove it if
3750 // it is not desired.
3751 bool has_send_side = false;
3752 for (auto it = send_config->rtp.extensions.begin();
3753 it != send_config->rtp.extensions.end(); ++it) {
3754 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3755 if (configure_send_side_) {
3756 has_send_side = true;
3757 } else {
3758 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003759 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003760 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003761 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003762 }
3763
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003764 if (configure_send_side_ && !has_send_side) {
Elad Alon157540a2019-02-08 23:37:52 +01003765 rtc::UniqueNumberGenerator<int> unique_id_generator;
3766 unique_id_generator.AddKnownId(0); // First valid RTP extension ID is 1.
3767 for (const RtpExtension& extension : send_config->rtp.extensions) {
3768 unique_id_generator.AddKnownId(extension.id);
3769 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003770 // Want send side, not present by default, so add it.
3771 send_config->rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +01003772 RtpExtension::kTransportSequenceNumberUri, unique_id_generator());
Erik Språng7c8cca32017-10-24 17:05:18 +02003773 }
3774
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003775 // ALR only enabled for screenshare.
3776 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3777 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003778
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003779 void OnVideoStreamsCreated(
3780 VideoSendStream* send_stream,
3781 const std::vector<VideoReceiveStream*>& receive_streams) override {
3782 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3783 // Video streams created, check that pacing factor is correctly configured.
3784 EXPECT_EQ(expected_pacing_factor_,
3785 internal_send_peer.GetPacingFactorOverride());
3786 observation_complete_.Set();
3787 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003788
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003789 void PerformTest() override {
3790 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3791 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003792
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003793 private:
3794 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003795 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003796};
3797
3798std::string GetAlrProbingExperimentString() {
3799 return std::string(
3800 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3801 "/1.0,2875,80,40,-60,3/";
3802}
3803const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3804
Sebastian Jansson63470292019-02-01 10:13:43 +01003805TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003806 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003807 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003808 PacingFactorObserver test_with_send_side(true,
3809 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003810 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003811}
Erik Språng7c8cca32017-10-24 17:05:18 +02003812
Sebastian Jansson63470292019-02-01 10:13:43 +01003813TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003814 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3815 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003816 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003817 RunBaseTest(&test_without_send_side);
3818}
3819
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003820// Test class takes as argument a function pointer to reset the send
3821// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3822// change the content type of a VideoSendStream, you need to recreate it.
3823// Stopping and recreating the stream can only be done on the main thread and in
3824// the context of VideoSendStreamTest (not BaseTest). The test switches from
3825// realtime to screenshare and back.
3826template <typename T>
3827class ContentSwitchTest : public test::SendTest {
3828 public:
3829 enum class StreamState {
3830 kBeforeSwitch = 0,
3831 kInScreenshare = 1,
3832 kAfterSwitchBack = 2,
3833 };
3834 static const uint32_t kMinPacketsToSend = 50;
3835
3836 explicit ContentSwitchTest(T* stream_reset_fun)
3837 : SendTest(test::CallTest::kDefaultTimeoutMs),
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003838 call_(nullptr),
3839 state_(StreamState::kBeforeSwitch),
3840 send_stream_(nullptr),
3841 send_stream_config_(nullptr),
3842 packets_sent_(0),
3843 stream_resetter_(stream_reset_fun) {
3844 RTC_DCHECK(stream_resetter_);
3845 }
3846
3847 void OnVideoStreamsCreated(
3848 VideoSendStream* send_stream,
3849 const std::vector<VideoReceiveStream*>& receive_streams) override {
3850 rtc::CritScope lock(&crit_);
3851 send_stream_ = send_stream;
3852 }
3853
3854 void ModifyVideoConfigs(
3855 VideoSendStream::Config* send_config,
3856 std::vector<VideoReceiveStream::Config>* receive_configs,
3857 VideoEncoderConfig* encoder_config) override {
3858 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3859 encoder_config->min_transmit_bitrate_bps = 0;
3860 encoder_config->content_type =
3861 VideoEncoderConfig::ContentType::kRealtimeVideo;
3862 send_stream_config_ = send_config->Copy();
3863 encoder_config_ = encoder_config->Copy();
3864 }
3865
3866 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3867 call_ = sender_call;
3868 }
3869
3870 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3871 rtc::CritScope lock(&crit_);
3872
3873 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3874 float pacing_factor =
3875 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3876 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3877 if (send_stream_->GetStats().content_type ==
3878 webrtc::VideoContentType::SCREENSHARE) {
3879 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3880 }
3881
3882 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3883
3884 // Wait until at least kMinPacketsToSend packets to be sent, so that
3885 // some frames would be encoded.
3886 if (++packets_sent_ < kMinPacketsToSend)
3887 return SEND_PACKET;
3888
3889 if (state_ != StreamState::kAfterSwitchBack) {
3890 // We've sent kMinPacketsToSend packets, switch the content type and move
3891 // move to the next state.
3892 // Note that we need to recreate the stream if changing content type.
3893 packets_sent_ = 0;
3894 if (encoder_config_.content_type ==
3895 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3896 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3897 } else {
3898 encoder_config_.content_type =
3899 VideoEncoderConfig::ContentType::kRealtimeVideo;
3900 }
3901 switch (state_) {
3902 case StreamState::kBeforeSwitch:
3903 state_ = StreamState::kInScreenshare;
3904 break;
3905 case StreamState::kInScreenshare:
3906 state_ = StreamState::kAfterSwitchBack;
3907 break;
3908 case StreamState::kAfterSwitchBack:
3909 RTC_NOTREACHED();
3910 break;
3911 }
3912 content_switch_event_.Set();
3913 return SEND_PACKET;
3914 }
3915
3916 observation_complete_.Set();
3917 return SEND_PACKET;
3918 }
3919
3920 void PerformTest() override {
3921 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3922 ASSERT_TRUE(
3923 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3924 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3925 }
3926
3927 ASSERT_TRUE(Wait())
3928 << "Timed out waiting for a frame sent after switch back";
3929 }
3930
3931 private:
3932 StreamState GetStreamState() {
3933 rtc::CritScope lock(&crit_);
3934 return state_;
3935 }
3936
3937 rtc::CriticalSection crit_;
3938 rtc::Event content_switch_event_;
3939 Call* call_;
3940 StreamState state_ RTC_GUARDED_BY(crit_);
3941 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3942 VideoSendStream::Config send_stream_config_;
3943 VideoEncoderConfig encoder_config_;
3944 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3945 T* stream_resetter_;
3946};
3947
Sebastian Jansson63470292019-02-01 10:13:43 +01003948TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003949 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3950 const VideoEncoderConfig& encoder_config,
3951 test::BaseTest* test) {
Danil Chapovalovd15a0282019-10-22 10:48:17 +02003952 SendTask(RTC_FROM_HERE, task_queue(),
Danil Chapovalov82a3f0a2019-10-21 09:24:27 +02003953 [this, &send_stream_config, &encoder_config, &test]() {
3954 Stop();
3955 DestroyVideoSendStreams();
3956 SetVideoSendConfig(send_stream_config);
3957 SetVideoEncoderConfig(encoder_config);
3958 CreateVideoSendStreams();
3959 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3960 test->OnVideoStreamsCreated(GetVideoSendStream(),
3961 video_receive_streams_);
3962 Start();
3963 });
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003964 };
3965 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3966 RunBaseTest(&test);
3967}
3968
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003969} // namespace webrtc