blob: 422b983ef9b431168e827b832917d18bbc9a9f0c [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
ossuf515ab82016-12-07 04:52:58 -080014#include "webrtc/call/call.h"
sprangdb2a9fc2017-08-09 06:42:32 -070015#include "webrtc/call/rtp_transport_controller_send.h"
pbosa96b60b2016-04-18 21:12:48 -070016#include "webrtc/common_video/include/frame_callback.h"
nisseea3a7982017-05-15 02:42:11 -070017#include "webrtc/common_video/include/video_frame.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010018#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
19#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000020#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
philipel0f9af012015-09-01 07:01:51 -070021#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h"
magjed509e4fe2016-11-18 01:34:11 -080022#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
philipel7fabd462015-09-03 04:42:32 -070023#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020024#include "webrtc/rtc_base/bind.h"
25#include "webrtc/rtc_base/checks.h"
26#include "webrtc/rtc_base/criticalsection.h"
27#include "webrtc/rtc_base/event.h"
28#include "webrtc/rtc_base/logging.h"
29#include "webrtc/rtc_base/platform_thread.h"
30#include "webrtc/rtc_base/rate_limiter.h"
31#include "webrtc/rtc_base/timeutils.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010032#include "webrtc/system_wrappers/include/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000033#include "webrtc/test/call_test.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000034#include "webrtc/test/configurable_frame_size_encoder.h"
Peter Boströmeb66e802015-06-05 11:08:03 +020035#include "webrtc/test/fake_texture_frame.h"
sprang168794c2017-07-06 04:38:06 -070036#include "webrtc/test/field_trial.h"
perkja49cbd32016-09-16 07:53:41 -070037#include "webrtc/test/frame_generator.h"
sprang168794c2017-07-06 04:38:06 -070038#include "webrtc/test/frame_generator_capturer.h"
nisse26acec42016-04-15 03:43:39 -070039#include "webrtc/test/frame_utils.h"
kwibergac9f8762016-09-30 22:29:43 -070040#include "webrtc/test/gtest.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000041#include "webrtc/test/null_transport.h"
danilchap3dc929e2016-11-02 08:21:59 -070042#include "webrtc/test/rtcp_packet_parser.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000043#include "webrtc/test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070044
pbos@webrtc.org273a4142014-12-01 15:23:21 +000045#include "webrtc/video/send_statistics_proxy.h"
charujainbf6a45b2016-11-03 04:21:42 -070046#include "webrtc/video/transport_adapter.h"
mbonadei52127002017-08-28 06:46:48 -070047#include "webrtc/call/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000048
49namespace webrtc {
50
sprang@webrtc.org346094c2014-02-18 08:40:33 +000051enum VideoFormat { kGeneric, kVP8, };
52
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070053void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
54 const std::vector<VideoFrame>& frames2);
55VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000056
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000057class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000058 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000059 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000060 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000061 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010062
63 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
64 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070065
66 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000067};
68
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000069TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070070 task_queue_.SendTask([this]() {
71 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000072
eladalon413ee9a2017-08-22 04:02:52 -070073 test::NullTransport transport;
74 CreateSendConfig(1, 0, 0, &transport);
75 CreateVideoStreams();
76 video_send_stream_->Start();
77 video_send_stream_->Start();
78 DestroyStreams();
79 DestroyCalls();
80 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000081}
82
83TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070084 task_queue_.SendTask([this]() {
85 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000086
eladalon413ee9a2017-08-22 04:02:52 -070087 test::NullTransport transport;
88 CreateSendConfig(1, 0, 0, &transport);
89 CreateVideoStreams();
90 video_send_stream_->Stop();
91 video_send_stream_->Stop();
92 DestroyStreams();
93 DestroyCalls();
94 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000095}
96
pbos@webrtc.org013d9942013-08-22 09:42:17 +000097TEST_F(VideoSendStreamTest, SupportsCName) {
98 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000099 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000100 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000101 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000102
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000103 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000104 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700105 test::RtcpPacketParser parser;
106 EXPECT_TRUE(parser.Parse(packet, length));
107 if (parser.sdes()->num_packets() > 0) {
108 EXPECT_EQ(1u, parser.sdes()->chunks().size());
109 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000110
danilchap3dc929e2016-11-02 08:21:59 -0700111 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000112 }
113
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000114 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000115 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000116
stefanff483612015-12-21 03:14:00 -0800117 void ModifyVideoConfigs(
118 VideoSendStream::Config* send_config,
119 std::vector<VideoReceiveStream::Config>* receive_configs,
120 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000121 send_config->rtp.c_name = kCName;
122 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000123
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000124 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100125 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126 }
127 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000128
stefane74eef12016-01-08 06:47:13 -0800129 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000130}
131
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000132TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000133 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000134 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000135 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000136 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100137 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000138 }
139
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000140 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000141 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000142 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000143
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000144 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
145 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
146 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700147 if (header.extension.absoluteSendTime != 0) {
148 // Wait for at least one packet with a non-zero send time. The send time
149 // is a 16-bit value derived from the system clock, and it is valid
150 // for a packet to have a zero send time. To tell that from an
151 // unpopulated value we'll wait for a packet with non-zero send time.
152 observation_complete_.Set();
153 } else {
154 LOG(LS_WARNING) << "Got a packet with zero absoluteSendTime, waiting"
155 " for another packet...";
156 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000157
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000158 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000159 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000160
stefanff483612015-12-21 03:14:00 -0800161 void ModifyVideoConfigs(
162 VideoSendStream::Config* send_config,
163 std::vector<VideoReceiveStream::Config>* receive_configs,
164 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200165 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100166 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700167 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000168 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000169
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000170 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100171 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000172 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000174
stefane74eef12016-01-08 06:47:13 -0800175 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000176}
177
pbos@webrtc.org29023282013-09-11 10:14:56 +0000178TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000179 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000180 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000181 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000182 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000183 : SendTest(kDefaultTimeoutMs),
184 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000185 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100186 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000187 }
188
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000189 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000190 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000191 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000192 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000193
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000194 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
195 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000196 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000197 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100198 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000199
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000200 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000201 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000202
stefanff483612015-12-21 03:14:00 -0800203 void ModifyVideoConfigs(
204 VideoSendStream::Config* send_config,
205 std::vector<VideoReceiveStream::Config>* receive_configs,
206 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000207 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100208 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700209 send_config->rtp.extensions.push_back(RtpExtension(
210 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000211 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000212
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000213 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100214 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000215 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000216
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000217 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000218 } test;
219
stefane74eef12016-01-08 06:47:13 -0800220 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000221}
222
sprang867fb522015-08-03 04:38:41 -0700223TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700224 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700225 class TransportWideSequenceNumberObserver : public test::SendTest {
226 public:
227 TransportWideSequenceNumberObserver()
228 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
229 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
230 kRtpExtensionTransportSequenceNumber, kExtensionId));
231 }
232
233 private:
234 Action OnSendRtp(const uint8_t* packet, size_t length) override {
235 RTPHeader header;
236 EXPECT_TRUE(parser_->Parse(packet, length, &header));
237
238 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
239 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
240 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
241
Peter Boström5811a392015-12-10 13:02:50 +0100242 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700243
244 return SEND_PACKET;
245 }
246
stefanff483612015-12-21 03:14:00 -0800247 void ModifyVideoConfigs(
248 VideoSendStream::Config* send_config,
249 std::vector<VideoReceiveStream::Config>* receive_configs,
250 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700251 send_config->encoder_settings.encoder = &encoder_;
sprang867fb522015-08-03 04:38:41 -0700252 }
253
254 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100255 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700256 }
257
258 test::FakeEncoder encoder_;
259 } test;
260
stefane74eef12016-01-08 06:47:13 -0800261 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700262}
263
perkj803d97f2016-11-01 11:45:46 -0700264TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
265 class VideoRotationObserver : public test::SendTest {
266 public:
267 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
268 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
269 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
270 }
271
272 Action OnSendRtp(const uint8_t* packet, size_t length) override {
273 RTPHeader header;
274 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700275 // Only the last packet of the frame is required to have the extension.
276 if (!header.markerBit)
277 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700278 EXPECT_TRUE(header.extension.hasVideoRotation);
279 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
280 observation_complete_.Set();
281 return SEND_PACKET;
282 }
283
284 void ModifyVideoConfigs(
285 VideoSendStream::Config* send_config,
286 std::vector<VideoReceiveStream::Config>* receive_configs,
287 VideoEncoderConfig* encoder_config) override {
288 send_config->rtp.extensions.clear();
289 send_config->rtp.extensions.push_back(RtpExtension(
290 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
291 }
292
293 void OnFrameGeneratorCapturerCreated(
294 test::FrameGeneratorCapturer* frame_generator_capturer) override {
295 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
296 }
297
298 void PerformTest() override {
299 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
300 }
301 } test;
302
303 RunBaseTest(&test);
304}
305
ilnik00d802b2017-04-11 10:34:31 -0700306TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700307 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700308 public:
ilnik10894992017-06-21 08:23:19 -0700309 VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
ilnik00d802b2017-04-11 10:34:31 -0700310 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
311 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
312 }
313
314 Action OnSendRtp(const uint8_t* packet, size_t length) override {
315 RTPHeader header;
316 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700317 // Only the last packet of the frame must have extension.
318 if (!header.markerBit)
319 return SEND_PACKET;
ilnik00d802b2017-04-11 10:34:31 -0700320 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700321 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
322 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700323 observation_complete_.Set();
324 return SEND_PACKET;
325 }
326
327 void ModifyVideoConfigs(
328 VideoSendStream::Config* send_config,
329 std::vector<VideoReceiveStream::Config>* receive_configs,
330 VideoEncoderConfig* encoder_config) override {
331 send_config->rtp.extensions.clear();
332 send_config->rtp.extensions.push_back(
333 RtpExtension(RtpExtension::kVideoContentTypeUri,
334 test::kVideoContentTypeExtensionId));
335 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
336 }
337
338 void PerformTest() override {
339 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
340 }
341 } test;
342
343 RunBaseTest(&test);
344}
345
ilnik04f4d122017-06-19 07:18:55 -0700346TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700347 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700348 public:
ilnik10894992017-06-21 08:23:19 -0700349 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700350 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
351 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
352 }
353
354 Action OnSendRtp(const uint8_t* packet, size_t length) override {
355 RTPHeader header;
356 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700357 // Only the last packet of the frame must have extension.
358 if (!header.markerBit)
359 return SEND_PACKET;
360 EXPECT_TRUE(header.extension.has_video_timing);
361 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700362 return SEND_PACKET;
363 }
364
365 void ModifyVideoConfigs(
366 VideoSendStream::Config* send_config,
367 std::vector<VideoReceiveStream::Config>* receive_configs,
368 VideoEncoderConfig* encoder_config) override {
369 send_config->rtp.extensions.clear();
370 send_config->rtp.extensions.push_back(RtpExtension(
371 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
372 }
373
374 void PerformTest() override {
375 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
376 }
377 } test;
378
379 RunBaseTest(&test);
380}
381
danilchap901b2df2017-07-28 08:56:04 -0700382class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000383 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000384 FakeReceiveStatistics(uint32_t send_ssrc,
385 uint32_t last_sequence_number,
386 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700387 uint8_t fraction_lost) {
388 stat_.SetMediaSsrc(send_ssrc);
389 stat_.SetExtHighestSeqNum(last_sequence_number);
390 stat_.SetCumulativeLost(cumulative_lost);
391 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000392 }
393
danilchap901b2df2017-07-28 08:56:04 -0700394 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
395 EXPECT_GE(max_blocks, 1u);
396 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000397 }
398
399 private:
danilchap901b2df2017-07-28 08:56:04 -0700400 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000401};
402
brandtre602f0a2016-10-31 03:40:49 -0700403class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100404 public:
brandtre602f0a2016-10-31 03:40:49 -0700405 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800406 bool use_nack,
407 bool expect_red,
408 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800409 const std::string& codec,
410 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800411 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800412 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100413 payload_name_(codec),
414 use_nack_(use_nack),
415 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700416 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800417 sent_media_(false),
418 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800419 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100420
brandtr20d45472017-01-02 00:34:27 -0800421 // Some of the test cases are expected to time out and thus we are using
422 // a shorter timeout window than the default here.
423 static constexpr size_t kTimeoutMs = 10000;
424
Stefan Holmer4654d202015-12-08 09:10:43 +0100425 private:
426 Action OnSendRtp(const uint8_t* packet, size_t length) override {
427 RTPHeader header;
428 EXPECT_TRUE(parser_->Parse(packet, length, &header));
429
Stefan Holmer4654d202015-12-08 09:10:43 +0100430 int encapsulated_payload_type = -1;
431 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100432 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100433 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
434 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100435 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100436 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
437 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100438 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100439 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100440 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
441 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100442 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
443 length) {
444 // Not padding-only, media received outside of RED.
445 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800446 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100447 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100448 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000449
Stefan Holmer4654d202015-12-08 09:10:43 +0100450 if (header_extensions_enabled_) {
451 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
452 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
453 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
454 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
455 // 24 bits wrap.
456 EXPECT_GT(prev_header_.extension.absoluteSendTime,
457 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000458 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100459 EXPECT_GE(header.extension.absoluteSendTime,
460 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200461 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100462 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
463 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
464 prev_header_.extension.transportSequenceNumber;
465 EXPECT_EQ(1, seq_num_diff);
466 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200467
Stefan Holmer4654d202015-12-08 09:10:43 +0100468 if (encapsulated_payload_type != -1) {
469 if (encapsulated_payload_type ==
470 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700471 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800472 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100473 } else {
brandtr65a1e772016-12-12 01:54:58 -0800474 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000475 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000476 }
477
brandtr20d45472017-01-02 00:34:27 -0800478 if (sent_media_ && sent_ulpfec_) {
479 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100480 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000481
Stefan Holmer4654d202015-12-08 09:10:43 +0100482 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000483
Stefan Holmer4654d202015-12-08 09:10:43 +0100484 return SEND_PACKET;
485 }
486
eladalon413ee9a2017-08-22 04:02:52 -0700487 test::PacketTransport* CreateSendTransport(
488 test::SingleThreadedTaskQueueForTesting* task_queue,
489 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100490 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
491 // Configure some network delay.
492 const int kNetworkDelayMs = 100;
493 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800494 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100495 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700496 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700497 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700498 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100499 }
500
stefanff483612015-12-21 03:14:00 -0800501 void ModifyVideoConfigs(
502 VideoSendStream::Config* send_config,
503 std::vector<VideoReceiveStream::Config>* receive_configs,
504 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100505 if (use_nack_) {
506 send_config->rtp.nack.rtp_history_ms =
507 (*receive_configs)[0].rtp.nack.rtp_history_ms =
508 VideoSendStreamTest::kNackRtpHistoryMs;
509 }
brandtr696c9c62016-12-19 05:47:28 -0800510 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100511 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700512 send_config->rtp.ulpfec.red_payload_type =
513 VideoSendStreamTest::kRedPayloadType;
514 send_config->rtp.ulpfec.ulpfec_payload_type =
515 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800516 EXPECT_FALSE(send_config->rtp.extensions.empty());
517 if (!header_extensions_enabled_) {
518 send_config->rtp.extensions.clear();
519 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100520 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700521 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100522 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700523 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
524 send_config->rtp.ulpfec.red_payload_type;
525 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
526 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100527 }
528
529 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800530 EXPECT_EQ(expect_ulpfec_, Wait())
531 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100532 }
533
brandtr696c9c62016-12-19 05:47:28 -0800534 VideoEncoder* const encoder_;
535 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100536 const bool use_nack_;
537 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700538 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800539 bool sent_media_;
540 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100541 bool header_extensions_enabled_;
542 RTPHeader prev_header_;
543};
544
brandtre602f0a2016-10-31 03:40:49 -0700545TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800546 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
547 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800548 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100549}
550
brandtre602f0a2016-10-31 03:40:49 -0700551TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800552 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
553 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100554 RunBaseTest(&test);
555}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000556
stefan60e10c72017-08-23 10:40:00 -0700557class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
558 protected:
559 VideoSendStreamWithoutUlpfecTest()
560 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
561
562 test::ScopedFieldTrials field_trial_;
563};
564
565TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
566 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
567 UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
568 RunBaseTest(&test);
569}
570
Peter Boström39593972016-02-15 11:27:15 +0100571// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
572// since we'll still have to re-request FEC packets, effectively wasting
573// bandwidth since the receiver has to wait for FEC retransmissions to determine
574// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700575TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800576 std::unique_ptr<VideoEncoder> encoder(
577 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
578 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100579 RunBaseTest(&test);
580}
581
582// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800583TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800584 std::unique_ptr<VideoEncoder> encoder(
585 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
586 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100587 RunBaseTest(&test);
588}
589
danilchap9f5b6222017-03-02 06:22:21 -0800590// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
591TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800592 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
593 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100594 RunBaseTest(&test);
595}
596
Peter Boström12996152016-05-14 02:03:18 +0200597#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800598// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
599TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800600 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
601 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800602 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000603}
Peter Boström12996152016-05-14 02:03:18 +0200604#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000605
brandtre78d2662017-01-16 05:57:16 -0800606TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800607 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800608 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800609 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
610 RunBaseTest(&test);
611}
612
brandtr39f97292016-11-16 22:57:50 -0800613// TODO(brandtr): Move these FlexFEC tests when we have created
614// FlexfecSendStream.
615class FlexfecObserver : public test::EndToEndTest {
616 public:
617 FlexfecObserver(bool header_extensions_enabled,
618 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800619 const std::string& codec,
620 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800621 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800622 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800623 payload_name_(codec),
624 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800625 sent_media_(false),
626 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800627 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800628
629 size_t GetNumFlexfecStreams() const override { return 1; }
630
631 private:
632 Action OnSendRtp(const uint8_t* packet, size_t length) override {
633 RTPHeader header;
634 EXPECT_TRUE(parser_->Parse(packet, length, &header));
635
brandtr39f97292016-11-16 22:57:50 -0800636 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
637 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
638 sent_flexfec_ = true;
639 } else {
640 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
641 header.payloadType);
642 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
643 sent_media_ = true;
644 }
645
646 if (header_extensions_enabled_) {
647 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
648 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
649 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
650 }
651
brandtr0c5a1542016-11-23 04:42:26 -0800652 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800653 observation_complete_.Set();
654 }
655
656 return SEND_PACKET;
657 }
658
eladalon413ee9a2017-08-22 04:02:52 -0700659 test::PacketTransport* CreateSendTransport(
660 test::SingleThreadedTaskQueueForTesting* task_queue,
661 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800662 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
663 // Therefore we need some network delay.
664 const int kNetworkDelayMs = 100;
665 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800666 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800667 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700668 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700669 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700670 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800671 }
672
673 void ModifyVideoConfigs(
674 VideoSendStream::Config* send_config,
675 std::vector<VideoReceiveStream::Config>* receive_configs,
676 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800677 if (use_nack_) {
678 send_config->rtp.nack.rtp_history_ms =
679 (*receive_configs)[0].rtp.nack.rtp_history_ms =
680 VideoSendStreamTest::kNackRtpHistoryMs;
681 }
brandtr696c9c62016-12-19 05:47:28 -0800682 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800683 send_config->encoder_settings.payload_name = payload_name_;
684 if (header_extensions_enabled_) {
685 send_config->rtp.extensions.push_back(RtpExtension(
686 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
687 send_config->rtp.extensions.push_back(RtpExtension(
688 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800689 } else {
690 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800691 }
692 }
693
694 void PerformTest() override {
695 EXPECT_TRUE(Wait())
696 << "Timed out waiting for FlexFEC and/or media packets.";
697 }
698
brandtr696c9c62016-12-19 05:47:28 -0800699 VideoEncoder* const encoder_;
700 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800701 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800702 bool sent_media_;
703 bool sent_flexfec_;
704 bool header_extensions_enabled_;
705};
706
brandtrd654a9b2016-12-05 05:38:19 -0800707TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800708 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
709 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800710 RunBaseTest(&test);
711}
712
713TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800714 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
715 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800716 RunBaseTest(&test);
717}
718
brandtr39f97292016-11-16 22:57:50 -0800719TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800720 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
721 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800722 RunBaseTest(&test);
723}
724
brandtr39f97292016-11-16 22:57:50 -0800725#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800726TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800727 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
728 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800729 RunBaseTest(&test);
730}
731
brandtrd654a9b2016-12-05 05:38:19 -0800732TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800733 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
734 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800735 RunBaseTest(&test);
736}
737#endif // defined(RTC_DISABLE_VP9)
738
brandtrd654a9b2016-12-05 05:38:19 -0800739TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800740 std::unique_ptr<VideoEncoder> encoder(
741 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
742 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800743 RunBaseTest(&test);
744}
745
brandtrd654a9b2016-12-05 05:38:19 -0800746TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800747 std::unique_ptr<VideoEncoder> encoder(
748 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
749 FlexfecObserver test(false, true, "H264", encoder.get());
750 RunBaseTest(&test);
751}
752
brandtre78d2662017-01-16 05:57:16 -0800753TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800754 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800755 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800756 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800757 RunBaseTest(&test);
758}
759
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000760void VideoSendStreamTest::TestNackRetransmission(
761 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000762 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000763 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000764 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000765 explicit NackObserver(uint32_t retransmit_ssrc,
766 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000767 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000768 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000769 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000770 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000771 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000772 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000773
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000774 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000775 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000776 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000777 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000778
779 // Nack second packet after receiving the third one.
780 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000781 uint16_t nack_sequence_number = header.sequenceNumber - 1;
782 nacked_sequence_number_ = nack_sequence_number;
danilchap8a1d2a32017-08-01 03:21:37 -0700783 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
terelius429c3452016-01-21 05:42:04 -0800784 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000785
pbosda903ea2015-10-02 02:36:56 -0700786 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100787 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000788
789 RTCPSender::FeedbackState feedback_state;
790
791 EXPECT_EQ(0,
792 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000793 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000794 }
795
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000796 uint16_t sequence_number = header.sequenceNumber;
797
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000798 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100799 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
800 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000801 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000802 const uint8_t* rtx_header = packet + header.headerLength;
803 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
804 }
805
806 if (sequence_number == nacked_sequence_number_) {
807 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000808 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100809 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000810 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000811
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000812 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000813 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000814
stefanff483612015-12-21 03:14:00 -0800815 void ModifyVideoConfigs(
816 VideoSendStream::Config* send_config,
817 std::vector<VideoReceiveStream::Config>* receive_configs,
818 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700819 transport_adapter_.reset(
820 new internal::TransportAdapter(send_config->send_transport));
821 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000822 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000823 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100824 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000825 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
826 }
827
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000828 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100829 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000830 }
831
kwiberg27f982b2016-03-01 11:52:33 -0800832 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000833 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000834 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000835 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000836 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000837 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000838
stefane74eef12016-01-08 06:47:13 -0800839 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000840}
841
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000842TEST_F(VideoSendStreamTest, RetransmitsNack) {
843 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100844 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000845}
846
847TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
848 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000849 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000850}
851
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000852void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
853 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000854 // Use a fake encoder to output a frame of every size in the range [90, 290],
855 // for each size making sure that the exact number of payload bytes received
856 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000857 static const size_t kMaxPacketSize = 128;
858 static const size_t start = 90;
859 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000860
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000861 // Observer that verifies that the expected number of packets and bytes
862 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000863 class FrameFragmentationTest : public test::SendTest,
864 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000865 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000866 FrameFragmentationTest(size_t max_packet_size,
867 size_t start_size,
868 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000869 bool test_generic_packetization,
870 bool use_fec)
871 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000872 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000873 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000874 stop_size_(stop_size),
875 test_generic_packetization_(test_generic_packetization),
876 use_fec_(use_fec),
877 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000878 accumulated_size_(0),
879 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000880 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000881 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000882 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000883 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000884 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700885 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000886 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000887
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000888 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000889 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000890 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000891 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000892 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000893
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000894 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000895
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000896 if (use_fec_) {
897 uint8_t payload_type = packet[header.headerLength];
898 bool is_fec = header.payloadType == kRedPayloadType &&
899 payload_type == kUlpfecPayloadType;
900 if (is_fec) {
901 fec_packet_received_ = true;
902 return SEND_PACKET;
903 }
904 }
905
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000906 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000907
908 if (use_fec_)
909 TriggerLossReport(header);
910
911 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200912 size_t overhead = header.headerLength + header.paddingLength;
913 // Only remove payload header and RED header if the packet actually
914 // contains payload.
915 if (length > overhead) {
916 overhead += (1 /* Generic header */);
917 if (use_fec_)
918 overhead += 1; // RED for FEC header.
919 }
920 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000921 accumulated_payload_ += length - overhead;
922 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000923
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000924 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000925 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000926 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
927 // With FEC enabled, frame size is incremented asynchronously, so
928 // "old" frames one byte too small may arrive. Accept, but don't
929 // increase expected frame size.
930 accumulated_size_ = 0;
931 accumulated_payload_ = 0;
932 return SEND_PACKET;
933 }
934
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000935 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000936 if (test_generic_packetization_) {
937 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
938 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000939
940 // Last packet of frame; reset counters.
941 accumulated_size_ = 0;
942 accumulated_payload_ = 0;
943 if (current_size_rtp_ == stop_size_) {
944 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100945 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000946 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000947 // Increase next expected frame size. If testing with FEC, make sure
948 // a FEC packet has been received for this frame size before
949 // proceeding, to make sure that redundancy packets don't exceed
950 // size limit.
951 if (!use_fec_) {
952 ++current_size_rtp_;
953 } else if (fec_packet_received_) {
954 fec_packet_received_ = false;
955 ++current_size_rtp_;
956 ++current_size_frame_;
957 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000958 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000959 }
960
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000961 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000962 }
963
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000964 void TriggerLossReport(const RTPHeader& header) {
965 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -0700966 const int kLossPercent = 5;
967 if (packet_count_++ % (100 / kLossPercent) != 0) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000968 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -0700969 kVideoSendSsrcs[0], header.sequenceNumber,
970 (packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
971 static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +0200972 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800973 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700974 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000975
pbosda903ea2015-10-02 02:36:56 -0700976 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100977 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000978
979 RTCPSender::FeedbackState feedback_state;
980
981 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
982 }
983 }
984
nisseef8b61e2016-04-29 06:09:15 -0700985 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000986 // Increase frame size for next encoded frame, in the context of the
987 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000988 if (!use_fec_ &&
989 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000990 ++current_size_frame_;
991 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000992 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000993 }
994
Stefan Holmere5904162015-03-26 11:11:06 +0100995 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -0700996 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +0100997 const int kMinBitrateBps = 30000;
998 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
999 return config;
1000 }
1001
stefanff483612015-12-21 03:14:00 -08001002 void ModifyVideoConfigs(
1003 VideoSendStream::Config* send_config,
1004 std::vector<VideoReceiveStream::Config>* receive_configs,
1005 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001006 transport_adapter_.reset(
1007 new internal::TransportAdapter(send_config->send_transport));
1008 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001009 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001010 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1011 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001012 }
1013
1014 if (!test_generic_packetization_)
1015 send_config->encoder_settings.payload_name = "VP8";
1016
1017 send_config->encoder_settings.encoder = &encoder_;
1018 send_config->rtp.max_packet_size = kMaxPacketSize;
1019 send_config->post_encode_callback = this;
1020
Erik Språng95261872015-04-10 11:58:49 +02001021 // Make sure there is at least one extension header, to make the RTP
1022 // header larger than the base length of 12 bytes.
1023 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001024
1025 // Setup screen content disables frame dropping which makes this easier.
1026 class VideoStreamFactory
1027 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1028 public:
1029 explicit VideoStreamFactory(size_t num_temporal_layers)
1030 : num_temporal_layers_(num_temporal_layers) {
1031 EXPECT_GT(num_temporal_layers, 0u);
1032 }
1033
1034 private:
1035 std::vector<VideoStream> CreateEncoderStreams(
1036 int width,
1037 int height,
1038 const VideoEncoderConfig& encoder_config) override {
1039 std::vector<VideoStream> streams =
1040 test::CreateVideoStreams(width, height, encoder_config);
1041 for (VideoStream& stream : streams) {
1042 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1043 1);
1044 }
1045 return streams;
1046 }
1047 const size_t num_temporal_layers_;
1048 };
1049
1050 encoder_config->video_stream_factory =
1051 new rtc::RefCountedObject<VideoStreamFactory>(2);
1052 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001053 }
1054
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001055 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001056 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001057 }
1058
kwiberg27f982b2016-03-01 11:52:33 -08001059 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001060 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001061
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001062 const size_t max_packet_size_;
1063 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001064 const bool test_generic_packetization_;
1065 const bool use_fec_;
1066
1067 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001068 size_t accumulated_size_;
1069 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001070 bool fec_packet_received_;
1071
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001072 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001073 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001074 };
1075
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001076 // Don't auto increment if FEC is used; continue sending frame size until
1077 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001078 FrameFragmentationTest test(
1079 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001080
stefane74eef12016-01-08 06:47:13 -08001081 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001082}
1083
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001084// TODO(sprang): Is there any way of speeding up these tests?
1085TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1086 TestPacketFragmentationSize(kGeneric, false);
1087}
1088
1089TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1090 TestPacketFragmentationSize(kGeneric, true);
1091}
1092
1093TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1094 TestPacketFragmentationSize(kVP8, false);
1095}
1096
1097TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1098 TestPacketFragmentationSize(kVP8, true);
1099}
1100
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001101// The test will go through a number of phases.
1102// 1. Start sending packets.
1103// 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 +00001104// suspend the stream.
1105// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001106// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001107// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001108// When the stream is detected again, and the stats show that the stream
1109// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001110TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1111 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001112
nissed30a1112016-04-18 05:15:22 -07001113 class RembObserver : public test::SendTest,
1114 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001115 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001116 RembObserver()
1117 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001118 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001119 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001120 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001121 rtp_count_(0),
1122 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001123 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001124 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001125 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001126
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001127 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001128 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001129 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001130 ++rtp_count_;
1131 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001132 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001133 last_sequence_number_ = header.sequenceNumber;
1134
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001135 if (test_state_ == kBeforeSuspend) {
1136 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001137 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001138 test_state_ = kDuringSuspend;
1139 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001140 if (header.paddingLength == 0) {
1141 // Received non-padding packet during suspension period. Reset the
1142 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001143 suspended_frame_count_ = 0;
1144 }
stefanf116bd02015-10-27 08:29:42 -07001145 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001146 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001147 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001148 // Non-padding packet observed. Test is almost complete. Will just
1149 // have to wait for the stats to change.
1150 test_state_ = kWaitingForStats;
1151 }
stefanf116bd02015-10-27 08:29:42 -07001152 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001153 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001154 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001155 if (stats.suspended == false) {
1156 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001157 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001158 }
stefanf116bd02015-10-27 08:29:42 -07001159 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001160 }
1161
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001162 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001163 }
1164
perkj26091b12016-09-01 01:17:40 -07001165 // This method implements the rtc::VideoSinkInterface. This is called when
1166 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001167 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001168 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001169 if (test_state_ == kDuringSuspend &&
1170 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001171 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001172 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001173 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001174 test_state_ = kWaitingForPacket;
1175 }
1176 }
1177
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001178 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001179 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001180 low_remb_bps_ = value;
1181 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001182
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001183 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001184 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001185 high_remb_bps_ = value;
1186 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001187
stefanff483612015-12-21 03:14:00 -08001188 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001189 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001190 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001191 stream_ = send_stream;
1192 }
1193
stefanff483612015-12-21 03:14:00 -08001194 void ModifyVideoConfigs(
1195 VideoSendStream::Config* send_config,
1196 std::vector<VideoReceiveStream::Config>* receive_configs,
1197 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001198 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001199 transport_adapter_.reset(
1200 new internal::TransportAdapter(send_config->send_transport));
1201 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001202 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001203 send_config->pre_encode_callback = this;
1204 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001205 int min_bitrate_bps =
1206 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001207 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001208 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001209 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001210 min_bitrate_bps + threshold_window + 5000);
1211 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1212 }
1213
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001214 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001215 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001216 }
1217
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001218 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001219 kBeforeSuspend,
1220 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001221 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001222 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001223 };
1224
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001225 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001226 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001227 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1228 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001229 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001230 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001231
pbosda903ea2015-10-02 02:36:56 -07001232 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001233 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001234 if (remb_value > 0) {
1235 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001236 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001237 }
1238 RTCPSender::FeedbackState feedback_state;
1239 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1240 }
1241
kwiberg27f982b2016-03-01 11:52:33 -08001242 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001243 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001244 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001245
Peter Boströmf2f82832015-05-01 13:00:41 +02001246 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001247 TestState test_state_ RTC_GUARDED_BY(crit_);
1248 int rtp_count_ RTC_GUARDED_BY(crit_);
1249 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1250 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1251 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1252 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001253 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001254
stefane74eef12016-01-08 06:47:13 -08001255 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001256}
1257
perkj71ee44c2016-06-15 00:47:53 -07001258// This test that padding stops being send after a while if the Camera stops
1259// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001260TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001261 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001262 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001263 NoPaddingWhenVideoIsMuted()
1264 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001265 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001266 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001267 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001268 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001269
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001270 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001271 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001272 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001273 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001274
1275 RTPHeader header;
1276 parser_->Parse(packet, length, &header);
1277 const bool only_padding =
1278 header.headerLength + header.paddingLength == length;
1279
1280 if (test_state_ == kBeforeStopCapture) {
1281 capturer_->Stop();
1282 test_state_ = kWaitingForPadding;
1283 } else if (test_state_ == kWaitingForPadding && only_padding) {
1284 test_state_ = kWaitingForNoPackets;
1285 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1286 only_padding) {
1287 observation_complete_.Set();
1288 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001289 return SEND_PACKET;
1290 }
1291
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001292 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001293 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001294 const int kNoPacketsThresholdMs = 2000;
1295 if (test_state_ == kWaitingForNoPackets &&
1296 (last_packet_time_ms_ > 0 &&
1297 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1298 kNoPacketsThresholdMs)) {
1299 capturer_->Start();
1300 test_state_ = kWaitingForPaddingAfterCameraRestart;
1301 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001302 return SEND_PACKET;
1303 }
1304
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001305 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001306
nisseef8b61e2016-04-29 06:09:15 -07001307 void OnFrameGeneratorCapturerCreated(
1308 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001309 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001310 capturer_ = frame_generator_capturer;
1311 }
1312
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001313 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001314 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001315 << "Timed out while waiting for RTP packets to stop being sent.";
1316 }
1317
perkj71ee44c2016-06-15 00:47:53 -07001318 enum TestState {
1319 kBeforeStopCapture,
1320 kWaitingForPadding,
1321 kWaitingForNoPackets,
1322 kWaitingForPaddingAfterCameraRestart
1323 };
1324
1325 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001326 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001327 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001328 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001329 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1330 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001331 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001332
stefane74eef12016-01-08 06:47:13 -08001333 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001334}
1335
isheriffcc5903e2016-10-04 08:29:38 -07001336TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1337 const int kCapacityKbps = 10000; // 10 Mbps
1338 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1339 public:
1340 PaddingIsPrimarilyRetransmissions()
1341 : EndToEndTest(kDefaultTimeoutMs),
1342 clock_(Clock::GetRealTimeClock()),
1343 padding_length_(0),
1344 total_length_(0),
1345 call_(nullptr) {}
1346
1347 private:
1348 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1349 call_ = sender_call;
1350 }
1351
1352 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1353 rtc::CritScope lock(&crit_);
1354
1355 RTPHeader header;
1356 parser_->Parse(packet, length, &header);
1357 padding_length_ += header.paddingLength;
1358 total_length_ += length;
1359 return SEND_PACKET;
1360 }
1361
eladalon413ee9a2017-08-22 04:02:52 -07001362 test::PacketTransport* CreateSendTransport(
1363 test::SingleThreadedTaskQueueForTesting* task_queue,
1364 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001365 const int kNetworkDelayMs = 50;
1366 FakeNetworkPipe::Config config;
1367 config.loss_percent = 10;
1368 config.link_capacity_kbps = kCapacityKbps;
1369 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001370 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001371 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001372 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001373 }
1374
1375 void ModifyVideoConfigs(
1376 VideoSendStream::Config* send_config,
1377 std::vector<VideoReceiveStream::Config>* receive_configs,
1378 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001379 // Turn on RTX.
1380 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1381 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001382 }
1383
1384 void PerformTest() override {
1385 // TODO(isheriff): Some platforms do not ramp up as expected to full
1386 // capacity due to packet scheduling delays. Fix that before getting
1387 // rid of this.
1388 SleepMs(5000);
1389 {
1390 rtc::CritScope lock(&crit_);
1391 // Expect padding to be a small percentage of total bytes sent.
1392 EXPECT_LT(padding_length_, .1 * total_length_);
1393 }
1394 }
1395
1396 rtc::CriticalSection crit_;
1397 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001398 size_t padding_length_ RTC_GUARDED_BY(crit_);
1399 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001400 Call* call_;
1401 } test;
1402
1403 RunBaseTest(&test);
1404}
1405
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001406// This test first observes "high" bitrate use at which point it sends a REMB to
1407// indicate that it should be lowered significantly. The test then observes that
1408// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1409// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001410//
1411// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1412// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001413TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1414 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001415 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001416 static const int kRembBitrateBps = 80000;
1417 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001418 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001419 public:
1420 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001421 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001422 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1423 stream_(nullptr),
1424 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001425
1426 private:
nisseef8b61e2016-04-29 06:09:15 -07001427 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001428 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001429 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001430
1431 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001432 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001433 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001434 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001435 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001436 if (!stats.substreams.empty()) {
1437 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001438 int total_bitrate_bps =
1439 stats.substreams.begin()->second.total_bitrate_bps;
1440 test::PrintResult("bitrate_stats_",
1441 "min_transmit_bitrate_low_remb",
1442 "bitrate_bps",
1443 static_cast<size_t>(total_bitrate_bps),
1444 "bps",
1445 false);
1446 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001447 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1448 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001449 rtp_rtcp_->Process();
1450 bitrate_capped_ = true;
1451 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001452 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001453 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001454 }
1455 }
stefanf116bd02015-10-27 08:29:42 -07001456 // Packets don't have to be delivered since the test is the receiver.
1457 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001458 }
1459
stefanff483612015-12-21 03:14:00 -08001460 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001461 VideoSendStream* send_stream,
1462 const std::vector<VideoReceiveStream*>& receive_streams) override {
1463 stream_ = send_stream;
1464 RtpRtcp::Configuration config;
1465 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001466 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001467 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1468 rtp_rtcp_->SetREMBStatus(true);
1469 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001470 }
1471
stefanff483612015-12-21 03:14:00 -08001472 void ModifyVideoConfigs(
1473 VideoSendStream::Config* send_config,
1474 std::vector<VideoReceiveStream::Config>* receive_configs,
1475 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001476 feedback_transport_.reset(
1477 new internal::TransportAdapter(send_config->send_transport));
1478 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001479 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001480 }
1481
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001482 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001483 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001484 << "Timeout while waiting for low bitrate stats after REMB.";
1485 }
1486
kwiberg27f982b2016-03-01 11:52:33 -08001487 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1488 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001489 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001490 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001491 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001492 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001493
stefane74eef12016-01-08 06:47:13 -08001494 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001495}
1496
Stefan Holmer280de9e2016-09-30 10:06:51 +02001497TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1498 static const int kStartBitrateBps = 300000;
1499 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001500 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001501 class ChangingNetworkRouteTest : public test::EndToEndTest {
1502 public:
eladalon413ee9a2017-08-22 04:02:52 -07001503 explicit ChangingNetworkRouteTest(
1504 test::SingleThreadedTaskQueueForTesting* task_queue)
1505 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1506 task_queue_(task_queue),
1507 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001508 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1509 kRtpExtensionTransportSequenceNumber, kExtensionId));
1510 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001511
1512 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1513 call_ = sender_call;
1514 }
1515
Stefan Holmer280de9e2016-09-30 10:06:51 +02001516 void ModifyVideoConfigs(
1517 VideoSendStream::Config* send_config,
1518 std::vector<VideoReceiveStream::Config>* receive_configs,
1519 VideoEncoderConfig* encoder_config) override {
1520 send_config->rtp.extensions.clear();
1521 send_config->rtp.extensions.push_back(RtpExtension(
1522 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1523 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1524 (*receive_configs)[0].rtp.transport_cc = true;
1525 }
1526
1527 void ModifyAudioConfigs(
1528 AudioSendStream::Config* send_config,
1529 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1530 send_config->rtp.extensions.clear();
1531 send_config->rtp.extensions.push_back(RtpExtension(
1532 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1533 (*receive_configs)[0].rtp.extensions.clear();
1534 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1535 (*receive_configs)[0].rtp.transport_cc = true;
1536 }
1537
Stefan Holmerbe402962016-07-08 16:16:41 +02001538 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1539 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1540 observation_complete_.Set();
1541 }
1542
1543 return SEND_PACKET;
1544 }
1545
1546 void PerformTest() override {
1547 rtc::NetworkRoute new_route(true, 10, 20, -1);
Stefan Holmerbe402962016-07-08 16:16:41 +02001548 Call::Config::BitrateConfig bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001549
1550 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1551 call_->OnNetworkRouteChanged("transport", new_route);
1552 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1553 call_->SetBitrateConfig(bitrate_config);
1554 });
1555
Stefan Holmerbe402962016-07-08 16:16:41 +02001556 EXPECT_TRUE(Wait())
1557 << "Timed out while waiting for start bitrate to be exceeded.";
1558
eladalon413ee9a2017-08-22 04:02:52 -07001559 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1560 bitrate_config.start_bitrate_bps = -1;
1561 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1562 call_->SetBitrateConfig(bitrate_config);
1563 // TODO(holmer): We should set the last sent packet id here and verify
1564 // that we correctly ignore any packet loss reported prior to that id.
1565 ++new_route.local_network_id;
1566 call_->OnNetworkRouteChanged("transport", new_route);
1567 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1568 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001569 }
1570
1571 private:
eladalon413ee9a2017-08-22 04:02:52 -07001572 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001573 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001574 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001575
1576 RunBaseTest(&test);
1577}
1578
michaelt79e05882016-11-08 02:50:09 -08001579TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1580 class ChangingTransportOverheadTest : public test::EndToEndTest {
1581 public:
eladalon413ee9a2017-08-22 04:02:52 -07001582 explicit ChangingTransportOverheadTest(
1583 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001584 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001585 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001586 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001587 packets_sent_(0),
1588 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001589
1590 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1591 call_ = sender_call;
1592 }
1593
1594 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001595 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001596 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001597 if (++packets_sent_ < 100)
1598 return SEND_PACKET;
1599 observation_complete_.Set();
1600 return SEND_PACKET;
1601 }
1602
michaelta3328772016-11-29 09:25:03 -08001603 void ModifyVideoConfigs(
1604 VideoSendStream::Config* send_config,
1605 std::vector<VideoReceiveStream::Config>* receive_configs,
1606 VideoEncoderConfig* encoder_config) override {
1607 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1608 }
1609
michaelt79e05882016-11-08 02:50:09 -08001610 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001611 task_queue_->SendTask([this]() {
1612 transport_overhead_ = 100;
1613 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1614 transport_overhead_);
1615 });
1616
michaelt79e05882016-11-08 02:50:09 -08001617 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001618
sprang21253fc2017-02-27 03:35:47 -08001619 {
1620 rtc::CritScope cs(&lock_);
1621 packets_sent_ = 0;
1622 }
eladalon413ee9a2017-08-22 04:02:52 -07001623
1624 task_queue_->SendTask([this]() {
1625 transport_overhead_ = 500;
1626 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1627 transport_overhead_);
1628 });
1629
michaelt79e05882016-11-08 02:50:09 -08001630 EXPECT_TRUE(Wait());
1631 }
1632
1633 private:
eladalon413ee9a2017-08-22 04:02:52 -07001634 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001635 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001636 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001637 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001638 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001639 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001640 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001641
1642 RunBaseTest(&test);
1643}
1644
sprangf24a0642017-02-28 13:23:26 -08001645// Test class takes takes as argument a switch selecting if type switch should
1646// occur and a function pointer to reset the send stream. This is necessary
1647// since you cannot change the content type of a VideoSendStream, you need to
1648// recreate it. Stopping and recreating the stream can only be done on the main
1649// thread and in the context of VideoSendStreamTest (not BaseTest).
1650template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001651class MaxPaddingSetTest : public test::SendTest {
1652 public:
1653 static const uint32_t kMinTransmitBitrateBps = 400000;
1654 static const uint32_t kActualEncodeBitrateBps = 40000;
1655 static const uint32_t kMinPacketsToSend = 50;
1656
sprangf24a0642017-02-28 13:23:26 -08001657 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001658 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001659 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001660 call_(nullptr),
1661 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001662 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001663 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001664 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001665 stream_resetter_(stream_reset_fun) {
1666 RTC_DCHECK(stream_resetter_);
1667 }
sprang9c0b5512016-07-06 00:54:28 -07001668
1669 void OnVideoStreamsCreated(
1670 VideoSendStream* send_stream,
1671 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001672 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001673 send_stream_ = send_stream;
1674 }
1675
1676 void ModifyVideoConfigs(
1677 VideoSendStream::Config* send_config,
1678 std::vector<VideoReceiveStream::Config>* receive_configs,
1679 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001680 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001681 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001682 encoder_config->min_transmit_bitrate_bps = 0;
1683 encoder_config->content_type =
1684 VideoEncoderConfig::ContentType::kRealtimeVideo;
1685 } else {
1686 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1687 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1688 }
sprangf24a0642017-02-28 13:23:26 -08001689 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001690 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001691 }
1692
1693 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1694 call_ = sender_call;
1695 }
1696
1697 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1698 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001699 if (running_without_padding_)
1700 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1701
1702 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1703 // we have reliable data.
1704 if (++packets_sent_ < kMinPacketsToSend)
1705 return SEND_PACKET;
1706
1707 if (running_without_padding_) {
1708 // We've sent kMinPacketsToSend packets with default configuration, switch
1709 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001710 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001711 packets_sent_ = 0;
1712 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1713 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001714 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001715 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001716 return SEND_PACKET;
1717 }
1718
1719 // Make sure the pacer has been configured with a min transmit bitrate.
1720 if (call_->GetStats().max_padding_bitrate_bps > 0)
1721 observation_complete_.Set();
1722
1723 return SEND_PACKET;
1724 }
1725
1726 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001727 if (RunningWithoutPadding()) {
1728 ASSERT_TRUE(
1729 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001730 (*stream_resetter_)(send_stream_config_, encoder_config_);
1731 }
1732
sprang9c0b5512016-07-06 00:54:28 -07001733 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1734 }
1735
1736 private:
sprangf24a0642017-02-28 13:23:26 -08001737 bool RunningWithoutPadding() const {
1738 rtc::CritScope lock(&crit_);
1739 return running_without_padding_;
1740 }
1741
sprang9c0b5512016-07-06 00:54:28 -07001742 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001743 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001744 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001745 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001746 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001747 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001748 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001749 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001750 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001751};
1752
1753TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001754 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1755 const VideoEncoderConfig& encoder_config) {};
1756 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001757 RunBaseTest(&test);
1758}
1759
1760TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001761 // Function for removing and recreating the send stream with a new config.
1762 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1763 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001764 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1765 Stop();
1766 sender_call_->DestroyVideoSendStream(video_send_stream_);
1767 video_send_config_ = send_stream_config.Copy();
1768 video_encoder_config_ = encoder_config.Copy();
1769 video_send_stream_ = sender_call_->CreateVideoSendStream(
1770 video_send_config_.Copy(), video_encoder_config_.Copy());
1771 video_send_stream_->SetSource(
1772 frame_generator_capturer_.get(),
1773 VideoSendStream::DegradationPreference::kMaintainResolution);
1774 Start();
1775 });
sprangf24a0642017-02-28 13:23:26 -08001776 };
1777 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001778 RunBaseTest(&test);
1779}
1780
perkjfa10b552016-10-02 23:45:26 -07001781// This test verifies that new frame sizes reconfigures encoders even though not
1782// (yet) sending. The purpose of this is to permit encoding as quickly as
1783// possible once we start sending. Likely the frames being input are from the
1784// same source that will be sent later, which just means that we're ready
1785// earlier.
1786TEST_F(VideoSendStreamTest,
1787 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1788 class EncoderObserver : public test::FakeEncoder {
1789 public:
1790 EncoderObserver()
1791 : FakeEncoder(Clock::GetRealTimeClock()),
1792 init_encode_called_(false, false),
1793 number_of_initializations_(0),
1794 last_initialized_frame_width_(0),
1795 last_initialized_frame_height_(0) {}
1796
1797 void WaitForResolution(int width, int height) {
1798 {
1799 rtc::CritScope lock(&crit_);
1800 if (last_initialized_frame_width_ == width &&
1801 last_initialized_frame_height_ == height) {
1802 return;
1803 }
1804 }
Erik Språng08127a92016-11-16 16:41:30 +01001805 EXPECT_TRUE(
1806 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001807 {
1808 rtc::CritScope lock(&crit_);
1809 EXPECT_EQ(width, last_initialized_frame_width_);
1810 EXPECT_EQ(height, last_initialized_frame_height_);
1811 }
1812 }
1813
1814 private:
1815 int32_t InitEncode(const VideoCodec* config,
1816 int32_t number_of_cores,
1817 size_t max_payload_size) override {
1818 rtc::CritScope lock(&crit_);
1819 last_initialized_frame_width_ = config->width;
1820 last_initialized_frame_height_ = config->height;
1821 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001822 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001823 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1824 }
1825
1826 int32_t Encode(const VideoFrame& input_image,
1827 const CodecSpecificInfo* codec_specific_info,
1828 const std::vector<FrameType>* frame_types) override {
1829 ADD_FAILURE()
1830 << "Unexpected Encode call since the send stream is not started";
1831 return 0;
1832 }
1833
1834 rtc::CriticalSection crit_;
1835 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001836 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1837 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1838 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001839 };
1840
perkjfa10b552016-10-02 23:45:26 -07001841 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001842 EncoderObserver encoder;
eladalon413ee9a2017-08-22 04:02:52 -07001843
1844 task_queue_.SendTask([this, &transport, &encoder]() {
1845 CreateSenderCall(Call::Config(event_log_.get()));
1846 CreateSendConfig(1, 0, 0, &transport);
1847 video_send_config_.encoder_settings.encoder = &encoder;
1848 CreateVideoStreams();
1849 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1850 kDefaultHeight);
1851 frame_generator_capturer_->Start();
1852 });
perkjfa10b552016-10-02 23:45:26 -07001853
1854 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001855
1856 task_queue_.SendTask([this]() {
1857 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1858 kDefaultHeight * 2);
1859 });
1860
perkjfa10b552016-10-02 23:45:26 -07001861 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001862
1863 task_queue_.SendTask([this]() {
1864 DestroyStreams();
1865 DestroyCalls();
1866 });
perkjfa10b552016-10-02 23:45:26 -07001867}
1868
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001869TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1870 class StartBitrateObserver : public test::FakeEncoder {
1871 public:
1872 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001873 : FakeEncoder(Clock::GetRealTimeClock()),
1874 start_bitrate_changed_(false, false),
1875 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001876 int32_t InitEncode(const VideoCodec* config,
1877 int32_t number_of_cores,
1878 size_t max_payload_size) override {
1879 rtc::CritScope lock(&crit_);
1880 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001881 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001882 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1883 }
1884
1885 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1886 rtc::CritScope lock(&crit_);
1887 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001888 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001889 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1890 }
1891
1892 int GetStartBitrateKbps() const {
1893 rtc::CritScope lock(&crit_);
1894 return start_bitrate_kbps_;
1895 }
1896
pbos14fe7082016-04-20 06:35:56 -07001897 bool WaitForStartBitrate() {
1898 return start_bitrate_changed_.Wait(
1899 VideoSendStreamTest::kDefaultTimeoutMs);
1900 }
1901
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001902 private:
pbos5ad935c2016-01-25 03:52:44 -08001903 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001904 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001905 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001906 };
1907
philipel4fb651d2017-04-10 03:54:05 -07001908 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001909
solenberg4fbae2b2015-08-28 04:07:10 -07001910 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001911 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001912
1913 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001914 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001915 sender_call_->SetBitrateConfig(bitrate_config);
1916
1917 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001918 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001919 // Since this test does not use a capturer, set |internal_source| = true.
1920 // Encoder configuration is otherwise updated on the next video frame.
1921 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001922
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001923 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001924
pbos14fe7082016-04-20 06:35:56 -07001925 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001926 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001927 encoder.GetStartBitrateKbps());
1928
perkjfa10b552016-10-02 23:45:26 -07001929 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001930 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001931
1932 // New bitrate should be reconfigured above the previous max. As there's no
1933 // network connection this shouldn't be flaky, as no bitrate should've been
1934 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001935 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001936 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1937 encoder.GetStartBitrateKbps());
1938
1939 DestroyStreams();
1940}
1941
perkj57c21f92016-06-17 07:27:16 -07001942// This test that if the encoder use an internal source, VideoEncoder::SetRates
1943// will be called with zero bitrate during initialization and that
1944// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1945// with zero bitrate.
1946TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1947 class StartStopBitrateObserver : public test::FakeEncoder {
1948 public:
1949 StartStopBitrateObserver()
1950 : FakeEncoder(Clock::GetRealTimeClock()),
1951 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001952 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001953 int32_t InitEncode(const VideoCodec* config,
1954 int32_t number_of_cores,
1955 size_t max_payload_size) override {
1956 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001957 encoder_init_.Set();
1958 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1959 }
1960
Erik Språng08127a92016-11-16 16:41:30 +01001961 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1962 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001963 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001964 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001965 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001966 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001967 }
1968
1969 bool WaitForEncoderInit() {
1970 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1971 }
Erik Språng08127a92016-11-16 16:41:30 +01001972
1973 bool WaitBitrateChanged(bool non_zero) {
1974 do {
1975 rtc::Optional<int> bitrate_kbps;
1976 {
1977 rtc::CritScope lock(&crit_);
1978 bitrate_kbps = bitrate_kbps_;
1979 }
1980 if (!bitrate_kbps)
1981 continue;
1982
1983 if ((non_zero && *bitrate_kbps > 0) ||
1984 (!non_zero && *bitrate_kbps == 0)) {
1985 return true;
1986 }
1987 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1988 return false;
perkj57c21f92016-06-17 07:27:16 -07001989 }
1990
1991 private:
1992 rtc::CriticalSection crit_;
1993 rtc::Event encoder_init_;
1994 rtc::Event bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001995 rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001996 };
1997
perkj57c21f92016-06-17 07:27:16 -07001998 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07001999 StartStopBitrateObserver encoder;
perkj57c21f92016-06-17 07:27:16 -07002000
eladalon413ee9a2017-08-22 04:02:52 -07002001 task_queue_.SendTask([this, &transport, &encoder]() {
2002 CreateSenderCall(Call::Config(event_log_.get()));
2003 CreateSendConfig(1, 0, 0, &transport);
2004
2005 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2006
2007 video_send_config_.encoder_settings.encoder = &encoder;
2008 video_send_config_.encoder_settings.internal_source = true;
2009
2010 CreateVideoStreams();
2011 });
perkj57c21f92016-06-17 07:27:16 -07002012
2013 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002014
eladalon413ee9a2017-08-22 04:02:52 -07002015 task_queue_.SendTask([this]() {
2016 video_send_stream_->Start();
2017 });
Erik Språng08127a92016-11-16 16:41:30 +01002018 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2019
eladalon413ee9a2017-08-22 04:02:52 -07002020 task_queue_.SendTask([this]() {
2021 video_send_stream_->Stop();
2022 });
Erik Språng08127a92016-11-16 16:41:30 +01002023 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2024
eladalon413ee9a2017-08-22 04:02:52 -07002025 task_queue_.SendTask([this]() {
2026 video_send_stream_->Start();
2027 });
Erik Språng08127a92016-11-16 16:41:30 +01002028 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002029
eladalon413ee9a2017-08-22 04:02:52 -07002030 task_queue_.SendTask([this]() {
2031 DestroyStreams();
2032 DestroyCalls();
2033 });
perkj57c21f92016-06-17 07:27:16 -07002034}
2035
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002036TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002037 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002038 public:
Peter Boström5811a392015-12-10 13:02:50 +01002039 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002040
nissed30a1112016-04-18 05:15:22 -07002041 void OnFrame(const VideoFrame& video_frame) override {
2042 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002043 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002044 }
2045
2046 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002047 const int kWaitFrameTimeoutMs = 3000;
2048 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002049 << "Timeout while waiting for output frames.";
2050 }
2051
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002052 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002053 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002054 }
2055
2056 private:
2057 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002058 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002059
2060 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002061 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002062 };
2063
solenberg4fbae2b2015-08-28 04:07:10 -07002064 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002065 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002066 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002067
eladalon413ee9a2017-08-22 04:02:52 -07002068 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2069 // Initialize send stream.
2070 CreateSenderCall(Call::Config(event_log_.get()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002071
eladalon413ee9a2017-08-22 04:02:52 -07002072 CreateSendConfig(1, 0, 0, &transport);
2073 video_send_config_.pre_encode_callback = &observer;
2074 CreateVideoStreams();
2075
2076 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2077 // alternatively.
2078 int width = 168;
2079 int height = 132;
2080
2081 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2082 width, height, 1, 1, kVideoRotation_0));
2083 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2084 width, height, 2, 2, kVideoRotation_0));
2085 input_frames.push_back(CreateVideoFrame(width, height, 3));
2086 input_frames.push_back(CreateVideoFrame(width, height, 4));
2087 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2088 width, height, 5, 5, kVideoRotation_0));
2089
2090 video_send_stream_->Start();
2091 test::FrameForwarder forwarder;
2092 video_send_stream_->SetSource(
2093 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
2094 for (size_t i = 0; i < input_frames.size(); i++) {
2095 forwarder.IncomingCapturedFrame(input_frames[i]);
2096 // Wait until the output frame is received before sending the next input
2097 // frame. Or the previous input frame may be replaced without delivering.
2098 observer.WaitOutputFrame();
2099 }
2100 video_send_stream_->Stop();
2101 video_send_stream_->SetSource(
2102 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
2103 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002104
2105 // Test if the input and output frames are the same. render_time_ms and
2106 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002107 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002108
eladalon413ee9a2017-08-22 04:02:52 -07002109 task_queue_.SendTask([this]() {
2110 DestroyStreams();
2111 DestroyCalls();
2112 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002113}
2114
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002115void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2116 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002117 EXPECT_EQ(frames1.size(), frames2.size());
2118 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002119 // Compare frame buffers, since we don't care about differing timestamps.
2120 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2121 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002122}
2123
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002124VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002125 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002126 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002127 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002128 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002129 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002130 // Use data as a ms timestamp.
2131 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002132 return frame;
2133}
2134
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002135TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2136 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2137 public:
eladalon413ee9a2017-08-22 04:02:52 -07002138 explicit EncoderStateObserver(
2139 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002140 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002141 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002142 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002143 initialized_(false),
2144 callback_registered_(false),
2145 num_releases_(0),
2146 released_(false) {}
2147
2148 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002149 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002150 return released_;
2151 }
2152
2153 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002154 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002155 return initialized_ && callback_registered_;
2156 }
2157
2158 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002159 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002160 return num_releases_;
2161 }
2162
2163 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002164 int32_t InitEncode(const VideoCodec* codecSettings,
2165 int32_t numberOfCores,
2166 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002167 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002168 EXPECT_FALSE(initialized_);
2169 initialized_ = true;
2170 released_ = false;
2171 return 0;
2172 }
2173
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002174 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002175 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002176 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002177 EXPECT_TRUE(IsReadyForEncode());
2178
Peter Boström5811a392015-12-10 13:02:50 +01002179 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002180 return 0;
2181 }
2182
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002183 int32_t RegisterEncodeCompleteCallback(
2184 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002185 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002186 EXPECT_TRUE(initialized_);
2187 callback_registered_ = true;
2188 return 0;
2189 }
2190
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002191 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002192 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002193 EXPECT_TRUE(IsReadyForEncode());
2194 EXPECT_FALSE(released_);
2195 initialized_ = false;
2196 callback_registered_ = false;
2197 released_ = true;
2198 ++num_releases_;
2199 return 0;
2200 }
2201
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002202 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002203 EXPECT_TRUE(IsReadyForEncode());
2204 return 0;
2205 }
2206
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002207 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002208 EXPECT_TRUE(IsReadyForEncode());
2209 return 0;
2210 }
2211
stefanff483612015-12-21 03:14:00 -08002212 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002213 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002214 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002215 stream_ = send_stream;
2216 }
2217
stefanff483612015-12-21 03:14:00 -08002218 void ModifyVideoConfigs(
2219 VideoSendStream::Config* send_config,
2220 std::vector<VideoReceiveStream::Config>* receive_configs,
2221 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002222 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002223 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002224 }
2225
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002226 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002227 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002228
2229 task_queue_->SendTask([this]() {
2230 EXPECT_EQ(0u, num_releases());
2231 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2232 EXPECT_EQ(0u, num_releases());
2233 stream_->Stop();
2234 // Encoder should not be released before destroying the VideoSendStream.
2235 EXPECT_FALSE(IsReleased());
2236 EXPECT_TRUE(IsReadyForEncode());
2237 stream_->Start();
2238 });
2239
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002240 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002241 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002242 }
2243
eladalon413ee9a2017-08-22 04:02:52 -07002244 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002245 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002246 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002247 bool initialized_ RTC_GUARDED_BY(crit_);
2248 bool callback_registered_ RTC_GUARDED_BY(crit_);
2249 size_t num_releases_ RTC_GUARDED_BY(crit_);
2250 bool released_ RTC_GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002251 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002252 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002253
stefane74eef12016-01-08 06:47:13 -08002254 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002255
2256 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002257 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002258}
2259
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002260TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2261 class VideoCodecConfigObserver : public test::SendTest,
2262 public test::FakeEncoder {
2263 public:
2264 VideoCodecConfigObserver()
2265 : SendTest(kDefaultTimeoutMs),
2266 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002267 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002268 num_initializations_(0),
2269 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002270
2271 private:
stefanff483612015-12-21 03:14:00 -08002272 void ModifyVideoConfigs(
2273 VideoSendStream::Config* send_config,
2274 std::vector<VideoReceiveStream::Config>* receive_configs,
2275 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002276 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002277 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002278 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002279 }
2280
stefanff483612015-12-21 03:14:00 -08002281 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002282 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002283 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002284 stream_ = send_stream;
2285 }
2286
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002287 int32_t InitEncode(const VideoCodec* config,
2288 int32_t number_of_cores,
2289 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002290 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002291 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002292 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002293 } else {
2294 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002295 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002296 }
2297 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002298 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002299 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2300 }
2301
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002302 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002303 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002304 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002305
sprangf24a0642017-02-28 13:23:26 -08002306 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002307 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002308 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002309 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002310 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2311 "new encoder settings.";
2312 }
2313
sprangf24a0642017-02-28 13:23:26 -08002314 const uint32_t kFirstMaxBitrateBps = 1000000;
2315 const uint32_t kSecondMaxBitrateBps = 2000000;
2316
pbos14fe7082016-04-20 06:35:56 -07002317 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002318 size_t num_initializations_;
2319 VideoSendStream* stream_;
2320 VideoEncoderConfig encoder_config_;
2321 } test;
2322
stefane74eef12016-01-08 06:47:13 -08002323 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002324}
2325
Peter Boström53eda3d2015-03-27 15:53:18 +01002326static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2327template <typename T>
2328class VideoCodecConfigObserver : public test::SendTest,
2329 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002330 public:
2331 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2332 const char* codec_name)
2333 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2334 FakeEncoder(Clock::GetRealTimeClock()),
2335 video_codec_type_(video_codec_type),
2336 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002337 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002338 num_initializations_(0),
2339 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002340 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2341 }
2342
2343 private:
perkjfa10b552016-10-02 23:45:26 -07002344 class VideoStreamFactory
2345 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2346 public:
2347 VideoStreamFactory() {}
2348
2349 private:
2350 std::vector<VideoStream> CreateEncoderStreams(
2351 int width,
2352 int height,
2353 const VideoEncoderConfig& encoder_config) override {
2354 std::vector<VideoStream> streams =
2355 test::CreateVideoStreams(width, height, encoder_config);
2356 for (size_t i = 0; i < streams.size(); ++i) {
2357 streams[i].temporal_layer_thresholds_bps.resize(
2358 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2359 }
2360 return streams;
2361 }
2362 };
2363
stefanff483612015-12-21 03:14:00 -08002364 void ModifyVideoConfigs(
2365 VideoSendStream::Config* send_config,
2366 std::vector<VideoReceiveStream::Config>* receive_configs,
2367 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002368 send_config->encoder_settings.encoder = this;
2369 send_config->encoder_settings.payload_name = codec_name_;
2370
kthelgason29a44e32016-09-27 03:52:02 -07002371 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002372 encoder_config->video_stream_factory =
2373 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002374 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002375 }
2376
stefanff483612015-12-21 03:14:00 -08002377 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002378 VideoSendStream* send_stream,
2379 const std::vector<VideoReceiveStream*>& receive_streams) override {
2380 stream_ = send_stream;
2381 }
2382
2383 int32_t InitEncode(const VideoCodec* config,
2384 int32_t number_of_cores,
2385 size_t max_payload_size) override {
2386 EXPECT_EQ(video_codec_type_, config->codecType);
2387 VerifyCodecSpecifics(*config);
2388 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002389 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002390 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2391 }
2392
2393 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002394 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2395 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002396
2397 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002398 EXPECT_TRUE(
2399 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002400 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002401
2402 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002403 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002404 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002405 ASSERT_TRUE(
2406 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002407 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002408 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2409 "new encoder settings.";
2410 }
2411
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002412 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002413 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002414 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002415 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2416 return 0;
2417 }
2418
2419 T encoder_settings_;
2420 const VideoCodecType video_codec_type_;
2421 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002422 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002423 size_t num_initializations_;
2424 VideoSendStream* stream_;
2425 VideoEncoderConfig encoder_config_;
2426};
2427
2428template <>
2429void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2430 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002431 EXPECT_EQ(
2432 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002433}
kthelgason29a44e32016-09-27 03:52:02 -07002434
2435template <>
2436rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2437VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2438 return new rtc::RefCountedObject<
2439 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2440}
2441
Peter Boström53eda3d2015-03-27 15:53:18 +01002442template <>
2443void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2444 const VideoCodec& config) const {
2445 // Check that the number of temporal layers has propagated properly to
2446 // VideoCodec.
2447 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002448 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002449
2450 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2451 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2452 config.simulcastStream[i].numberOfTemporalLayers);
2453 }
2454
2455 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002456 // reconfiguring the encoder and not match the set config. Also copy the
mflodmancc3d4422017-08-03 08:27:51 -07002457 // TemporalLayersFactory pointer that has been injected by VideoStreamEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002458 VideoCodecVP8 encoder_settings = encoder_settings_;
2459 encoder_settings.numberOfTemporalLayers =
2460 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002461 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002462 EXPECT_EQ(
2463 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002464}
kthelgason29a44e32016-09-27 03:52:02 -07002465
2466template <>
2467rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2468VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2469 return new rtc::RefCountedObject<
2470 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2471}
2472
Peter Boström53eda3d2015-03-27 15:53:18 +01002473template <>
2474void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2475 const VideoCodec& config) const {
2476 // Check that the number of temporal layers has propagated properly to
2477 // VideoCodec.
2478 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002479 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002480
2481 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2482 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2483 config.simulcastStream[i].numberOfTemporalLayers);
2484 }
2485
2486 // Set expected temporal layers as they should have been set when
2487 // reconfiguring the encoder and not match the set config.
2488 VideoCodecVP9 encoder_settings = encoder_settings_;
2489 encoder_settings.numberOfTemporalLayers =
2490 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002491 EXPECT_EQ(
2492 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002493}
2494
kthelgason29a44e32016-09-27 03:52:02 -07002495template <>
2496rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2497VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2498 return new rtc::RefCountedObject<
2499 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2500}
2501
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002502TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002503 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002504 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002505}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002506
Peter Boström53eda3d2015-03-27 15:53:18 +01002507TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2508 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002509 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002510}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002511
Peter Boström53eda3d2015-03-27 15:53:18 +01002512TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2513 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002514 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002515}
2516
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002517TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002518 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002519 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002520 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2521 rtp_packets_sent_(0),
2522 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002523
2524 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002525 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002526 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002527 RTPHeader header;
2528 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002529 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002530 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2531 return SEND_PACKET;
2532 }
2533
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002534 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002535 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002536 test::RtcpPacketParser parser;
2537 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002538
danilchap3dc929e2016-11-02 08:21:59 -07002539 if (parser.sender_report()->num_packets() > 0) {
2540 // Only compare sent media bytes if SenderPacketCount matches the
2541 // number of sent rtp packets (a new rtp packet could be sent before
2542 // the rtcp packet).
2543 if (parser.sender_report()->sender_octet_count() > 0 &&
2544 parser.sender_report()->sender_packet_count() ==
2545 rtp_packets_sent_) {
2546 EXPECT_EQ(media_bytes_sent_,
2547 parser.sender_report()->sender_octet_count());
2548 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002549 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002550 }
2551
2552 return SEND_PACKET;
2553 }
2554
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002555 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002556 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002557 }
2558
stefan4b569042015-11-11 06:39:57 -08002559 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002560 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2561 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002562 } test;
2563
stefane74eef12016-01-08 06:47:13 -08002564 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002565}
2566
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002567TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2568 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002569
2570 class VideoStreamFactory
2571 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2572 public:
2573 VideoStreamFactory() {}
2574
2575 private:
2576 std::vector<VideoStream> CreateEncoderStreams(
2577 int width,
2578 int height,
2579 const VideoEncoderConfig& encoder_config) override {
2580 std::vector<VideoStream> streams =
2581 test::CreateVideoStreams(width, height, encoder_config);
2582 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2583 streams[0].temporal_layer_thresholds_bps.push_back(
2584 kScreencastTargetBitrateKbps * 1000);
2585 return streams;
2586 }
2587 };
2588
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002589 class ScreencastTargetBitrateTest : public test::SendTest,
2590 public test::FakeEncoder {
2591 public:
2592 ScreencastTargetBitrateTest()
2593 : SendTest(kDefaultTimeoutMs),
2594 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2595
2596 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002597 int32_t InitEncode(const VideoCodec* config,
2598 int32_t number_of_cores,
2599 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002600 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2601 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002602 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002603 return test::FakeEncoder::InitEncode(
2604 config, number_of_cores, max_payload_size);
2605 }
stefanff483612015-12-21 03:14:00 -08002606 void ModifyVideoConfigs(
2607 VideoSendStream::Config* send_config,
2608 std::vector<VideoReceiveStream::Config>* receive_configs,
2609 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002610 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002611 EXPECT_EQ(1u, encoder_config->number_of_streams);
2612 encoder_config->video_stream_factory =
2613 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002614 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002615 }
2616
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002617 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002618 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002619 << "Timed out while waiting for the encoder to be initialized.";
2620 }
2621 } test;
2622
stefane74eef12016-01-08 06:47:13 -08002623 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002624}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002625
philipelc6957c72016-04-28 15:52:49 +02002626TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002627 // These are chosen to be "kind of odd" to not be accidentally checked against
2628 // default values.
2629 static const int kMinBitrateKbps = 137;
2630 static const int kStartBitrateKbps = 345;
2631 static const int kLowerMaxBitrateKbps = 312;
2632 static const int kMaxBitrateKbps = 413;
2633 static const int kIncreasedStartBitrateKbps = 451;
2634 static const int kIncreasedMaxBitrateKbps = 597;
2635 class EncoderBitrateThresholdObserver : public test::SendTest,
2636 public test::FakeEncoder {
2637 public:
eladalon413ee9a2017-08-22 04:02:52 -07002638 explicit EncoderBitrateThresholdObserver(
2639 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002640 : SendTest(kDefaultTimeoutMs),
2641 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002642 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002643 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002644 bitrate_changed_event_(false, false),
2645 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002646 num_initializations_(0),
2647 call_(nullptr),
2648 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002649
2650 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002651 int32_t InitEncode(const VideoCodec* codecSettings,
2652 int32_t numberOfCores,
2653 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002654 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2655 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002656 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002657 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2658 codecSettings->minBitrate);
2659 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2660 codecSettings->startBitrate);
2661 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2662 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002663 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002664 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002665 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2666 codecSettings->maxBitrate);
2667 // The start bitrate should be kept (-1) and capped to the max bitrate.
2668 // Since this is not an end-to-end call no receiver should have been
2669 // returning a REMB that could lower this estimate.
2670 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002671 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002672 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2673 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002674 // The start bitrate will be whatever the rate BitRateController
2675 // has currently configured but in the span of the set max and min
2676 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002677 }
2678 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002679 init_encode_event_.Set();
2680
pbos@webrtc.org00873182014-11-25 14:03:34 +00002681 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2682 maxPayloadSize);
2683 }
2684
Erik Språng08127a92016-11-16 16:41:30 +01002685 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2686 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002687 {
2688 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002689 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2690 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002691 }
Erik Språng08127a92016-11-16 16:41:30 +01002692 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002693 }
2694 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002695 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002696 }
2697
2698 void WaitForSetRates(uint32_t expected_bitrate) {
2699 EXPECT_TRUE(
2700 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2701 << "Timed out while waiting encoder rate to be set.";
2702 rtc::CritScope lock(&crit_);
2703 EXPECT_EQ(expected_bitrate, target_bitrate_);
2704 }
2705
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002706 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002707 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002708 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2709 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2710 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002711 return config;
2712 }
2713
perkjfa10b552016-10-02 23:45:26 -07002714 class VideoStreamFactory
2715 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2716 public:
2717 explicit VideoStreamFactory(int min_bitrate_bps)
2718 : min_bitrate_bps_(min_bitrate_bps) {}
2719
2720 private:
2721 std::vector<VideoStream> CreateEncoderStreams(
2722 int width,
2723 int height,
2724 const VideoEncoderConfig& encoder_config) override {
2725 std::vector<VideoStream> streams =
2726 test::CreateVideoStreams(width, height, encoder_config);
2727 streams[0].min_bitrate_bps = min_bitrate_bps_;
2728 return streams;
2729 }
2730
2731 const int min_bitrate_bps_;
2732 };
2733
stefanff483612015-12-21 03:14:00 -08002734 void ModifyVideoConfigs(
2735 VideoSendStream::Config* send_config,
2736 std::vector<VideoReceiveStream::Config>* receive_configs,
2737 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002738 send_config->encoder_settings.encoder = this;
2739 // Set bitrates lower/higher than min/max to make sure they are properly
2740 // capped.
perkjfa10b552016-10-02 23:45:26 -07002741 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2742 // Create a new StreamFactory to be able to set
2743 // |VideoStream.min_bitrate_bps|.
2744 encoder_config->video_stream_factory =
2745 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002746 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002747 }
2748
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002749 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002750 call_ = sender_call;
2751 }
2752
stefanff483612015-12-21 03:14:00 -08002753 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002754 VideoSendStream* send_stream,
2755 const std::vector<VideoReceiveStream*>& receive_streams) override {
2756 send_stream_ = send_stream;
2757 }
2758
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002759 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002760 ASSERT_TRUE(
2761 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002762 << "Timed out while waiting for encoder to be configured.";
2763 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002764 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002765 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2766 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002767 task_queue_->SendTask([this, &bitrate_config]() {
2768 call_->SetBitrateConfig(bitrate_config);
2769 });
perkj26091b12016-09-01 01:17:40 -07002770 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2771 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002772 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002773 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002774 ASSERT_TRUE(
2775 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002776 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002777 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002778 WaitForSetRates(kLowerMaxBitrateKbps);
2779
2780 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2781 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2782 ASSERT_TRUE(
2783 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002784 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002785 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002786 // Expected target bitrate is the start bitrate set in the call to
2787 // call_->SetBitrateConfig.
2788 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002789 }
2790
eladalon413ee9a2017-08-22 04:02:52 -07002791 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002792 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002793 rtc::Event bitrate_changed_event_;
2794 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002795 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002796
pbos@webrtc.org00873182014-11-25 14:03:34 +00002797 int num_initializations_;
2798 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002799 webrtc::VideoSendStream* send_stream_;
2800 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002801 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002802
stefane74eef12016-01-08 06:47:13 -08002803 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002804}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002805
2806TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2807 static const size_t kNumStreams = 3;
2808 // Unusual resolutions to make sure that they are the ones being reported.
2809 static const struct {
2810 int width;
2811 int height;
2812 } kEncodedResolution[kNumStreams] = {
2813 {241, 181}, {300, 121}, {121, 221}};
2814 class ScreencastTargetBitrateTest : public test::SendTest,
2815 public test::FakeEncoder {
2816 public:
2817 ScreencastTargetBitrateTest()
2818 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002819 test::FakeEncoder(Clock::GetRealTimeClock()),
2820 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002821
2822 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002823 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002824 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002825 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002826 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002827 specifics.codecType = kVideoCodecGeneric;
2828
2829 uint8_t buffer[16] = {0};
2830 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2831 encoded._timeStamp = input_image.timestamp();
2832 encoded.capture_time_ms_ = input_image.render_time_ms();
2833
2834 for (size_t i = 0; i < kNumStreams; ++i) {
2835 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2836 encoded._frameType = (*frame_types)[i];
2837 encoded._encodedWidth = kEncodedResolution[i].width;
2838 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002839 EncodedImageCallback* callback;
2840 {
2841 rtc::CritScope cs(&crit_sect_);
2842 callback = callback_;
2843 }
2844 RTC_DCHECK(callback);
2845 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002846 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002847 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002848 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002849 }
2850
Peter Boström5811a392015-12-10 13:02:50 +01002851 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002852 return 0;
2853 }
stefanff483612015-12-21 03:14:00 -08002854 void ModifyVideoConfigs(
2855 VideoSendStream::Config* send_config,
2856 std::vector<VideoReceiveStream::Config>* receive_configs,
2857 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002858 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002859 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002860 }
2861
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002862 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002863
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002864 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002865 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002866 << "Timed out while waiting for the encoder to send one frame.";
2867 VideoSendStream::Stats stats = send_stream_->GetStats();
2868
2869 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002870 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002871 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002872 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002873 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002874 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002875 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002876 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2877 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002878 }
2879 }
2880
stefanff483612015-12-21 03:14:00 -08002881 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002882 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002883 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002884 send_stream_ = send_stream;
2885 }
2886
2887 VideoSendStream* send_stream_;
2888 } test;
2889
stefane74eef12016-01-08 06:47:13 -08002890 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002891}
philipel0f9af012015-09-01 07:01:51 -07002892
Peter Boström12996152016-05-14 02:03:18 +02002893#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002894class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002895 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002896 Vp9HeaderObserver()
2897 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002898 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002899 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2900 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002901 frames_sent_(0),
2902 expected_width_(0),
2903 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002904
stefanff483612015-12-21 03:14:00 -08002905 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002906 VideoSendStream::Config* send_config,
2907 std::vector<VideoReceiveStream::Config>* receive_configs,
2908 VideoEncoderConfig* encoder_config) {}
2909
Åsa Perssonff24c042015-12-04 10:58:08 +01002910 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002911
2912 private:
minyue20c84cc2017-04-10 16:57:57 -07002913 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002914
perkjfa10b552016-10-02 23:45:26 -07002915 class VideoStreamFactory
2916 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2917 public:
2918 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2919 : number_of_temporal_layers_(number_of_temporal_layers) {}
2920
2921 private:
2922 std::vector<VideoStream> CreateEncoderStreams(
2923 int width,
2924 int height,
2925 const VideoEncoderConfig& encoder_config) override {
2926 std::vector<VideoStream> streams =
2927 test::CreateVideoStreams(width, height, encoder_config);
2928 streams[0].temporal_layer_thresholds_bps.resize(
2929 number_of_temporal_layers_ - 1);
2930 return streams;
2931 }
2932
2933 const size_t number_of_temporal_layers_;
2934 };
2935
stefanff483612015-12-21 03:14:00 -08002936 void ModifyVideoConfigs(
2937 VideoSendStream::Config* send_config,
2938 std::vector<VideoReceiveStream::Config>* receive_configs,
2939 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002940 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002941 send_config->encoder_settings.payload_name = "VP9";
2942 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002943 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002944 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2945 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002946 EXPECT_EQ(1u, encoder_config->number_of_streams);
2947 encoder_config->video_stream_factory =
2948 new rtc::RefCountedObject<VideoStreamFactory>(
2949 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002950 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002951 }
2952
perkjfa10b552016-10-02 23:45:26 -07002953 void ModifyVideoCaptureStartResolution(int* width,
2954 int* height,
2955 int* frame_rate) override {
2956 expected_width_ = *width;
2957 expected_height_ = *height;
2958 }
2959
philipel0f9af012015-09-01 07:01:51 -07002960 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002961 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2962 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002963 }
2964
2965 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2966 RTPHeader header;
2967 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2968
Åsa Perssonff24c042015-12-04 10:58:08 +01002969 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2970 const uint8_t* payload = packet + header.headerLength;
2971 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002972
Åsa Perssonff24c042015-12-04 10:58:08 +01002973 bool new_packet = packets_sent_ == 0 ||
2974 IsNewerSequenceNumber(header.sequenceNumber,
2975 last_header_.sequenceNumber);
2976 if (payload_length > 0 && new_packet) {
2977 RtpDepacketizer::ParsedPayload parsed;
2978 RtpDepacketizerVp9 depacketizer;
2979 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2980 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2981 // Verify common fields for all configurations.
2982 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2983 CompareConsecutiveFrames(header, parsed.type.Video);
2984 // Verify configuration specific settings.
2985 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002986
Åsa Perssonff24c042015-12-04 10:58:08 +01002987 ++packets_sent_;
2988 if (header.markerBit) {
2989 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002990 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002991 last_header_ = header;
2992 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002993 }
philipel0f9af012015-09-01 07:01:51 -07002994 return SEND_PACKET;
2995 }
2996
philipel7fabd462015-09-03 04:42:32 -07002997 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002998 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2999 if (last_vp9_.picture_id > vp9.picture_id) {
3000 return vp9.picture_id == 0; // Wrap.
3001 } else {
3002 return vp9.picture_id == last_vp9_.picture_id + 1;
3003 }
3004 }
3005
3006 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003007 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3008 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3009 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3010 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3011 vp9.spatial_idx);
3012 }
3013
3014 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3015 uint8_t num_layers) const {
3016 switch (num_layers) {
3017 case 0:
3018 VerifyTemporalLayerStructure0(vp9);
3019 break;
3020 case 1:
3021 VerifyTemporalLayerStructure1(vp9);
3022 break;
3023 case 2:
3024 VerifyTemporalLayerStructure2(vp9);
3025 break;
3026 case 3:
3027 VerifyTemporalLayerStructure3(vp9);
3028 break;
3029 default:
3030 RTC_NOTREACHED();
3031 }
3032 }
3033
3034 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3035 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3036 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3037 EXPECT_FALSE(vp9.temporal_up_switch);
3038 }
3039
3040 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3041 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3042 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3043 EXPECT_FALSE(vp9.temporal_up_switch);
3044 }
3045
3046 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3047 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3048 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3049 EXPECT_LE(vp9.temporal_idx, 1);
3050 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3051 if (IsNewPictureId(vp9)) {
3052 uint8_t expected_tid =
3053 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3054 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3055 }
3056 }
3057
3058 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3059 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3060 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3061 EXPECT_LE(vp9.temporal_idx, 2);
3062 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3063 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3064 switch (vp9.temporal_idx) {
3065 case 0:
3066 EXPECT_EQ(2, last_vp9_.temporal_idx);
3067 EXPECT_FALSE(vp9.temporal_up_switch);
3068 break;
3069 case 1:
3070 EXPECT_EQ(2, last_vp9_.temporal_idx);
3071 EXPECT_TRUE(vp9.temporal_up_switch);
3072 break;
3073 case 2:
3074 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3075 break;
3076 }
3077 }
3078 }
3079
3080 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3081 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3082 return;
3083
3084 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3085 if (vp9.temporal_idx == 0)
3086 ++expected_tl0_idx;
3087 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3088 }
3089
3090 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3091 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3092 }
3093
3094 // Flexible mode (F=1): Non-flexible mode (F=0):
3095 //
3096 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3097 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3098 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3099 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3100 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3101 // M: | EXTENDED PID | M: | EXTENDED PID |
3102 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3103 // L: | T |U| S |D| L: | T |U| S |D|
3104 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3105 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3106 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3107 // X: |EXTENDED P_DIFF| V: | SS .. |
3108 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3109 // V: | SS .. |
3110 // +-+-+-+-+-+-+-+-+
3111 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3112 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3113 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3114 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
3115 EXPECT_GE(vp9.spatial_idx, 0); // S
3116 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3117 if (vp9.ss_data_available) // V
3118 VerifySsData(vp9);
3119
3120 if (frames_sent_ == 0)
3121 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3122
3123 if (!vp9.inter_pic_predicted) {
3124 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3125 EXPECT_FALSE(vp9.temporal_up_switch);
3126 }
3127 }
3128
3129 // Scalability structure (SS).
3130 //
3131 // +-+-+-+-+-+-+-+-+
3132 // V: | N_S |Y|G|-|-|-|
3133 // +-+-+-+-+-+-+-+-+
3134 // Y: | WIDTH | N_S + 1 times
3135 // +-+-+-+-+-+-+-+-+
3136 // | HEIGHT |
3137 // +-+-+-+-+-+-+-+-+
3138 // G: | N_G |
3139 // +-+-+-+-+-+-+-+-+
3140 // N_G: | T |U| R |-|-| N_G times
3141 // +-+-+-+-+-+-+-+-+
3142 // | P_DIFF | R times
3143 // +-+-+-+-+-+-+-+-+
3144 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3145 EXPECT_TRUE(vp9.ss_data_available); // V
3146 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3147 vp9.num_spatial_layers);
3148 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003149 int expected_width = expected_width_;
3150 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003151 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003152 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3153 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3154 expected_width /= 2;
3155 expected_height /= 2;
3156 }
3157 }
3158
3159 void CompareConsecutiveFrames(const RTPHeader& header,
3160 const RTPVideoHeader& video) const {
3161 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3162
3163 bool new_frame = packets_sent_ == 0 ||
3164 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003165 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003166 if (!new_frame) {
3167 EXPECT_FALSE(last_header_.markerBit);
3168 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3169 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3170 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3171 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3172 VerifySpatialIdxWithinFrame(vp9);
3173 return;
3174 }
3175 // New frame.
3176 EXPECT_TRUE(vp9.beginning_of_frame);
3177
3178 // Compare with last packet in previous frame.
3179 if (frames_sent_ == 0)
3180 return;
3181 EXPECT_TRUE(last_vp9_.end_of_frame);
3182 EXPECT_TRUE(last_header_.markerBit);
3183 EXPECT_TRUE(ContinuousPictureId(vp9));
3184 VerifyTl0Idx(vp9);
3185 }
3186
kwiberg27f982b2016-03-01 11:52:33 -08003187 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003188 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003189 webrtc::VideoEncoderConfig encoder_config_;
3190 RTPHeader last_header_;
3191 RTPVideoHeaderVP9 last_vp9_;
3192 size_t packets_sent_;
3193 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003194 int expected_width_;
3195 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003196};
3197
Åsa Perssonff24c042015-12-04 10:58:08 +01003198TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3199 const uint8_t kNumTemporalLayers = 1;
3200 const uint8_t kNumSpatialLayers = 1;
3201 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3202}
3203
3204TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3205 const uint8_t kNumTemporalLayers = 2;
3206 const uint8_t kNumSpatialLayers = 1;
3207 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3208}
3209
3210TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3211 const uint8_t kNumTemporalLayers = 3;
3212 const uint8_t kNumSpatialLayers = 1;
3213 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3214}
3215
3216TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3217 const uint8_t kNumTemporalLayers = 1;
3218 const uint8_t kNumSpatialLayers = 2;
3219 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3220}
3221
3222TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3223 const uint8_t kNumTemporalLayers = 2;
3224 const uint8_t kNumSpatialLayers = 2;
3225 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3226}
3227
3228TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3229 const uint8_t kNumTemporalLayers = 3;
3230 const uint8_t kNumSpatialLayers = 2;
3231 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3232}
3233
3234void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3235 uint8_t num_spatial_layers) {
3236 static const size_t kNumFramesToSend = 100;
3237 // Set to < kNumFramesToSend and coprime to length of temporal layer
3238 // structures to verify temporal id reset on key frame.
3239 static const int kKeyFrameInterval = 31;
3240 class NonFlexibleMode : public Vp9HeaderObserver {
3241 public:
3242 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3243 : num_temporal_layers_(num_temporal_layers),
3244 num_spatial_layers_(num_spatial_layers),
3245 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003246 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003247 VideoSendStream::Config* send_config,
3248 std::vector<VideoReceiveStream::Config>* receive_configs,
3249 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003250 vp9_settings_.flexibleMode = false;
3251 vp9_settings_.frameDroppingOn = false;
3252 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3253 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3254 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003255 }
3256
Åsa Perssonff24c042015-12-04 10:58:08 +01003257 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
3258 bool ss_data_expected = !vp9.inter_pic_predicted &&
3259 vp9.beginning_of_frame && vp9.spatial_idx == 0;
3260 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
3261 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08003262 EXPECT_EQ(!vp9.inter_pic_predicted,
3263 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003264
3265 if (IsNewPictureId(vp9)) {
3266 EXPECT_EQ(0, vp9.spatial_idx);
3267 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
3268 }
3269
3270 VerifyFixedTemporalLayerStructure(vp9,
3271 l_field_ ? num_temporal_layers_ : 0);
3272
3273 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003274 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003275 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003276 const uint8_t num_temporal_layers_;
3277 const uint8_t num_spatial_layers_;
3278 const bool l_field_;
3279 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003280
stefane74eef12016-01-08 06:47:13 -08003281 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003282}
3283
asaperssond9f641e2016-01-21 01:11:35 -08003284TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3285 static const size_t kNumFramesToSend = 50;
3286 static const int kWidth = 4;
3287 static const int kHeight = 4;
3288 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3289 void ModifyVideoConfigsHook(
3290 VideoSendStream::Config* send_config,
3291 std::vector<VideoReceiveStream::Config>* receive_configs,
3292 VideoEncoderConfig* encoder_config) override {
3293 vp9_settings_.flexibleMode = false;
3294 vp9_settings_.numberOfTemporalLayers = 1;
3295 vp9_settings_.numberOfSpatialLayers = 1;
3296
perkjfa10b552016-10-02 23:45:26 -07003297 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003298 }
3299
3300 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3301 if (frames_sent_ > kNumFramesToSend)
3302 observation_complete_.Set();
3303 }
perkjfa10b552016-10-02 23:45:26 -07003304
3305 void ModifyVideoCaptureStartResolution(int* width,
3306 int* height,
3307 int* frame_rate) override {
3308 expected_width_ = kWidth;
3309 expected_height_ = kHeight;
3310 *width = kWidth;
3311 *height = kHeight;
3312 }
asaperssond9f641e2016-01-21 01:11:35 -08003313 } test;
3314
3315 RunBaseTest(&test);
3316}
3317
kjellanderf9e2a362017-03-24 12:17:33 -07003318#if defined(WEBRTC_ANDROID)
3319// Crashes on Android; bugs.webrtc.org/7401
3320#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3321#else
3322#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3323#endif
3324TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003325 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003326 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003327 VideoSendStream::Config* send_config,
3328 std::vector<VideoReceiveStream::Config>* receive_configs,
3329 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003330 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003331 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003332 vp9_settings_.numberOfTemporalLayers = 1;
3333 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003334 }
3335
Åsa Perssonff24c042015-12-04 10:58:08 +01003336 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3337 EXPECT_TRUE(vp9_header.flexible_mode);
3338 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3339 if (vp9_header.inter_pic_predicted) {
3340 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003341 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003342 }
3343 }
3344 } test;
3345
stefane74eef12016-01-08 06:47:13 -08003346 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003347}
Peter Boström12996152016-05-14 02:03:18 +02003348#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003349
perkj803d97f2016-11-01 11:45:46 -07003350void VideoSendStreamTest::TestRequestSourceRotateVideo(
3351 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003352 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003353
3354 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003355 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003356 video_send_config_.rtp.extensions.clear();
3357 if (support_orientation_ext) {
3358 video_send_config_.rtp.extensions.push_back(
3359 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3360 }
3361
3362 CreateVideoStreams();
3363 test::FrameForwarder forwarder;
3364 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003365 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003366
3367 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3368 support_orientation_ext);
3369
3370 DestroyStreams();
3371}
3372
3373TEST_F(VideoSendStreamTest,
3374 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3375 TestRequestSourceRotateVideo(false);
3376}
3377
3378TEST_F(VideoSendStreamTest,
3379 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3380 TestRequestSourceRotateVideo(true);
3381}
3382
michaelta3328772016-11-29 09:25:03 -08003383// This test verifies that overhead is removed from the bandwidth estimate by
3384// testing that the maximum possible target payload rate is smaller than the
3385// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003386TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003387 test::ScopedFieldTrials override_field_trials(
3388 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3389 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3390 public test::FakeEncoder {
3391 public:
eladalon413ee9a2017-08-22 04:02:52 -07003392 explicit RemoveOverheadFromBandwidthTest(
3393 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003394 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3395 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003396 task_queue_(task_queue),
michaelta3328772016-11-29 09:25:03 -08003397 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003398 max_bitrate_bps_(0),
3399 first_packet_sent_(false),
3400 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003401
3402 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3403 uint32_t frameRate) override {
3404 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003405 // Wait for the first sent packet so that videosendstream knows
3406 // rtp_overhead.
3407 if (first_packet_sent_) {
3408 max_bitrate_bps_ = bitrate.get_sum_bps();
3409 bitrate_changed_event_.Set();
3410 }
michaelta3328772016-11-29 09:25:03 -08003411 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3412 }
3413
3414 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3415 call_ = sender_call;
3416 }
3417
3418 void ModifyVideoConfigs(
3419 VideoSendStream::Config* send_config,
3420 std::vector<VideoReceiveStream::Config>* receive_configs,
3421 VideoEncoderConfig* encoder_config) override {
3422 send_config->rtp.max_packet_size = 1200;
3423 send_config->encoder_settings.encoder = this;
3424 EXPECT_FALSE(send_config->rtp.extensions.empty());
3425 }
3426
michaelt192132e2017-01-26 09:05:27 -08003427 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3428 rtc::CritScope lock(&crit_);
3429 first_packet_sent_ = true;
3430 return SEND_PACKET;
3431 }
3432
michaelta3328772016-11-29 09:25:03 -08003433 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003434 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003435 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003436 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003437 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003438 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3439 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003440 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003441 task_queue_->SendTask([this, &bitrate_config]() {
3442 call_->SetBitrateConfig(bitrate_config);
3443 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3444 });
michaelta3328772016-11-29 09:25:03 -08003445
3446 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003447 // overhead of 40B per packet video produces 2240bps overhead.
3448 // So the encoder BW should be set to 57760bps.
3449 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003450 {
3451 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003452 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003453 }
3454 }
3455
3456 private:
eladalon413ee9a2017-08-22 04:02:52 -07003457 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelta3328772016-11-29 09:25:03 -08003458 Call* call_;
3459 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003460 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3461 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003462 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003463 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003464 RunBaseTest(&test);
3465}
3466
sprang168794c2017-07-06 04:38:06 -07003467TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3468 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003469
3470 class KeepaliveObserver : public test::SendTest {
3471 public:
3472 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3473
sprangdb2a9fc2017-08-09 06:42:32 -07003474 void OnRtpTransportControllerSendCreated(
3475 RtpTransportControllerSend* controller) override {
3476 RtpKeepAliveConfig config;
3477 config.timeout_interval_ms = kTimeoutMs;
3478 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3479 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003480 }
3481
sprang168794c2017-07-06 04:38:06 -07003482 private:
3483 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3484 RTPHeader header;
3485 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3486
sprangd2702ef2017-07-10 08:41:10 -07003487 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003488 // The video stream has started. Stop it now.
3489 if (capturer_)
3490 capturer_->Stop();
3491 } else {
3492 observation_complete_.Set();
3493 }
3494
3495 return SEND_PACKET;
3496 }
3497
sprang168794c2017-07-06 04:38:06 -07003498 void PerformTest() override {
3499 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3500 }
3501
3502 void OnFrameGeneratorCapturerCreated(
3503 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3504 capturer_ = frame_generator_capturer;
3505 }
3506
3507 test::FrameGeneratorCapturer* capturer_ = nullptr;
3508 } test;
3509
3510 RunBaseTest(&test);
3511}
3512
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003513} // namespace webrtc