blob: 0e4c11461cde27725135af2994254b451046541f [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"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "rtc_base/time_utils.h"
Elad Alon157540a2019-02-08 23:37:52 +010041#include "rtc_base/unique_id_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020042#include "system_wrappers/include/sleep.h"
43#include "test/call_test.h"
44#include "test/configurable_frame_size_encoder.h"
Niels Möller4db138e2018-04-19 09:04:13 +020045#include "test/fake_encoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020046#include "test/fake_texture_frame.h"
47#include "test/field_trial.h"
48#include "test/frame_generator.h"
49#include "test/frame_generator_capturer.h"
50#include "test/frame_utils.h"
Danil Chapovalov45d725d2018-02-19 19:09:53 +010051#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020052#include "test/gtest.h"
53#include "test/null_transport.h"
54#include "test/rtcp_packet_parser.h"
Tommi25eb47c2019-08-29 16:39:05 +020055#include "test/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020056#include "test/testsupport/perf_test.h"
Niels Möllercbcbc222018-09-28 09:07:24 +020057#include "test/video_encoder_proxy_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "video/send_statistics_proxy.h"
59#include "video/transport_adapter.h"
Sebastian Janssona45c8da2018-01-16 10:55:29 +010060#include "video/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000061
62namespace webrtc {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010063namespace test {
64class VideoSendStreamPeer {
65 public:
66 explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
67 : internal_stream_(
68 static_cast<internal::VideoSendStream*>(base_class_stream)) {}
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020069 absl::optional<float> GetPacingFactorOverride() const {
Sebastian Janssona45c8da2018-01-16 10:55:29 +010070 return internal_stream_->GetPacingFactorOverride();
71 }
72
73 private:
74 internal::VideoSendStream const* const internal_stream_;
75};
76} // namespace test
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000077
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080078namespace {
Elad Alond8d32482019-02-18 23:45:57 +010079enum : int { // The first valid value is 1.
80 kAbsSendTimeExtensionId = 1,
81 kTimestampOffsetExtensionId,
82 kTransportSequenceNumberExtensionId,
83 kVideoContentTypeExtensionId,
84 kVideoRotationExtensionId,
85 kVideoTimingExtensionId,
86};
87
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080088constexpr int64_t kRtcpIntervalMs = 1000;
89
Yves Gerey665174f2018-06-19 15:03:05 +020090enum VideoFormat {
91 kGeneric,
92 kVP8,
93};
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080094} // namespace
sprang@webrtc.org346094c2014-02-18 08:40:33 +000095
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070096VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000097
Sebastian Jansson63470292019-02-01 10:13:43 +010098class VideoSendStreamTest : public test::CallTest {
Elad Alond8d32482019-02-18 23:45:57 +010099 public:
100 VideoSendStreamTest() {
101 RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
102 kTransportSequenceNumberExtensionId));
103 }
104
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000105 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000106 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000107 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000108 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +0100109
110 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
111 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -0700112
113 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000114};
115
Sebastian Jansson63470292019-02-01 10:13:43 +0100116TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700117 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200118 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000119
eladalon413ee9a2017-08-22 04:02:52 -0700120 test::NullTransport transport;
121 CreateSendConfig(1, 0, 0, &transport);
122 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200123 GetVideoSendStream()->Start();
124 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700125 DestroyStreams();
126 DestroyCalls();
127 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000128}
129
Sebastian Jansson63470292019-02-01 10:13:43 +0100130TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -0700131 task_queue_.SendTask([this]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200132 CreateSenderCall();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000133
eladalon413ee9a2017-08-22 04:02:52 -0700134 test::NullTransport transport;
135 CreateSendConfig(1, 0, 0, &transport);
136 CreateVideoStreams();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200137 GetVideoSendStream()->Stop();
138 GetVideoSendStream()->Stop();
eladalon413ee9a2017-08-22 04:02:52 -0700139 DestroyStreams();
140 DestroyCalls();
141 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000142}
143
Sebastian Jansson63470292019-02-01 10:13:43 +0100144TEST_F(VideoSendStreamTest, SupportsCName) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000145 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000146 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000147 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000148 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000149
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000150 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000151 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700152 test::RtcpPacketParser parser;
153 EXPECT_TRUE(parser.Parse(packet, length));
154 if (parser.sdes()->num_packets() > 0) {
155 EXPECT_EQ(1u, parser.sdes()->chunks().size());
156 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000157
danilchap3dc929e2016-11-02 08:21:59 -0700158 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000159 }
160
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000161 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000162 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000163
stefanff483612015-12-21 03:14:00 -0800164 void ModifyVideoConfigs(
165 VideoSendStream::Config* send_config,
166 std::vector<VideoReceiveStream::Config>* receive_configs,
167 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000168 send_config->rtp.c_name = kCName;
169 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000170
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000171 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100172 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 }
174 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000175
stefane74eef12016-01-08 06:47:13 -0800176 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000177}
178
Sebastian Jansson63470292019-02-01 10:13:43 +0100179TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000180 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000181 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000182 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000183 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100184 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000185 }
186
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000187 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000188 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000189 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000190
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000191 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
192 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
193 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700194 if (header.extension.absoluteSendTime != 0) {
195 // Wait for at least one packet with a non-zero send time. The send time
196 // is a 16-bit value derived from the system clock, and it is valid
197 // for a packet to have a zero send time. To tell that from an
198 // unpopulated value we'll wait for a packet with non-zero send time.
199 observation_complete_.Set();
200 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100201 RTC_LOG(LS_WARNING)
202 << "Got a packet with zero absoluteSendTime, waiting"
203 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700204 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000205
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000206 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000207 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000208
stefanff483612015-12-21 03:14:00 -0800209 void ModifyVideoConfigs(
210 VideoSendStream::Config* send_config,
211 std::vector<VideoReceiveStream::Config>* receive_configs,
212 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200213 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100214 send_config->rtp.extensions.push_back(
215 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000216 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000217
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000218 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100219 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000220 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000221 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000222
stefane74eef12016-01-08 06:47:13 -0800223 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000224}
225
Sebastian Jansson63470292019-02-01 10:13:43 +0100226TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000227 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000228 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000229 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000230 TransmissionTimeOffsetObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200231 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200232 return std::make_unique<test::DelayedEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200233 Clock::GetRealTimeClock(), kEncodeDelayMs);
234 }) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000235 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100236 kRtpExtensionTransmissionTimeOffset, kTimestampOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000237 }
238
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000239 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000240 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000241 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000242 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000243
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000244 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
245 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000246 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000247 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100248 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000249
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000250 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000251 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000252
stefanff483612015-12-21 03:14:00 -0800253 void ModifyVideoConfigs(
254 VideoSendStream::Config* send_config,
255 std::vector<VideoReceiveStream::Config>* receive_configs,
256 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200257 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Stefan Holmer12952972015-10-29 15:13:24 +0100258 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700259 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100260 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000261 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000262
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000263 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100264 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000265 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000266
Niels Möller4db138e2018-04-19 09:04:13 +0200267 test::FunctionVideoEncoderFactory encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000268 } test;
269
stefane74eef12016-01-08 06:47:13 -0800270 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000271}
272
Sebastian Jansson63470292019-02-01 10:13:43 +0100273TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
Elad Alond8d32482019-02-18 23:45:57 +0100274 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700275 class TransportWideSequenceNumberObserver : public test::SendTest {
276 public:
277 TransportWideSequenceNumberObserver()
Niels Möller4db138e2018-04-19 09:04:13 +0200278 : SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200279 return std::make_unique<test::FakeEncoder>(
Niels Möller4db138e2018-04-19 09:04:13 +0200280 Clock::GetRealTimeClock());
281 }) {
sprang867fb522015-08-03 04:38:41 -0700282 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
283 kRtpExtensionTransportSequenceNumber, kExtensionId));
284 }
285
286 private:
287 Action OnSendRtp(const uint8_t* packet, size_t length) override {
288 RTPHeader header;
289 EXPECT_TRUE(parser_->Parse(packet, length, &header));
290
291 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
292 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
293 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
294
Peter Boström5811a392015-12-10 13:02:50 +0100295 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700296
297 return SEND_PACKET;
298 }
299
stefanff483612015-12-21 03:14:00 -0800300 void ModifyVideoConfigs(
301 VideoSendStream::Config* send_config,
302 std::vector<VideoReceiveStream::Config>* receive_configs,
303 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +0200304 send_config->encoder_settings.encoder_factory = &encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700305 }
306
307 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100308 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700309 }
310
Niels Möller4db138e2018-04-19 09:04:13 +0200311 test::FunctionVideoEncoderFactory encoder_factory_;
sprang867fb522015-08-03 04:38:41 -0700312 } test;
313
stefane74eef12016-01-08 06:47:13 -0800314 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700315}
316
Sebastian Jansson63470292019-02-01 10:13:43 +0100317TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
perkj803d97f2016-11-01 11:45:46 -0700318 class VideoRotationObserver : public test::SendTest {
319 public:
320 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
321 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100322 kRtpExtensionVideoRotation, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700323 }
324
325 Action OnSendRtp(const uint8_t* packet, size_t length) override {
326 RTPHeader header;
327 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700328 // Only the last packet of the frame is required to have the extension.
329 if (!header.markerBit)
330 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700331 EXPECT_TRUE(header.extension.hasVideoRotation);
332 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
333 observation_complete_.Set();
334 return SEND_PACKET;
335 }
336
337 void ModifyVideoConfigs(
338 VideoSendStream::Config* send_config,
339 std::vector<VideoReceiveStream::Config>* receive_configs,
340 VideoEncoderConfig* encoder_config) override {
341 send_config->rtp.extensions.clear();
342 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100343 RtpExtension::kVideoRotationUri, kVideoRotationExtensionId));
perkj803d97f2016-11-01 11:45:46 -0700344 }
345
346 void OnFrameGeneratorCapturerCreated(
347 test::FrameGeneratorCapturer* frame_generator_capturer) override {
348 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
349 }
350
351 void PerformTest() override {
352 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
353 }
354 } test;
355
356 RunBaseTest(&test);
357}
358
Sebastian Jansson63470292019-02-01 10:13:43 +0100359TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700360 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700361 public:
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100362 VideoContentTypeObserver()
363 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
ilnik00d802b2017-04-11 10:34:31 -0700364 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100365 kRtpExtensionVideoContentType, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700366 }
367
368 Action OnSendRtp(const uint8_t* packet, size_t length) override {
369 RTPHeader header;
370 EXPECT_TRUE(parser_->Parse(packet, length, &header));
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100371 // Only the last packet of the key-frame must have extension.
372 if (!header.markerBit || first_frame_sent_)
ilnik7a3006b2017-05-23 09:34:21 -0700373 return SEND_PACKET;
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100374 // First marker bit seen means that the first frame is sent.
375 first_frame_sent_ = true;
ilnik00d802b2017-04-11 10:34:31 -0700376 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700377 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
378 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700379 observation_complete_.Set();
380 return SEND_PACKET;
381 }
382
383 void ModifyVideoConfigs(
384 VideoSendStream::Config* send_config,
385 std::vector<VideoReceiveStream::Config>* receive_configs,
386 VideoEncoderConfig* encoder_config) override {
387 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100388 send_config->rtp.extensions.push_back(RtpExtension(
389 RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
ilnik00d802b2017-04-11 10:34:31 -0700390 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
391 }
392
393 void PerformTest() override {
394 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
395 }
Ilya Nikolaevskiyefbb9782018-03-12 10:42:08 +0100396
397 private:
398 bool first_frame_sent_;
ilnik00d802b2017-04-11 10:34:31 -0700399 } test;
400
401 RunBaseTest(&test);
402}
403
Sebastian Jansson63470292019-02-01 10:13:43 +0100404TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700405 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700406 public:
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100407 VideoTimingObserver()
408 : SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
Elad Alond8d32482019-02-18 23:45:57 +0100409 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
410 kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700411 }
412
413 Action OnSendRtp(const uint8_t* packet, size_t length) override {
414 RTPHeader header;
415 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700416 // Only the last packet of the frame must have extension.
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100417 // Also don't check packets of the second frame if they happen to get
418 // through before the test terminates.
419 if (!header.markerBit || first_frame_sent_)
ilnik10894992017-06-21 08:23:19 -0700420 return SEND_PACKET;
421 EXPECT_TRUE(header.extension.has_video_timing);
422 observation_complete_.Set();
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100423 first_frame_sent_ = true;
ilnik04f4d122017-06-19 07:18:55 -0700424 return SEND_PACKET;
425 }
426
427 void ModifyVideoConfigs(
428 VideoSendStream::Config* send_config,
429 std::vector<VideoReceiveStream::Config>* receive_configs,
430 VideoEncoderConfig* encoder_config) override {
431 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100432 send_config->rtp.extensions.push_back(
433 RtpExtension(RtpExtension::kVideoTimingUri, kVideoTimingExtensionId));
ilnik04f4d122017-06-19 07:18:55 -0700434 }
435
436 void PerformTest() override {
437 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
438 }
Ilya Nikolaevskiy90d0a622019-01-15 14:28:59 +0100439
440 private:
441 bool first_frame_sent_;
ilnik04f4d122017-06-19 07:18:55 -0700442 } test;
443
444 RunBaseTest(&test);
445}
446
danilchap901b2df2017-07-28 08:56:04 -0700447class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000448 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000449 FakeReceiveStatistics(uint32_t send_ssrc,
450 uint32_t last_sequence_number,
451 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700452 uint8_t fraction_lost) {
453 stat_.SetMediaSsrc(send_ssrc);
454 stat_.SetExtHighestSeqNum(last_sequence_number);
455 stat_.SetCumulativeLost(cumulative_lost);
456 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000457 }
458
danilchap901b2df2017-07-28 08:56:04 -0700459 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
460 EXPECT_GE(max_blocks, 1u);
461 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000462 }
463
464 private:
danilchap901b2df2017-07-28 08:56:04 -0700465 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000466};
467
brandtre602f0a2016-10-31 03:40:49 -0700468class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100469 public:
Danil Chapovalov65feec52019-08-14 18:58:17 +0200470 // Some of the test cases are expected to time out.
471 // Use a shorter timeout window than the default one for those.
472 static constexpr int kReducedTimeoutMs = 10000;
473
brandtre602f0a2016-10-31 03:40:49 -0700474 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800475 bool use_nack,
476 bool expect_red,
477 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800478 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200479 VideoEncoderFactory* encoder_factory)
Danil Chapovalov65feec52019-08-14 18:58:17 +0200480 : EndToEndTest(expect_ulpfec ? VideoSendStreamTest::kDefaultTimeoutMs
481 : kReducedTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200482 encoder_factory_(encoder_factory),
Peter Boström39593972016-02-15 11:27:15 +0100483 payload_name_(codec),
484 use_nack_(use_nack),
485 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700486 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800487 sent_media_(false),
488 sent_ulpfec_(false),
Elad Alond8d32482019-02-18 23:45:57 +0100489 header_extensions_enabled_(header_extensions_enabled) {
490 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
491 kAbsSendTimeExtensionId);
492 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
493 kTransportSequenceNumberExtensionId);
494 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100495
496 private:
497 Action OnSendRtp(const uint8_t* packet, size_t length) override {
498 RTPHeader header;
499 EXPECT_TRUE(parser_->Parse(packet, length, &header));
500
Stefan Holmer4654d202015-12-08 09:10:43 +0100501 int encapsulated_payload_type = -1;
502 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100503 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100504 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
505 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100506 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100507 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
508 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100509 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100510 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100511 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
512 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100513 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
514 length) {
515 // Not padding-only, media received outside of RED.
516 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800517 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100518 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100519 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000520
Stefan Holmer4654d202015-12-08 09:10:43 +0100521 if (header_extensions_enabled_) {
522 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
523 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
524 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
525 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
526 // 24 bits wrap.
527 EXPECT_GT(prev_header_.extension.absoluteSendTime,
528 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000529 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100530 EXPECT_GE(header.extension.absoluteSendTime,
531 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200532 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100533 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
534 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
535 prev_header_.extension.transportSequenceNumber;
536 EXPECT_EQ(1, seq_num_diff);
537 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200538
Stefan Holmer4654d202015-12-08 09:10:43 +0100539 if (encapsulated_payload_type != -1) {
540 if (encapsulated_payload_type ==
541 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700542 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800543 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100544 } else {
brandtr65a1e772016-12-12 01:54:58 -0800545 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000546 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000547 }
548
brandtr20d45472017-01-02 00:34:27 -0800549 if (sent_media_ && sent_ulpfec_) {
550 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100551 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000552
Stefan Holmer4654d202015-12-08 09:10:43 +0100553 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000554
Stefan Holmer4654d202015-12-08 09:10:43 +0100555 return SEND_PACKET;
556 }
557
Danil Chapovalov44db4362019-09-30 04:16:28 +0200558 std::unique_ptr<test::PacketTransport> CreateSendTransport(
559 TaskQueueBase* task_queue,
eladalon413ee9a2017-08-22 04:02:52 -0700560 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100561 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
562 // Configure some network delay.
563 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200564 BuiltInNetworkBehaviorConfig config;
brandtr65a1e772016-12-12 01:54:58 -0800565 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100566 config.queue_delay_ms = kNetworkDelayMs;
Danil Chapovalov44db4362019-09-30 04:16:28 +0200567 return std::make_unique<test::PacketTransport>(
eladalon413ee9a2017-08-22 04:02:52 -0700568 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200569 VideoSendStreamTest::payload_type_map_,
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200570 std::make_unique<FakeNetworkPipe>(
Artem Titov4e199e92018-08-20 13:30:39 +0200571 Clock::GetRealTimeClock(),
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200572 std::make_unique<SimulatedNetwork>(config)));
Peter Boström39593972016-02-15 11:27:15 +0100573 }
574
stefanff483612015-12-21 03:14:00 -0800575 void ModifyVideoConfigs(
576 VideoSendStream::Config* send_config,
577 std::vector<VideoReceiveStream::Config>* receive_configs,
578 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100579 if (use_nack_) {
580 send_config->rtp.nack.rtp_history_ms =
581 (*receive_configs)[0].rtp.nack.rtp_history_ms =
582 VideoSendStreamTest::kNackRtpHistoryMs;
583 }
Niels Möller4db138e2018-04-19 09:04:13 +0200584 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200585 send_config->rtp.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700586 send_config->rtp.ulpfec.red_payload_type =
587 VideoSendStreamTest::kRedPayloadType;
588 send_config->rtp.ulpfec.ulpfec_payload_type =
589 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800590 if (!header_extensions_enabled_) {
591 send_config->rtp.extensions.clear();
592 } else {
Elad Alond8d32482019-02-18 23:45:57 +0100593 send_config->rtp.extensions.push_back(
594 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100595 }
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +0200596 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
Niels Möller259a4972018-04-05 15:36:51 +0200597 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
nisse3b3622f2017-09-26 02:49:21 -0700598 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700599 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700600 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700601 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100602 }
603
604 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800605 EXPECT_EQ(expect_ulpfec_, Wait())
606 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100607 }
608
Niels Möller4db138e2018-04-19 09:04:13 +0200609 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800610 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100611 const bool use_nack_;
612 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700613 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800614 bool sent_media_;
615 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100616 bool header_extensions_enabled_;
617 RTPHeader prev_header_;
618};
619
Sebastian Jansson63470292019-02-01 10:13:43 +0100620TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200621 test::FunctionVideoEncoderFactory encoder_factory(
622 []() { return VP8Encoder::Create(); });
623 UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800624 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100625}
626
Sebastian Jansson63470292019-02-01 10:13:43 +0100627TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
Niels Möller4db138e2018-04-19 09:04:13 +0200628 test::FunctionVideoEncoderFactory encoder_factory(
629 []() { return VP8Encoder::Create(); });
630 UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100631 RunBaseTest(&test);
632}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000633
Sebastian Janssonc714b6e2018-08-30 15:45:41 +0200634class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
stefan60e10c72017-08-23 10:40:00 -0700635 protected:
636 VideoSendStreamWithoutUlpfecTest()
637 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
638
639 test::ScopedFieldTrials field_trial_;
640};
641
642TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
Niels Möller4db138e2018-04-19 09:04:13 +0200643 test::FunctionVideoEncoderFactory encoder_factory(
644 []() { return VP8Encoder::Create(); });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200645 UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
stefan60e10c72017-08-23 10:40:00 -0700646 RunBaseTest(&test);
647}
648
Peter Boström39593972016-02-15 11:27:15 +0100649// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
650// since we'll still have to re-request FEC packets, effectively wasting
651// bandwidth since the receiver has to wait for FEC retransmissions to determine
652// that the received state is actually decodable.
Sebastian Jansson63470292019-02-01 10:13:43 +0100653TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200654 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200655 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200656 });
Kári Tristan Helgason798ee752018-07-11 16:04:57 +0200657 UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100658 RunBaseTest(&test);
659}
660
661// Without retransmissions FEC for H264 is fine.
Sebastian Jansson63470292019-02-01 10:13:43 +0100662TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200663 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200664 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200665 });
666 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100667 RunBaseTest(&test);
668}
669
Danil Chapovalov65feec52019-08-14 18:58:17 +0200670TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp8WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200671 test::FunctionVideoEncoderFactory encoder_factory(
672 []() { return VP8Encoder::Create(); });
673 UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
Peter Boström39593972016-02-15 11:27:15 +0100674 RunBaseTest(&test);
675}
676
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100677#if defined(RTC_ENABLE_VP9)
Danil Chapovalov65feec52019-08-14 18:58:17 +0200678TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp9WithNackEnabled) {
Niels Möller4db138e2018-04-19 09:04:13 +0200679 test::FunctionVideoEncoderFactory encoder_factory(
680 []() { return VP9Encoder::Create(); });
681 UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
stefane74eef12016-01-08 06:47:13 -0800682 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000683}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100684#endif // defined(RTC_ENABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000685
Sebastian Jansson63470292019-02-01 10:13:43 +0100686TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100687 std::unique_ptr<TaskQueueFactory> task_queue_factory =
688 CreateDefaultTaskQueueFactory();
689 test::FunctionVideoEncoderFactory encoder_factory([&]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200690 return std::make_unique<test::MultithreadedFakeH264Encoder>(
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100691 Clock::GetRealTimeClock(), task_queue_factory.get());
Niels Möller4db138e2018-04-19 09:04:13 +0200692 });
693 UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
brandtr696c9c62016-12-19 05:47:28 -0800694 RunBaseTest(&test);
695}
696
brandtr39f97292016-11-16 22:57:50 -0800697// TODO(brandtr): Move these FlexFEC tests when we have created
698// FlexfecSendStream.
699class FlexfecObserver : public test::EndToEndTest {
700 public:
701 FlexfecObserver(bool header_extensions_enabled,
702 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800703 const std::string& codec,
Niels Möller4db138e2018-04-19 09:04:13 +0200704 VideoEncoderFactory* encoder_factory,
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100705 size_t num_video_streams)
brandtr39f97292016-11-16 22:57:50 -0800706 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +0200707 encoder_factory_(encoder_factory),
brandtr39f97292016-11-16 22:57:50 -0800708 payload_name_(codec),
709 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800710 sent_media_(false),
711 sent_flexfec_(false),
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100712 header_extensions_enabled_(header_extensions_enabled),
Elad Alond8d32482019-02-18 23:45:57 +0100713 num_video_streams_(num_video_streams) {
714 parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
715 kAbsSendTimeExtensionId);
716 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
717 kTimestampOffsetExtensionId);
718 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
719 kTransportSequenceNumberExtensionId);
720 }
brandtr39f97292016-11-16 22:57:50 -0800721
722 size_t GetNumFlexfecStreams() const override { return 1; }
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100723 size_t GetNumVideoStreams() const override { return num_video_streams_; }
brandtr39f97292016-11-16 22:57:50 -0800724
725 private:
726 Action OnSendRtp(const uint8_t* packet, size_t length) override {
727 RTPHeader header;
728 EXPECT_TRUE(parser_->Parse(packet, length, &header));
729
brandtr39f97292016-11-16 22:57:50 -0800730 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
731 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
732 sent_flexfec_ = true;
733 } else {
734 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
735 header.payloadType);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200736 EXPECT_THAT(::testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
737 num_video_streams_),
738 ::testing::Contains(header.ssrc));
brandtr39f97292016-11-16 22:57:50 -0800739 sent_media_ = true;
740 }
741
742 if (header_extensions_enabled_) {
743 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
744 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
745 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
746 }
747
brandtr0c5a1542016-11-23 04:42:26 -0800748 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800749 observation_complete_.Set();
750 }
751
752 return SEND_PACKET;
753 }
754
Danil Chapovalov44db4362019-09-30 04:16:28 +0200755 std::unique_ptr<test::PacketTransport> CreateSendTransport(
756 TaskQueueBase* task_queue,
eladalon413ee9a2017-08-22 04:02:52 -0700757 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800758 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
759 // Therefore we need some network delay.
760 const int kNetworkDelayMs = 100;
Artem Titov75e36472018-10-08 12:28:56 +0200761 BuiltInNetworkBehaviorConfig config;
brandtrd654a9b2016-12-05 05:38:19 -0800762 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800763 config.queue_delay_ms = kNetworkDelayMs;
Danil Chapovalov44db4362019-09-30 04:16:28 +0200764 return std::make_unique<test::PacketTransport>(
eladalon413ee9a2017-08-22 04:02:52 -0700765 task_queue, sender_call, this, test::PacketTransport::kSender,
Artem Titov4e199e92018-08-20 13:30:39 +0200766 VideoSendStreamTest::payload_type_map_,
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200767 std::make_unique<FakeNetworkPipe>(
Artem Titov4e199e92018-08-20 13:30:39 +0200768 Clock::GetRealTimeClock(),
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200769 std::make_unique<SimulatedNetwork>(config)));
brandtr39f97292016-11-16 22:57:50 -0800770 }
771
Björn Terelius24d251f2019-10-02 00:37:36 +0200772 std::unique_ptr<test::PacketTransport> CreateReceiveTransport(
773 TaskQueueBase* task_queue) override {
774 // We need the RTT to be >200 ms to send FEC and the network delay for the
775 // send transport is 100 ms, so add 100 ms (but no loss) on the return link.
776 BuiltInNetworkBehaviorConfig config;
777 config.loss_percent = 0;
778 config.queue_delay_ms = 100;
779 return std::make_unique<test::PacketTransport>(
780 task_queue, nullptr, this, test::PacketTransport::kReceiver,
781 VideoSendStreamTest::payload_type_map_,
782 std::make_unique<FakeNetworkPipe>(
783 Clock::GetRealTimeClock(),
784 std::make_unique<SimulatedNetwork>(config)));
785 }
786
brandtr39f97292016-11-16 22:57:50 -0800787 void ModifyVideoConfigs(
788 VideoSendStream::Config* send_config,
789 std::vector<VideoReceiveStream::Config>* receive_configs,
790 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800791 if (use_nack_) {
792 send_config->rtp.nack.rtp_history_ms =
793 (*receive_configs)[0].rtp.nack.rtp_history_ms =
794 VideoSendStreamTest::kNackRtpHistoryMs;
795 }
Niels Möller4db138e2018-04-19 09:04:13 +0200796 send_config->encoder_settings.encoder_factory = encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +0200797 send_config->rtp.payload_name = payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800798 if (header_extensions_enabled_) {
Elad Alond8d32482019-02-18 23:45:57 +0100799 send_config->rtp.extensions.push_back(
800 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
brandtr39f97292016-11-16 22:57:50 -0800801 send_config->rtp.extensions.push_back(RtpExtension(
Elad Alond8d32482019-02-18 23:45:57 +0100802 RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800803 } else {
804 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800805 }
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +0200806 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
Niels Möller259a4972018-04-05 15:36:51 +0200807 encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
brandtr39f97292016-11-16 22:57:50 -0800808 }
809
810 void PerformTest() override {
811 EXPECT_TRUE(Wait())
812 << "Timed out waiting for FlexFEC and/or media packets.";
813 }
814
Niels Möller4db138e2018-04-19 09:04:13 +0200815 VideoEncoderFactory* encoder_factory_;
brandtr696c9c62016-12-19 05:47:28 -0800816 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800817 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800818 bool sent_media_;
819 bool sent_flexfec_;
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100820 const bool header_extensions_enabled_;
821 const size_t num_video_streams_;
brandtr39f97292016-11-16 22:57:50 -0800822};
823
Sebastian Jansson63470292019-02-01 10:13:43 +0100824TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200825 test::FunctionVideoEncoderFactory encoder_factory(
826 []() { return VP8Encoder::Create(); });
827 FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
Danil Chapovalov45d725d2018-02-19 19:09:53 +0100828 RunBaseTest(&test);
829}
830
Sebastian Jansson63470292019-02-01 10:13:43 +0100831TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200832 test::FunctionVideoEncoderFactory encoder_factory(
833 []() { return VP8Encoder::Create(); });
834 FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
brandtrd654a9b2016-12-05 05:38:19 -0800835 RunBaseTest(&test);
836}
837
Sebastian Jansson63470292019-02-01 10:13:43 +0100838TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200839 test::FunctionVideoEncoderFactory encoder_factory(
840 []() { return VP8Encoder::Create(); });
841 FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
brandtrd654a9b2016-12-05 05:38:19 -0800842 RunBaseTest(&test);
843}
844
Sebastian Jansson63470292019-02-01 10:13:43 +0100845TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200846 test::FunctionVideoEncoderFactory encoder_factory(
847 []() { return VP8Encoder::Create(); });
848 FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800849 RunBaseTest(&test);
850}
851
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100852#if defined(RTC_ENABLE_VP9)
Sebastian Jansson63470292019-02-01 10:13:43 +0100853TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200854 test::FunctionVideoEncoderFactory encoder_factory(
855 []() { return VP9Encoder::Create(); });
856 FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800857 RunBaseTest(&test);
858}
859
Sebastian Jansson63470292019-02-01 10:13:43 +0100860TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200861 test::FunctionVideoEncoderFactory encoder_factory(
862 []() { return VP9Encoder::Create(); });
863 FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800864 RunBaseTest(&test);
865}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100866#endif // defined(RTC_ENABLE_VP9)
brandtr39f97292016-11-16 22:57:50 -0800867
Sebastian Jansson63470292019-02-01 10:13:43 +0100868TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200869 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200870 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200871 });
872 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800873 RunBaseTest(&test);
874}
875
Sebastian Jansson63470292019-02-01 10:13:43 +0100876TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
Niels Möller4db138e2018-04-19 09:04:13 +0200877 test::FunctionVideoEncoderFactory encoder_factory([]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200878 return std::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
Niels Möller4db138e2018-04-19 09:04:13 +0200879 });
880 FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
brandtr696c9c62016-12-19 05:47:28 -0800881 RunBaseTest(&test);
882}
883
Sebastian Jansson63470292019-02-01 10:13:43 +0100884TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100885 std::unique_ptr<TaskQueueFactory> task_queue_factory =
886 CreateDefaultTaskQueueFactory();
887 test::FunctionVideoEncoderFactory encoder_factory([&]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200888 return std::make_unique<test::MultithreadedFakeH264Encoder>(
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100889 Clock::GetRealTimeClock(), task_queue_factory.get());
Niels Möller4db138e2018-04-19 09:04:13 +0200890 });
891
892 FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
brandtr39f97292016-11-16 22:57:50 -0800893 RunBaseTest(&test);
894}
895
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000896void VideoSendStreamTest::TestNackRetransmission(
897 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000898 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000899 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000900 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000901 explicit NackObserver(uint32_t retransmit_ssrc,
902 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000903 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000904 send_count_(0),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100905 retransmit_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000906 retransmit_ssrc_(retransmit_ssrc),
Sebastian Janssond3f38162018-02-28 16:14:44 +0100907 retransmit_payload_type_(retransmit_payload_type) {}
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000908
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000909 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000910 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000911 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000912 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000913
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200914 // NACK packets two times at some arbitrary points.
915 const int kNackedPacketsAtOnceCount = 3;
916 const int kRetransmitTarget = kNackedPacketsAtOnceCount * 2;
917
918 // Skip padding packets because they will never be retransmitted.
919 if (header.paddingLength + header.headerLength == length) {
920 return SEND_PACKET;
921 }
922
Sebastian Janssond3f38162018-02-28 16:14:44 +0100923 ++send_count_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200924
925 // NACK packets at arbitrary points.
Sebastian Janssond3f38162018-02-28 16:14:44 +0100926 if (send_count_ == 5 || send_count_ == 25) {
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200927 nacked_sequence_numbers_.insert(
928 nacked_sequence_numbers_.end(),
929 non_padding_sequence_numbers_.end() - kNackedPacketsAtOnceCount,
930 non_padding_sequence_numbers_.end());
Sebastian Janssond3f38162018-02-28 16:14:44 +0100931
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000932 RtpRtcp::Configuration config;
933 config.clock = Clock::GetRealTimeClock();
934 config.outgoing_transport = transport_adapter_.get();
935 config.rtcp_report_interval_ms = kRtcpIntervalMs;
936 RTCPSender rtcp_sender(config);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000937
pbosda903ea2015-10-02 02:36:56 -0700938 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100939 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000940
941 RTCPSender::FeedbackState feedback_state;
942
Sebastian Janssond3f38162018-02-28 16:14:44 +0100943 EXPECT_EQ(0, rtcp_sender.SendRTCP(
944 feedback_state, kRtcpNack,
945 static_cast<int>(nacked_sequence_numbers_.size()),
946 &nacked_sequence_numbers_.front()));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000947 }
948
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000949 uint16_t sequence_number = header.sequenceNumber;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000950 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100951 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
952 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000953 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000954 const uint8_t* rtx_header = packet + header.headerLength;
955 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
956 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200957
Steve Antonbd631a02019-03-28 10:51:27 -0700958 auto found = absl::c_find(nacked_sequence_numbers_, sequence_number);
Sebastian Janssond3f38162018-02-28 16:14:44 +0100959 if (found != nacked_sequence_numbers_.end()) {
960 nacked_sequence_numbers_.erase(found);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000961
Sebastian Janssond3f38162018-02-28 16:14:44 +0100962 if (++retransmit_count_ == kRetransmitTarget) {
963 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
964 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
965 observation_complete_.Set();
966 }
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200967 } else {
968 non_padding_sequence_numbers_.push_back(sequence_number);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000969 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000970
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000971 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000972 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000973
stefanff483612015-12-21 03:14:00 -0800974 void ModifyVideoConfigs(
975 VideoSendStream::Config* send_config,
976 std::vector<VideoReceiveStream::Config>* receive_configs,
977 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700978 transport_adapter_.reset(
979 new internal::TransportAdapter(send_config->send_transport));
980 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000981 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000982 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100983 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000984 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
985 }
986
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000987 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100988 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000989 }
990
kwiberg27f982b2016-03-01 11:52:33 -0800991 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000992 int send_count_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100993 int retransmit_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000994 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000995 uint8_t retransmit_payload_type_;
Sebastian Janssond3f38162018-02-28 16:14:44 +0100996 std::vector<uint16_t> nacked_sequence_numbers_;
Ilya Nikolaevskiy6003e7a2018-10-15 10:47:23 +0200997 std::vector<uint16_t> non_padding_sequence_numbers_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000998 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000999
stefane74eef12016-01-08 06:47:13 -08001000 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +00001001}
1002
Sebastian Jansson63470292019-02-01 10:13:43 +01001003TEST_F(VideoSendStreamTest, RetransmitsNack) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001004 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001005 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001006}
1007
Sebastian Jansson63470292019-02-01 10:13:43 +01001008TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001009 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001010 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +00001011}
1012
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001013void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
1014 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001015 // Use a fake encoder to output a frame of every size in the range [90, 290],
1016 // for each size making sure that the exact number of payload bytes received
1017 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001018 static const size_t kMaxPacketSize = 128;
1019 static const size_t start = 90;
1020 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001021
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001022 // Observer that verifies that the expected number of packets and bytes
1023 // arrive for each frame size, from start_size to stop_size.
Niels Möller759f9592018-10-09 14:57:01 +02001024 class FrameFragmentationTest : public test::SendTest {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001025 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001026 FrameFragmentationTest(size_t max_packet_size,
1027 size_t start_size,
1028 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001029 bool test_generic_packetization,
1030 bool use_fec)
1031 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001032 encoder_(stop),
Niels Möller4db138e2018-04-19 09:04:13 +02001033 encoder_factory_(&encoder_),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001034 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001035 stop_size_(stop_size),
1036 test_generic_packetization_(test_generic_packetization),
1037 use_fec_(use_fec),
1038 packet_count_(0),
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001039 packets_lost_(0),
1040 last_packet_count_(0),
1041 last_packets_lost_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001042 accumulated_size_(0),
1043 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001044 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001045 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001046 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001047 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001048 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -07001049 RTC_DCHECK_GT(stop_size, max_packet_size);
Philip Eliassond52a1a62018-09-07 13:03:55 +00001050 if (!test_generic_packetization_)
1051 encoder_.SetCodecType(kVideoCodecVP8);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001052 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001053
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001054 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001055 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001056 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001057 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001058 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001059
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001060 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001061
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001062 if (use_fec_) {
1063 uint8_t payload_type = packet[header.headerLength];
1064 bool is_fec = header.payloadType == kRedPayloadType &&
1065 payload_type == kUlpfecPayloadType;
1066 if (is_fec) {
1067 fec_packet_received_ = true;
1068 return SEND_PACKET;
1069 }
1070 }
1071
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001072 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001073
1074 if (use_fec_)
1075 TriggerLossReport(header);
1076
1077 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +02001078 size_t overhead = header.headerLength + header.paddingLength;
1079 // Only remove payload header and RED header if the packet actually
1080 // contains payload.
1081 if (length > overhead) {
1082 overhead += (1 /* Generic header */);
1083 if (use_fec_)
1084 overhead += 1; // RED for FEC header.
1085 }
1086 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001087 accumulated_payload_ += length - overhead;
1088 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001089
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001090 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001091 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001092 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
1093 // With FEC enabled, frame size is incremented asynchronously, so
1094 // "old" frames one byte too small may arrive. Accept, but don't
1095 // increase expected frame size.
1096 accumulated_size_ = 0;
1097 accumulated_payload_ = 0;
1098 return SEND_PACKET;
1099 }
1100
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001101 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001102 if (test_generic_packetization_) {
1103 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
1104 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001105
1106 // Last packet of frame; reset counters.
1107 accumulated_size_ = 0;
1108 accumulated_payload_ = 0;
1109 if (current_size_rtp_ == stop_size_) {
1110 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +01001111 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001112 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001113 // Increase next expected frame size. If testing with FEC, make sure
1114 // a FEC packet has been received for this frame size before
1115 // proceeding, to make sure that redundancy packets don't exceed
1116 // size limit.
1117 if (!use_fec_) {
1118 ++current_size_rtp_;
1119 } else if (fec_packet_received_) {
1120 fec_packet_received_ = false;
1121 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001122
1123 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001124 ++current_size_frame_;
1125 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001126 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001127 }
1128
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001129 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001130 }
1131
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001132 void TriggerLossReport(const RTPHeader& header) {
1133 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -07001134 const int kLossPercent = 5;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001135 if (++packet_count_ % (100 / kLossPercent) == 0) {
1136 packets_lost_++;
1137 int loss_delta = packets_lost_ - last_packets_lost_;
1138 int packets_delta = packet_count_ - last_packet_count_;
1139 last_packet_count_ = packet_count_;
1140 last_packets_lost_ = packets_lost_;
1141 uint8_t loss_ratio =
1142 static_cast<uint8_t>(loss_delta * 255 / packets_delta);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001143 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -07001144 kVideoSendSsrcs[0], header.sequenceNumber,
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001145 packets_lost_, // Cumulative lost.
1146 loss_ratio); // Loss percent.
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001147 RtpRtcp::Configuration config;
1148 config.clock = Clock::GetRealTimeClock();
1149 config.receive_statistics = &lossy_receive_stats;
1150 config.outgoing_transport = transport_adapter_.get();
1151 config.rtcp_report_interval_ms = kRtcpIntervalMs;
1152 RTCPSender rtcp_sender(config);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001153
pbosda903ea2015-10-02 02:36:56 -07001154 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001155 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001156
1157 RTCPSender::FeedbackState feedback_state;
1158
1159 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1160 }
1161 }
1162
Niels Möller759f9592018-10-09 14:57:01 +02001163 void UpdateConfiguration() {
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001164 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001165 // Increase frame size for next encoded frame, in the context of the
1166 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001167 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001168 ++current_size_frame_;
1169 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001170 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001171 }
Niels Möllerde8e6e62018-11-13 15:10:33 +01001172 void ModifySenderBitrateConfig(
1173 BitrateConstraints* bitrate_config) override {
Stefan Holmere5904162015-03-26 11:11:06 +01001174 const int kMinBitrateBps = 30000;
Niels Möllerde8e6e62018-11-13 15:10:33 +01001175 bitrate_config->min_bitrate_bps = kMinBitrateBps;
Stefan Holmere5904162015-03-26 11:11:06 +01001176 }
1177
stefanff483612015-12-21 03:14:00 -08001178 void ModifyVideoConfigs(
1179 VideoSendStream::Config* send_config,
1180 std::vector<VideoReceiveStream::Config>* receive_configs,
1181 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001182 transport_adapter_.reset(
1183 new internal::TransportAdapter(send_config->send_transport));
1184 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001185 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001186 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1187 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001188 }
1189
1190 if (!test_generic_packetization_)
Niels Möller259a4972018-04-05 15:36:51 +02001191 send_config->rtp.payload_name = "VP8";
Philip Eliassond52a1a62018-09-07 13:03:55 +00001192
Niels Möller4db138e2018-04-19 09:04:13 +02001193 send_config->encoder_settings.encoder_factory = &encoder_factory_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001194 send_config->rtp.max_packet_size = kMaxPacketSize;
Niels Möller759f9592018-10-09 14:57:01 +02001195 encoder_.RegisterPostEncodeCallback([this]() { UpdateConfiguration(); });
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001196
Erik Språng95261872015-04-10 11:58:49 +02001197 // Make sure there is at least one extension header, to make the RTP
1198 // header larger than the base length of 12 bytes.
1199 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001200
1201 // Setup screen content disables frame dropping which makes this easier.
Åsa Perssond34597c2018-10-22 17:34:02 +02001202 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
1203 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
sprang4847ae62017-06-27 07:06:52 -07001204 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001205 }
1206
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001207 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001208 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001209 }
1210
kwiberg27f982b2016-03-01 11:52:33 -08001211 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001212 test::ConfigurableFrameSizeEncoder encoder_;
Niels Möllercbcbc222018-09-28 09:07:24 +02001213 test::VideoEncoderProxyFactory encoder_factory_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001214
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001215 const size_t max_packet_size_;
1216 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001217 const bool test_generic_packetization_;
1218 const bool use_fec_;
1219
1220 uint32_t packet_count_;
Sebastian Jansson56fa0502018-02-01 13:00:57 +01001221 uint32_t packets_lost_;
1222 uint32_t last_packet_count_;
1223 uint32_t last_packets_lost_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001224 size_t accumulated_size_;
1225 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001226 bool fec_packet_received_;
1227
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001228 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001229 rtc::CriticalSection mutex_;
1230 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001231 };
1232
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001233 // Don't auto increment if FEC is used; continue sending frame size until
1234 // a FEC packet has been received.
Yves Gerey665174f2018-06-19 15:03:05 +02001235 FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
1236 with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001237
stefane74eef12016-01-08 06:47:13 -08001238 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001239}
1240
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001241// TODO(sprang): Is there any way of speeding up these tests?
Sebastian Jansson63470292019-02-01 10:13:43 +01001242TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001243 TestPacketFragmentationSize(kGeneric, false);
1244}
1245
Sebastian Jansson63470292019-02-01 10:13:43 +01001246TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001247 TestPacketFragmentationSize(kGeneric, true);
1248}
1249
Sebastian Jansson63470292019-02-01 10:13:43 +01001250TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001251 TestPacketFragmentationSize(kVP8, false);
1252}
1253
Sebastian Jansson63470292019-02-01 10:13:43 +01001254TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001255 TestPacketFragmentationSize(kVP8, true);
1256}
1257
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001258// The test will go through a number of phases.
1259// 1. Start sending packets.
1260// 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 +00001261// suspend the stream.
1262// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001263// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001264// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001265// When the stream is detected again, and the stats show that the stream
1266// is no longer suspended, the test ends.
Sebastian Jansson63470292019-02-01 10:13:43 +01001267TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001268 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001269
Niels Möller412d1852019-01-02 09:42:54 +01001270 class RembObserver : public test::SendTest {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001271 public:
Niels Möller412d1852019-01-02 09:42:54 +01001272 class CaptureObserver : public rtc::VideoSinkInterface<VideoFrame> {
1273 public:
1274 explicit CaptureObserver(RembObserver* remb_observer)
1275 : remb_observer_(remb_observer) {}
1276
1277 void OnFrame(const VideoFrame&) {
1278 rtc::CritScope lock(&remb_observer_->crit_);
1279 if (remb_observer_->test_state_ == kDuringSuspend &&
1280 ++remb_observer_->suspended_frame_count_ > kSuspendTimeFrames) {
1281 VideoSendStream::Stats stats = remb_observer_->stream_->GetStats();
1282 EXPECT_TRUE(stats.suspended);
1283 remb_observer_->SendRtcpFeedback(remb_observer_->high_remb_bps_);
1284 remb_observer_->test_state_ = kWaitingForPacket;
1285 }
1286 }
1287
1288 private:
1289 RembObserver* const remb_observer_;
1290 };
1291
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001292 RembObserver()
1293 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001294 clock_(Clock::GetRealTimeClock()),
Niels Möller412d1852019-01-02 09:42:54 +01001295 capture_observer_(this),
Erik Språng737336d2016-07-29 12:59:36 +02001296 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001297 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001298 rtp_count_(0),
1299 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001300 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001301 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001302 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001303
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001304 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001305 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001306 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001307 ++rtp_count_;
1308 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001309 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001310 last_sequence_number_ = header.sequenceNumber;
1311
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001312 if (test_state_ == kBeforeSuspend) {
1313 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001314 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001315 test_state_ = kDuringSuspend;
1316 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001317 if (header.paddingLength == 0) {
1318 // Received non-padding packet during suspension period. Reset the
1319 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001320 suspended_frame_count_ = 0;
1321 }
stefanf116bd02015-10-27 08:29:42 -07001322 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001323 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001324 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001325 // Non-padding packet observed. Test is almost complete. Will just
1326 // have to wait for the stats to change.
1327 test_state_ = kWaitingForStats;
1328 }
stefanf116bd02015-10-27 08:29:42 -07001329 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001330 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001331 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001332 if (stats.suspended == false) {
1333 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001334 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001335 }
stefanf116bd02015-10-27 08:29:42 -07001336 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001337 }
1338
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001339 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001340 }
1341
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001342 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001343 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001344 low_remb_bps_ = value;
1345 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001346
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001347 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001348 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001349 high_remb_bps_ = value;
1350 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001351
stefanff483612015-12-21 03:14:00 -08001352 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001353 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001354 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001355 stream_ = send_stream;
1356 }
1357
Niels Möller412d1852019-01-02 09:42:54 +01001358 void OnFrameGeneratorCapturerCreated(
1359 test::FrameGeneratorCapturer* frame_generator_capturer) override {
1360 frame_generator_capturer->AddOrUpdateSink(&capture_observer_,
1361 rtc::VideoSinkWants());
1362 }
1363
stefanff483612015-12-21 03:14:00 -08001364 void ModifyVideoConfigs(
1365 VideoSendStream::Config* send_config,
1366 std::vector<VideoReceiveStream::Config>* receive_configs,
1367 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001368 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001369 transport_adapter_.reset(
1370 new internal::TransportAdapter(send_config->send_transport));
1371 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001372 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001373 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001374 int min_bitrate_bps =
1375 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001376 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001377 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001378 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001379 min_bitrate_bps + threshold_window + 5000);
1380 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1381 }
1382
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001383 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001384 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001385 }
1386
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001387 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001388 kBeforeSuspend,
1389 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001390 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001391 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001392 };
1393
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001394 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001395 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001396 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1397 last_sequence_number_, rtp_count_, 0);
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +00001398 RtpRtcp::Configuration config;
1399 config.clock = clock_;
1400 config.receive_statistics = &receive_stats;
1401 config.outgoing_transport = transport_adapter_.get();
1402 config.rtcp_report_interval_ms = kRtcpIntervalMs;
1403 RTCPSender rtcp_sender(config);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001404
pbosda903ea2015-10-02 02:36:56 -07001405 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001406 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001407 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001408 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001409 }
1410 RTCPSender::FeedbackState feedback_state;
1411 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1412 }
1413
kwiberg27f982b2016-03-01 11:52:33 -08001414 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001415 Clock* const clock_;
Niels Möller412d1852019-01-02 09:42:54 +01001416 CaptureObserver capture_observer_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001417 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001418
Peter Boströmf2f82832015-05-01 13:00:41 +02001419 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001420 TestState test_state_ RTC_GUARDED_BY(crit_);
1421 int rtp_count_ RTC_GUARDED_BY(crit_);
1422 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1423 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1424 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1425 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001426 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001427
stefane74eef12016-01-08 06:47:13 -08001428 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001429}
1430
perkj71ee44c2016-06-15 00:47:53 -07001431// This test that padding stops being send after a while if the Camera stops
1432// producing video frames and that padding resumes if the camera restarts.
Sebastian Jansson63470292019-02-01 10:13:43 +01001433TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001434 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001435 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001436 NoPaddingWhenVideoIsMuted()
1437 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001438 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001439 last_packet_time_ms_(-1),
Yves Gerey665174f2018-06-19 15:03:05 +02001440 capturer_(nullptr) {}
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001441
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001442 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001443 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001444 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001445 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001446
1447 RTPHeader header;
1448 parser_->Parse(packet, length, &header);
1449 const bool only_padding =
1450 header.headerLength + header.paddingLength == length;
1451
1452 if (test_state_ == kBeforeStopCapture) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001453 // Packets are flowing, stop camera.
perkj71ee44c2016-06-15 00:47:53 -07001454 capturer_->Stop();
1455 test_state_ = kWaitingForPadding;
1456 } else if (test_state_ == kWaitingForPadding && only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001457 // We're still getting padding, after stopping camera.
perkj71ee44c2016-06-15 00:47:53 -07001458 test_state_ = kWaitingForNoPackets;
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001459 } else if (test_state_ == kWaitingForMediaAfterCameraRestart &&
1460 !only_padding) {
1461 // Media packets are flowing again, stop camera a second time.
1462 capturer_->Stop();
1463 test_state_ = kWaitingForPaddingAfterCameraStopsAgain;
1464 } else if (test_state_ == kWaitingForPaddingAfterCameraStopsAgain &&
perkj71ee44c2016-06-15 00:47:53 -07001465 only_padding) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001466 // Padding is still flowing, test ok.
perkj71ee44c2016-06-15 00:47:53 -07001467 observation_complete_.Set();
1468 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001469 return SEND_PACKET;
1470 }
1471
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001472 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001473 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001474 const int kNoPacketsThresholdMs = 2000;
1475 if (test_state_ == kWaitingForNoPackets &&
1476 (last_packet_time_ms_ > 0 &&
1477 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1478 kNoPacketsThresholdMs)) {
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001479 // No packets seen for |kNoPacketsThresholdMs|, restart camera.
perkj71ee44c2016-06-15 00:47:53 -07001480 capturer_->Start();
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001481 test_state_ = kWaitingForMediaAfterCameraRestart;
perkj71ee44c2016-06-15 00:47:53 -07001482 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001483 return SEND_PACKET;
1484 }
1485
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001486 void ModifyVideoConfigs(
1487 VideoSendStream::Config* send_config,
1488 std::vector<VideoReceiveStream::Config>* receive_configs,
1489 VideoEncoderConfig* encoder_config) override {
1490 // Make sure padding is sent if encoder is not producing media.
1491 encoder_config->min_transmit_bitrate_bps = 50000;
1492 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001493
nisseef8b61e2016-04-29 06:09:15 -07001494 void OnFrameGeneratorCapturerCreated(
1495 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001496 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001497 capturer_ = frame_generator_capturer;
1498 }
1499
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001500 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001501 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001502 << "Timed out while waiting for RTP packets to stop being sent.";
1503 }
1504
perkj71ee44c2016-06-15 00:47:53 -07001505 enum TestState {
1506 kBeforeStopCapture,
1507 kWaitingForPadding,
1508 kWaitingForNoPackets,
Erik Språng4f3cc6e2018-11-06 12:17:32 +01001509 kWaitingForMediaAfterCameraRestart,
1510 kWaitingForPaddingAfterCameraStopsAgain
perkj71ee44c2016-06-15 00:47:53 -07001511 };
1512
1513 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001514 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001515 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001516 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001517 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1518 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001519 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001520
stefane74eef12016-01-08 06:47:13 -08001521 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001522}
1523
Sebastian Jansson63470292019-02-01 10:13:43 +01001524TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
isheriffcc5903e2016-10-04 08:29:38 -07001525 const int kCapacityKbps = 10000; // 10 Mbps
1526 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1527 public:
1528 PaddingIsPrimarilyRetransmissions()
1529 : EndToEndTest(kDefaultTimeoutMs),
1530 clock_(Clock::GetRealTimeClock()),
1531 padding_length_(0),
1532 total_length_(0),
1533 call_(nullptr) {}
1534
1535 private:
1536 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1537 call_ = sender_call;
1538 }
1539
1540 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1541 rtc::CritScope lock(&crit_);
1542
1543 RTPHeader header;
1544 parser_->Parse(packet, length, &header);
1545 padding_length_ += header.paddingLength;
1546 total_length_ += length;
1547 return SEND_PACKET;
1548 }
1549
Danil Chapovalov44db4362019-09-30 04:16:28 +02001550 std::unique_ptr<test::PacketTransport> CreateSendTransport(
1551 TaskQueueBase* task_queue,
eladalon413ee9a2017-08-22 04:02:52 -07001552 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001553 const int kNetworkDelayMs = 50;
Artem Titov75e36472018-10-08 12:28:56 +02001554 BuiltInNetworkBehaviorConfig config;
isheriffcc5903e2016-10-04 08:29:38 -07001555 config.loss_percent = 10;
1556 config.link_capacity_kbps = kCapacityKbps;
1557 config.queue_delay_ms = kNetworkDelayMs;
Danil Chapovalov44db4362019-09-30 04:16:28 +02001558 return std::make_unique<test::PacketTransport>(
Artem Titov4e199e92018-08-20 13:30:39 +02001559 task_queue, sender_call, this, test::PacketTransport::kSender,
1560 payload_type_map_,
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001561 std::make_unique<FakeNetworkPipe>(
Artem Titov4e199e92018-08-20 13:30:39 +02001562 Clock::GetRealTimeClock(),
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001563 std::make_unique<SimulatedNetwork>(config)));
isheriffcc5903e2016-10-04 08:29:38 -07001564 }
1565
1566 void ModifyVideoConfigs(
1567 VideoSendStream::Config* send_config,
1568 std::vector<VideoReceiveStream::Config>* receive_configs,
1569 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001570 // Turn on RTX.
1571 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1572 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001573 }
1574
1575 void PerformTest() override {
1576 // TODO(isheriff): Some platforms do not ramp up as expected to full
1577 // capacity due to packet scheduling delays. Fix that before getting
1578 // rid of this.
1579 SleepMs(5000);
1580 {
1581 rtc::CritScope lock(&crit_);
1582 // Expect padding to be a small percentage of total bytes sent.
1583 EXPECT_LT(padding_length_, .1 * total_length_);
1584 }
1585 }
1586
1587 rtc::CriticalSection crit_;
1588 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001589 size_t padding_length_ RTC_GUARDED_BY(crit_);
1590 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001591 Call* call_;
1592 } test;
1593
1594 RunBaseTest(&test);
1595}
1596
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001597// This test first observes "high" bitrate use at which point it sends a REMB to
1598// indicate that it should be lowered significantly. The test then observes that
1599// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1600// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001601//
1602// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1603// bitrate since no receiver block or remb is sent in the initial phase.
Sebastian Jansson63470292019-02-01 10:13:43 +01001604TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001605 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001606 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001607 static const int kRembBitrateBps = 80000;
1608 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001609 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001610 public:
1611 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001612 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001613 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1614 stream_(nullptr),
1615 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001616
1617 private:
nisseef8b61e2016-04-29 06:09:15 -07001618 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001619 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001620 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001621
1622 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001623 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001624 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001625 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001626 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001627 if (!stats.substreams.empty()) {
1628 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001629 int total_bitrate_bps =
1630 stats.substreams.begin()->second.total_bitrate_bps;
Yves Gerey665174f2018-06-19 15:03:05 +02001631 test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
1632 "bitrate_bps", static_cast<size_t>(total_bitrate_bps),
1633 "bps", false);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001634 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001635 rtp_rtcp_->SetRemb(kRembBitrateBps,
1636 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001637 rtp_rtcp_->Process();
1638 bitrate_capped_ = true;
1639 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001640 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001641 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001642 }
1643 }
stefanf116bd02015-10-27 08:29:42 -07001644 // Packets don't have to be delivered since the test is the receiver.
1645 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001646 }
1647
stefanff483612015-12-21 03:14:00 -08001648 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001649 VideoSendStream* send_stream,
1650 const std::vector<VideoReceiveStream*>& receive_streams) override {
1651 stream_ = send_stream;
1652 RtpRtcp::Configuration config;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001653 config.clock = Clock::GetRealTimeClock();
stefanf116bd02015-10-27 08:29:42 -07001654 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001655 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +01001656 rtp_rtcp_ = RtpRtcp::Create(config);
stefanf116bd02015-10-27 08:29:42 -07001657 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001658 }
1659
stefanff483612015-12-21 03:14:00 -08001660 void ModifyVideoConfigs(
1661 VideoSendStream::Config* send_config,
1662 std::vector<VideoReceiveStream::Config>* receive_configs,
1663 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001664 feedback_transport_.reset(
1665 new internal::TransportAdapter(send_config->send_transport));
1666 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001667 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001668 }
1669
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001670 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001671 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001672 << "Timeout while waiting for low bitrate stats after REMB.";
1673 }
1674
kwiberg27f982b2016-03-01 11:52:33 -08001675 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1676 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001677 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001678 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001679 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001680 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001681
stefane74eef12016-01-08 06:47:13 -08001682 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001683}
1684
Sebastian Jansson63470292019-02-01 10:13:43 +01001685TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001686 static const int kStartBitrateBps = 300000;
1687 static const int kNewMaxBitrateBps = 1234567;
Elad Alond8d32482019-02-18 23:45:57 +01001688 static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001689 class ChangingNetworkRouteTest : public test::EndToEndTest {
1690 public:
eladalon413ee9a2017-08-22 04:02:52 -07001691 explicit ChangingNetworkRouteTest(
Yves Gerey6516f762019-08-29 11:50:23 +02001692 test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue)
eladalon413ee9a2017-08-22 04:02:52 -07001693 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1694 task_queue_(task_queue),
1695 call_(nullptr) {
Tommi31d1bce2019-08-27 11:34:20 +02001696 module_process_thread_.Detach();
1697 task_queue_thread_.Detach();
Stefan Holmer280de9e2016-09-30 10:06:51 +02001698 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1699 kRtpExtensionTransportSequenceNumber, kExtensionId));
1700 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001701
1702 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommi31d1bce2019-08-27 11:34:20 +02001703 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1704 RTC_DCHECK(!call_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001705 call_ = sender_call;
1706 }
1707
Stefan Holmer280de9e2016-09-30 10:06:51 +02001708 void ModifyVideoConfigs(
1709 VideoSendStream::Config* send_config,
1710 std::vector<VideoReceiveStream::Config>* receive_configs,
1711 VideoEncoderConfig* encoder_config) override {
Tommi31d1bce2019-08-27 11:34:20 +02001712 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Stefan Holmer280de9e2016-09-30 10:06:51 +02001713 send_config->rtp.extensions.clear();
1714 send_config->rtp.extensions.push_back(RtpExtension(
1715 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1716 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1717 (*receive_configs)[0].rtp.transport_cc = true;
1718 }
1719
1720 void ModifyAudioConfigs(
1721 AudioSendStream::Config* send_config,
1722 std::vector<AudioReceiveStream::Config>* receive_configs) override {
Tommi31d1bce2019-08-27 11:34:20 +02001723 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Stefan Holmer280de9e2016-09-30 10:06:51 +02001724 send_config->rtp.extensions.clear();
1725 send_config->rtp.extensions.push_back(RtpExtension(
1726 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1727 (*receive_configs)[0].rtp.extensions.clear();
1728 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1729 (*receive_configs)[0].rtp.transport_cc = true;
1730 }
1731
Stefan Holmerbe402962016-07-08 16:16:41 +02001732 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Tommi31d1bce2019-08-27 11:34:20 +02001733 RTC_DCHECK_RUN_ON(&module_process_thread_);
1734 task_queue_->PostTask([this]() {
1735 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1736 if (!call_)
1737 return;
1738 Call::Stats stats = call_->GetStats();
1739 if (stats.send_bandwidth_bps > kStartBitrateBps)
1740 observation_complete_.Set();
1741 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001742 return SEND_PACKET;
1743 }
1744
Tommi31d1bce2019-08-27 11:34:20 +02001745 void OnStreamsStopped() override {
1746 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1747 call_ = nullptr;
1748 }
1749
Stefan Holmerbe402962016-07-08 16:16:41 +02001750 void PerformTest() override {
Steve Antonea1bb352018-07-23 10:12:37 -07001751 rtc::NetworkRoute new_route;
1752 new_route.connected = true;
1753 new_route.local_network_id = 10;
1754 new_route.remote_network_id = 20;
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01001755 BitrateConstraints bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001756
1757 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Tommi31d1bce2019-08-27 11:34:20 +02001758 RTC_DCHECK_RUN_ON(&task_queue_thread_);
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001759 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1760 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001761 bitrate_config.start_bitrate_bps = kStartBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001762 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1763 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001764 });
1765
Stefan Holmerbe402962016-07-08 16:16:41 +02001766 EXPECT_TRUE(Wait())
1767 << "Timed out while waiting for start bitrate to be exceeded.";
1768
eladalon413ee9a2017-08-22 04:02:52 -07001769 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
Tommi31d1bce2019-08-27 11:34:20 +02001770 RTC_DCHECK_RUN_ON(&task_queue_thread_);
eladalon413ee9a2017-08-22 04:02:52 -07001771 bitrate_config.start_bitrate_bps = -1;
1772 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001773 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
1774 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07001775 // TODO(holmer): We should set the last sent packet id here and verify
1776 // that we correctly ignore any packet loss reported prior to that id.
1777 ++new_route.local_network_id;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001778 call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
1779 new_route);
eladalon413ee9a2017-08-22 04:02:52 -07001780 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1781 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001782 }
1783
1784 private:
Tommi31d1bce2019-08-27 11:34:20 +02001785 webrtc::SequenceChecker module_process_thread_;
1786 webrtc::SequenceChecker task_queue_thread_;
Yves Gerey6516f762019-08-29 11:50:23 +02001787 test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
Tommi31d1bce2019-08-27 11:34:20 +02001788 Call* call_ RTC_GUARDED_BY(task_queue_thread_);
eladalon413ee9a2017-08-22 04:02:52 -07001789 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001790
1791 RunBaseTest(&test);
1792}
1793
Sebastian Jansson63470292019-02-01 10:13:43 +01001794TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
michaelt79e05882016-11-08 02:50:09 -08001795 class ChangingTransportOverheadTest : public test::EndToEndTest {
1796 public:
eladalon413ee9a2017-08-22 04:02:52 -07001797 explicit ChangingTransportOverheadTest(
Yves Gerey6516f762019-08-29 11:50:23 +02001798 test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001799 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001800 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001801 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001802 packets_sent_(0),
1803 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001804
1805 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1806 call_ = sender_call;
1807 }
1808
1809 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001810 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001811 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001812 if (++packets_sent_ < 100)
1813 return SEND_PACKET;
1814 observation_complete_.Set();
1815 return SEND_PACKET;
1816 }
1817
michaelta3328772016-11-29 09:25:03 -08001818 void ModifyVideoConfigs(
1819 VideoSendStream::Config* send_config,
1820 std::vector<VideoReceiveStream::Config>* receive_configs,
1821 VideoEncoderConfig* encoder_config) override {
1822 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1823 }
1824
michaelt79e05882016-11-08 02:50:09 -08001825 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001826 task_queue_->SendTask([this]() {
1827 transport_overhead_ = 100;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001828 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1829 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001830 });
1831
michaelt79e05882016-11-08 02:50:09 -08001832 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001833
sprang21253fc2017-02-27 03:35:47 -08001834 {
1835 rtc::CritScope cs(&lock_);
1836 packets_sent_ = 0;
1837 }
eladalon413ee9a2017-08-22 04:02:52 -07001838
1839 task_queue_->SendTask([this]() {
1840 transport_overhead_ = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +02001841 call_->GetTransportControllerSend()->OnTransportOverheadChanged(
1842 transport_overhead_);
eladalon413ee9a2017-08-22 04:02:52 -07001843 });
1844
michaelt79e05882016-11-08 02:50:09 -08001845 EXPECT_TRUE(Wait());
1846 }
1847
1848 private:
Yves Gerey6516f762019-08-29 11:50:23 +02001849 test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001850 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001851 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001852 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001853 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001854 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001855 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001856
1857 RunBaseTest(&test);
1858}
1859
sprangf24a0642017-02-28 13:23:26 -08001860// Test class takes takes as argument a switch selecting if type switch should
1861// occur and a function pointer to reset the send stream. This is necessary
1862// since you cannot change the content type of a VideoSendStream, you need to
1863// recreate it. Stopping and recreating the stream can only be done on the main
1864// thread and in the context of VideoSendStreamTest (not BaseTest).
1865template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001866class MaxPaddingSetTest : public test::SendTest {
1867 public:
1868 static const uint32_t kMinTransmitBitrateBps = 400000;
1869 static const uint32_t kActualEncodeBitrateBps = 40000;
1870 static const uint32_t kMinPacketsToSend = 50;
1871
Yves Gerey6516f762019-08-29 11:50:23 +02001872 MaxPaddingSetTest(
1873 bool test_switch_content_type,
1874 T* stream_reset_fun,
1875 test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue)
sprang9c0b5512016-07-06 00:54:28 -07001876 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001877 running_without_padding_(test_switch_content_type),
Tommiaaaf8042019-08-05 14:56:33 +02001878 stream_resetter_(stream_reset_fun),
1879 task_queue_(task_queue) {
tommi39e12892017-03-13 05:15:14 -07001880 RTC_DCHECK(stream_resetter_);
Tommi31d1bce2019-08-27 11:34:20 +02001881 module_process_thread_.Detach();
1882 task_queue_thread_.Detach();
sprang9c0b5512016-07-06 00:54:28 -07001883 }
1884
1885 void ModifyVideoConfigs(
1886 VideoSendStream::Config* send_config,
1887 std::vector<VideoReceiveStream::Config>* receive_configs,
1888 VideoEncoderConfig* encoder_config) override {
Tommi31d1bce2019-08-27 11:34:20 +02001889 RTC_DCHECK_RUN_ON(&task_queue_thread_);
kwibergaf476c72016-11-28 15:21:39 -08001890 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
Tommi31d1bce2019-08-27 11:34:20 +02001891 if (running_without_padding_) {
sprang9c0b5512016-07-06 00:54:28 -07001892 encoder_config->min_transmit_bitrate_bps = 0;
1893 encoder_config->content_type =
1894 VideoEncoderConfig::ContentType::kRealtimeVideo;
1895 } else {
1896 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1897 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1898 }
sprangf24a0642017-02-28 13:23:26 -08001899 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001900 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001901 }
1902
1903 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
Tommi31d1bce2019-08-27 11:34:20 +02001904 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1905 RTC_DCHECK(task_queue_->IsCurrent());
1906 RTC_DCHECK(!call_);
1907 RTC_DCHECK(sender_call);
sprang9c0b5512016-07-06 00:54:28 -07001908 call_ = sender_call;
1909 }
1910
Tommiaaaf8042019-08-05 14:56:33 +02001911 // Called on the pacer thread.
sprang9c0b5512016-07-06 00:54:28 -07001912 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Tommi31d1bce2019-08-27 11:34:20 +02001913 RTC_DCHECK_RUN_ON(&module_process_thread_);
Tommiaaaf8042019-08-05 14:56:33 +02001914
Tommi31d1bce2019-08-27 11:34:20 +02001915 // Check the stats on the correct thread and signal the 'complete' flag
1916 // once we detect that we're done.
Tommiaaaf8042019-08-05 14:56:33 +02001917
Tommi31d1bce2019-08-27 11:34:20 +02001918 task_queue_->PostTask([this]() {
1919 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1920 // In case we get a callback during teardown.
1921 // When this happens, OnStreamsStopped() has been called already,
1922 // |call_| is null and the streams are being torn down.
1923 if (!call_)
1924 return;
sprang9c0b5512016-07-06 00:54:28 -07001925
Tommi31d1bce2019-08-27 11:34:20 +02001926 ++packets_sent_;
sprang9c0b5512016-07-06 00:54:28 -07001927
Tommi31d1bce2019-08-27 11:34:20 +02001928 Call::Stats stats = call_->GetStats();
1929 if (running_without_padding_) {
1930 EXPECT_EQ(0, stats.max_padding_bitrate_bps);
sprang9c0b5512016-07-06 00:54:28 -07001931
Tommi31d1bce2019-08-27 11:34:20 +02001932 // Wait until at least kMinPacketsToSend frames have been encoded, so
1933 // that we have reliable data.
1934 if (packets_sent_ < kMinPacketsToSend)
1935 return;
1936
1937 // We've sent kMinPacketsToSend packets with default configuration,
1938 // switch to enabling screen content and setting min transmit bitrate.
1939 // Note that we need to recreate the stream if changing content type.
1940 packets_sent_ = 0;
1941
1942 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1943 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
1944
1945 running_without_padding_ = false;
1946 (*stream_resetter_)(send_stream_config_, encoder_config_);
1947 } else {
1948 // Make sure the pacer has been configured with a min transmit bitrate.
1949 if (stats.max_padding_bitrate_bps > 0) {
1950 observation_complete_.Set();
1951 }
1952 }
1953 });
sprang9c0b5512016-07-06 00:54:28 -07001954
1955 return SEND_PACKET;
1956 }
1957
Tommi31d1bce2019-08-27 11:34:20 +02001958 // Called on |task_queue_|
1959 void OnStreamsStopped() override {
1960 RTC_DCHECK_RUN_ON(&task_queue_thread_);
1961 RTC_DCHECK(task_queue_->IsCurrent());
1962 call_ = nullptr;
1963 }
sprangf24a0642017-02-28 13:23:26 -08001964
Tommi31d1bce2019-08-27 11:34:20 +02001965 void PerformTest() override {
sprang9c0b5512016-07-06 00:54:28 -07001966 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1967 }
1968
1969 private:
Tommi31d1bce2019-08-27 11:34:20 +02001970 webrtc::SequenceChecker task_queue_thread_;
1971 Call* call_ RTC_GUARDED_BY(task_queue_thread_) = nullptr;
1972 VideoSendStream::Config send_stream_config_{nullptr};
sprang9c0b5512016-07-06 00:54:28 -07001973 VideoEncoderConfig encoder_config_;
Tommi31d1bce2019-08-27 11:34:20 +02001974 webrtc::SequenceChecker module_process_thread_;
1975 uint32_t packets_sent_ RTC_GUARDED_BY(task_queue_thread_) = 0;
1976 bool running_without_padding_ RTC_GUARDED_BY(task_queue_thread_);
sprangf24a0642017-02-28 13:23:26 -08001977 T* const stream_resetter_;
Yves Gerey6516f762019-08-29 11:50:23 +02001978 test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
sprang9c0b5512016-07-06 00:54:28 -07001979};
1980
Sebastian Jansson63470292019-02-01 10:13:43 +01001981TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001982 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1983 const VideoEncoderConfig& encoder_config) {};
Tommiaaaf8042019-08-05 14:56:33 +02001984 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun, &task_queue_);
sprang9c0b5512016-07-06 00:54:28 -07001985 RunBaseTest(&test);
1986}
1987
Sebastian Jansson63470292019-02-01 10:13:43 +01001988TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001989 // Function for removing and recreating the send stream with a new config.
1990 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1991 const VideoEncoderConfig& encoder_config) {
Tommi31d1bce2019-08-27 11:34:20 +02001992 RTC_DCHECK(task_queue_.IsCurrent());
1993 Stop();
1994 DestroyVideoSendStreams();
1995 SetVideoSendConfig(send_stream_config);
1996 SetVideoEncoderConfig(encoder_config);
1997 CreateVideoSendStreams();
1998 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
1999 Start();
sprangf24a0642017-02-28 13:23:26 -08002000 };
Tommiaaaf8042019-08-05 14:56:33 +02002001 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun, &task_queue_);
sprang9c0b5512016-07-06 00:54:28 -07002002 RunBaseTest(&test);
2003}
2004
perkjfa10b552016-10-02 23:45:26 -07002005// This test verifies that new frame sizes reconfigures encoders even though not
2006// (yet) sending. The purpose of this is to permit encoding as quickly as
2007// possible once we start sending. Likely the frames being input are from the
2008// same source that will be sent later, which just means that we're ready
2009// earlier.
Sebastian Jansson63470292019-02-01 10:13:43 +01002010TEST_F(VideoSendStreamTest,
perkjfa10b552016-10-02 23:45:26 -07002011 EncoderReconfigureOnResolutionChangeWhenNotSending) {
2012 class EncoderObserver : public test::FakeEncoder {
2013 public:
2014 EncoderObserver()
2015 : FakeEncoder(Clock::GetRealTimeClock()),
perkjfa10b552016-10-02 23:45:26 -07002016 number_of_initializations_(0),
2017 last_initialized_frame_width_(0),
2018 last_initialized_frame_height_(0) {}
2019
2020 void WaitForResolution(int width, int height) {
2021 {
2022 rtc::CritScope lock(&crit_);
2023 if (last_initialized_frame_width_ == width &&
2024 last_initialized_frame_height_ == height) {
2025 return;
2026 }
2027 }
Erik Språng08127a92016-11-16 16:41:30 +01002028 EXPECT_TRUE(
2029 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07002030 {
2031 rtc::CritScope lock(&crit_);
2032 EXPECT_EQ(width, last_initialized_frame_width_);
2033 EXPECT_EQ(height, last_initialized_frame_height_);
2034 }
2035 }
2036
2037 private:
2038 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002039 const Settings& settings) override {
perkjfa10b552016-10-02 23:45:26 -07002040 rtc::CritScope lock(&crit_);
2041 last_initialized_frame_width_ = config->width;
2042 last_initialized_frame_height_ = config->height;
2043 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01002044 init_encode_called_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002045 return FakeEncoder::InitEncode(config, settings);
perkjfa10b552016-10-02 23:45:26 -07002046 }
2047
2048 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01002049 const std::vector<VideoFrameType>* frame_types) override {
perkjfa10b552016-10-02 23:45:26 -07002050 ADD_FAILURE()
2051 << "Unexpected Encode call since the send stream is not started";
2052 return 0;
2053 }
2054
2055 rtc::CriticalSection crit_;
2056 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07002057 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
2058 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
2059 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002060 };
2061
perkjfa10b552016-10-02 23:45:26 -07002062 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07002063 EncoderObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002064 test::VideoEncoderProxyFactory encoder_factory(&encoder);
eladalon413ee9a2017-08-22 04:02:52 -07002065
Niels Möller4db138e2018-04-19 09:04:13 +02002066 task_queue_.SendTask([this, &transport, &encoder_factory]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002067 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002068 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002069 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002070 CreateVideoStreams();
2071 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
2072 kDefaultHeight);
2073 frame_generator_capturer_->Start();
2074 });
perkjfa10b552016-10-02 23:45:26 -07002075
2076 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07002077
2078 task_queue_.SendTask([this]() {
2079 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
2080 kDefaultHeight * 2);
2081 });
2082
perkjfa10b552016-10-02 23:45:26 -07002083 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07002084
2085 task_queue_.SendTask([this]() {
2086 DestroyStreams();
2087 DestroyCalls();
2088 });
perkjfa10b552016-10-02 23:45:26 -07002089}
2090
Sebastian Jansson63470292019-02-01 10:13:43 +01002091TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002092 class StartBitrateObserver : public test::FakeEncoder {
2093 public:
2094 StartBitrateObserver()
Ilya Nikolaevskiy2d821c32019-06-26 14:39:36 +02002095 : FakeEncoder(Clock::GetRealTimeClock()), start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002096 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002097 const Settings& settings) override {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002098 rtc::CritScope lock(&crit_);
2099 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07002100 start_bitrate_changed_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002101 return FakeEncoder::InitEncode(config, settings);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002102 }
2103
Erik Språng16cb8f52019-04-12 13:59:09 +02002104 void SetRates(const RateControlParameters& parameters) override {
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002105 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002106 start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
pbos14fe7082016-04-20 06:35:56 -07002107 start_bitrate_changed_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002108 FakeEncoder::SetRates(parameters);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002109 }
2110
2111 int GetStartBitrateKbps() const {
2112 rtc::CritScope lock(&crit_);
2113 return start_bitrate_kbps_;
2114 }
2115
pbos14fe7082016-04-20 06:35:56 -07002116 bool WaitForStartBitrate() {
2117 return start_bitrate_changed_.Wait(
2118 VideoSendStreamTest::kDefaultTimeoutMs);
2119 }
2120
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002121 private:
pbos5ad935c2016-01-25 03:52:44 -08002122 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07002123 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07002124 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002125 };
2126
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002127 CreateSenderCall();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002128
solenberg4fbae2b2015-08-28 04:07:10 -07002129 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002130 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002131
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002132 BitrateConstraints bitrate_config;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002133 bitrate_config.start_bitrate_bps =
2134 2 * GetVideoEncoderConfig()->max_bitrate_bps;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002135 sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2136 bitrate_config);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002137
2138 StartBitrateObserver encoder;
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002139 test::VideoEncoderProxyFactory encoder_factory(&encoder);
perkjfa10b552016-10-02 23:45:26 -07002140 // Since this test does not use a capturer, set |internal_source| = true.
2141 // Encoder configuration is otherwise updated on the next video frame.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002142 encoder_factory.SetHasInternalSource(true);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002143 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002144
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002145 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002146
pbos14fe7082016-04-20 06:35:56 -07002147 EXPECT_TRUE(encoder.WaitForStartBitrate());
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002148 EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002149 encoder.GetStartBitrateKbps());
2150
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002151 GetVideoEncoderConfig()->max_bitrate_bps =
2152 2 * bitrate_config.start_bitrate_bps;
2153 GetVideoSendStream()->ReconfigureVideoEncoder(
2154 GetVideoEncoderConfig()->Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002155
2156 // New bitrate should be reconfigured above the previous max. As there's no
2157 // network connection this shouldn't be flaky, as no bitrate should've been
2158 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07002159 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00002160 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
2161 encoder.GetStartBitrateKbps());
2162
2163 DestroyStreams();
2164}
2165
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002166class StartStopBitrateObserver : public test::FakeEncoder {
2167 public:
Niels Möllerc572ff32018-11-07 08:43:50 +01002168 StartStopBitrateObserver() : FakeEncoder(Clock::GetRealTimeClock()) {}
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002169 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002170 const Settings& settings) override {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002171 rtc::CritScope lock(&crit_);
2172 encoder_init_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002173 return FakeEncoder::InitEncode(config, settings);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002174 }
2175
Erik Språng16cb8f52019-04-12 13:59:09 +02002176 void SetRates(const RateControlParameters& parameters) override {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002177 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002178 bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002179 bitrate_changed_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002180 FakeEncoder::SetRates(parameters);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002181 }
2182
2183 bool WaitForEncoderInit() {
2184 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
2185 }
2186
2187 bool WaitBitrateChanged(bool non_zero) {
2188 do {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002189 absl::optional<int> bitrate_kbps;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002190 {
2191 rtc::CritScope lock(&crit_);
2192 bitrate_kbps = bitrate_kbps_;
2193 }
2194 if (!bitrate_kbps)
2195 continue;
2196
2197 if ((non_zero && *bitrate_kbps > 0) ||
2198 (!non_zero && *bitrate_kbps == 0)) {
2199 return true;
2200 }
2201 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
2202 return false;
2203 }
2204
2205 private:
2206 rtc::CriticalSection crit_;
2207 rtc::Event encoder_init_;
2208 rtc::Event bitrate_changed_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02002209 absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002210};
2211
perkj57c21f92016-06-17 07:27:16 -07002212// This test that if the encoder use an internal source, VideoEncoder::SetRates
2213// will be called with zero bitrate during initialization and that
2214// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
2215// with zero bitrate.
Sebastian Jansson63470292019-02-01 10:13:43 +01002216TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
perkj57c21f92016-06-17 07:27:16 -07002217 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002218 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002219 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002220 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002221 test::FrameForwarder forwarder;
perkj57c21f92016-06-17 07:27:16 -07002222
Niels Möller4db138e2018-04-19 09:04:13 +02002223 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002224 CreateSenderCall();
eladalon413ee9a2017-08-22 04:02:52 -07002225 CreateSendConfig(1, 0, 0, &transport);
2226
2227 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002228 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
eladalon413ee9a2017-08-22 04:02:52 -07002229
2230 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002231 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002232 GetVideoSendStream()->Start();
2233 GetVideoSendStream()->SetSource(&forwarder,
2234 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002235 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
eladalon413ee9a2017-08-22 04:02:52 -07002236 });
perkj57c21f92016-06-17 07:27:16 -07002237
2238 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002239
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002240 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002241 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2242
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002243 task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
Erik Språng08127a92016-11-16 16:41:30 +01002244 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2245
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002246 task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
Erik Språng08127a92016-11-16 16:41:30 +01002247 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002248
eladalon413ee9a2017-08-22 04:02:52 -07002249 task_queue_.SendTask([this]() {
2250 DestroyStreams();
2251 DestroyCalls();
2252 });
perkj57c21f92016-06-17 07:27:16 -07002253}
2254
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002255// Tests that when the encoder uses an internal source, the VideoEncoder will
2256// be updated with a new bitrate when turning the VideoSendStream on/off with
2257// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
2258// is reconfigured with new active layers.
Sebastian Jansson63470292019-02-01 10:13:43 +01002259TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002260 test::NullTransport transport;
2261 StartStopBitrateObserver encoder;
Niels Möllercbcbc222018-09-28 09:07:24 +02002262 test::VideoEncoderProxyFactory encoder_factory(&encoder);
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00002263 encoder_factory.SetHasInternalSource(true);
Niels Möller4db138e2018-04-19 09:04:13 +02002264 test::FrameForwarder forwarder;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002265
Niels Möller4db138e2018-04-19 09:04:13 +02002266 task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02002267 CreateSenderCall();
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002268 // Create two simulcast streams.
2269 CreateSendConfig(2, 0, 0, &transport);
2270
2271 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002272 GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002273
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002274 CreateVideoStreams();
Niels Möller4db138e2018-04-19 09:04:13 +02002275
2276 // Inject a frame, to force encoder creation.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002277 GetVideoSendStream()->Start();
2278 GetVideoSendStream()->SetSource(&forwarder,
2279 DegradationPreference::DISABLED);
Niels Möller4db138e2018-04-19 09:04:13 +02002280 forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002281 });
2282
2283 EXPECT_TRUE(encoder.WaitForEncoderInit());
2284
2285 // When we turn on the simulcast layers it will update the BitrateAllocator,
2286 // which in turn updates the VideoEncoder's bitrate.
2287 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002288 GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002289 });
2290 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2291
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002292 GetVideoEncoderConfig()->simulcast_layers[0].active = true;
2293 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002294 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002295 GetVideoSendStream()->ReconfigureVideoEncoder(
2296 GetVideoEncoderConfig()->Copy());
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002297 });
2298 // TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
2299 // update the VideoBitrateAllocator and BitrateAllocator of which layers are
2300 // active. Once the change is made for a "soft" reconfiguration we can remove
2301 // the expecation for an encoder init. We can also test that bitrate changes
2302 // when just updating individual active layers, which should change the
2303 // bitrate set to the video encoder.
2304 EXPECT_TRUE(encoder.WaitForEncoderInit());
2305 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2306
2307 // Turning off both simulcast layers should trigger a bitrate change of 0.
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002308 GetVideoEncoderConfig()->simulcast_layers[0].active = false;
2309 GetVideoEncoderConfig()->simulcast_layers[1].active = false;
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002310 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02002311 GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
Seth Hampsoncc7125f2018-02-02 08:46:16 -08002312 });
2313 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2314
2315 task_queue_.SendTask([this]() {
2316 DestroyStreams();
2317 DestroyCalls();
2318 });
2319}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002320
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002321VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002322 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002323 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002324 memset(buffer.get(), data, kSizeY);
Artem Titov1ebfb6a2019-01-03 23:49:37 +01002325 VideoFrame frame =
2326 webrtc::VideoFrame::Builder()
2327 .set_video_frame_buffer(I420Buffer::Create(width, height))
2328 .set_rotation(webrtc::kVideoRotation_0)
2329 .set_timestamp_us(data)
2330 .build();
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002331 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002332 // Use data as a ms timestamp.
2333 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002334 return frame;
2335}
2336
Sebastian Jansson63470292019-02-01 10:13:43 +01002337TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002338 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2339 public:
eladalon413ee9a2017-08-22 04:02:52 -07002340 explicit EncoderStateObserver(
Yves Gerey6516f762019-08-29 11:50:23 +02002341 test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002342 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002343 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002344 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002345 initialized_(false),
2346 callback_registered_(false),
2347 num_releases_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002348 released_(false),
2349 encoder_factory_(this) {}
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002350
2351 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002352 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002353 return released_;
2354 }
2355
2356 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002357 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002358 return initialized_ && callback_registered_;
2359 }
2360
2361 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002362 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002363 return num_releases_;
2364 }
2365
2366 private:
Elad Alon8f01c4e2019-06-28 15:19:43 +02002367 void SetFecControllerOverride(
2368 FecControllerOverride* fec_controller_override) override {
2369 // Ignored.
2370 }
2371
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002372 int32_t InitEncode(const VideoCodec* codecSettings,
Elad Alon370f93a2019-06-11 14:57:57 +02002373 const Settings& settings) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002374 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002375 EXPECT_FALSE(initialized_);
2376 initialized_ = true;
2377 released_ = false;
2378 return 0;
2379 }
2380
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002381 int32_t Encode(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +01002382 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002383 EXPECT_TRUE(IsReadyForEncode());
2384
Peter Boström5811a392015-12-10 13:02:50 +01002385 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002386 return 0;
2387 }
2388
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002389 int32_t RegisterEncodeCompleteCallback(
2390 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002391 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002392 EXPECT_TRUE(initialized_);
2393 callback_registered_ = true;
2394 return 0;
2395 }
2396
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002397 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002398 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002399 EXPECT_TRUE(IsReadyForEncode());
2400 EXPECT_FALSE(released_);
2401 initialized_ = false;
2402 callback_registered_ = false;
2403 released_ = true;
2404 ++num_releases_;
2405 return 0;
2406 }
2407
Erik Språng6f46e4a2019-04-24 18:33:27 +02002408 void SetRates(const RateControlParameters& parameters) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002409 EXPECT_TRUE(IsReadyForEncode());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002410 }
2411
stefanff483612015-12-21 03:14:00 -08002412 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002413 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002414 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002415 stream_ = send_stream;
2416 }
2417
stefanff483612015-12-21 03:14:00 -08002418 void ModifyVideoConfigs(
2419 VideoSendStream::Config* send_config,
2420 std::vector<VideoReceiveStream::Config>* receive_configs,
2421 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002422 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkj26091b12016-09-01 01:17:40 -07002423 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002424 }
2425
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002426 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002427 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002428
2429 task_queue_->SendTask([this]() {
2430 EXPECT_EQ(0u, num_releases());
2431 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2432 EXPECT_EQ(0u, num_releases());
2433 stream_->Stop();
2434 // Encoder should not be released before destroying the VideoSendStream.
2435 EXPECT_FALSE(IsReleased());
2436 EXPECT_TRUE(IsReadyForEncode());
2437 stream_->Start();
2438 });
2439
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002440 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002441 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002442 }
2443
Yves Gerey6516f762019-08-29 11:50:23 +02002444 test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002445 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002446 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002447 bool initialized_ RTC_GUARDED_BY(crit_);
2448 bool callback_registered_ RTC_GUARDED_BY(crit_);
2449 size_t num_releases_ RTC_GUARDED_BY(crit_);
2450 bool released_ RTC_GUARDED_BY(crit_);
Niels Möllercbcbc222018-09-28 09:07:24 +02002451 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002452 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002453 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002454
stefane74eef12016-01-08 06:47:13 -08002455 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002456
2457 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002458 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002459}
2460
Sergey Silkin571e6c92018-04-03 10:03:31 +02002461static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
Peter Boström53eda3d2015-03-27 15:53:18 +01002462template <typename T>
2463class VideoCodecConfigObserver : public test::SendTest,
2464 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002465 public:
2466 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2467 const char* codec_name)
2468 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2469 FakeEncoder(Clock::GetRealTimeClock()),
2470 video_codec_type_(video_codec_type),
2471 codec_name_(codec_name),
Erik Språng737336d2016-07-29 12:59:36 +02002472 num_initializations_(0),
Niels Möller4db138e2018-04-19 09:04:13 +02002473 stream_(nullptr),
2474 encoder_factory_(this) {
Sergey Silkin86684962018-03-28 19:32:37 +02002475 InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002476 }
2477
2478 private:
stefanff483612015-12-21 03:14:00 -08002479 void ModifyVideoConfigs(
2480 VideoSendStream::Config* send_config,
2481 std::vector<VideoReceiveStream::Config>* receive_configs,
2482 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002483 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02002484 send_config->rtp.payload_name = codec_name_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002485
Niels Möller259a4972018-04-05 15:36:51 +02002486 encoder_config->codec_type = video_codec_type_;
kthelgason29a44e32016-09-27 03:52:02 -07002487 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
Åsa Perssond34597c2018-10-22 17:34:02 +02002488 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2489 encoder_config->simulcast_layers[0].num_temporal_layers =
2490 kVideoCodecConfigObserverNumberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07002491 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002492 }
2493
stefanff483612015-12-21 03:14:00 -08002494 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002495 VideoSendStream* send_stream,
2496 const std::vector<VideoReceiveStream*>& receive_streams) override {
2497 stream_ = send_stream;
2498 }
2499
2500 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002501 const Settings& settings) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002502 EXPECT_EQ(video_codec_type_, config->codecType);
2503 VerifyCodecSpecifics(*config);
2504 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002505 init_encode_event_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002506 return FakeEncoder::InitEncode(config, settings);
Peter Boström53eda3d2015-03-27 15:53:18 +01002507 }
2508
Sergey Silkin86684962018-03-28 19:32:37 +02002509 void InitCodecSpecifics();
Peter Boström53eda3d2015-03-27 15:53:18 +01002510 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002511 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2512 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002513
2514 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002515 EXPECT_TRUE(
2516 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002517 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002518
Sergey Silkin86684962018-03-28 19:32:37 +02002519 // Change encoder settings to actually trigger reconfiguration.
2520 encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
kthelgason29a44e32016-09-27 03:52:02 -07002521 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002522 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002523 ASSERT_TRUE(
2524 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002525 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002526 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2527 "new encoder settings.";
2528 }
2529
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002530 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01002531 const std::vector<VideoFrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002532 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2533 return 0;
2534 }
2535
2536 T encoder_settings_;
2537 const VideoCodecType video_codec_type_;
2538 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002539 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002540 size_t num_initializations_;
2541 VideoSendStream* stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002542 test::VideoEncoderProxyFactory encoder_factory_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002543 VideoEncoderConfig encoder_config_;
2544};
2545
2546template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002547void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
2548 encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
2549}
2550
2551template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002552void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2553 const VideoCodec& config) const {
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002554 // Check that the number of temporal layers has propagated properly to
2555 // VideoCodec.
2556 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2557 config.H264().numberOfTemporalLayers);
2558
2559 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2560 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2561 config.simulcastStream[i].numberOfTemporalLayers);
2562 }
2563
2564 // Set expected temporal layers as they should have been set when
2565 // reconfiguring the encoder and not match the set config.
2566 VideoCodecH264 encoder_settings = encoder_settings_;
2567 encoder_settings.numberOfTemporalLayers =
2568 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002569 EXPECT_EQ(
Johnny Lee1a1c52b2019-02-08 14:25:40 -05002570 0, memcmp(&config.H264(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002571}
kthelgason29a44e32016-09-27 03:52:02 -07002572
2573template <>
2574rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2575VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2576 return new rtc::RefCountedObject<
2577 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2578}
2579
Peter Boström53eda3d2015-03-27 15:53:18 +01002580template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002581void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
2582 encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
2583}
2584
2585template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002586void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2587 const VideoCodec& config) const {
2588 // Check that the number of temporal layers has propagated properly to
2589 // VideoCodec.
2590 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002591 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002592
2593 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2594 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2595 config.simulcastStream[i].numberOfTemporalLayers);
2596 }
2597
2598 // Set expected temporal layers as they should have been set when
Erik Språng82fad3d2018-03-21 09:57:23 +01002599 // reconfiguring the encoder and not match the set config.
Peter Boström53eda3d2015-03-27 15:53:18 +01002600 VideoCodecVP8 encoder_settings = encoder_settings_;
2601 encoder_settings.numberOfTemporalLayers =
2602 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002603 EXPECT_EQ(
2604 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002605}
kthelgason29a44e32016-09-27 03:52:02 -07002606
2607template <>
2608rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2609VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2610 return new rtc::RefCountedObject<
2611 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2612}
2613
Peter Boström53eda3d2015-03-27 15:53:18 +01002614template <>
Sergey Silkin86684962018-03-28 19:32:37 +02002615void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
2616 encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
2617}
2618
2619template <>
Peter Boström53eda3d2015-03-27 15:53:18 +01002620void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2621 const VideoCodec& config) const {
2622 // Check that the number of temporal layers has propagated properly to
2623 // VideoCodec.
2624 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002625 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002626
2627 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2628 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2629 config.simulcastStream[i].numberOfTemporalLayers);
2630 }
2631
2632 // Set expected temporal layers as they should have been set when
2633 // reconfiguring the encoder and not match the set config.
2634 VideoCodecVP9 encoder_settings = encoder_settings_;
2635 encoder_settings.numberOfTemporalLayers =
2636 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002637 EXPECT_EQ(
2638 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002639}
2640
kthelgason29a44e32016-09-27 03:52:02 -07002641template <>
2642rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2643VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2644 return new rtc::RefCountedObject<
2645 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2646}
2647
Sebastian Jansson63470292019-02-01 10:13:43 +01002648TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002649 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002650 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002651}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002652
Sebastian Jansson63470292019-02-01 10:13:43 +01002653TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002654 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002655 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002656}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002657
Sebastian Jansson63470292019-02-01 10:13:43 +01002658TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002659 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002660 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002661}
2662
Sebastian Jansson63470292019-02-01 10:13:43 +01002663TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002664 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002665 public:
Yves Gerey665174f2018-06-19 15:03:05 +02002666 RtcpSenderReportTest()
2667 : SendTest(kDefaultTimeoutMs),
2668 rtp_packets_sent_(0),
2669 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002670
2671 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002672 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002673 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002674 RTPHeader header;
2675 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002676 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002677 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2678 return SEND_PACKET;
2679 }
2680
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002681 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002682 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002683 test::RtcpPacketParser parser;
2684 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002685
danilchap3dc929e2016-11-02 08:21:59 -07002686 if (parser.sender_report()->num_packets() > 0) {
2687 // Only compare sent media bytes if SenderPacketCount matches the
2688 // number of sent rtp packets (a new rtp packet could be sent before
2689 // the rtcp packet).
2690 if (parser.sender_report()->sender_octet_count() > 0 &&
2691 parser.sender_report()->sender_packet_count() ==
2692 rtp_packets_sent_) {
2693 EXPECT_EQ(media_bytes_sent_,
2694 parser.sender_report()->sender_octet_count());
2695 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002696 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002697 }
2698
2699 return SEND_PACKET;
2700 }
2701
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002702 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002703 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002704 }
2705
stefan4b569042015-11-11 06:39:57 -08002706 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002707 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2708 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002709 } test;
2710
stefane74eef12016-01-08 06:47:13 -08002711 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002712}
2713
Sebastian Jansson63470292019-02-01 10:13:43 +01002714TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
Sergey Silkina796a7e2018-03-01 15:11:29 +01002715 static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
perkjfa10b552016-10-02 23:45:26 -07002716
2717 class VideoStreamFactory
2718 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2719 public:
2720 VideoStreamFactory() {}
2721
2722 private:
2723 std::vector<VideoStream> CreateEncoderStreams(
2724 int width,
2725 int height,
2726 const VideoEncoderConfig& encoder_config) override {
2727 std::vector<VideoStream> streams =
2728 test::CreateVideoStreams(width, height, encoder_config);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002729 RTC_CHECK_GT(streams[0].max_bitrate_bps,
2730 kScreencastMaxTargetBitrateDeltaKbps);
2731 streams[0].target_bitrate_bps =
2732 streams[0].max_bitrate_bps -
2733 kScreencastMaxTargetBitrateDeltaKbps * 1000;
perkjfa10b552016-10-02 23:45:26 -07002734 return streams;
2735 }
2736 };
2737
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002738 class ScreencastTargetBitrateTest : public test::SendTest,
2739 public test::FakeEncoder {
2740 public:
2741 ScreencastTargetBitrateTest()
2742 : SendTest(kDefaultTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02002743 test::FakeEncoder(Clock::GetRealTimeClock()),
2744 encoder_factory_(this) {}
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002745
2746 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002747 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +02002748 const Settings& settings) override {
Erik Språng5e898d62018-07-06 16:32:20 +02002749 EXPECT_EQ(config->numberOfSimulcastStreams, 1);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002750 EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
Erik Språng5e898d62018-07-06 16:32:20 +02002751 config->simulcastStream[0].maxBitrate -
2752 config->simulcastStream[0].targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002753 observation_complete_.Set();
Elad Alon370f93a2019-06-11 14:57:57 +02002754 return test::FakeEncoder::InitEncode(config, settings);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002755 }
Elad Alon370f93a2019-06-11 14:57:57 +02002756
stefanff483612015-12-21 03:14:00 -08002757 void ModifyVideoConfigs(
2758 VideoSendStream::Config* send_config,
2759 std::vector<VideoReceiveStream::Config>* receive_configs,
2760 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002761 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07002762 EXPECT_EQ(1u, encoder_config->number_of_streams);
2763 encoder_config->video_stream_factory =
2764 new rtc::RefCountedObject<VideoStreamFactory>();
Åsa Perssond34597c2018-10-22 17:34:02 +02002765 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2766 encoder_config->simulcast_layers[0].num_temporal_layers = 2;
Erik Språng143cec12015-04-28 10:01:41 +02002767 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002768 }
2769
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002770 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002771 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002772 << "Timed out while waiting for the encoder to be initialized.";
2773 }
Niels Möllercbcbc222018-09-28 09:07:24 +02002774 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002775 } test;
2776
stefane74eef12016-01-08 06:47:13 -08002777 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002778}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002779
Sebastian Jansson63470292019-02-01 10:13:43 +01002780TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002781 // These are chosen to be "kind of odd" to not be accidentally checked against
2782 // default values.
2783 static const int kMinBitrateKbps = 137;
2784 static const int kStartBitrateKbps = 345;
2785 static const int kLowerMaxBitrateKbps = 312;
2786 static const int kMaxBitrateKbps = 413;
2787 static const int kIncreasedStartBitrateKbps = 451;
2788 static const int kIncreasedMaxBitrateKbps = 597;
Erik Språng7ca375c2019-02-06 16:20:17 +01002789 // If these fields trial are on, we get lower bitrates than expected by this
2790 // test, due to the packetization overhead and encoder pushback.
Niels Möller6613f8e2019-01-10 10:30:21 +01002791 webrtc::test::ScopedFieldTrials field_trials(
2792 std::string(field_trial::GetFieldTrialString()) +
Erik Språng7ca375c2019-02-06 16:20:17 +01002793 "WebRTC-SubtractPacketizationOverhead/Disabled/"
2794 "WebRTC-VideoRateControl/bitrate_adjuster:false/");
Niels Möller6613f8e2019-01-10 10:30:21 +01002795
pbos@webrtc.org00873182014-11-25 14:03:34 +00002796 class EncoderBitrateThresholdObserver : public test::SendTest,
Sergey Silkin5ee69672019-07-02 14:18:34 +02002797 public VideoBitrateAllocatorFactory,
pbos@webrtc.org00873182014-11-25 14:03:34 +00002798 public test::FakeEncoder {
2799 public:
eladalon413ee9a2017-08-22 04:02:52 -07002800 explicit EncoderBitrateThresholdObserver(
Yves Gerey6516f762019-08-29 11:50:23 +02002801 test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002802 : SendTest(kDefaultTimeoutMs),
2803 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002804 task_queue_(task_queue),
perkj26091b12016-09-01 01:17:40 -07002805 target_bitrate_(0),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002806 num_rate_allocator_creations_(0),
2807 num_encoder_initializations_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002808 call_(nullptr),
Niels Möller4db138e2018-04-19 09:04:13 +02002809 send_stream_(nullptr),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002810 encoder_factory_(this),
2811 bitrate_allocator_factory_(
2812 CreateBuiltinVideoBitrateAllocatorFactory()) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002813
2814 private:
Sergey Silkin5ee69672019-07-02 14:18:34 +02002815 std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
2816 const VideoCodec& codec) override {
2817 EXPECT_GE(codec.startBitrate, codec.minBitrate);
2818 EXPECT_LE(codec.startBitrate, codec.maxBitrate);
2819 if (num_rate_allocator_creations_ == 0) {
2820 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps), codec.minBitrate);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002821 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002822 codec.startBitrate);
2823 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps), codec.maxBitrate);
2824 } else if (num_rate_allocator_creations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002825 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002826 codec.maxBitrate);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002827 // The start bitrate should be kept (-1) and capped to the max bitrate.
2828 // Since this is not an end-to-end call no receiver should have been
2829 // returning a REMB that could lower this estimate.
Sergey Silkin5ee69672019-07-02 14:18:34 +02002830 EXPECT_EQ(codec.startBitrate, codec.maxBitrate);
2831 } else if (num_rate_allocator_creations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002832 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
Sergey Silkin5ee69672019-07-02 14:18:34 +02002833 codec.maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002834 // The start bitrate will be whatever the rate BitRateController
2835 // has currently configured but in the span of the set max and min
2836 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002837 }
Sergey Silkin5ee69672019-07-02 14:18:34 +02002838 ++num_rate_allocator_creations_;
2839 create_rate_allocator_event_.Set();
2840
2841 return bitrate_allocator_factory_->CreateVideoBitrateAllocator(codec);
2842 }
2843
2844 int32_t InitEncode(const VideoCodec* codecSettings,
2845 const Settings& settings) override {
2846 EXPECT_EQ(0, num_encoder_initializations_);
2847 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2848 codecSettings->minBitrate);
2849 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2850 codecSettings->startBitrate);
2851 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2852 codecSettings->maxBitrate);
2853
2854 ++num_encoder_initializations_;
2855
2856 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002857 init_encode_event_.Set();
2858
Elad Alon370f93a2019-06-11 14:57:57 +02002859 return FakeEncoder::InitEncode(codecSettings, settings);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002860 }
2861
Erik Språng16cb8f52019-04-12 13:59:09 +02002862 void SetRates(const RateControlParameters& parameters) override {
perkj26091b12016-09-01 01:17:40 -07002863 {
2864 rtc::CritScope lock(&crit_);
Erik Språng16cb8f52019-04-12 13:59:09 +02002865 if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) {
2866 FakeEncoder::SetRates(parameters);
2867 return;
perkjfa10b552016-10-02 23:45:26 -07002868 }
Erik Språng16cb8f52019-04-12 13:59:09 +02002869 target_bitrate_ = parameters.bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002870 }
2871 bitrate_changed_event_.Set();
Erik Språng16cb8f52019-04-12 13:59:09 +02002872 FakeEncoder::SetRates(parameters);
perkj26091b12016-09-01 01:17:40 -07002873 }
2874
2875 void WaitForSetRates(uint32_t expected_bitrate) {
Niels Möller6bb5ab92019-01-11 11:11:10 +01002876 // Wait for the expected rate to be set. In some cases there can be
2877 // more than one update pending, in which case we keep waiting
2878 // until the correct value has been observed.
2879 const int64_t start_time = rtc::TimeMillis();
2880 do {
2881 rtc::CritScope lock(&crit_);
2882 if (target_bitrate_ == expected_bitrate) {
2883 return;
2884 }
2885 } while (bitrate_changed_event_.Wait(
2886 std::max(int64_t{1}, VideoSendStreamTest::kDefaultTimeoutMs -
2887 (rtc::TimeMillis() - start_time))));
Niels Möller6613f8e2019-01-10 10:30:21 +01002888 rtc::CritScope lock(&crit_);
Niels Möller6bb5ab92019-01-11 11:11:10 +01002889 EXPECT_EQ(target_bitrate_, expected_bitrate)
2890 << "Timed out while waiting encoder rate to be set.";
perkj26091b12016-09-01 01:17:40 -07002891 }
2892
Niels Möllerde8e6e62018-11-13 15:10:33 +01002893 void ModifySenderBitrateConfig(
2894 BitrateConstraints* bitrate_config) override {
2895 bitrate_config->min_bitrate_bps = kMinBitrateKbps * 1000;
2896 bitrate_config->start_bitrate_bps = kStartBitrateKbps * 1000;
2897 bitrate_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002898 }
2899
stefanff483612015-12-21 03:14:00 -08002900 void ModifyVideoConfigs(
2901 VideoSendStream::Config* send_config,
2902 std::vector<VideoReceiveStream::Config>* receive_configs,
2903 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02002904 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002905 send_config->encoder_settings.bitrate_allocator_factory = this;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002906 // Set bitrates lower/higher than min/max to make sure they are properly
2907 // capped.
perkjfa10b552016-10-02 23:45:26 -07002908 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
Åsa Persson21740532019-04-15 14:00:30 +02002909 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
2910 encoder_config->simulcast_layers[0].min_bitrate_bps =
2911 kMinBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002912 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002913 }
2914
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002915 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002916 call_ = sender_call;
2917 }
2918
stefanff483612015-12-21 03:14:00 -08002919 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002920 VideoSendStream* send_stream,
2921 const std::vector<VideoReceiveStream*>& receive_streams) override {
2922 send_stream_ = send_stream;
2923 }
2924
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002925 void PerformTest() override {
Sergey Silkin5ee69672019-07-02 14:18:34 +02002926 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2927 VideoSendStreamTest::kDefaultTimeoutMs))
2928 << "Timed out while waiting for rate allocator to be created.";
pbos14fe7082016-04-20 06:35:56 -07002929 ASSERT_TRUE(
2930 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002931 << "Timed out while waiting for encoder to be configured.";
2932 WaitForSetRates(kStartBitrateKbps);
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01002933 BitrateConstraints bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002934 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2935 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002936 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002937 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
2938 bitrate_config);
eladalon413ee9a2017-08-22 04:02:52 -07002939 });
perkj26091b12016-09-01 01:17:40 -07002940 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2941 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002942 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002943 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Sergey Silkin5ee69672019-07-02 14:18:34 +02002944 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2945 VideoSendStreamTest::kDefaultTimeoutMs));
2946 EXPECT_EQ(2, num_rate_allocator_creations_)
2947 << "Rate allocator should have been recreated.";
2948
perkjfa10b552016-10-02 23:45:26 -07002949 WaitForSetRates(kLowerMaxBitrateKbps);
Sergey Silkin5ee69672019-07-02 14:18:34 +02002950 EXPECT_EQ(1, num_encoder_initializations_);
perkjfa10b552016-10-02 23:45:26 -07002951
2952 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2953 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Sergey Silkin5ee69672019-07-02 14:18:34 +02002954 ASSERT_TRUE(create_rate_allocator_event_.Wait(
2955 VideoSendStreamTest::kDefaultTimeoutMs));
2956 EXPECT_EQ(3, num_rate_allocator_creations_)
2957 << "Rate allocator should have been recreated.";
2958
perkj26091b12016-09-01 01:17:40 -07002959 // Expected target bitrate is the start bitrate set in the call to
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002960 // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
perkj26091b12016-09-01 01:17:40 -07002961 WaitForSetRates(kIncreasedStartBitrateKbps);
Sergey Silkin5ee69672019-07-02 14:18:34 +02002962 EXPECT_EQ(1, num_encoder_initializations_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002963 }
2964
Yves Gerey6516f762019-08-29 11:50:23 +02002965 test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002966 rtc::Event create_rate_allocator_event_;
pbos14fe7082016-04-20 06:35:56 -07002967 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002968 rtc::Event bitrate_changed_event_;
2969 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002970 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002971
Sergey Silkin5ee69672019-07-02 14:18:34 +02002972 int num_rate_allocator_creations_;
2973 int num_encoder_initializations_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002974 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002975 webrtc::VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02002976 test::VideoEncoderProxyFactory encoder_factory_;
Sergey Silkin5ee69672019-07-02 14:18:34 +02002977 std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
Stefan Holmere5904162015-03-26 11:11:06 +01002978 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002979 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002980
stefane74eef12016-01-08 06:47:13 -08002981 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002982}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002983
Sebastian Jansson63470292019-02-01 10:13:43 +01002984TEST_F(VideoSendStreamTest, ReportsSentResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002985 static const size_t kNumStreams = 3;
2986 // Unusual resolutions to make sure that they are the ones being reported.
2987 static const struct {
2988 int width;
2989 int height;
Yves Gerey665174f2018-06-19 15:03:05 +02002990 } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002991 class ScreencastTargetBitrateTest : public test::SendTest,
2992 public test::FakeEncoder {
2993 public:
2994 ScreencastTargetBitrateTest()
2995 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002996 test::FakeEncoder(Clock::GetRealTimeClock()),
Niels Möller4db138e2018-04-19 09:04:13 +02002997 send_stream_(nullptr),
2998 encoder_factory_(this) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002999
3000 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003001 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +01003002 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003003 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003004 specifics.codecType = kVideoCodecGeneric;
3005
3006 uint8_t buffer[16] = {0};
3007 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
Niels Möller23775882018-08-16 10:24:12 +02003008 encoded.SetTimestamp(input_image.timestamp());
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003009 encoded.capture_time_ms_ = input_image.render_time_ms();
3010
3011 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003012 encoded._frameType = (*frame_types)[i];
3013 encoded._encodedWidth = kEncodedResolution[i].width;
3014 encoded._encodedHeight = kEncodedResolution[i].height;
Niels Möllerd3b8c632018-08-27 15:33:42 +02003015 encoded.SetSpatialIndex(i);
brandtre78d2662017-01-16 05:57:16 -08003016 EncodedImageCallback* callback;
3017 {
3018 rtc::CritScope cs(&crit_sect_);
3019 callback = callback_;
3020 }
3021 RTC_DCHECK(callback);
3022 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07003023 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003024 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07003025 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003026 }
3027
Peter Boström5811a392015-12-10 13:02:50 +01003028 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003029 return 0;
3030 }
stefanff483612015-12-21 03:14:00 -08003031 void ModifyVideoConfigs(
3032 VideoSendStream::Config* send_config,
3033 std::vector<VideoReceiveStream::Config>* receive_configs,
3034 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003035 send_config->encoder_settings.encoder_factory = &encoder_factory_;
perkjfa10b552016-10-02 23:45:26 -07003036 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003037 }
3038
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003039 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003040
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003041 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003042 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003043 << "Timed out while waiting for the encoder to send one frame.";
3044 VideoSendStream::Stats stats = send_stream_->GetStats();
3045
3046 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003047 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003048 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003049 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003050 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003051 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003052 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003053 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
3054 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003055 }
3056 }
3057
stefanff483612015-12-21 03:14:00 -08003058 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003059 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003060 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003061 send_stream_ = send_stream;
3062 }
3063
3064 VideoSendStream* send_stream_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003065 test::VideoEncoderProxyFactory encoder_factory_;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003066 } test;
3067
stefane74eef12016-01-08 06:47:13 -08003068 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003069}
philipel0f9af012015-09-01 07:01:51 -07003070
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003071#if defined(RTC_ENABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01003072class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07003073 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01003074 Vp9HeaderObserver()
3075 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
Niels Möller4db138e2018-04-19 09:04:13 +02003076 encoder_factory_([]() { return VP9Encoder::Create(); }),
Åsa Perssonff24c042015-12-04 10:58:08 +01003077 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
3078 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07003079 frames_sent_(0),
3080 expected_width_(0),
3081 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07003082
stefanff483612015-12-21 03:14:00 -08003083 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003084 VideoSendStream::Config* send_config,
3085 std::vector<VideoReceiveStream::Config>* receive_configs,
3086 VideoEncoderConfig* encoder_config) {}
3087
Åsa Perssonff24c042015-12-04 10:58:08 +01003088 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07003089
3090 private:
minyue20c84cc2017-04-10 16:57:57 -07003091 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07003092
stefanff483612015-12-21 03:14:00 -08003093 void ModifyVideoConfigs(
3094 VideoSendStream::Config* send_config,
3095 std::vector<VideoReceiveStream::Config>* receive_configs,
3096 VideoEncoderConfig* encoder_config) override {
Niels Möller4db138e2018-04-19 09:04:13 +02003097 send_config->encoder_settings.encoder_factory = &encoder_factory_;
Niels Möller259a4972018-04-05 15:36:51 +02003098 send_config->rtp.payload_name = "VP9";
3099 send_config->rtp.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08003100 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07003101 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
Yves Gerey665174f2018-06-19 15:03:05 +02003102 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07003103 EXPECT_EQ(1u, encoder_config->number_of_streams);
Åsa Perssond34597c2018-10-22 17:34:02 +02003104 EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
3105 encoder_config->simulcast_layers[0].num_temporal_layers =
3106 vp9_settings_.numberOfTemporalLayers;
perkj26091b12016-09-01 01:17:40 -07003107 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07003108 }
3109
perkjfa10b552016-10-02 23:45:26 -07003110 void ModifyVideoCaptureStartResolution(int* width,
3111 int* height,
3112 int* frame_rate) override {
3113 expected_width_ = *width;
3114 expected_height_ = *height;
3115 }
3116
philipel0f9af012015-09-01 07:01:51 -07003117 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003118 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
3119 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003120 }
3121
3122 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3123 RTPHeader header;
3124 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3125
Åsa Perssonff24c042015-12-04 10:58:08 +01003126 EXPECT_EQ(kVp9PayloadType, header.payloadType);
3127 const uint8_t* payload = packet + header.headerLength;
3128 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07003129
Åsa Perssonff24c042015-12-04 10:58:08 +01003130 bool new_packet = packets_sent_ == 0 ||
3131 IsNewerSequenceNumber(header.sequenceNumber,
3132 last_header_.sequenceNumber);
3133 if (payload_length > 0 && new_packet) {
3134 RtpDepacketizer::ParsedPayload parsed;
3135 RtpDepacketizerVp9 depacketizer;
3136 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
philipelcb96ad82018-07-02 14:41:58 +02003137 EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
Åsa Perssonff24c042015-12-04 10:58:08 +01003138 // Verify common fields for all configurations.
philipel29d88462018-08-08 14:26:00 +02003139 const auto& vp9_header =
3140 absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
3141 VerifyCommonHeader(vp9_header);
philipelcb96ad82018-07-02 14:41:58 +02003142 CompareConsecutiveFrames(header, parsed.video_header());
Åsa Perssonff24c042015-12-04 10:58:08 +01003143 // Verify configuration specific settings.
philipel29d88462018-08-08 14:26:00 +02003144 InspectHeader(vp9_header);
philipel0f9af012015-09-01 07:01:51 -07003145
Åsa Perssonff24c042015-12-04 10:58:08 +01003146 ++packets_sent_;
3147 if (header.markerBit) {
3148 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07003149 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003150 last_header_ = header;
philipel29d88462018-08-08 14:26:00 +02003151 last_vp9_ = vp9_header;
philipel0f9af012015-09-01 07:01:51 -07003152 }
philipel0f9af012015-09-01 07:01:51 -07003153 return SEND_PACKET;
3154 }
3155
philipel7fabd462015-09-03 04:42:32 -07003156 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003157 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3158 if (last_vp9_.picture_id > vp9.picture_id) {
3159 return vp9.picture_id == 0; // Wrap.
3160 } else {
3161 return vp9.picture_id == last_vp9_.picture_id + 1;
3162 }
3163 }
3164
3165 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003166 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3167 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3168 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3169 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3170 vp9.spatial_idx);
3171 }
3172
3173 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3174 uint8_t num_layers) const {
3175 switch (num_layers) {
3176 case 0:
3177 VerifyTemporalLayerStructure0(vp9);
3178 break;
3179 case 1:
3180 VerifyTemporalLayerStructure1(vp9);
3181 break;
3182 case 2:
3183 VerifyTemporalLayerStructure2(vp9);
3184 break;
3185 case 3:
3186 VerifyTemporalLayerStructure3(vp9);
3187 break;
3188 default:
3189 RTC_NOTREACHED();
3190 }
3191 }
3192
3193 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3194 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3195 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3196 EXPECT_FALSE(vp9.temporal_up_switch);
3197 }
3198
3199 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3200 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3201 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3202 EXPECT_FALSE(vp9.temporal_up_switch);
3203 }
3204
3205 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3206 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3207 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3208 EXPECT_LE(vp9.temporal_idx, 1);
3209 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3210 if (IsNewPictureId(vp9)) {
3211 uint8_t expected_tid =
3212 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3213 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3214 }
3215 }
3216
3217 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3218 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3219 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3220 EXPECT_LE(vp9.temporal_idx, 2);
3221 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3222 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3223 switch (vp9.temporal_idx) {
3224 case 0:
3225 EXPECT_EQ(2, last_vp9_.temporal_idx);
3226 EXPECT_FALSE(vp9.temporal_up_switch);
3227 break;
3228 case 1:
3229 EXPECT_EQ(2, last_vp9_.temporal_idx);
3230 EXPECT_TRUE(vp9.temporal_up_switch);
3231 break;
3232 case 2:
Sergey Silkin377ef242018-05-07 09:17:12 +02003233 EXPECT_LT(last_vp9_.temporal_idx, 2);
3234 EXPECT_TRUE(vp9.temporal_up_switch);
Åsa Perssonff24c042015-12-04 10:58:08 +01003235 break;
3236 }
3237 }
3238 }
3239
3240 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3241 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3242 return;
3243
3244 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3245 if (vp9.temporal_idx == 0)
3246 ++expected_tl0_idx;
3247 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3248 }
3249
3250 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3251 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3252 }
3253
3254 // Flexible mode (F=1): Non-flexible mode (F=0):
3255 //
3256 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3257 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3258 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3259 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3260 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3261 // M: | EXTENDED PID | M: | EXTENDED PID |
3262 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3263 // L: | T |U| S |D| L: | T |U| S |D|
3264 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3265 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3266 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3267 // X: |EXTENDED P_DIFF| V: | SS .. |
3268 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3269 // V: | SS .. |
3270 // +-+-+-+-+-+-+-+-+
3271 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3272 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3273 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3274 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003275
3276 if (vp9_settings_.numberOfSpatialLayers > 1) {
3277 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3278 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3279 EXPECT_EQ(vp9.spatial_idx, 0);
3280 } else {
3281 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3282 }
3283
3284 if (vp9_settings_.numberOfTemporalLayers > 1) {
3285 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3286 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3287 EXPECT_EQ(vp9.temporal_idx, 0);
3288 } else {
3289 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3290 }
3291
Åsa Perssonff24c042015-12-04 10:58:08 +01003292 if (vp9.ss_data_available) // V
3293 VerifySsData(vp9);
3294
3295 if (frames_sent_ == 0)
3296 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3297
3298 if (!vp9.inter_pic_predicted) {
3299 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3300 EXPECT_FALSE(vp9.temporal_up_switch);
3301 }
3302 }
3303
3304 // Scalability structure (SS).
3305 //
3306 // +-+-+-+-+-+-+-+-+
3307 // V: | N_S |Y|G|-|-|-|
3308 // +-+-+-+-+-+-+-+-+
3309 // Y: | WIDTH | N_S + 1 times
3310 // +-+-+-+-+-+-+-+-+
3311 // | HEIGHT |
3312 // +-+-+-+-+-+-+-+-+
3313 // G: | N_G |
3314 // +-+-+-+-+-+-+-+-+
3315 // N_G: | T |U| R |-|-| N_G times
3316 // +-+-+-+-+-+-+-+-+
3317 // | P_DIFF | R times
3318 // +-+-+-+-+-+-+-+-+
3319 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3320 EXPECT_TRUE(vp9.ss_data_available); // V
3321 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3322 vp9.num_spatial_layers);
3323 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003324 int expected_width = expected_width_;
3325 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003326 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003327 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3328 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3329 expected_width /= 2;
3330 expected_height /= 2;
3331 }
3332 }
3333
3334 void CompareConsecutiveFrames(const RTPHeader& header,
3335 const RTPVideoHeader& video) const {
philipel29d88462018-08-08 14:26:00 +02003336 const auto& vp9_header =
3337 absl::get<RTPVideoHeaderVP9>(video.video_type_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003338
3339 bool new_frame = packets_sent_ == 0 ||
3340 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003341 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003342 if (!new_frame) {
3343 EXPECT_FALSE(last_header_.markerBit);
3344 EXPECT_EQ(last_header_.timestamp, header.timestamp);
philipel29d88462018-08-08 14:26:00 +02003345 EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
3346 EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
3347 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
3348 VerifySpatialIdxWithinFrame(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003349 return;
3350 }
3351 // New frame.
philipel29d88462018-08-08 14:26:00 +02003352 EXPECT_TRUE(vp9_header.beginning_of_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003353
3354 // Compare with last packet in previous frame.
3355 if (frames_sent_ == 0)
3356 return;
3357 EXPECT_TRUE(last_vp9_.end_of_frame);
3358 EXPECT_TRUE(last_header_.markerBit);
philipel29d88462018-08-08 14:26:00 +02003359 EXPECT_TRUE(ContinuousPictureId(vp9_header));
3360 VerifyTl0Idx(vp9_header);
Åsa Perssonff24c042015-12-04 10:58:08 +01003361 }
3362
Niels Möller4db138e2018-04-19 09:04:13 +02003363 test::FunctionVideoEncoderFactory encoder_factory_;
philipel0f9af012015-09-01 07:01:51 -07003364 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003365 webrtc::VideoEncoderConfig encoder_config_;
3366 RTPHeader last_header_;
3367 RTPVideoHeaderVP9 last_vp9_;
3368 size_t packets_sent_;
3369 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003370 int expected_width_;
3371 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003372};
3373
Sebastian Jansson63470292019-02-01 10:13:43 +01003374TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003375 const uint8_t kNumTemporalLayers = 1;
3376 const uint8_t kNumSpatialLayers = 1;
3377 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3378}
3379
Sebastian Jansson63470292019-02-01 10:13:43 +01003380TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003381 const uint8_t kNumTemporalLayers = 2;
3382 const uint8_t kNumSpatialLayers = 1;
3383 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3384}
3385
Sebastian Jansson63470292019-02-01 10:13:43 +01003386TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003387 const uint8_t kNumTemporalLayers = 3;
3388 const uint8_t kNumSpatialLayers = 1;
3389 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3390}
3391
Sebastian Jansson63470292019-02-01 10:13:43 +01003392TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003393 const uint8_t kNumTemporalLayers = 1;
3394 const uint8_t kNumSpatialLayers = 2;
3395 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3396}
3397
Sebastian Jansson63470292019-02-01 10:13:43 +01003398TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003399 const uint8_t kNumTemporalLayers = 2;
3400 const uint8_t kNumSpatialLayers = 2;
3401 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3402}
3403
Sebastian Jansson63470292019-02-01 10:13:43 +01003404TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003405 const uint8_t kNumTemporalLayers = 3;
3406 const uint8_t kNumSpatialLayers = 2;
3407 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3408}
3409
3410void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3411 uint8_t num_spatial_layers) {
3412 static const size_t kNumFramesToSend = 100;
3413 // Set to < kNumFramesToSend and coprime to length of temporal layer
3414 // structures to verify temporal id reset on key frame.
3415 static const int kKeyFrameInterval = 31;
Sergey Silkin86684962018-03-28 19:32:37 +02003416
3417 static const int kWidth = kMinVp9SpatialLayerWidth;
3418 static const int kHeight = kMinVp9SpatialLayerHeight;
3419 static const float kGoodBitsPerPixel = 0.1f;
Åsa Perssonff24c042015-12-04 10:58:08 +01003420 class NonFlexibleMode : public Vp9HeaderObserver {
3421 public:
3422 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3423 : num_temporal_layers_(num_temporal_layers),
3424 num_spatial_layers_(num_spatial_layers),
3425 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
Sergey Silkin86684962018-03-28 19:32:37 +02003426
stefanff483612015-12-21 03:14:00 -08003427 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003428 VideoSendStream::Config* send_config,
3429 std::vector<VideoReceiveStream::Config>* receive_configs,
3430 VideoEncoderConfig* encoder_config) override {
Niels Möller04dd1762018-03-23 16:05:22 +01003431 encoder_config->codec_type = kVideoCodecVP9;
Sergey Silkin86684962018-03-28 19:32:37 +02003432 int bitrate_bps = 0;
3433 for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
3434 const int width = kWidth << sl_idx;
3435 const int height = kHeight << sl_idx;
3436 const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
3437 bitrate_bps += static_cast<int>(width * height * bpp * 30);
3438 }
3439 encoder_config->max_bitrate_bps = bitrate_bps * 2;
3440
Åsa Perssonff24c042015-12-04 10:58:08 +01003441 vp9_settings_.flexibleMode = false;
3442 vp9_settings_.frameDroppingOn = false;
3443 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3444 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3445 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003446 }
3447
Sergey Silkin86684962018-03-28 19:32:37 +02003448 void ModifyVideoCaptureStartResolution(int* width,
3449 int* height,
3450 int* frame_rate) override {
3451 expected_width_ = kWidth << (num_spatial_layers_ - 1);
3452 expected_height_ = kHeight << (num_spatial_layers_ - 1);
3453 *width = expected_width_;
3454 *height = expected_height_;
3455 }
3456
Åsa Perssonff24c042015-12-04 10:58:08 +01003457 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003458 bool ss_data_expected =
3459 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3460 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003461 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003462 if (num_spatial_layers_ > 1) {
3463 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3464 } else {
3465 EXPECT_FALSE(vp9.inter_layer_predicted);
3466 }
3467
asapersson38bb8ad2015-12-14 01:41:19 -08003468 EXPECT_EQ(!vp9.inter_pic_predicted,
3469 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003470
3471 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003472 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3473 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3474 } else {
3475 EXPECT_EQ(0, vp9.spatial_idx);
3476 }
3477 if (num_spatial_layers_ > 1)
3478 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003479 }
3480
3481 VerifyFixedTemporalLayerStructure(vp9,
3482 l_field_ ? num_temporal_layers_ : 0);
3483
3484 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003485 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003486 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003487 const uint8_t num_temporal_layers_;
3488 const uint8_t num_spatial_layers_;
3489 const bool l_field_;
3490 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003491
stefane74eef12016-01-08 06:47:13 -08003492 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003493}
3494
Sebastian Jansson63470292019-02-01 10:13:43 +01003495TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
asaperssond9f641e2016-01-21 01:11:35 -08003496 static const size_t kNumFramesToSend = 50;
3497 static const int kWidth = 4;
3498 static const int kHeight = 4;
3499 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3500 void ModifyVideoConfigsHook(
3501 VideoSendStream::Config* send_config,
3502 std::vector<VideoReceiveStream::Config>* receive_configs,
3503 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003504 encoder_config->codec_type = kVideoCodecVP9;
asaperssond9f641e2016-01-21 01:11:35 -08003505 vp9_settings_.flexibleMode = false;
3506 vp9_settings_.numberOfTemporalLayers = 1;
3507 vp9_settings_.numberOfSpatialLayers = 1;
3508
perkjfa10b552016-10-02 23:45:26 -07003509 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003510 }
3511
3512 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3513 if (frames_sent_ > kNumFramesToSend)
3514 observation_complete_.Set();
3515 }
perkjfa10b552016-10-02 23:45:26 -07003516
3517 void ModifyVideoCaptureStartResolution(int* width,
3518 int* height,
3519 int* frame_rate) override {
3520 expected_width_ = kWidth;
3521 expected_height_ = kHeight;
3522 *width = kWidth;
3523 *height = kHeight;
3524 }
asaperssond9f641e2016-01-21 01:11:35 -08003525 } test;
3526
3527 RunBaseTest(&test);
3528}
3529
kjellanderf9e2a362017-03-24 12:17:33 -07003530#if defined(WEBRTC_ANDROID)
3531// Crashes on Android; bugs.webrtc.org/7401
3532#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3533#else
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003534// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
3535// the test after webrtc:9270 is implemented.
3536#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3537// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
kjellanderf9e2a362017-03-24 12:17:33 -07003538#endif
Sebastian Jansson63470292019-02-01 10:13:43 +01003539TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003540 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003541 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003542 VideoSendStream::Config* send_config,
3543 std::vector<VideoReceiveStream::Config>* receive_configs,
3544 VideoEncoderConfig* encoder_config) override {
Niels Möller259a4972018-04-05 15:36:51 +02003545 encoder_config->codec_type = kVideoCodecVP9;
Åsa Perssonff24c042015-12-04 10:58:08 +01003546 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003547 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003548 vp9_settings_.numberOfTemporalLayers = 1;
3549 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003550 }
3551
Åsa Perssonff24c042015-12-04 10:58:08 +01003552 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3553 EXPECT_TRUE(vp9_header.flexible_mode);
3554 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3555 if (vp9_header.inter_pic_predicted) {
3556 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003557 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003558 }
3559 }
3560 } test;
3561
stefane74eef12016-01-08 06:47:13 -08003562 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003563}
Mirko Bonadei8ef57932018-11-16 14:38:03 +01003564#endif // defined(RTC_ENABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003565
perkj803d97f2016-11-01 11:45:46 -07003566void VideoSendStreamTest::TestRequestSourceRotateVideo(
3567 bool support_orientation_ext) {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +02003568 CreateSenderCall();
perkj803d97f2016-11-01 11:45:46 -07003569
3570 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003571 CreateSendConfig(1, 0, 0, &transport);
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003572 GetVideoSendConfig()->rtp.extensions.clear();
perkj803d97f2016-11-01 11:45:46 -07003573 if (support_orientation_ext) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003574 GetVideoSendConfig()->rtp.extensions.push_back(
perkj803d97f2016-11-01 11:45:46 -07003575 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3576 }
3577
3578 CreateVideoStreams();
3579 test::FrameForwarder forwarder;
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003580 GetVideoSendStream()->SetSource(&forwarder,
3581 DegradationPreference::MAINTAIN_FRAMERATE);
perkj803d97f2016-11-01 11:45:46 -07003582
3583 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3584 support_orientation_ext);
3585
3586 DestroyStreams();
3587}
3588
Sebastian Jansson63470292019-02-01 10:13:43 +01003589TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003590 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3591 TestRequestSourceRotateVideo(false);
3592}
3593
Sebastian Jansson63470292019-02-01 10:13:43 +01003594TEST_F(VideoSendStreamTest,
perkj803d97f2016-11-01 11:45:46 -07003595 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3596 TestRequestSourceRotateVideo(true);
3597}
3598
Sebastian Jansson63470292019-02-01 10:13:43 +01003599TEST_F(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) {
Åsa Perssonf06bacc2018-10-12 11:07:20 +02003600 static const int kMaxFps = 22;
3601 class FpsObserver : public test::SendTest,
3602 public test::FrameGeneratorCapturer::SinkWantsObserver {
3603 public:
3604 FpsObserver() : SendTest(kDefaultTimeoutMs) {}
3605
3606 void OnFrameGeneratorCapturerCreated(
3607 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3608 frame_generator_capturer->SetSinkWantsObserver(this);
3609 }
3610
3611 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
3612 const rtc::VideoSinkWants& wants) override {
3613 if (wants.max_framerate_fps == kMaxFps)
3614 observation_complete_.Set();
3615 }
3616
3617 void ModifyVideoConfigs(
3618 VideoSendStream::Config* send_config,
3619 std::vector<VideoReceiveStream::Config>* receive_configs,
3620 VideoEncoderConfig* encoder_config) override {
3621 encoder_config->simulcast_layers[0].max_framerate = kMaxFps;
3622 }
3623
3624 void PerformTest() override {
3625 EXPECT_TRUE(Wait()) << "Timed out while waiting for fps to be reported.";
3626 }
3627 } test;
3628
3629 RunBaseTest(&test);
3630}
3631
michaelta3328772016-11-29 09:25:03 -08003632// This test verifies that overhead is removed from the bandwidth estimate by
3633// testing that the maximum possible target payload rate is smaller than the
3634// maximum bandwidth estimate by the overhead rate.
Sebastian Jansson63470292019-02-01 10:13:43 +01003635TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003636 test::ScopedFieldTrials override_field_trials(
3637 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3638 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3639 public test::FakeEncoder {
3640 public:
eladalon413ee9a2017-08-22 04:02:52 -07003641 explicit RemoveOverheadFromBandwidthTest(
Yves Gerey6516f762019-08-29 11:50:23 +02003642 test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003643 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3644 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003645 task_queue_(task_queue),
Niels Möller4db138e2018-04-19 09:04:13 +02003646 encoder_factory_(this),
michaelta3328772016-11-29 09:25:03 -08003647 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003648 max_bitrate_bps_(0),
Niels Möllerc572ff32018-11-07 08:43:50 +01003649 first_packet_sent_(false) {}
michaelta3328772016-11-29 09:25:03 -08003650
Erik Språng16cb8f52019-04-12 13:59:09 +02003651 void SetRates(const RateControlParameters& parameters) override {
michaelta3328772016-11-29 09:25:03 -08003652 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003653 // Wait for the first sent packet so that videosendstream knows
3654 // rtp_overhead.
3655 if (first_packet_sent_) {
Erik Språng16cb8f52019-04-12 13:59:09 +02003656 max_bitrate_bps_ = parameters.bitrate.get_sum_bps();
michaelt192132e2017-01-26 09:05:27 -08003657 bitrate_changed_event_.Set();
3658 }
Erik Språng16cb8f52019-04-12 13:59:09 +02003659 return FakeEncoder::SetRates(parameters);
michaelta3328772016-11-29 09:25:03 -08003660 }
3661
3662 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3663 call_ = sender_call;
3664 }
3665
3666 void ModifyVideoConfigs(
3667 VideoSendStream::Config* send_config,
3668 std::vector<VideoReceiveStream::Config>* receive_configs,
3669 VideoEncoderConfig* encoder_config) override {
3670 send_config->rtp.max_packet_size = 1200;
Niels Möller4db138e2018-04-19 09:04:13 +02003671 send_config->encoder_settings.encoder_factory = &encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003672 EXPECT_FALSE(send_config->rtp.extensions.empty());
3673 }
3674
michaelt192132e2017-01-26 09:05:27 -08003675 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3676 rtc::CritScope lock(&crit_);
3677 first_packet_sent_ = true;
3678 return SEND_PACKET;
3679 }
3680
michaelta3328772016-11-29 09:25:03 -08003681 void PerformTest() override {
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +01003682 BitrateConstraints bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003683 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003684 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003685 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003686 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3687 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003688 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003689 task_queue_->SendTask([this, &bitrate_config]() {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003690 call_->GetTransportControllerSend()->SetSdpBitrateParameters(
3691 bitrate_config);
Stefan Holmer64be7fa2018-10-04 15:21:55 +02003692 call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
eladalon413ee9a2017-08-22 04:02:52 -07003693 });
michaelta3328772016-11-29 09:25:03 -08003694
3695 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003696 // overhead of 40B per packet video produces 2240bps overhead.
3697 // So the encoder BW should be set to 57760bps.
Niels Möller4db138e2018-04-19 09:04:13 +02003698 EXPECT_TRUE(
3699 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
michaelta3328772016-11-29 09:25:03 -08003700 {
3701 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003702 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003703 }
3704 }
3705
3706 private:
Yves Gerey6516f762019-08-29 11:50:23 +02003707 test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
Niels Möllercbcbc222018-09-28 09:07:24 +02003708 test::VideoEncoderProxyFactory encoder_factory_;
michaelta3328772016-11-29 09:25:03 -08003709 Call* call_;
3710 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003711 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3712 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003713 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003714 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003715 RunBaseTest(&test);
3716}
3717
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003718class PacingFactorObserver : public test::SendTest {
3719 public:
3720 PacingFactorObserver(bool configure_send_side,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003721 absl::optional<float> expected_pacing_factor)
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003722 : test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
3723 configure_send_side_(configure_send_side),
3724 expected_pacing_factor_(expected_pacing_factor) {}
Erik Språng7c8cca32017-10-24 17:05:18 +02003725
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003726 void ModifyVideoConfigs(
3727 VideoSendStream::Config* send_config,
3728 std::vector<VideoReceiveStream::Config>* receive_configs,
3729 VideoEncoderConfig* encoder_config) override {
3730 // Check if send-side bwe extension is already present, and remove it if
3731 // it is not desired.
3732 bool has_send_side = false;
3733 for (auto it = send_config->rtp.extensions.begin();
3734 it != send_config->rtp.extensions.end(); ++it) {
3735 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3736 if (configure_send_side_) {
3737 has_send_side = true;
3738 } else {
3739 send_config->rtp.extensions.erase(it);
Erik Språng7c8cca32017-10-24 17:05:18 +02003740 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003741 break;
Erik Språng7c8cca32017-10-24 17:05:18 +02003742 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003743 }
3744
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003745 if (configure_send_side_ && !has_send_side) {
Elad Alon157540a2019-02-08 23:37:52 +01003746 rtc::UniqueNumberGenerator<int> unique_id_generator;
3747 unique_id_generator.AddKnownId(0); // First valid RTP extension ID is 1.
3748 for (const RtpExtension& extension : send_config->rtp.extensions) {
3749 unique_id_generator.AddKnownId(extension.id);
3750 }
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003751 // Want send side, not present by default, so add it.
3752 send_config->rtp.extensions.emplace_back(
Elad Alon157540a2019-02-08 23:37:52 +01003753 RtpExtension::kTransportSequenceNumberUri, unique_id_generator());
Erik Språng7c8cca32017-10-24 17:05:18 +02003754 }
3755
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003756 // ALR only enabled for screenshare.
3757 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3758 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003759
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003760 void OnVideoStreamsCreated(
3761 VideoSendStream* send_stream,
3762 const std::vector<VideoReceiveStream*>& receive_streams) override {
3763 auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
3764 // Video streams created, check that pacing factor is correctly configured.
3765 EXPECT_EQ(expected_pacing_factor_,
3766 internal_send_peer.GetPacingFactorOverride());
3767 observation_complete_.Set();
3768 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003769
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003770 void PerformTest() override {
3771 EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
3772 }
Erik Språng7c8cca32017-10-24 17:05:18 +02003773
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003774 private:
3775 const bool configure_send_side_;
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003776 const absl::optional<float> expected_pacing_factor_;
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003777};
3778
3779std::string GetAlrProbingExperimentString() {
3780 return std::string(
3781 AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
3782 "/1.0,2875,80,40,-60,3/";
3783}
3784const float kAlrProbingExperimentPaceMultiplier = 1.0f;
3785
Sebastian Jansson63470292019-02-01 10:13:43 +01003786TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003787 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
Erik Språng7c8cca32017-10-24 17:05:18 +02003788 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003789 PacingFactorObserver test_with_send_side(true,
3790 kAlrProbingExperimentPaceMultiplier);
Erik Språng7c8cca32017-10-24 17:05:18 +02003791 RunBaseTest(&test_with_send_side);
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003792}
Erik Språng7c8cca32017-10-24 17:05:18 +02003793
Sebastian Jansson63470292019-02-01 10:13:43 +01003794TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
Sebastian Janssona45c8da2018-01-16 10:55:29 +01003795 test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
3796 // Send-side bwe off, use configuration should not be overridden.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +02003797 PacingFactorObserver test_without_send_side(false, absl::nullopt);
Erik Språng7c8cca32017-10-24 17:05:18 +02003798 RunBaseTest(&test_without_send_side);
3799}
3800
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003801// Test class takes as argument a function pointer to reset the send
3802// stream and call OnVideoStreamsCreated. This is necessary since you cannot
3803// change the content type of a VideoSendStream, you need to recreate it.
3804// Stopping and recreating the stream can only be done on the main thread and in
3805// the context of VideoSendStreamTest (not BaseTest). The test switches from
3806// realtime to screenshare and back.
3807template <typename T>
3808class ContentSwitchTest : public test::SendTest {
3809 public:
3810 enum class StreamState {
3811 kBeforeSwitch = 0,
3812 kInScreenshare = 1,
3813 kAfterSwitchBack = 2,
3814 };
3815 static const uint32_t kMinPacketsToSend = 50;
3816
3817 explicit ContentSwitchTest(T* stream_reset_fun)
3818 : SendTest(test::CallTest::kDefaultTimeoutMs),
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003819 call_(nullptr),
3820 state_(StreamState::kBeforeSwitch),
3821 send_stream_(nullptr),
3822 send_stream_config_(nullptr),
3823 packets_sent_(0),
3824 stream_resetter_(stream_reset_fun) {
3825 RTC_DCHECK(stream_resetter_);
3826 }
3827
3828 void OnVideoStreamsCreated(
3829 VideoSendStream* send_stream,
3830 const std::vector<VideoReceiveStream*>& receive_streams) override {
3831 rtc::CritScope lock(&crit_);
3832 send_stream_ = send_stream;
3833 }
3834
3835 void ModifyVideoConfigs(
3836 VideoSendStream::Config* send_config,
3837 std::vector<VideoReceiveStream::Config>* receive_configs,
3838 VideoEncoderConfig* encoder_config) override {
3839 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
3840 encoder_config->min_transmit_bitrate_bps = 0;
3841 encoder_config->content_type =
3842 VideoEncoderConfig::ContentType::kRealtimeVideo;
3843 send_stream_config_ = send_config->Copy();
3844 encoder_config_ = encoder_config->Copy();
3845 }
3846
3847 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3848 call_ = sender_call;
3849 }
3850
3851 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3852 rtc::CritScope lock(&crit_);
3853
3854 auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
3855 float pacing_factor =
3856 internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
3857 float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
3858 if (send_stream_->GetStats().content_type ==
3859 webrtc::VideoContentType::SCREENSHARE) {
3860 expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
3861 }
3862
3863 EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
3864
3865 // Wait until at least kMinPacketsToSend packets to be sent, so that
3866 // some frames would be encoded.
3867 if (++packets_sent_ < kMinPacketsToSend)
3868 return SEND_PACKET;
3869
3870 if (state_ != StreamState::kAfterSwitchBack) {
3871 // We've sent kMinPacketsToSend packets, switch the content type and move
3872 // move to the next state.
3873 // Note that we need to recreate the stream if changing content type.
3874 packets_sent_ = 0;
3875 if (encoder_config_.content_type ==
3876 VideoEncoderConfig::ContentType::kRealtimeVideo) {
3877 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
3878 } else {
3879 encoder_config_.content_type =
3880 VideoEncoderConfig::ContentType::kRealtimeVideo;
3881 }
3882 switch (state_) {
3883 case StreamState::kBeforeSwitch:
3884 state_ = StreamState::kInScreenshare;
3885 break;
3886 case StreamState::kInScreenshare:
3887 state_ = StreamState::kAfterSwitchBack;
3888 break;
3889 case StreamState::kAfterSwitchBack:
3890 RTC_NOTREACHED();
3891 break;
3892 }
3893 content_switch_event_.Set();
3894 return SEND_PACKET;
3895 }
3896
3897 observation_complete_.Set();
3898 return SEND_PACKET;
3899 }
3900
3901 void PerformTest() override {
3902 while (GetStreamState() != StreamState::kAfterSwitchBack) {
3903 ASSERT_TRUE(
3904 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
3905 (*stream_resetter_)(send_stream_config_, encoder_config_, this);
3906 }
3907
3908 ASSERT_TRUE(Wait())
3909 << "Timed out waiting for a frame sent after switch back";
3910 }
3911
3912 private:
3913 StreamState GetStreamState() {
3914 rtc::CritScope lock(&crit_);
3915 return state_;
3916 }
3917
3918 rtc::CriticalSection crit_;
3919 rtc::Event content_switch_event_;
3920 Call* call_;
3921 StreamState state_ RTC_GUARDED_BY(crit_);
3922 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
3923 VideoSendStream::Config send_stream_config_;
3924 VideoEncoderConfig encoder_config_;
3925 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
3926 T* stream_resetter_;
3927};
3928
Sebastian Jansson63470292019-02-01 10:13:43 +01003929TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003930 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
3931 const VideoEncoderConfig& encoder_config,
3932 test::BaseTest* test) {
3933 task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
3934 Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +02003935 DestroyVideoSendStreams();
3936 SetVideoSendConfig(send_stream_config);
3937 SetVideoEncoderConfig(encoder_config);
3938 CreateVideoSendStreams();
3939 SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
3940 test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
Ilya Nikolaevskiy4425b052018-03-15 11:42:00 +01003941 Start();
3942 });
3943 };
3944 ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
3945 RunBaseTest(&test);
3946}
3947
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003948} // namespace webrtc