blob: 890413f177ce969150e5d1cdc17e63e209e3e43c [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"
pbosa96b60b2016-04-18 21:12:48 -070015#include "webrtc/common_video/include/frame_callback.h"
nisseea3a7982017-05-15 02:42:11 -070016#include "webrtc/common_video/include/video_frame.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010017#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
18#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000019#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
philipel0f9af012015-09-01 07:01:51 -070020#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h"
magjed509e4fe2016-11-18 01:34:11 -080021#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
philipel7fabd462015-09-03 04:42:32 -070022#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020023#include "webrtc/rtc_base/bind.h"
24#include "webrtc/rtc_base/checks.h"
25#include "webrtc/rtc_base/criticalsection.h"
26#include "webrtc/rtc_base/event.h"
27#include "webrtc/rtc_base/logging.h"
28#include "webrtc/rtc_base/platform_thread.h"
29#include "webrtc/rtc_base/rate_limiter.h"
30#include "webrtc/rtc_base/timeutils.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010031#include "webrtc/system_wrappers/include/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000032#include "webrtc/test/call_test.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000033#include "webrtc/test/configurable_frame_size_encoder.h"
Peter Boströmeb66e802015-06-05 11:08:03 +020034#include "webrtc/test/fake_texture_frame.h"
sprang168794c2017-07-06 04:38:06 -070035#include "webrtc/test/field_trial.h"
perkja49cbd32016-09-16 07:53:41 -070036#include "webrtc/test/frame_generator.h"
sprang168794c2017-07-06 04:38:06 -070037#include "webrtc/test/frame_generator_capturer.h"
nisse26acec42016-04-15 03:43:39 -070038#include "webrtc/test/frame_utils.h"
kwibergac9f8762016-09-30 22:29:43 -070039#include "webrtc/test/gtest.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000040#include "webrtc/test/null_transport.h"
danilchap3dc929e2016-11-02 08:21:59 -070041#include "webrtc/test/rtcp_packet_parser.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000042#include "webrtc/test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070043
pbos@webrtc.org273a4142014-12-01 15:23:21 +000044#include "webrtc/video/send_statistics_proxy.h"
charujainbf6a45b2016-11-03 04:21:42 -070045#include "webrtc/video/transport_adapter.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000046#include "webrtc/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000047
48namespace webrtc {
49
sprang@webrtc.org346094c2014-02-18 08:40:33 +000050enum VideoFormat { kGeneric, kVP8, };
51
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070052void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
53 const std::vector<VideoFrame>& frames2);
54VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000055
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000056class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000057 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000058 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000059 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000060 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010061
62 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
63 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070064
65 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000066};
67
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000068TEST_F(VideoSendStreamTest, CanStartStartedStream) {
philipel4fb651d2017-04-10 03:54:05 -070069 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000070
solenberg4fbae2b2015-08-28 04:07:10 -070071 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -080072 CreateSendConfig(1, 0, 0, &transport);
Stefan Holmer9fea80f2016-01-07 17:43:18 +010073 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080074 video_send_stream_->Start();
75 video_send_stream_->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000076 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000077}
78
79TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
philipel4fb651d2017-04-10 03:54:05 -070080 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000081
solenberg4fbae2b2015-08-28 04:07:10 -070082 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -080083 CreateSendConfig(1, 0, 0, &transport);
Stefan Holmer9fea80f2016-01-07 17:43:18 +010084 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080085 video_send_stream_->Stop();
86 video_send_stream_->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000087 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000088}
89
pbos@webrtc.org013d9942013-08-22 09:42:17 +000090TEST_F(VideoSendStreamTest, SupportsCName) {
91 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000092 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000093 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000094 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +000095
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000096 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000097 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -070098 test::RtcpPacketParser parser;
99 EXPECT_TRUE(parser.Parse(packet, length));
100 if (parser.sdes()->num_packets() > 0) {
101 EXPECT_EQ(1u, parser.sdes()->chunks().size());
102 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000103
danilchap3dc929e2016-11-02 08:21:59 -0700104 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000105 }
106
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000107 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000108 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000109
stefanff483612015-12-21 03:14:00 -0800110 void ModifyVideoConfigs(
111 VideoSendStream::Config* send_config,
112 std::vector<VideoReceiveStream::Config>* receive_configs,
113 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000114 send_config->rtp.c_name = kCName;
115 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000116
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000117 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100118 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000119 }
120 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000121
stefane74eef12016-01-08 06:47:13 -0800122 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000123}
124
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000125TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000127 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000128 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000129 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100130 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000131 }
132
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000133 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000134 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000135 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000136
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000137 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
138 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
139 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700140 if (header.extension.absoluteSendTime != 0) {
141 // Wait for at least one packet with a non-zero send time. The send time
142 // is a 16-bit value derived from the system clock, and it is valid
143 // for a packet to have a zero send time. To tell that from an
144 // unpopulated value we'll wait for a packet with non-zero send time.
145 observation_complete_.Set();
146 } else {
147 LOG(LS_WARNING) << "Got a packet with zero absoluteSendTime, waiting"
148 " for another packet...";
149 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000150
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000151 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000152 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000153
stefanff483612015-12-21 03:14:00 -0800154 void ModifyVideoConfigs(
155 VideoSendStream::Config* send_config,
156 std::vector<VideoReceiveStream::Config>* receive_configs,
157 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200158 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100159 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700160 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000161 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000162
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000163 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100164 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000165 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000166 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000167
stefane74eef12016-01-08 06:47:13 -0800168 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000169}
170
pbos@webrtc.org29023282013-09-11 10:14:56 +0000171TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000172 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000174 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000175 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000176 : SendTest(kDefaultTimeoutMs),
177 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000178 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100179 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000180 }
181
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000182 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000183 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000184 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000185 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000186
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000187 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
188 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000189 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000190 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100191 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000192
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000193 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000194 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000195
stefanff483612015-12-21 03:14:00 -0800196 void ModifyVideoConfigs(
197 VideoSendStream::Config* send_config,
198 std::vector<VideoReceiveStream::Config>* receive_configs,
199 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000200 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100201 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700202 send_config->rtp.extensions.push_back(RtpExtension(
203 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000204 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000205
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000206 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100207 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000208 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000209
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000210 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000211 } test;
212
stefane74eef12016-01-08 06:47:13 -0800213 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000214}
215
sprang867fb522015-08-03 04:38:41 -0700216TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700217 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700218 class TransportWideSequenceNumberObserver : public test::SendTest {
219 public:
220 TransportWideSequenceNumberObserver()
221 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
222 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
223 kRtpExtensionTransportSequenceNumber, kExtensionId));
224 }
225
226 private:
227 Action OnSendRtp(const uint8_t* packet, size_t length) override {
228 RTPHeader header;
229 EXPECT_TRUE(parser_->Parse(packet, length, &header));
230
231 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
232 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
233 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
234
Peter Boström5811a392015-12-10 13:02:50 +0100235 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700236
237 return SEND_PACKET;
238 }
239
stefanff483612015-12-21 03:14:00 -0800240 void ModifyVideoConfigs(
241 VideoSendStream::Config* send_config,
242 std::vector<VideoReceiveStream::Config>* receive_configs,
243 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700244 send_config->encoder_settings.encoder = &encoder_;
sprang867fb522015-08-03 04:38:41 -0700245 }
246
247 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100248 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700249 }
250
251 test::FakeEncoder encoder_;
252 } test;
253
stefane74eef12016-01-08 06:47:13 -0800254 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700255}
256
perkj803d97f2016-11-01 11:45:46 -0700257TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
258 class VideoRotationObserver : public test::SendTest {
259 public:
260 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
261 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
262 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
263 }
264
265 Action OnSendRtp(const uint8_t* packet, size_t length) override {
266 RTPHeader header;
267 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700268 // Only the last packet of the frame is required to have the extension.
269 if (!header.markerBit)
270 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700271 EXPECT_TRUE(header.extension.hasVideoRotation);
272 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
273 observation_complete_.Set();
274 return SEND_PACKET;
275 }
276
277 void ModifyVideoConfigs(
278 VideoSendStream::Config* send_config,
279 std::vector<VideoReceiveStream::Config>* receive_configs,
280 VideoEncoderConfig* encoder_config) override {
281 send_config->rtp.extensions.clear();
282 send_config->rtp.extensions.push_back(RtpExtension(
283 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
284 }
285
286 void OnFrameGeneratorCapturerCreated(
287 test::FrameGeneratorCapturer* frame_generator_capturer) override {
288 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
289 }
290
291 void PerformTest() override {
292 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
293 }
294 } test;
295
296 RunBaseTest(&test);
297}
298
ilnik00d802b2017-04-11 10:34:31 -0700299TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700300 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700301 public:
ilnik10894992017-06-21 08:23:19 -0700302 VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
ilnik00d802b2017-04-11 10:34:31 -0700303 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
304 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
305 }
306
307 Action OnSendRtp(const uint8_t* packet, size_t length) override {
308 RTPHeader header;
309 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700310 // Only the last packet of the frame must have extension.
311 if (!header.markerBit)
312 return SEND_PACKET;
ilnik00d802b2017-04-11 10:34:31 -0700313 EXPECT_TRUE(header.extension.hasVideoContentType);
314 EXPECT_EQ(VideoContentType::SCREENSHARE,
315 header.extension.videoContentType);
316 observation_complete_.Set();
317 return SEND_PACKET;
318 }
319
320 void ModifyVideoConfigs(
321 VideoSendStream::Config* send_config,
322 std::vector<VideoReceiveStream::Config>* receive_configs,
323 VideoEncoderConfig* encoder_config) override {
324 send_config->rtp.extensions.clear();
325 send_config->rtp.extensions.push_back(
326 RtpExtension(RtpExtension::kVideoContentTypeUri,
327 test::kVideoContentTypeExtensionId));
328 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
329 }
330
331 void PerformTest() override {
332 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
333 }
334 } test;
335
ilnikcf705c52017-06-08 06:18:53 -0700336 test::ScopedFieldTrials override_field_trials(
337 "WebRTC-VideoContentTypeExtension/Enabled/");
ilnik00d802b2017-04-11 10:34:31 -0700338 RunBaseTest(&test);
339}
340
ilnik04f4d122017-06-19 07:18:55 -0700341TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700342 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700343 public:
ilnik10894992017-06-21 08:23:19 -0700344 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700345 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
346 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
347 }
348
349 Action OnSendRtp(const uint8_t* packet, size_t length) override {
350 RTPHeader header;
351 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700352 // Only the last packet of the frame must have extension.
353 if (!header.markerBit)
354 return SEND_PACKET;
355 EXPECT_TRUE(header.extension.has_video_timing);
356 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700357 return SEND_PACKET;
358 }
359
360 void ModifyVideoConfigs(
361 VideoSendStream::Config* send_config,
362 std::vector<VideoReceiveStream::Config>* receive_configs,
363 VideoEncoderConfig* encoder_config) override {
364 send_config->rtp.extensions.clear();
365 send_config->rtp.extensions.push_back(RtpExtension(
366 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
367 }
368
369 void PerformTest() override {
370 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
371 }
372 } test;
373
374 RunBaseTest(&test);
375}
376
danilchap901b2df2017-07-28 08:56:04 -0700377class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000378 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000379 FakeReceiveStatistics(uint32_t send_ssrc,
380 uint32_t last_sequence_number,
381 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700382 uint8_t fraction_lost) {
383 stat_.SetMediaSsrc(send_ssrc);
384 stat_.SetExtHighestSeqNum(last_sequence_number);
385 stat_.SetCumulativeLost(cumulative_lost);
386 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000387 }
388
danilchap901b2df2017-07-28 08:56:04 -0700389 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
390 EXPECT_GE(max_blocks, 1u);
391 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000392 }
393
394 private:
danilchap901b2df2017-07-28 08:56:04 -0700395 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000396};
397
brandtre602f0a2016-10-31 03:40:49 -0700398class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100399 public:
brandtre602f0a2016-10-31 03:40:49 -0700400 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800401 bool use_nack,
402 bool expect_red,
403 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800404 const std::string& codec,
405 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800406 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800407 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100408 payload_name_(codec),
409 use_nack_(use_nack),
410 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700411 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800412 sent_media_(false),
413 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800414 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100415
brandtr20d45472017-01-02 00:34:27 -0800416 // Some of the test cases are expected to time out and thus we are using
417 // a shorter timeout window than the default here.
418 static constexpr size_t kTimeoutMs = 10000;
419
Stefan Holmer4654d202015-12-08 09:10:43 +0100420 private:
421 Action OnSendRtp(const uint8_t* packet, size_t length) override {
422 RTPHeader header;
423 EXPECT_TRUE(parser_->Parse(packet, length, &header));
424
Stefan Holmer4654d202015-12-08 09:10:43 +0100425 int encapsulated_payload_type = -1;
426 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100427 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100428 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
429 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100430 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100431 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
432 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100433 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100434 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100435 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
436 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100437 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
438 length) {
439 // Not padding-only, media received outside of RED.
440 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800441 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100442 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100443 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000444
Stefan Holmer4654d202015-12-08 09:10:43 +0100445 if (header_extensions_enabled_) {
446 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
447 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
448 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
449 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
450 // 24 bits wrap.
451 EXPECT_GT(prev_header_.extension.absoluteSendTime,
452 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000453 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100454 EXPECT_GE(header.extension.absoluteSendTime,
455 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200456 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100457 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
458 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
459 prev_header_.extension.transportSequenceNumber;
460 EXPECT_EQ(1, seq_num_diff);
461 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200462
Stefan Holmer4654d202015-12-08 09:10:43 +0100463 if (encapsulated_payload_type != -1) {
464 if (encapsulated_payload_type ==
465 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700466 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800467 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100468 } else {
brandtr65a1e772016-12-12 01:54:58 -0800469 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000470 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000471 }
472
brandtr20d45472017-01-02 00:34:27 -0800473 if (sent_media_ && sent_ulpfec_) {
474 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100475 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000476
Stefan Holmer4654d202015-12-08 09:10:43 +0100477 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000478
Stefan Holmer4654d202015-12-08 09:10:43 +0100479 return SEND_PACKET;
480 }
481
Peter Boström39593972016-02-15 11:27:15 +0100482 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
483 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
484 // Configure some network delay.
485 const int kNetworkDelayMs = 100;
486 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800487 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100488 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700489 return new test::PacketTransport(
490 sender_call, this, test::PacketTransport::kSender,
491 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100492 }
493
stefanff483612015-12-21 03:14:00 -0800494 void ModifyVideoConfigs(
495 VideoSendStream::Config* send_config,
496 std::vector<VideoReceiveStream::Config>* receive_configs,
497 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100498 if (use_nack_) {
499 send_config->rtp.nack.rtp_history_ms =
500 (*receive_configs)[0].rtp.nack.rtp_history_ms =
501 VideoSendStreamTest::kNackRtpHistoryMs;
502 }
brandtr696c9c62016-12-19 05:47:28 -0800503 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100504 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700505 send_config->rtp.ulpfec.red_payload_type =
506 VideoSendStreamTest::kRedPayloadType;
507 send_config->rtp.ulpfec.ulpfec_payload_type =
508 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800509 EXPECT_FALSE(send_config->rtp.extensions.empty());
510 if (!header_extensions_enabled_) {
511 send_config->rtp.extensions.clear();
512 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100513 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700514 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100515 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700516 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
517 send_config->rtp.ulpfec.red_payload_type;
518 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
519 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100520 }
521
522 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800523 EXPECT_EQ(expect_ulpfec_, Wait())
524 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100525 }
526
brandtr696c9c62016-12-19 05:47:28 -0800527 VideoEncoder* const encoder_;
528 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100529 const bool use_nack_;
530 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700531 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800532 bool sent_media_;
533 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100534 bool header_extensions_enabled_;
535 RTPHeader prev_header_;
536};
537
brandtre602f0a2016-10-31 03:40:49 -0700538TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800539 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
540 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800541 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100542}
543
brandtre602f0a2016-10-31 03:40:49 -0700544TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800545 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
546 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100547 RunBaseTest(&test);
548}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000549
Peter Boström39593972016-02-15 11:27:15 +0100550// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
551// since we'll still have to re-request FEC packets, effectively wasting
552// bandwidth since the receiver has to wait for FEC retransmissions to determine
553// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700554TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800555 std::unique_ptr<VideoEncoder> encoder(
556 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
557 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100558 RunBaseTest(&test);
559}
560
561// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800562TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800563 std::unique_ptr<VideoEncoder> encoder(
564 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
565 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100566 RunBaseTest(&test);
567}
568
danilchap9f5b6222017-03-02 06:22:21 -0800569// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
570TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800571 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
572 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100573 RunBaseTest(&test);
574}
575
Peter Boström12996152016-05-14 02:03:18 +0200576#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800577// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
578TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800579 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
580 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800581 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000582}
Peter Boström12996152016-05-14 02:03:18 +0200583#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000584
brandtre78d2662017-01-16 05:57:16 -0800585TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800586 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800587 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800588 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
589 RunBaseTest(&test);
590}
591
brandtr39f97292016-11-16 22:57:50 -0800592// TODO(brandtr): Move these FlexFEC tests when we have created
593// FlexfecSendStream.
594class FlexfecObserver : public test::EndToEndTest {
595 public:
596 FlexfecObserver(bool header_extensions_enabled,
597 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800598 const std::string& codec,
599 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800600 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800601 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800602 payload_name_(codec),
603 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800604 sent_media_(false),
605 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800606 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800607
608 size_t GetNumFlexfecStreams() const override { return 1; }
609
610 private:
611 Action OnSendRtp(const uint8_t* packet, size_t length) override {
612 RTPHeader header;
613 EXPECT_TRUE(parser_->Parse(packet, length, &header));
614
brandtr39f97292016-11-16 22:57:50 -0800615 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
616 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
617 sent_flexfec_ = true;
618 } else {
619 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
620 header.payloadType);
621 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
622 sent_media_ = true;
623 }
624
625 if (header_extensions_enabled_) {
626 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
627 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
628 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
629 }
630
brandtr0c5a1542016-11-23 04:42:26 -0800631 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800632 observation_complete_.Set();
633 }
634
635 return SEND_PACKET;
636 }
637
638 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
639 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
640 // Therefore we need some network delay.
641 const int kNetworkDelayMs = 100;
642 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800643 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800644 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700645 return new test::PacketTransport(
646 sender_call, this, test::PacketTransport::kSender,
647 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800648 }
649
650 void ModifyVideoConfigs(
651 VideoSendStream::Config* send_config,
652 std::vector<VideoReceiveStream::Config>* receive_configs,
653 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800654 if (use_nack_) {
655 send_config->rtp.nack.rtp_history_ms =
656 (*receive_configs)[0].rtp.nack.rtp_history_ms =
657 VideoSendStreamTest::kNackRtpHistoryMs;
658 }
brandtr696c9c62016-12-19 05:47:28 -0800659 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800660 send_config->encoder_settings.payload_name = payload_name_;
661 if (header_extensions_enabled_) {
662 send_config->rtp.extensions.push_back(RtpExtension(
663 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
664 send_config->rtp.extensions.push_back(RtpExtension(
665 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800666 } else {
667 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800668 }
669 }
670
671 void PerformTest() override {
672 EXPECT_TRUE(Wait())
673 << "Timed out waiting for FlexFEC and/or media packets.";
674 }
675
brandtr696c9c62016-12-19 05:47:28 -0800676 VideoEncoder* const encoder_;
677 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800678 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800679 bool sent_media_;
680 bool sent_flexfec_;
681 bool header_extensions_enabled_;
682};
683
brandtrd654a9b2016-12-05 05:38:19 -0800684TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800685 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
686 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800687 RunBaseTest(&test);
688}
689
690TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800691 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
692 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800693 RunBaseTest(&test);
694}
695
brandtr39f97292016-11-16 22:57:50 -0800696TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800697 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
698 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800699 RunBaseTest(&test);
700}
701
brandtr39f97292016-11-16 22:57:50 -0800702#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800703TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800704 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
705 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800706 RunBaseTest(&test);
707}
708
brandtrd654a9b2016-12-05 05:38:19 -0800709TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800710 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
711 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800712 RunBaseTest(&test);
713}
714#endif // defined(RTC_DISABLE_VP9)
715
brandtrd654a9b2016-12-05 05:38:19 -0800716TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800717 std::unique_ptr<VideoEncoder> encoder(
718 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
719 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800720 RunBaseTest(&test);
721}
722
brandtrd654a9b2016-12-05 05:38:19 -0800723TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800724 std::unique_ptr<VideoEncoder> encoder(
725 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
726 FlexfecObserver test(false, true, "H264", encoder.get());
727 RunBaseTest(&test);
728}
729
brandtre78d2662017-01-16 05:57:16 -0800730TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800731 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800732 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800733 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800734 RunBaseTest(&test);
735}
736
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000737void VideoSendStreamTest::TestNackRetransmission(
738 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000739 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000740 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000741 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000742 explicit NackObserver(uint32_t retransmit_ssrc,
743 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000744 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000745 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000746 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000747 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000748 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000749 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000750
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000751 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000752 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000753 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000754 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000755
756 // Nack second packet after receiving the third one.
757 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000758 uint16_t nack_sequence_number = header.sequenceNumber - 1;
759 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000760 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200761 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800762 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000763
pbosda903ea2015-10-02 02:36:56 -0700764 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100765 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000766
767 RTCPSender::FeedbackState feedback_state;
768
769 EXPECT_EQ(0,
770 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000771 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000772 }
773
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000774 uint16_t sequence_number = header.sequenceNumber;
775
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000776 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100777 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
778 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000779 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000780 const uint8_t* rtx_header = packet + header.headerLength;
781 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
782 }
783
784 if (sequence_number == nacked_sequence_number_) {
785 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000786 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100787 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000788 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000789
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000790 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000791 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000792
stefanff483612015-12-21 03:14:00 -0800793 void ModifyVideoConfigs(
794 VideoSendStream::Config* send_config,
795 std::vector<VideoReceiveStream::Config>* receive_configs,
796 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700797 transport_adapter_.reset(
798 new internal::TransportAdapter(send_config->send_transport));
799 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000800 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000801 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100802 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000803 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
804 }
805
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000806 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100807 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000808 }
809
kwiberg27f982b2016-03-01 11:52:33 -0800810 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000811 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000812 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000813 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000814 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000815 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000816
stefane74eef12016-01-08 06:47:13 -0800817 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000818}
819
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000820TEST_F(VideoSendStreamTest, RetransmitsNack) {
821 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100822 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000823}
824
825TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
826 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000827 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000828}
829
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000830void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
831 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000832 // Use a fake encoder to output a frame of every size in the range [90, 290],
833 // for each size making sure that the exact number of payload bytes received
834 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000835 static const size_t kMaxPacketSize = 128;
836 static const size_t start = 90;
837 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000838
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000839 // Observer that verifies that the expected number of packets and bytes
840 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000841 class FrameFragmentationTest : public test::SendTest,
842 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000843 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000844 FrameFragmentationTest(size_t max_packet_size,
845 size_t start_size,
846 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000847 bool test_generic_packetization,
848 bool use_fec)
849 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000850 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000851 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000852 stop_size_(stop_size),
853 test_generic_packetization_(test_generic_packetization),
854 use_fec_(use_fec),
855 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000856 accumulated_size_(0),
857 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000858 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000859 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000860 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000861 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000862 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700863 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000864 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000865
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000866 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000867 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000868 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000869 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000870 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000871
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000872 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000873
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000874 if (use_fec_) {
875 uint8_t payload_type = packet[header.headerLength];
876 bool is_fec = header.payloadType == kRedPayloadType &&
877 payload_type == kUlpfecPayloadType;
878 if (is_fec) {
879 fec_packet_received_ = true;
880 return SEND_PACKET;
881 }
882 }
883
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000884 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000885
886 if (use_fec_)
887 TriggerLossReport(header);
888
889 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200890 size_t overhead = header.headerLength + header.paddingLength;
891 // Only remove payload header and RED header if the packet actually
892 // contains payload.
893 if (length > overhead) {
894 overhead += (1 /* Generic header */);
895 if (use_fec_)
896 overhead += 1; // RED for FEC header.
897 }
898 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000899 accumulated_payload_ += length - overhead;
900 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000901
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000902 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000903 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000904 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
905 // With FEC enabled, frame size is incremented asynchronously, so
906 // "old" frames one byte too small may arrive. Accept, but don't
907 // increase expected frame size.
908 accumulated_size_ = 0;
909 accumulated_payload_ = 0;
910 return SEND_PACKET;
911 }
912
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000913 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000914 if (test_generic_packetization_) {
915 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
916 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000917
918 // Last packet of frame; reset counters.
919 accumulated_size_ = 0;
920 accumulated_payload_ = 0;
921 if (current_size_rtp_ == stop_size_) {
922 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100923 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000924 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000925 // Increase next expected frame size. If testing with FEC, make sure
926 // a FEC packet has been received for this frame size before
927 // proceeding, to make sure that redundancy packets don't exceed
928 // size limit.
929 if (!use_fec_) {
930 ++current_size_rtp_;
931 } else if (fec_packet_received_) {
932 fec_packet_received_ = false;
933 ++current_size_rtp_;
934 ++current_size_frame_;
935 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000936 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000937 }
938
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000939 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000940 }
941
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000942 void TriggerLossReport(const RTPHeader& header) {
943 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -0700944 const int kLossPercent = 5;
945 if (packet_count_++ % (100 / kLossPercent) != 0) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000946 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -0700947 kVideoSendSsrcs[0], header.sequenceNumber,
948 (packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
949 static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +0200950 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800951 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700952 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000953
pbosda903ea2015-10-02 02:36:56 -0700954 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100955 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000956
957 RTCPSender::FeedbackState feedback_state;
958
959 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
960 }
961 }
962
nisseef8b61e2016-04-29 06:09:15 -0700963 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000964 // Increase frame size for next encoded frame, in the context of the
965 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000966 if (!use_fec_ &&
967 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000968 ++current_size_frame_;
969 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000970 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000971 }
972
Stefan Holmere5904162015-03-26 11:11:06 +0100973 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -0700974 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +0100975 const int kMinBitrateBps = 30000;
976 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
977 return config;
978 }
979
stefanff483612015-12-21 03:14:00 -0800980 void ModifyVideoConfigs(
981 VideoSendStream::Config* send_config,
982 std::vector<VideoReceiveStream::Config>* receive_configs,
983 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700984 transport_adapter_.reset(
985 new internal::TransportAdapter(send_config->send_transport));
986 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000987 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -0700988 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
989 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000990 }
991
992 if (!test_generic_packetization_)
993 send_config->encoder_settings.payload_name = "VP8";
994
995 send_config->encoder_settings.encoder = &encoder_;
996 send_config->rtp.max_packet_size = kMaxPacketSize;
997 send_config->post_encode_callback = this;
998
Erik Språng95261872015-04-10 11:58:49 +0200999 // Make sure there is at least one extension header, to make the RTP
1000 // header larger than the base length of 12 bytes.
1001 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001002
1003 // Setup screen content disables frame dropping which makes this easier.
1004 class VideoStreamFactory
1005 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1006 public:
1007 explicit VideoStreamFactory(size_t num_temporal_layers)
1008 : num_temporal_layers_(num_temporal_layers) {
1009 EXPECT_GT(num_temporal_layers, 0u);
1010 }
1011
1012 private:
1013 std::vector<VideoStream> CreateEncoderStreams(
1014 int width,
1015 int height,
1016 const VideoEncoderConfig& encoder_config) override {
1017 std::vector<VideoStream> streams =
1018 test::CreateVideoStreams(width, height, encoder_config);
1019 for (VideoStream& stream : streams) {
1020 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1021 1);
1022 }
1023 return streams;
1024 }
1025 const size_t num_temporal_layers_;
1026 };
1027
1028 encoder_config->video_stream_factory =
1029 new rtc::RefCountedObject<VideoStreamFactory>(2);
1030 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001031 }
1032
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001033 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001034 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001035 }
1036
kwiberg27f982b2016-03-01 11:52:33 -08001037 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001038 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001039
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001040 const size_t max_packet_size_;
1041 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001042 const bool test_generic_packetization_;
1043 const bool use_fec_;
1044
1045 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001046 size_t accumulated_size_;
1047 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001048 bool fec_packet_received_;
1049
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001050 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001051 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001052 };
1053
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001054 // Don't auto increment if FEC is used; continue sending frame size until
1055 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001056 FrameFragmentationTest test(
1057 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001058
stefane74eef12016-01-08 06:47:13 -08001059 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001060}
1061
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001062// TODO(sprang): Is there any way of speeding up these tests?
1063TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1064 TestPacketFragmentationSize(kGeneric, false);
1065}
1066
1067TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1068 TestPacketFragmentationSize(kGeneric, true);
1069}
1070
1071TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1072 TestPacketFragmentationSize(kVP8, false);
1073}
1074
1075TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1076 TestPacketFragmentationSize(kVP8, true);
1077}
1078
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001079// The test will go through a number of phases.
1080// 1. Start sending packets.
1081// 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 +00001082// suspend the stream.
1083// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001084// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001085// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001086// When the stream is detected again, and the stats show that the stream
1087// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001088TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1089 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001090
nissed30a1112016-04-18 05:15:22 -07001091 class RembObserver : public test::SendTest,
1092 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001093 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001094 RembObserver()
1095 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001096 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001097 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001098 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001099 rtp_count_(0),
1100 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001101 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001102 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001103 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001104
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001105 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001106 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001107 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001108 ++rtp_count_;
1109 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001110 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001111 last_sequence_number_ = header.sequenceNumber;
1112
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001113 if (test_state_ == kBeforeSuspend) {
1114 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001115 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001116 test_state_ = kDuringSuspend;
1117 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001118 if (header.paddingLength == 0) {
1119 // Received non-padding packet during suspension period. Reset the
1120 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001121 suspended_frame_count_ = 0;
1122 }
stefanf116bd02015-10-27 08:29:42 -07001123 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001124 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001125 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001126 // Non-padding packet observed. Test is almost complete. Will just
1127 // have to wait for the stats to change.
1128 test_state_ = kWaitingForStats;
1129 }
stefanf116bd02015-10-27 08:29:42 -07001130 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001131 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001132 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001133 if (stats.suspended == false) {
1134 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001135 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001136 }
stefanf116bd02015-10-27 08:29:42 -07001137 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001138 }
1139
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001140 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001141 }
1142
perkj26091b12016-09-01 01:17:40 -07001143 // This method implements the rtc::VideoSinkInterface. This is called when
1144 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001145 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001146 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001147 if (test_state_ == kDuringSuspend &&
1148 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001149 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001150 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001151 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001152 test_state_ = kWaitingForPacket;
1153 }
1154 }
1155
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001156 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001157 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001158 low_remb_bps_ = value;
1159 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001160
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001161 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001162 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001163 high_remb_bps_ = value;
1164 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001165
stefanff483612015-12-21 03:14:00 -08001166 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001167 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001168 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001169 stream_ = send_stream;
1170 }
1171
stefanff483612015-12-21 03:14:00 -08001172 void ModifyVideoConfigs(
1173 VideoSendStream::Config* send_config,
1174 std::vector<VideoReceiveStream::Config>* receive_configs,
1175 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001176 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001177 transport_adapter_.reset(
1178 new internal::TransportAdapter(send_config->send_transport));
1179 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001180 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001181 send_config->pre_encode_callback = this;
1182 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001183 int min_bitrate_bps =
1184 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001185 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001186 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001187 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001188 min_bitrate_bps + threshold_window + 5000);
1189 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1190 }
1191
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001192 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001193 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001194 }
1195
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001196 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001197 kBeforeSuspend,
1198 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001199 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001200 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001201 };
1202
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001203 virtual void SendRtcpFeedback(int remb_value)
1204 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001205 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1206 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001207 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001208 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001209
pbosda903ea2015-10-02 02:36:56 -07001210 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001211 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001212 if (remb_value > 0) {
1213 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001214 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001215 }
1216 RTCPSender::FeedbackState feedback_state;
1217 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1218 }
1219
kwiberg27f982b2016-03-01 11:52:33 -08001220 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001221 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001222 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001223
Peter Boströmf2f82832015-05-01 13:00:41 +02001224 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001225 TestState test_state_ GUARDED_BY(crit_);
1226 int rtp_count_ GUARDED_BY(crit_);
1227 int last_sequence_number_ GUARDED_BY(crit_);
1228 int suspended_frame_count_ GUARDED_BY(crit_);
1229 int low_remb_bps_ GUARDED_BY(crit_);
1230 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001231 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001232
stefane74eef12016-01-08 06:47:13 -08001233 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001234}
1235
perkj71ee44c2016-06-15 00:47:53 -07001236// This test that padding stops being send after a while if the Camera stops
1237// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001238TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001239 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001240 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001241 NoPaddingWhenVideoIsMuted()
1242 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001243 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001244 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001245 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001246 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001247
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001248 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001249 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001250 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001251 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001252
1253 RTPHeader header;
1254 parser_->Parse(packet, length, &header);
1255 const bool only_padding =
1256 header.headerLength + header.paddingLength == length;
1257
1258 if (test_state_ == kBeforeStopCapture) {
1259 capturer_->Stop();
1260 test_state_ = kWaitingForPadding;
1261 } else if (test_state_ == kWaitingForPadding && only_padding) {
1262 test_state_ = kWaitingForNoPackets;
1263 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1264 only_padding) {
1265 observation_complete_.Set();
1266 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001267 return SEND_PACKET;
1268 }
1269
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001270 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001271 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001272 const int kNoPacketsThresholdMs = 2000;
1273 if (test_state_ == kWaitingForNoPackets &&
1274 (last_packet_time_ms_ > 0 &&
1275 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1276 kNoPacketsThresholdMs)) {
1277 capturer_->Start();
1278 test_state_ = kWaitingForPaddingAfterCameraRestart;
1279 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001280 return SEND_PACKET;
1281 }
1282
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001283 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001284
nisseef8b61e2016-04-29 06:09:15 -07001285 void OnFrameGeneratorCapturerCreated(
1286 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001287 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001288 capturer_ = frame_generator_capturer;
1289 }
1290
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001291 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001292 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001293 << "Timed out while waiting for RTP packets to stop being sent.";
1294 }
1295
perkj71ee44c2016-06-15 00:47:53 -07001296 enum TestState {
1297 kBeforeStopCapture,
1298 kWaitingForPadding,
1299 kWaitingForNoPackets,
1300 kWaitingForPaddingAfterCameraRestart
1301 };
1302
1303 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001304 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001305 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001306 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001307 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1308 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001309 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001310
stefane74eef12016-01-08 06:47:13 -08001311 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001312}
1313
isheriffcc5903e2016-10-04 08:29:38 -07001314TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1315 const int kCapacityKbps = 10000; // 10 Mbps
1316 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1317 public:
1318 PaddingIsPrimarilyRetransmissions()
1319 : EndToEndTest(kDefaultTimeoutMs),
1320 clock_(Clock::GetRealTimeClock()),
1321 padding_length_(0),
1322 total_length_(0),
1323 call_(nullptr) {}
1324
1325 private:
1326 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1327 call_ = sender_call;
1328 }
1329
1330 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1331 rtc::CritScope lock(&crit_);
1332
1333 RTPHeader header;
1334 parser_->Parse(packet, length, &header);
1335 padding_length_ += header.paddingLength;
1336 total_length_ += length;
1337 return SEND_PACKET;
1338 }
1339
1340 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1341 const int kNetworkDelayMs = 50;
1342 FakeNetworkPipe::Config config;
1343 config.loss_percent = 10;
1344 config.link_capacity_kbps = kCapacityKbps;
1345 config.queue_delay_ms = kNetworkDelayMs;
1346 return new test::PacketTransport(sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001347 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001348 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001349 }
1350
1351 void ModifyVideoConfigs(
1352 VideoSendStream::Config* send_config,
1353 std::vector<VideoReceiveStream::Config>* receive_configs,
1354 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001355 // Turn on RTX.
1356 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1357 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001358 }
1359
1360 void PerformTest() override {
1361 // TODO(isheriff): Some platforms do not ramp up as expected to full
1362 // capacity due to packet scheduling delays. Fix that before getting
1363 // rid of this.
1364 SleepMs(5000);
1365 {
1366 rtc::CritScope lock(&crit_);
1367 // Expect padding to be a small percentage of total bytes sent.
1368 EXPECT_LT(padding_length_, .1 * total_length_);
1369 }
1370 }
1371
1372 rtc::CriticalSection crit_;
1373 Clock* const clock_;
1374 size_t padding_length_ GUARDED_BY(crit_);
1375 size_t total_length_ GUARDED_BY(crit_);
1376 Call* call_;
1377 } test;
1378
1379 RunBaseTest(&test);
1380}
1381
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001382// This test first observes "high" bitrate use at which point it sends a REMB to
1383// indicate that it should be lowered significantly. The test then observes that
1384// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1385// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001386//
1387// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1388// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001389TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1390 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001391 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001392 static const int kRembBitrateBps = 80000;
1393 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001394 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001395 public:
1396 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001397 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001398 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1399 stream_(nullptr),
1400 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001401
1402 private:
nisseef8b61e2016-04-29 06:09:15 -07001403 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001404 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001405 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001406
1407 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001408 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001409 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001410 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001411 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001412 if (!stats.substreams.empty()) {
1413 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001414 int total_bitrate_bps =
1415 stats.substreams.begin()->second.total_bitrate_bps;
1416 test::PrintResult("bitrate_stats_",
1417 "min_transmit_bitrate_low_remb",
1418 "bitrate_bps",
1419 static_cast<size_t>(total_bitrate_bps),
1420 "bps",
1421 false);
1422 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001423 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1424 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001425 rtp_rtcp_->Process();
1426 bitrate_capped_ = true;
1427 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001428 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001429 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001430 }
1431 }
stefanf116bd02015-10-27 08:29:42 -07001432 // Packets don't have to be delivered since the test is the receiver.
1433 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001434 }
1435
stefanff483612015-12-21 03:14:00 -08001436 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001437 VideoSendStream* send_stream,
1438 const std::vector<VideoReceiveStream*>& receive_streams) override {
1439 stream_ = send_stream;
1440 RtpRtcp::Configuration config;
1441 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001442 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001443 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1444 rtp_rtcp_->SetREMBStatus(true);
1445 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001446 }
1447
stefanff483612015-12-21 03:14:00 -08001448 void ModifyVideoConfigs(
1449 VideoSendStream::Config* send_config,
1450 std::vector<VideoReceiveStream::Config>* receive_configs,
1451 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001452 feedback_transport_.reset(
1453 new internal::TransportAdapter(send_config->send_transport));
1454 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001455 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001456 }
1457
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001458 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001459 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001460 << "Timeout while waiting for low bitrate stats after REMB.";
1461 }
1462
kwiberg27f982b2016-03-01 11:52:33 -08001463 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1464 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001465 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001466 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001467 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001468 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001469
stefane74eef12016-01-08 06:47:13 -08001470 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001471}
1472
Stefan Holmer280de9e2016-09-30 10:06:51 +02001473TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1474 static const int kStartBitrateBps = 300000;
1475 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001476 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001477 class ChangingNetworkRouteTest : public test::EndToEndTest {
1478 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001479 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001480 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1481 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1482 kRtpExtensionTransportSequenceNumber, kExtensionId));
1483 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001484
1485 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1486 call_ = sender_call;
1487 }
1488
Stefan Holmer280de9e2016-09-30 10:06:51 +02001489 void ModifyVideoConfigs(
1490 VideoSendStream::Config* send_config,
1491 std::vector<VideoReceiveStream::Config>* receive_configs,
1492 VideoEncoderConfig* encoder_config) override {
1493 send_config->rtp.extensions.clear();
1494 send_config->rtp.extensions.push_back(RtpExtension(
1495 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1496 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1497 (*receive_configs)[0].rtp.transport_cc = true;
1498 }
1499
1500 void ModifyAudioConfigs(
1501 AudioSendStream::Config* send_config,
1502 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1503 send_config->rtp.extensions.clear();
1504 send_config->rtp.extensions.push_back(RtpExtension(
1505 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1506 (*receive_configs)[0].rtp.extensions.clear();
1507 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1508 (*receive_configs)[0].rtp.transport_cc = true;
1509 }
1510
Stefan Holmerbe402962016-07-08 16:16:41 +02001511 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1512 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1513 observation_complete_.Set();
1514 }
1515
1516 return SEND_PACKET;
1517 }
1518
1519 void PerformTest() override {
1520 rtc::NetworkRoute new_route(true, 10, 20, -1);
1521 call_->OnNetworkRouteChanged("transport", new_route);
1522 Call::Config::BitrateConfig bitrate_config;
1523 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1524 call_->SetBitrateConfig(bitrate_config);
1525 EXPECT_TRUE(Wait())
1526 << "Timed out while waiting for start bitrate to be exceeded.";
1527
1528 bitrate_config.start_bitrate_bps = -1;
1529 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1530 call_->SetBitrateConfig(bitrate_config);
1531 // TODO(holmer): We should set the last sent packet id here and verify
1532 // that we correctly ignore any packet loss reported prior to that id.
1533 ++new_route.local_network_id;
1534 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001535 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001536 }
1537
1538 private:
1539 Call* call_;
1540 } test;
1541
1542 RunBaseTest(&test);
1543}
1544
michaelt79e05882016-11-08 02:50:09 -08001545TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1546 class ChangingTransportOverheadTest : public test::EndToEndTest {
1547 public:
1548 ChangingTransportOverheadTest()
1549 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1550 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001551 packets_sent_(0),
1552 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001553
1554 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1555 call_ = sender_call;
1556 }
1557
1558 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001559 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001560 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001561 if (++packets_sent_ < 100)
1562 return SEND_PACKET;
1563 observation_complete_.Set();
1564 return SEND_PACKET;
1565 }
1566
michaelta3328772016-11-29 09:25:03 -08001567 void ModifyVideoConfigs(
1568 VideoSendStream::Config* send_config,
1569 std::vector<VideoReceiveStream::Config>* receive_configs,
1570 VideoEncoderConfig* encoder_config) override {
1571 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1572 }
1573
michaelt79e05882016-11-08 02:50:09 -08001574 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08001575 transport_overhead_ = 100;
michaelt79e05882016-11-08 02:50:09 -08001576 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1577 transport_overhead_);
1578 EXPECT_TRUE(Wait());
sprang21253fc2017-02-27 03:35:47 -08001579 {
1580 rtc::CritScope cs(&lock_);
1581 packets_sent_ = 0;
1582 }
michaelta3328772016-11-29 09:25:03 -08001583 transport_overhead_ = 500;
michaelt79e05882016-11-08 02:50:09 -08001584 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1585 transport_overhead_);
1586 EXPECT_TRUE(Wait());
1587 }
1588
1589 private:
1590 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001591 rtc::CriticalSection lock_;
1592 int packets_sent_ GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001593 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001594 const size_t kMaxRtpPacketSize = 1000;
michaelt79e05882016-11-08 02:50:09 -08001595 } test;
1596
1597 RunBaseTest(&test);
1598}
1599
sprangf24a0642017-02-28 13:23:26 -08001600// Test class takes takes as argument a switch selecting if type switch should
1601// occur and a function pointer to reset the send stream. This is necessary
1602// since you cannot change the content type of a VideoSendStream, you need to
1603// recreate it. Stopping and recreating the stream can only be done on the main
1604// thread and in the context of VideoSendStreamTest (not BaseTest).
1605template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001606class MaxPaddingSetTest : public test::SendTest {
1607 public:
1608 static const uint32_t kMinTransmitBitrateBps = 400000;
1609 static const uint32_t kActualEncodeBitrateBps = 40000;
1610 static const uint32_t kMinPacketsToSend = 50;
1611
sprangf24a0642017-02-28 13:23:26 -08001612 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001613 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001614 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001615 call_(nullptr),
1616 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001617 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001618 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001619 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001620 stream_resetter_(stream_reset_fun) {
1621 RTC_DCHECK(stream_resetter_);
1622 }
sprang9c0b5512016-07-06 00:54:28 -07001623
1624 void OnVideoStreamsCreated(
1625 VideoSendStream* send_stream,
1626 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001627 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001628 send_stream_ = send_stream;
1629 }
1630
1631 void ModifyVideoConfigs(
1632 VideoSendStream::Config* send_config,
1633 std::vector<VideoReceiveStream::Config>* receive_configs,
1634 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001635 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001636 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001637 encoder_config->min_transmit_bitrate_bps = 0;
1638 encoder_config->content_type =
1639 VideoEncoderConfig::ContentType::kRealtimeVideo;
1640 } else {
1641 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1642 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1643 }
sprangf24a0642017-02-28 13:23:26 -08001644 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001645 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001646 }
1647
1648 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1649 call_ = sender_call;
1650 }
1651
1652 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1653 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001654 if (running_without_padding_)
1655 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1656
1657 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1658 // we have reliable data.
1659 if (++packets_sent_ < kMinPacketsToSend)
1660 return SEND_PACKET;
1661
1662 if (running_without_padding_) {
1663 // We've sent kMinPacketsToSend packets with default configuration, switch
1664 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001665 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001666 packets_sent_ = 0;
1667 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1668 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001669 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001670 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001671 return SEND_PACKET;
1672 }
1673
1674 // Make sure the pacer has been configured with a min transmit bitrate.
1675 if (call_->GetStats().max_padding_bitrate_bps > 0)
1676 observation_complete_.Set();
1677
1678 return SEND_PACKET;
1679 }
1680
1681 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001682 if (RunningWithoutPadding()) {
1683 ASSERT_TRUE(
1684 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001685 (*stream_resetter_)(send_stream_config_, encoder_config_);
1686 }
1687
sprang9c0b5512016-07-06 00:54:28 -07001688 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1689 }
1690
1691 private:
sprangf24a0642017-02-28 13:23:26 -08001692 bool RunningWithoutPadding() const {
1693 rtc::CritScope lock(&crit_);
1694 return running_without_padding_;
1695 }
1696
sprang9c0b5512016-07-06 00:54:28 -07001697 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001698 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001699 Call* call_;
sprangf24a0642017-02-28 13:23:26 -08001700 VideoSendStream* send_stream_ GUARDED_BY(crit_);
1701 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001702 VideoEncoderConfig encoder_config_;
1703 uint32_t packets_sent_ GUARDED_BY(crit_);
1704 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001705 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001706};
1707
1708TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001709 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1710 const VideoEncoderConfig& encoder_config) {};
1711 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001712 RunBaseTest(&test);
1713}
1714
1715TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001716 // Function for removing and recreating the send stream with a new config.
1717 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1718 const VideoEncoderConfig& encoder_config) {
1719 Stop();
1720 sender_call_->DestroyVideoSendStream(video_send_stream_);
1721 video_send_config_ = send_stream_config.Copy();
1722 video_encoder_config_ = encoder_config.Copy();
1723 video_send_stream_ = sender_call_->CreateVideoSendStream(
1724 video_send_config_.Copy(), video_encoder_config_.Copy());
1725 video_send_stream_->SetSource(
1726 frame_generator_capturer_.get(),
1727 VideoSendStream::DegradationPreference::kMaintainResolution);
1728 Start();
1729 };
1730 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001731 RunBaseTest(&test);
1732}
1733
perkjfa10b552016-10-02 23:45:26 -07001734// This test verifies that new frame sizes reconfigures encoders even though not
1735// (yet) sending. The purpose of this is to permit encoding as quickly as
1736// possible once we start sending. Likely the frames being input are from the
1737// same source that will be sent later, which just means that we're ready
1738// earlier.
1739TEST_F(VideoSendStreamTest,
1740 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1741 class EncoderObserver : public test::FakeEncoder {
1742 public:
1743 EncoderObserver()
1744 : FakeEncoder(Clock::GetRealTimeClock()),
1745 init_encode_called_(false, false),
1746 number_of_initializations_(0),
1747 last_initialized_frame_width_(0),
1748 last_initialized_frame_height_(0) {}
1749
1750 void WaitForResolution(int width, int height) {
1751 {
1752 rtc::CritScope lock(&crit_);
1753 if (last_initialized_frame_width_ == width &&
1754 last_initialized_frame_height_ == height) {
1755 return;
1756 }
1757 }
Erik Språng08127a92016-11-16 16:41:30 +01001758 EXPECT_TRUE(
1759 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001760 {
1761 rtc::CritScope lock(&crit_);
1762 EXPECT_EQ(width, last_initialized_frame_width_);
1763 EXPECT_EQ(height, last_initialized_frame_height_);
1764 }
1765 }
1766
1767 private:
1768 int32_t InitEncode(const VideoCodec* config,
1769 int32_t number_of_cores,
1770 size_t max_payload_size) override {
1771 rtc::CritScope lock(&crit_);
1772 last_initialized_frame_width_ = config->width;
1773 last_initialized_frame_height_ = config->height;
1774 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001775 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001776 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1777 }
1778
1779 int32_t Encode(const VideoFrame& input_image,
1780 const CodecSpecificInfo* codec_specific_info,
1781 const std::vector<FrameType>* frame_types) override {
1782 ADD_FAILURE()
1783 << "Unexpected Encode call since the send stream is not started";
1784 return 0;
1785 }
1786
1787 rtc::CriticalSection crit_;
1788 rtc::Event init_encode_called_;
1789 size_t number_of_initializations_ GUARDED_BY(&crit_);
1790 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1791 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1792 };
1793
philipel4fb651d2017-04-10 03:54:05 -07001794 CreateSenderCall(Call::Config(event_log_.get()));
perkjfa10b552016-10-02 23:45:26 -07001795 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001796 CreateSendConfig(1, 0, 0, &transport);
perkjfa10b552016-10-02 23:45:26 -07001797 EncoderObserver encoder;
1798 video_send_config_.encoder_settings.encoder = &encoder;
1799 CreateVideoStreams();
1800 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1801 kDefaultHeight);
1802 frame_generator_capturer_->Start();
1803
1804 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1805 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1806 kDefaultHeight * 2);
1807 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1808 DestroyStreams();
1809}
1810
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001811TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1812 class StartBitrateObserver : public test::FakeEncoder {
1813 public:
1814 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001815 : FakeEncoder(Clock::GetRealTimeClock()),
1816 start_bitrate_changed_(false, false),
1817 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001818 int32_t InitEncode(const VideoCodec* config,
1819 int32_t number_of_cores,
1820 size_t max_payload_size) override {
1821 rtc::CritScope lock(&crit_);
1822 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001823 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001824 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1825 }
1826
1827 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1828 rtc::CritScope lock(&crit_);
1829 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001830 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001831 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1832 }
1833
1834 int GetStartBitrateKbps() const {
1835 rtc::CritScope lock(&crit_);
1836 return start_bitrate_kbps_;
1837 }
1838
pbos14fe7082016-04-20 06:35:56 -07001839 bool WaitForStartBitrate() {
1840 return start_bitrate_changed_.Wait(
1841 VideoSendStreamTest::kDefaultTimeoutMs);
1842 }
1843
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001844 private:
pbos5ad935c2016-01-25 03:52:44 -08001845 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001846 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001847 int start_bitrate_kbps_ GUARDED_BY(crit_);
1848 };
1849
philipel4fb651d2017-04-10 03:54:05 -07001850 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001851
solenberg4fbae2b2015-08-28 04:07:10 -07001852 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001853 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001854
1855 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001856 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001857 sender_call_->SetBitrateConfig(bitrate_config);
1858
1859 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001860 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001861 // Since this test does not use a capturer, set |internal_source| = true.
1862 // Encoder configuration is otherwise updated on the next video frame.
1863 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001864
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001865 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001866
pbos14fe7082016-04-20 06:35:56 -07001867 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001868 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001869 encoder.GetStartBitrateKbps());
1870
perkjfa10b552016-10-02 23:45:26 -07001871 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001872 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001873
1874 // New bitrate should be reconfigured above the previous max. As there's no
1875 // network connection this shouldn't be flaky, as no bitrate should've been
1876 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001877 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001878 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1879 encoder.GetStartBitrateKbps());
1880
1881 DestroyStreams();
1882}
1883
perkj57c21f92016-06-17 07:27:16 -07001884// This test that if the encoder use an internal source, VideoEncoder::SetRates
1885// will be called with zero bitrate during initialization and that
1886// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1887// with zero bitrate.
1888TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1889 class StartStopBitrateObserver : public test::FakeEncoder {
1890 public:
1891 StartStopBitrateObserver()
1892 : FakeEncoder(Clock::GetRealTimeClock()),
1893 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001894 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001895 int32_t InitEncode(const VideoCodec* config,
1896 int32_t number_of_cores,
1897 size_t max_payload_size) override {
1898 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001899 encoder_init_.Set();
1900 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1901 }
1902
Erik Språng08127a92016-11-16 16:41:30 +01001903 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1904 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001905 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001906 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001907 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001908 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001909 }
1910
1911 bool WaitForEncoderInit() {
1912 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1913 }
Erik Språng08127a92016-11-16 16:41:30 +01001914
1915 bool WaitBitrateChanged(bool non_zero) {
1916 do {
1917 rtc::Optional<int> bitrate_kbps;
1918 {
1919 rtc::CritScope lock(&crit_);
1920 bitrate_kbps = bitrate_kbps_;
1921 }
1922 if (!bitrate_kbps)
1923 continue;
1924
1925 if ((non_zero && *bitrate_kbps > 0) ||
1926 (!non_zero && *bitrate_kbps == 0)) {
1927 return true;
1928 }
1929 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1930 return false;
perkj57c21f92016-06-17 07:27:16 -07001931 }
1932
1933 private:
1934 rtc::CriticalSection crit_;
1935 rtc::Event encoder_init_;
1936 rtc::Event bitrate_changed_;
Erik Språng08127a92016-11-16 16:41:30 +01001937 rtc::Optional<int> bitrate_kbps_ GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001938 };
1939
philipel4fb651d2017-04-10 03:54:05 -07001940 CreateSenderCall(Call::Config(event_log_.get()));
perkj57c21f92016-06-17 07:27:16 -07001941
1942 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001943 CreateSendConfig(1, 0, 0, &transport);
perkj57c21f92016-06-17 07:27:16 -07001944
Sergey Ulanove2b15012016-11-22 16:08:30 -08001945 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
1946
perkj57c21f92016-06-17 07:27:16 -07001947 StartStopBitrateObserver encoder;
1948 video_send_config_.encoder_settings.encoder = &encoder;
1949 video_send_config_.encoder_settings.internal_source = true;
1950
1951 CreateVideoStreams();
1952
1953 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01001954
perkj57c21f92016-06-17 07:27:16 -07001955 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001956 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
1957
perkj57c21f92016-06-17 07:27:16 -07001958 video_send_stream_->Stop();
Erik Språng08127a92016-11-16 16:41:30 +01001959 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
1960
perkj57c21f92016-06-17 07:27:16 -07001961 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001962 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07001963
1964 DestroyStreams();
1965}
1966
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001967TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07001968 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001969 public:
Peter Boström5811a392015-12-10 13:02:50 +01001970 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001971
nissed30a1112016-04-18 05:15:22 -07001972 void OnFrame(const VideoFrame& video_frame) override {
1973 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01001974 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001975 }
1976
1977 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01001978 const int kWaitFrameTimeoutMs = 3000;
1979 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001980 << "Timeout while waiting for output frames.";
1981 }
1982
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001983 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001984 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001985 }
1986
1987 private:
1988 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001989 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001990
1991 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01001992 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001993 };
1994
1995 // Initialize send stream.
philipel4fb651d2017-04-10 03:54:05 -07001996 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001997
solenberg4fbae2b2015-08-28 04:07:10 -07001998 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001999 CreateSendConfig(1, 0, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002000 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08002001 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002002 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002003
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002004 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002005 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002006 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002007 int width = 168;
2008 int height = 132;
2009
Magnus Jedvert90e31902017-06-07 11:32:50 +02002010 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2011 width, height, 1, 1, kVideoRotation_0));
2012 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2013 width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002014 input_frames.push_back(CreateVideoFrame(width, height, 3));
2015 input_frames.push_back(CreateVideoFrame(width, height, 4));
Magnus Jedvert90e31902017-06-07 11:32:50 +02002016 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2017 width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002018
stefanff483612015-12-21 03:14:00 -08002019 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07002020 test::FrameForwarder forwarder;
perkj803d97f2016-11-01 11:45:46 -07002021 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07002022 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002023 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07002024 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002025 // Wait until the output frame is received before sending the next input
2026 // frame. Or the previous input frame may be replaced without delivering.
2027 observer.WaitOutputFrame();
2028 }
stefanff483612015-12-21 03:14:00 -08002029 video_send_stream_->Stop();
perkj803d97f2016-11-01 11:45:46 -07002030 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07002031 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002032
2033 // Test if the input and output frames are the same. render_time_ms and
2034 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002035 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002036
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002037 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002038}
2039
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002040void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2041 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002042 EXPECT_EQ(frames1.size(), frames2.size());
2043 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002044 // Compare frame buffers, since we don't care about differing timestamps.
2045 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2046 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002047}
2048
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002049VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002050 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002051 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002052 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002053 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002054 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002055 // Use data as a ms timestamp.
2056 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002057 return frame;
2058}
2059
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002060TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2061 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2062 public:
2063 EncoderStateObserver()
2064 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002065 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002066 initialized_(false),
2067 callback_registered_(false),
2068 num_releases_(0),
2069 released_(false) {}
2070
2071 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002072 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002073 return released_;
2074 }
2075
2076 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002077 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002078 return initialized_ && callback_registered_;
2079 }
2080
2081 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002082 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002083 return num_releases_;
2084 }
2085
2086 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002087 int32_t InitEncode(const VideoCodec* codecSettings,
2088 int32_t numberOfCores,
2089 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002090 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002091 EXPECT_FALSE(initialized_);
2092 initialized_ = true;
2093 released_ = false;
2094 return 0;
2095 }
2096
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002097 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002098 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002099 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002100 EXPECT_TRUE(IsReadyForEncode());
2101
Peter Boström5811a392015-12-10 13:02:50 +01002102 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002103 return 0;
2104 }
2105
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002106 int32_t RegisterEncodeCompleteCallback(
2107 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002108 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002109 EXPECT_TRUE(initialized_);
2110 callback_registered_ = true;
2111 return 0;
2112 }
2113
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002114 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002115 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002116 EXPECT_TRUE(IsReadyForEncode());
2117 EXPECT_FALSE(released_);
2118 initialized_ = false;
2119 callback_registered_ = false;
2120 released_ = true;
2121 ++num_releases_;
2122 return 0;
2123 }
2124
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002125 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002126 EXPECT_TRUE(IsReadyForEncode());
2127 return 0;
2128 }
2129
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002130 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002131 EXPECT_TRUE(IsReadyForEncode());
2132 return 0;
2133 }
2134
stefanff483612015-12-21 03:14:00 -08002135 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002136 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002137 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002138 stream_ = send_stream;
2139 }
2140
stefanff483612015-12-21 03:14:00 -08002141 void ModifyVideoConfigs(
2142 VideoSendStream::Config* send_config,
2143 std::vector<VideoReceiveStream::Config>* receive_configs,
2144 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002145 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002146 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002147 }
2148
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002149 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002150 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01002151 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07002152 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01002153 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002154 stream_->Stop();
2155 // Encoder should not be released before destroying the VideoSendStream.
2156 EXPECT_FALSE(IsReleased());
2157 EXPECT_TRUE(IsReadyForEncode());
2158 stream_->Start();
2159 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002160 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002161 }
2162
Peter Boströmf2f82832015-05-01 13:00:41 +02002163 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002164 VideoSendStream* stream_;
2165 bool initialized_ GUARDED_BY(crit_);
2166 bool callback_registered_ GUARDED_BY(crit_);
2167 size_t num_releases_ GUARDED_BY(crit_);
2168 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002169 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002170 } test_encoder;
2171
stefane74eef12016-01-08 06:47:13 -08002172 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002173
2174 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002175 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002176}
2177
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002178TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2179 class VideoCodecConfigObserver : public test::SendTest,
2180 public test::FakeEncoder {
2181 public:
2182 VideoCodecConfigObserver()
2183 : SendTest(kDefaultTimeoutMs),
2184 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002185 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002186 num_initializations_(0),
2187 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002188
2189 private:
stefanff483612015-12-21 03:14:00 -08002190 void ModifyVideoConfigs(
2191 VideoSendStream::Config* send_config,
2192 std::vector<VideoReceiveStream::Config>* receive_configs,
2193 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002194 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002195 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002196 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002197 }
2198
stefanff483612015-12-21 03:14:00 -08002199 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002200 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002201 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002202 stream_ = send_stream;
2203 }
2204
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002205 int32_t InitEncode(const VideoCodec* config,
2206 int32_t number_of_cores,
2207 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002208 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002209 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002210 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002211 } else {
2212 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002213 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002214 }
2215 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002216 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002217 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2218 }
2219
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002220 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002221 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002222 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002223
sprangf24a0642017-02-28 13:23:26 -08002224 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002225 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002226 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002227 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002228 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2229 "new encoder settings.";
2230 }
2231
sprangf24a0642017-02-28 13:23:26 -08002232 const uint32_t kFirstMaxBitrateBps = 1000000;
2233 const uint32_t kSecondMaxBitrateBps = 2000000;
2234
pbos14fe7082016-04-20 06:35:56 -07002235 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002236 size_t num_initializations_;
2237 VideoSendStream* stream_;
2238 VideoEncoderConfig encoder_config_;
2239 } test;
2240
stefane74eef12016-01-08 06:47:13 -08002241 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002242}
2243
Peter Boström53eda3d2015-03-27 15:53:18 +01002244static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2245template <typename T>
2246class VideoCodecConfigObserver : public test::SendTest,
2247 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002248 public:
2249 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2250 const char* codec_name)
2251 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2252 FakeEncoder(Clock::GetRealTimeClock()),
2253 video_codec_type_(video_codec_type),
2254 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002255 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002256 num_initializations_(0),
2257 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002258 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2259 }
2260
2261 private:
perkjfa10b552016-10-02 23:45:26 -07002262 class VideoStreamFactory
2263 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2264 public:
2265 VideoStreamFactory() {}
2266
2267 private:
2268 std::vector<VideoStream> CreateEncoderStreams(
2269 int width,
2270 int height,
2271 const VideoEncoderConfig& encoder_config) override {
2272 std::vector<VideoStream> streams =
2273 test::CreateVideoStreams(width, height, encoder_config);
2274 for (size_t i = 0; i < streams.size(); ++i) {
2275 streams[i].temporal_layer_thresholds_bps.resize(
2276 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2277 }
2278 return streams;
2279 }
2280 };
2281
stefanff483612015-12-21 03:14:00 -08002282 void ModifyVideoConfigs(
2283 VideoSendStream::Config* send_config,
2284 std::vector<VideoReceiveStream::Config>* receive_configs,
2285 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002286 send_config->encoder_settings.encoder = this;
2287 send_config->encoder_settings.payload_name = codec_name_;
2288
kthelgason29a44e32016-09-27 03:52:02 -07002289 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002290 encoder_config->video_stream_factory =
2291 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002292 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002293 }
2294
stefanff483612015-12-21 03:14:00 -08002295 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002296 VideoSendStream* send_stream,
2297 const std::vector<VideoReceiveStream*>& receive_streams) override {
2298 stream_ = send_stream;
2299 }
2300
2301 int32_t InitEncode(const VideoCodec* config,
2302 int32_t number_of_cores,
2303 size_t max_payload_size) override {
2304 EXPECT_EQ(video_codec_type_, config->codecType);
2305 VerifyCodecSpecifics(*config);
2306 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002307 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002308 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2309 }
2310
2311 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002312 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2313 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002314
2315 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002316 EXPECT_TRUE(
2317 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002318 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002319
2320 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002321 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002322 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002323 ASSERT_TRUE(
2324 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002325 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002326 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2327 "new encoder settings.";
2328 }
2329
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002330 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002331 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002332 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002333 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2334 return 0;
2335 }
2336
2337 T encoder_settings_;
2338 const VideoCodecType video_codec_type_;
2339 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002340 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002341 size_t num_initializations_;
2342 VideoSendStream* stream_;
2343 VideoEncoderConfig encoder_config_;
2344};
2345
2346template <>
2347void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2348 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002349 EXPECT_EQ(
2350 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002351}
kthelgason29a44e32016-09-27 03:52:02 -07002352
2353template <>
2354rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2355VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2356 return new rtc::RefCountedObject<
2357 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2358}
2359
Peter Boström53eda3d2015-03-27 15:53:18 +01002360template <>
2361void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2362 const VideoCodec& config) const {
2363 // Check that the number of temporal layers has propagated properly to
2364 // VideoCodec.
2365 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002366 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002367
2368 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2369 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2370 config.simulcastStream[i].numberOfTemporalLayers);
2371 }
2372
2373 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002374 // reconfiguring the encoder and not match the set config. Also copy the
2375 // TemporalLayersFactory pointer that has been injected by ViEEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002376 VideoCodecVP8 encoder_settings = encoder_settings_;
2377 encoder_settings.numberOfTemporalLayers =
2378 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002379 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002380 EXPECT_EQ(
2381 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002382}
kthelgason29a44e32016-09-27 03:52:02 -07002383
2384template <>
2385rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2386VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2387 return new rtc::RefCountedObject<
2388 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2389}
2390
Peter Boström53eda3d2015-03-27 15:53:18 +01002391template <>
2392void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2393 const VideoCodec& config) const {
2394 // Check that the number of temporal layers has propagated properly to
2395 // VideoCodec.
2396 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002397 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002398
2399 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2400 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2401 config.simulcastStream[i].numberOfTemporalLayers);
2402 }
2403
2404 // Set expected temporal layers as they should have been set when
2405 // reconfiguring the encoder and not match the set config.
2406 VideoCodecVP9 encoder_settings = encoder_settings_;
2407 encoder_settings.numberOfTemporalLayers =
2408 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002409 EXPECT_EQ(
2410 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002411}
2412
kthelgason29a44e32016-09-27 03:52:02 -07002413template <>
2414rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2415VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2416 return new rtc::RefCountedObject<
2417 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2418}
2419
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002420TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002421 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002422 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002423}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002424
Peter Boström53eda3d2015-03-27 15:53:18 +01002425TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2426 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002427 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002428}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002429
Peter Boström53eda3d2015-03-27 15:53:18 +01002430TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2431 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002432 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002433}
2434
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002435TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002436 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002437 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002438 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2439 rtp_packets_sent_(0),
2440 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002441
2442 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002443 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002444 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002445 RTPHeader header;
2446 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002447 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002448 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2449 return SEND_PACKET;
2450 }
2451
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002452 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002453 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002454 test::RtcpPacketParser parser;
2455 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002456
danilchap3dc929e2016-11-02 08:21:59 -07002457 if (parser.sender_report()->num_packets() > 0) {
2458 // Only compare sent media bytes if SenderPacketCount matches the
2459 // number of sent rtp packets (a new rtp packet could be sent before
2460 // the rtcp packet).
2461 if (parser.sender_report()->sender_octet_count() > 0 &&
2462 parser.sender_report()->sender_packet_count() ==
2463 rtp_packets_sent_) {
2464 EXPECT_EQ(media_bytes_sent_,
2465 parser.sender_report()->sender_octet_count());
2466 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002467 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002468 }
2469
2470 return SEND_PACKET;
2471 }
2472
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002473 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002474 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002475 }
2476
stefan4b569042015-11-11 06:39:57 -08002477 rtc::CriticalSection crit_;
2478 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2479 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002480 } test;
2481
stefane74eef12016-01-08 06:47:13 -08002482 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002483}
2484
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002485TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2486 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002487
2488 class VideoStreamFactory
2489 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2490 public:
2491 VideoStreamFactory() {}
2492
2493 private:
2494 std::vector<VideoStream> CreateEncoderStreams(
2495 int width,
2496 int height,
2497 const VideoEncoderConfig& encoder_config) override {
2498 std::vector<VideoStream> streams =
2499 test::CreateVideoStreams(width, height, encoder_config);
2500 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2501 streams[0].temporal_layer_thresholds_bps.push_back(
2502 kScreencastTargetBitrateKbps * 1000);
2503 return streams;
2504 }
2505 };
2506
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002507 class ScreencastTargetBitrateTest : public test::SendTest,
2508 public test::FakeEncoder {
2509 public:
2510 ScreencastTargetBitrateTest()
2511 : SendTest(kDefaultTimeoutMs),
2512 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2513
2514 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002515 int32_t InitEncode(const VideoCodec* config,
2516 int32_t number_of_cores,
2517 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002518 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2519 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002520 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002521 return test::FakeEncoder::InitEncode(
2522 config, number_of_cores, max_payload_size);
2523 }
stefanff483612015-12-21 03:14:00 -08002524 void ModifyVideoConfigs(
2525 VideoSendStream::Config* send_config,
2526 std::vector<VideoReceiveStream::Config>* receive_configs,
2527 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002528 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002529 EXPECT_EQ(1u, encoder_config->number_of_streams);
2530 encoder_config->video_stream_factory =
2531 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002532 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002533 }
2534
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002535 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002536 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002537 << "Timed out while waiting for the encoder to be initialized.";
2538 }
2539 } test;
2540
stefane74eef12016-01-08 06:47:13 -08002541 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002542}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002543
philipelc6957c72016-04-28 15:52:49 +02002544TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002545 // These are chosen to be "kind of odd" to not be accidentally checked against
2546 // default values.
2547 static const int kMinBitrateKbps = 137;
2548 static const int kStartBitrateKbps = 345;
2549 static const int kLowerMaxBitrateKbps = 312;
2550 static const int kMaxBitrateKbps = 413;
2551 static const int kIncreasedStartBitrateKbps = 451;
2552 static const int kIncreasedMaxBitrateKbps = 597;
2553 class EncoderBitrateThresholdObserver : public test::SendTest,
2554 public test::FakeEncoder {
2555 public:
2556 EncoderBitrateThresholdObserver()
2557 : SendTest(kDefaultTimeoutMs),
2558 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002559 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002560 bitrate_changed_event_(false, false),
2561 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002562 num_initializations_(0),
2563 call_(nullptr),
2564 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002565
2566 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002567 int32_t InitEncode(const VideoCodec* codecSettings,
2568 int32_t numberOfCores,
2569 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002570 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2571 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002572 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002573 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2574 codecSettings->minBitrate);
2575 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2576 codecSettings->startBitrate);
2577 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2578 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002579 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002580 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002581 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2582 codecSettings->maxBitrate);
2583 // The start bitrate should be kept (-1) and capped to the max bitrate.
2584 // Since this is not an end-to-end call no receiver should have been
2585 // returning a REMB that could lower this estimate.
2586 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002587 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002588 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2589 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002590 // The start bitrate will be whatever the rate BitRateController
2591 // has currently configured but in the span of the set max and min
2592 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002593 }
2594 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002595 init_encode_event_.Set();
2596
pbos@webrtc.org00873182014-11-25 14:03:34 +00002597 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2598 maxPayloadSize);
2599 }
2600
Erik Språng08127a92016-11-16 16:41:30 +01002601 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2602 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002603 {
2604 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002605 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2606 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002607 }
Erik Språng08127a92016-11-16 16:41:30 +01002608 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002609 }
2610 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002611 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002612 }
2613
2614 void WaitForSetRates(uint32_t expected_bitrate) {
2615 EXPECT_TRUE(
2616 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2617 << "Timed out while waiting encoder rate to be set.";
2618 rtc::CritScope lock(&crit_);
2619 EXPECT_EQ(expected_bitrate, target_bitrate_);
2620 }
2621
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002622 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002623 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002624 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2625 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2626 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002627 return config;
2628 }
2629
perkjfa10b552016-10-02 23:45:26 -07002630 class VideoStreamFactory
2631 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2632 public:
2633 explicit VideoStreamFactory(int min_bitrate_bps)
2634 : min_bitrate_bps_(min_bitrate_bps) {}
2635
2636 private:
2637 std::vector<VideoStream> CreateEncoderStreams(
2638 int width,
2639 int height,
2640 const VideoEncoderConfig& encoder_config) override {
2641 std::vector<VideoStream> streams =
2642 test::CreateVideoStreams(width, height, encoder_config);
2643 streams[0].min_bitrate_bps = min_bitrate_bps_;
2644 return streams;
2645 }
2646
2647 const int min_bitrate_bps_;
2648 };
2649
stefanff483612015-12-21 03:14:00 -08002650 void ModifyVideoConfigs(
2651 VideoSendStream::Config* send_config,
2652 std::vector<VideoReceiveStream::Config>* receive_configs,
2653 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002654 send_config->encoder_settings.encoder = this;
2655 // Set bitrates lower/higher than min/max to make sure they are properly
2656 // capped.
perkjfa10b552016-10-02 23:45:26 -07002657 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2658 // Create a new StreamFactory to be able to set
2659 // |VideoStream.min_bitrate_bps|.
2660 encoder_config->video_stream_factory =
2661 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002662 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002663 }
2664
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002665 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002666 call_ = sender_call;
2667 }
2668
stefanff483612015-12-21 03:14:00 -08002669 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002670 VideoSendStream* send_stream,
2671 const std::vector<VideoReceiveStream*>& receive_streams) override {
2672 send_stream_ = send_stream;
2673 }
2674
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002675 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002676 ASSERT_TRUE(
2677 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002678 << "Timed out while waiting for encoder to be configured.";
2679 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002680 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002681 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2682 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2683 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002684 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2685 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002686 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002687 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002688 ASSERT_TRUE(
2689 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002690 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002691 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002692 WaitForSetRates(kLowerMaxBitrateKbps);
2693
2694 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2695 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2696 ASSERT_TRUE(
2697 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002698 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002699 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002700 // Expected target bitrate is the start bitrate set in the call to
2701 // call_->SetBitrateConfig.
2702 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002703 }
2704
pbos14fe7082016-04-20 06:35:56 -07002705 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002706 rtc::Event bitrate_changed_event_;
2707 rtc::CriticalSection crit_;
2708 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002709
pbos@webrtc.org00873182014-11-25 14:03:34 +00002710 int num_initializations_;
2711 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002712 webrtc::VideoSendStream* send_stream_;
2713 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002714 } test;
2715
stefane74eef12016-01-08 06:47:13 -08002716 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002717}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002718
2719TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2720 static const size_t kNumStreams = 3;
2721 // Unusual resolutions to make sure that they are the ones being reported.
2722 static const struct {
2723 int width;
2724 int height;
2725 } kEncodedResolution[kNumStreams] = {
2726 {241, 181}, {300, 121}, {121, 221}};
2727 class ScreencastTargetBitrateTest : public test::SendTest,
2728 public test::FakeEncoder {
2729 public:
2730 ScreencastTargetBitrateTest()
2731 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002732 test::FakeEncoder(Clock::GetRealTimeClock()),
2733 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002734
2735 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002736 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002737 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002738 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002739 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002740 specifics.codecType = kVideoCodecGeneric;
2741
2742 uint8_t buffer[16] = {0};
2743 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2744 encoded._timeStamp = input_image.timestamp();
2745 encoded.capture_time_ms_ = input_image.render_time_ms();
2746
2747 for (size_t i = 0; i < kNumStreams; ++i) {
2748 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2749 encoded._frameType = (*frame_types)[i];
2750 encoded._encodedWidth = kEncodedResolution[i].width;
2751 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002752 EncodedImageCallback* callback;
2753 {
2754 rtc::CritScope cs(&crit_sect_);
2755 callback = callback_;
2756 }
2757 RTC_DCHECK(callback);
2758 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002759 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002760 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002761 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002762 }
2763
Peter Boström5811a392015-12-10 13:02:50 +01002764 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002765 return 0;
2766 }
stefanff483612015-12-21 03:14:00 -08002767 void ModifyVideoConfigs(
2768 VideoSendStream::Config* send_config,
2769 std::vector<VideoReceiveStream::Config>* receive_configs,
2770 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002771 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002772 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002773 }
2774
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002775 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002776
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002777 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002778 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002779 << "Timed out while waiting for the encoder to send one frame.";
2780 VideoSendStream::Stats stats = send_stream_->GetStats();
2781
2782 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002783 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002784 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002785 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002786 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002787 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002788 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002789 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2790 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002791 }
2792 }
2793
stefanff483612015-12-21 03:14:00 -08002794 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002795 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002796 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002797 send_stream_ = send_stream;
2798 }
2799
2800 VideoSendStream* send_stream_;
2801 } test;
2802
stefane74eef12016-01-08 06:47:13 -08002803 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002804}
philipel0f9af012015-09-01 07:01:51 -07002805
Peter Boström12996152016-05-14 02:03:18 +02002806#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002807class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002808 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002809 Vp9HeaderObserver()
2810 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002811 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002812 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2813 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002814 frames_sent_(0),
2815 expected_width_(0),
2816 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002817
stefanff483612015-12-21 03:14:00 -08002818 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002819 VideoSendStream::Config* send_config,
2820 std::vector<VideoReceiveStream::Config>* receive_configs,
2821 VideoEncoderConfig* encoder_config) {}
2822
Åsa Perssonff24c042015-12-04 10:58:08 +01002823 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002824
2825 private:
minyue20c84cc2017-04-10 16:57:57 -07002826 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002827
perkjfa10b552016-10-02 23:45:26 -07002828 class VideoStreamFactory
2829 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2830 public:
2831 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2832 : number_of_temporal_layers_(number_of_temporal_layers) {}
2833
2834 private:
2835 std::vector<VideoStream> CreateEncoderStreams(
2836 int width,
2837 int height,
2838 const VideoEncoderConfig& encoder_config) override {
2839 std::vector<VideoStream> streams =
2840 test::CreateVideoStreams(width, height, encoder_config);
2841 streams[0].temporal_layer_thresholds_bps.resize(
2842 number_of_temporal_layers_ - 1);
2843 return streams;
2844 }
2845
2846 const size_t number_of_temporal_layers_;
2847 };
2848
stefanff483612015-12-21 03:14:00 -08002849 void ModifyVideoConfigs(
2850 VideoSendStream::Config* send_config,
2851 std::vector<VideoReceiveStream::Config>* receive_configs,
2852 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002853 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002854 send_config->encoder_settings.payload_name = "VP9";
2855 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002856 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002857 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2858 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002859 EXPECT_EQ(1u, encoder_config->number_of_streams);
2860 encoder_config->video_stream_factory =
2861 new rtc::RefCountedObject<VideoStreamFactory>(
2862 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002863 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002864 }
2865
perkjfa10b552016-10-02 23:45:26 -07002866 void ModifyVideoCaptureStartResolution(int* width,
2867 int* height,
2868 int* frame_rate) override {
2869 expected_width_ = *width;
2870 expected_height_ = *height;
2871 }
2872
philipel0f9af012015-09-01 07:01:51 -07002873 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002874 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2875 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002876 }
2877
2878 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2879 RTPHeader header;
2880 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2881
Åsa Perssonff24c042015-12-04 10:58:08 +01002882 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2883 const uint8_t* payload = packet + header.headerLength;
2884 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002885
Åsa Perssonff24c042015-12-04 10:58:08 +01002886 bool new_packet = packets_sent_ == 0 ||
2887 IsNewerSequenceNumber(header.sequenceNumber,
2888 last_header_.sequenceNumber);
2889 if (payload_length > 0 && new_packet) {
2890 RtpDepacketizer::ParsedPayload parsed;
2891 RtpDepacketizerVp9 depacketizer;
2892 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2893 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2894 // Verify common fields for all configurations.
2895 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2896 CompareConsecutiveFrames(header, parsed.type.Video);
2897 // Verify configuration specific settings.
2898 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002899
Åsa Perssonff24c042015-12-04 10:58:08 +01002900 ++packets_sent_;
2901 if (header.markerBit) {
2902 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002903 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002904 last_header_ = header;
2905 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002906 }
philipel0f9af012015-09-01 07:01:51 -07002907 return SEND_PACKET;
2908 }
2909
philipel7fabd462015-09-03 04:42:32 -07002910 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002911 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2912 if (last_vp9_.picture_id > vp9.picture_id) {
2913 return vp9.picture_id == 0; // Wrap.
2914 } else {
2915 return vp9.picture_id == last_vp9_.picture_id + 1;
2916 }
2917 }
2918
2919 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002920 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2921 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2922 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2923 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2924 vp9.spatial_idx);
2925 }
2926
2927 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2928 uint8_t num_layers) const {
2929 switch (num_layers) {
2930 case 0:
2931 VerifyTemporalLayerStructure0(vp9);
2932 break;
2933 case 1:
2934 VerifyTemporalLayerStructure1(vp9);
2935 break;
2936 case 2:
2937 VerifyTemporalLayerStructure2(vp9);
2938 break;
2939 case 3:
2940 VerifyTemporalLayerStructure3(vp9);
2941 break;
2942 default:
2943 RTC_NOTREACHED();
2944 }
2945 }
2946
2947 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2948 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2949 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2950 EXPECT_FALSE(vp9.temporal_up_switch);
2951 }
2952
2953 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2954 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2955 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2956 EXPECT_FALSE(vp9.temporal_up_switch);
2957 }
2958
2959 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2960 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2961 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2962 EXPECT_LE(vp9.temporal_idx, 1);
2963 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2964 if (IsNewPictureId(vp9)) {
2965 uint8_t expected_tid =
2966 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
2967 EXPECT_EQ(expected_tid, vp9.temporal_idx);
2968 }
2969 }
2970
2971 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
2972 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2973 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
2974 EXPECT_LE(vp9.temporal_idx, 2);
2975 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
2976 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
2977 switch (vp9.temporal_idx) {
2978 case 0:
2979 EXPECT_EQ(2, last_vp9_.temporal_idx);
2980 EXPECT_FALSE(vp9.temporal_up_switch);
2981 break;
2982 case 1:
2983 EXPECT_EQ(2, last_vp9_.temporal_idx);
2984 EXPECT_TRUE(vp9.temporal_up_switch);
2985 break;
2986 case 2:
2987 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
2988 break;
2989 }
2990 }
2991 }
2992
2993 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
2994 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
2995 return;
2996
2997 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
2998 if (vp9.temporal_idx == 0)
2999 ++expected_tl0_idx;
3000 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3001 }
3002
3003 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3004 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3005 }
3006
3007 // Flexible mode (F=1): Non-flexible mode (F=0):
3008 //
3009 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3010 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3011 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3012 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3013 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3014 // M: | EXTENDED PID | M: | EXTENDED PID |
3015 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3016 // L: | T |U| S |D| L: | T |U| S |D|
3017 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3018 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3019 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3020 // X: |EXTENDED P_DIFF| V: | SS .. |
3021 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3022 // V: | SS .. |
3023 // +-+-+-+-+-+-+-+-+
3024 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3025 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3026 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3027 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
3028 EXPECT_GE(vp9.spatial_idx, 0); // S
3029 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3030 if (vp9.ss_data_available) // V
3031 VerifySsData(vp9);
3032
3033 if (frames_sent_ == 0)
3034 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3035
3036 if (!vp9.inter_pic_predicted) {
3037 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3038 EXPECT_FALSE(vp9.temporal_up_switch);
3039 }
3040 }
3041
3042 // Scalability structure (SS).
3043 //
3044 // +-+-+-+-+-+-+-+-+
3045 // V: | N_S |Y|G|-|-|-|
3046 // +-+-+-+-+-+-+-+-+
3047 // Y: | WIDTH | N_S + 1 times
3048 // +-+-+-+-+-+-+-+-+
3049 // | HEIGHT |
3050 // +-+-+-+-+-+-+-+-+
3051 // G: | N_G |
3052 // +-+-+-+-+-+-+-+-+
3053 // N_G: | T |U| R |-|-| N_G times
3054 // +-+-+-+-+-+-+-+-+
3055 // | P_DIFF | R times
3056 // +-+-+-+-+-+-+-+-+
3057 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3058 EXPECT_TRUE(vp9.ss_data_available); // V
3059 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3060 vp9.num_spatial_layers);
3061 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003062 int expected_width = expected_width_;
3063 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003064 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003065 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3066 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3067 expected_width /= 2;
3068 expected_height /= 2;
3069 }
3070 }
3071
3072 void CompareConsecutiveFrames(const RTPHeader& header,
3073 const RTPVideoHeader& video) const {
3074 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3075
3076 bool new_frame = packets_sent_ == 0 ||
3077 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003078 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003079 if (!new_frame) {
3080 EXPECT_FALSE(last_header_.markerBit);
3081 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3082 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3083 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3084 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3085 VerifySpatialIdxWithinFrame(vp9);
3086 return;
3087 }
3088 // New frame.
3089 EXPECT_TRUE(vp9.beginning_of_frame);
3090
3091 // Compare with last packet in previous frame.
3092 if (frames_sent_ == 0)
3093 return;
3094 EXPECT_TRUE(last_vp9_.end_of_frame);
3095 EXPECT_TRUE(last_header_.markerBit);
3096 EXPECT_TRUE(ContinuousPictureId(vp9));
3097 VerifyTl0Idx(vp9);
3098 }
3099
kwiberg27f982b2016-03-01 11:52:33 -08003100 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003101 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003102 webrtc::VideoEncoderConfig encoder_config_;
3103 RTPHeader last_header_;
3104 RTPVideoHeaderVP9 last_vp9_;
3105 size_t packets_sent_;
3106 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003107 int expected_width_;
3108 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003109};
3110
Åsa Perssonff24c042015-12-04 10:58:08 +01003111TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3112 const uint8_t kNumTemporalLayers = 1;
3113 const uint8_t kNumSpatialLayers = 1;
3114 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3115}
3116
3117TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3118 const uint8_t kNumTemporalLayers = 2;
3119 const uint8_t kNumSpatialLayers = 1;
3120 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3121}
3122
3123TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3124 const uint8_t kNumTemporalLayers = 3;
3125 const uint8_t kNumSpatialLayers = 1;
3126 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3127}
3128
3129TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3130 const uint8_t kNumTemporalLayers = 1;
3131 const uint8_t kNumSpatialLayers = 2;
3132 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3133}
3134
3135TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3136 const uint8_t kNumTemporalLayers = 2;
3137 const uint8_t kNumSpatialLayers = 2;
3138 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3139}
3140
3141TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3142 const uint8_t kNumTemporalLayers = 3;
3143 const uint8_t kNumSpatialLayers = 2;
3144 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3145}
3146
3147void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3148 uint8_t num_spatial_layers) {
3149 static const size_t kNumFramesToSend = 100;
3150 // Set to < kNumFramesToSend and coprime to length of temporal layer
3151 // structures to verify temporal id reset on key frame.
3152 static const int kKeyFrameInterval = 31;
3153 class NonFlexibleMode : public Vp9HeaderObserver {
3154 public:
3155 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3156 : num_temporal_layers_(num_temporal_layers),
3157 num_spatial_layers_(num_spatial_layers),
3158 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003159 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003160 VideoSendStream::Config* send_config,
3161 std::vector<VideoReceiveStream::Config>* receive_configs,
3162 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003163 vp9_settings_.flexibleMode = false;
3164 vp9_settings_.frameDroppingOn = false;
3165 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3166 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3167 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003168 }
3169
Åsa Perssonff24c042015-12-04 10:58:08 +01003170 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
3171 bool ss_data_expected = !vp9.inter_pic_predicted &&
3172 vp9.beginning_of_frame && vp9.spatial_idx == 0;
3173 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
3174 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08003175 EXPECT_EQ(!vp9.inter_pic_predicted,
3176 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003177
3178 if (IsNewPictureId(vp9)) {
3179 EXPECT_EQ(0, vp9.spatial_idx);
3180 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
3181 }
3182
3183 VerifyFixedTemporalLayerStructure(vp9,
3184 l_field_ ? num_temporal_layers_ : 0);
3185
3186 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003187 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003188 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003189 const uint8_t num_temporal_layers_;
3190 const uint8_t num_spatial_layers_;
3191 const bool l_field_;
3192 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003193
stefane74eef12016-01-08 06:47:13 -08003194 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003195}
3196
asaperssond9f641e2016-01-21 01:11:35 -08003197TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3198 static const size_t kNumFramesToSend = 50;
3199 static const int kWidth = 4;
3200 static const int kHeight = 4;
3201 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3202 void ModifyVideoConfigsHook(
3203 VideoSendStream::Config* send_config,
3204 std::vector<VideoReceiveStream::Config>* receive_configs,
3205 VideoEncoderConfig* encoder_config) override {
3206 vp9_settings_.flexibleMode = false;
3207 vp9_settings_.numberOfTemporalLayers = 1;
3208 vp9_settings_.numberOfSpatialLayers = 1;
3209
perkjfa10b552016-10-02 23:45:26 -07003210 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003211 }
3212
3213 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3214 if (frames_sent_ > kNumFramesToSend)
3215 observation_complete_.Set();
3216 }
perkjfa10b552016-10-02 23:45:26 -07003217
3218 void ModifyVideoCaptureStartResolution(int* width,
3219 int* height,
3220 int* frame_rate) override {
3221 expected_width_ = kWidth;
3222 expected_height_ = kHeight;
3223 *width = kWidth;
3224 *height = kHeight;
3225 }
asaperssond9f641e2016-01-21 01:11:35 -08003226 } test;
3227
3228 RunBaseTest(&test);
3229}
3230
kjellanderf9e2a362017-03-24 12:17:33 -07003231#if defined(WEBRTC_ANDROID)
3232// Crashes on Android; bugs.webrtc.org/7401
3233#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3234#else
3235#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3236#endif
3237TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003238 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003239 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003240 VideoSendStream::Config* send_config,
3241 std::vector<VideoReceiveStream::Config>* receive_configs,
3242 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003243 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003244 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003245 vp9_settings_.numberOfTemporalLayers = 1;
3246 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003247 }
3248
Åsa Perssonff24c042015-12-04 10:58:08 +01003249 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3250 EXPECT_TRUE(vp9_header.flexible_mode);
3251 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3252 if (vp9_header.inter_pic_predicted) {
3253 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003254 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003255 }
3256 }
3257 } test;
3258
stefane74eef12016-01-08 06:47:13 -08003259 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003260}
Peter Boström12996152016-05-14 02:03:18 +02003261#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003262
perkj803d97f2016-11-01 11:45:46 -07003263void VideoSendStreamTest::TestRequestSourceRotateVideo(
3264 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003265 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003266
3267 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003268 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003269 video_send_config_.rtp.extensions.clear();
3270 if (support_orientation_ext) {
3271 video_send_config_.rtp.extensions.push_back(
3272 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3273 }
3274
3275 CreateVideoStreams();
3276 test::FrameForwarder forwarder;
3277 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003278 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003279
3280 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3281 support_orientation_ext);
3282
3283 DestroyStreams();
3284}
3285
3286TEST_F(VideoSendStreamTest,
3287 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3288 TestRequestSourceRotateVideo(false);
3289}
3290
3291TEST_F(VideoSendStreamTest,
3292 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3293 TestRequestSourceRotateVideo(true);
3294}
3295
michaelta3328772016-11-29 09:25:03 -08003296// This test verifies that overhead is removed from the bandwidth estimate by
3297// testing that the maximum possible target payload rate is smaller than the
3298// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003299TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003300 test::ScopedFieldTrials override_field_trials(
3301 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3302 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3303 public test::FakeEncoder {
3304 public:
3305 RemoveOverheadFromBandwidthTest()
3306 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3307 FakeEncoder(Clock::GetRealTimeClock()),
3308 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003309 max_bitrate_bps_(0),
3310 first_packet_sent_(false),
3311 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003312
3313 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3314 uint32_t frameRate) override {
3315 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003316 // Wait for the first sent packet so that videosendstream knows
3317 // rtp_overhead.
3318 if (first_packet_sent_) {
3319 max_bitrate_bps_ = bitrate.get_sum_bps();
3320 bitrate_changed_event_.Set();
3321 }
michaelta3328772016-11-29 09:25:03 -08003322 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3323 }
3324
3325 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3326 call_ = sender_call;
3327 }
3328
3329 void ModifyVideoConfigs(
3330 VideoSendStream::Config* send_config,
3331 std::vector<VideoReceiveStream::Config>* receive_configs,
3332 VideoEncoderConfig* encoder_config) override {
3333 send_config->rtp.max_packet_size = 1200;
3334 send_config->encoder_settings.encoder = this;
3335 EXPECT_FALSE(send_config->rtp.extensions.empty());
3336 }
3337
michaelt192132e2017-01-26 09:05:27 -08003338 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3339 rtc::CritScope lock(&crit_);
3340 first_packet_sent_ = true;
3341 return SEND_PACKET;
3342 }
3343
michaelta3328772016-11-29 09:25:03 -08003344 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003345 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003346 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003347 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003348 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003349 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3350 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003351 bitrate_config.min_bitrate_bps = kMinBitrateBps;
michaelta3328772016-11-29 09:25:03 -08003352 call_->SetBitrateConfig(bitrate_config);
michaelt273f31b2017-02-08 08:21:52 -08003353 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
michaelta3328772016-11-29 09:25:03 -08003354
3355 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003356 // overhead of 40B per packet video produces 2240bps overhead.
3357 // So the encoder BW should be set to 57760bps.
3358 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003359 {
3360 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003361 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003362 }
3363 }
3364
3365 private:
3366 Call* call_;
3367 rtc::CriticalSection crit_;
michaelt192132e2017-01-26 09:05:27 -08003368 uint32_t max_bitrate_bps_ GUARDED_BY(&crit_);
3369 bool first_packet_sent_ GUARDED_BY(&crit_);
3370 rtc::Event bitrate_changed_event_;
michaelta3328772016-11-29 09:25:03 -08003371 } test;
3372
3373 RunBaseTest(&test);
3374}
3375
sprang168794c2017-07-06 04:38:06 -07003376TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3377 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003378
3379 class KeepaliveObserver : public test::SendTest {
3380 public:
3381 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3382
sprange5c4a812017-07-11 03:44:17 -07003383 Call::Config GetSenderCallConfig() override {
3384 Call::Config config = SendTest::GetSenderCallConfig();
3385 config.keepalive_config.timeout_interval_ms = kTimeoutMs;
3386 config.keepalive_config.payload_type =
3387 CallTest::kDefaultKeepalivePayloadType;
3388 return config;
3389 }
3390
sprang168794c2017-07-06 04:38:06 -07003391 private:
3392 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3393 RTPHeader header;
3394 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3395
sprangd2702ef2017-07-10 08:41:10 -07003396 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003397 // The video stream has started. Stop it now.
3398 if (capturer_)
3399 capturer_->Stop();
3400 } else {
3401 observation_complete_.Set();
3402 }
3403
3404 return SEND_PACKET;
3405 }
3406
sprang168794c2017-07-06 04:38:06 -07003407 void PerformTest() override {
3408 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3409 }
3410
3411 void OnFrameGeneratorCapturerCreated(
3412 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3413 capturer_ = frame_generator_capturer;
3414 }
3415
3416 test::FrameGeneratorCapturer* capturer_ = nullptr;
3417 } test;
3418
3419 RunBaseTest(&test);
3420}
3421
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003422} // namespace webrtc